duanlang0025 2019-04-14 16:44
浏览 89

WP_Query中的Meta_Query数组使用高级自定义字段(动态用于多个过滤字段)wordpress - php

I am going to try and explain this the best that I can but I find it rather complex and out of my comfort zone. I have spent a week trying to find the answers online and I have hit a snag.

Backstory : I am building a tool that can filter custom post types by all of the custom fields attached to that custom post type, and also custom fields attached to other custom post types via the "Relationship" field of ACF (advanced custom fields). You can see it here : roottiedev.wpengine.com/strains

I have most everything working so far. The user can use the filter sidebar to select any of the fields and values they want to filter by. The javascript applies these fields to the URL string. ex) https://roottiedev.wpengine.com/strains?feelings_$_feeling=Happy

Because some custom fields are 2 dimensional (repeater or group fields in ACF) I have to use the above example, with a $ between the parent key and child key.

There is a rewrite ever since wordpress 4.8.3 where ACF tells you that you have to change the _$ to a _%. You can see the documentation here : (scroll down to point 4.) https://www.advancedcustomfields.com/resources/query-posts-custom-fields/

This all works, as long as I am using one field. It seems like the second I try to do multiple fields, or the second I try to use a field that doesn't use a 'meta_compare' of "LIKE" (for example, on the filters you will see I have two slider select bars that say "THC %" and "CBD %") that everything fails. The sliders don't use a compare of "LIKE" they are using either ">=" or "<=" instead.

My $_GET in my functions.php to rewrite the "add_action('pre_get_posts', 'my_pre_get_posts');" seems to work just fine using IF statements, but again, could also be the cause of it not working on multiple fields.

Ok, so hopefully that explains what I am attempting to do. Here is the code snippets that I feel are relevant.


    // START THE CUSTOM LOOP
remove_action( 'genesis_loop', 'genesis_do_loop' );
add_action('genesis_loop', 'roottie_strains', 10);
function roottie_strains () {

// grab the meta query relation. Will all fields be 'and' or 'or'
$meta_query = array( 'relation' => 'AND' );

// loop through $meta_query to grab key and values
foreach ( wp_parse_args( $query_string ) as $key => $value ) {
$meta_query[] = array( 'key' => $key, 'value' => $value );
}


$args = array(
'posts_per_page' => 18,
'post_type' => 'strains',
'post_status' => 'publish',
'order' => ASC,
'paged' => get_query_var( 'paged' ),
'meta_query' => $meta_query,
);




// https://www.advancedcustomfields.com/resources/query-posts-custom-fields/
// THIS IS APPARENTLY NEEDED DUE TO CHANGES IN ESC_SQL() FOR WORDPRESS 4.8.3. WE CHANGE _$_ TO _%_ INSTEAD
add_filter('posts_where', 'my_posts_where');
function my_posts_where( $where ) {
/* if( isset($_GET['feelings_$_feeling']) ) {
$where = str_replace("meta_key = 'feelings_$", "meta_key LIKE 'feelings_%", $where);
return $where;
} */

$rootkeys[] = $_GET;
global $wpdb; //TESTING
foreach($rootkeys as $rootkey) {
foreach($rootkey as $key => $value) {
$partialkey = explode("$",$key);
$keya = $partialkey[0];
$keyb = 'meta_key = \''.$keya.'$';
$keyc = 'meta_key LIKE \''.$keya.'%'; //this = was LIKE, should it be?
// $where = str_replace($keyb, $keyc, $where);
$where = str_replace($keyb, $keyc, $wpdb->remove_placeholder_escape($where));
}
}
return $where;


}

Then, for the functions.php file, here is my rewrite :

// GET URL STRING FOR FILTERING ON ANY POST. FILTER WP_QUERY BY URL STRING EX roottie.com/brands?field=blue
add_action('pre_get_posts', 'my_pre_get_posts');
function my_pre_get_posts( $query ) {

// do not modify queries in the admin
// 
if( is_admin() ) {
return $query;  
}



// only modify queries for 'strains' post type
// 
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'strains' ) {
// allow the url to alter the query
if( isset($_GET['strain_type']) ) {
$query->set('meta_key', 'strain_type');
$query->set('meta_value', $_GET['strain_type']);
}
if( isset($_GET['feelings_$_feeling']) ) {
$query->set('meta_key', 'feelings_$_feeling');
$query->set('meta_value', $_GET['feelings_$_feeling']);
} 
if( isset($_GET['medical_use_$_medical']) ) {
$query->set('meta_key', 'medical_use_$_medical');
$query->set('meta_value', $_GET['medical_use_$_medical']);
}
if( isset($_GET['sflavours_$_sflavour']) ) {
$query->set('meta_key', 'sflavours_$_sflavour');
$query->set('meta_value', $_GET['sflavours_$_sflavour']);
} 
if( isset($_GET['thc_min']) ) {
$query->set('meta_key', 'thc_min');
$query->set('meta_value', $_GET['thc_min']);
$query->set('meta_compare', '>=');
$query->set('meta_type', 'NUMERIC');
}
if( isset($_GET['thc_max']) ) {
$query->set('meta_key', 'thc_max');
$query->set('meta_value', $_GET['thc_max']);
$query->set('meta_compare', '<=');
$query->set('meta_type', 'NUMERIC');
} 
if( isset($_GET['cbd_min']) ) {
$query->set('meta_key', 'cbd_min');
$query->set('meta_value', $_GET['cbd_min']);
$query->set('meta_compare', '>=');
$query->set('meta_type', 'NUMERIC');
}
if( isset($_GET['cbd_max']) ) {
$query->set('meta_key', 'cbd_max');
$query->set('meta_value', $_GET['cbd_max']);
$query->set('meta_compare', '<=');
$query->set('meta_type', 'NUMERIC');
}
}




// return
return $query;
}

Any help or point in the right direction would be huge! I can't figure out if the issue is with the "compare" or if the issue is in looping through all of the fields in the meta_query re-write for version 4.8.3 (where we take feelings_$ and rewrite it to feelings_%

For an example of an output, if we use this url :

https://roottiedev.wpengine.com/strains?thc_min=5&thc_max=20&cbd_min=5&cbd_max=20&feelings_$_feeling=Uplifted

The is the dump of the wp_query

SELECT SQL_CALC_FOUND_ROWS wp_roottie_posts.ID FROM wp_roottie_posts INNER JOIN wp_roottie_postmeta ON ( wp_roottie_posts.ID = wp_roottie_postmeta.post_id ) WHERE 1=1 AND ( ( wp_roottie_postmeta.meta_key = 'thc_max' AND CAST(wp_roottie_postmeta.meta_value AS SIGNED) <= '20' ) ) AND wp_roottie_posts.post_type = 'strains' AND ((wp_roottie_posts.post_status = 'publish')) GROUP BY wp_roottie_posts.ID ORDER BY wp_roottie_posts.post_date ASC LIMIT 0, 18

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 基于卷积神经网络的声纹识别
    • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
    • ¥100 为什么这个恒流源电路不能恒流?
    • ¥15 有偿求跨组件数据流路径图
    • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
    • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
    • ¥15 CSAPPattacklab
    • ¥15 一直显示正在等待HID—ISP
    • ¥15 Python turtle 画图
    • ¥15 stm32开发clion时遇到的编译问题