我编写了一个非常复杂的脚本,它基本上允许用户从类别、标签以及搜索词中进行选择。然后通过WP\\u查询运行这些参数。
我可以使用“AND”关系成功地获得我想要的结果,这适用于用户将搜索参数填充到所有字段的情况;搜索词、标记和;类别。它还可以将三个参数中的一个参数留空,两个参数留空,并在所有参数留空时返回所有产品。
然后,我尝试添加一个选项来使用关系“OR”。这将允许他们仍然添加三个搜索参数,但结果只需应用于其中一个参数。如果用户仅从标记和类别中进行选择,则此操作有效,但是如果用户使用搜索词参数,则不会返回正确的结果。
我认为这是因为关系只设置为标签和类别,我需要将其扩展到搜索词。
希望您能够理解我试图实现的目标,在我的代码片段中,您可以假设所有变量的填充都是正确的,我只是想寻求帮助,将搜索项添加为关系为“OR”的参数。以下是我当前的WP\\U查询:
$paged = !empty($_POST[\'page\']) ? $_POST[\'page\'] : 1;
$display_count = !empty($_POST[\'display_count\']) ? $_POST[\'display_count\'] : 9;
$direction = !empty($_POST[\'direction\']) ? $_POST[\'direction\'] : \'\';
$search_term = !empty($_POST[\'search_term\']) ? $_POST[\'search_term\'] : \'\';
$search_tags = !empty($_POST[\'search_tags\']) ? $_POST[\'search_tags\'] : \'\';
$search_categories = !empty($_POST[\'search_categories\']) ? $_POST[\'search_categories\'] : \'\';
$search_relation = !empty($_POST[\'search_relation\']) ? $_POST[\'search_relation\'] : \'AND\';
$offset_modifier = 0;
if ($direction === \'prev\') :
$offset_modifier = $paged - 2;
elseif ($direction === \'next\') :
$offset_modifier = $paged;
elseif ($direction === \'last\') :
$offset_modifier = $paged - 1;
endif;
$offsetcalc = $offset_modifier * $display_count;
$args = array(
\'post_type\' => \'product\',
\'post_status\' => \'publish\',
\'orderby\' => \'menu_order\',
\'order\' => \'ASC\',
\'posts_per_page\' => $display_count,
\'page\' => $paged,
\'offset\' => $offsetcalc,
\'tax_query\' => array()
);
if ( $search_term != \'\' ) :
$args[\'s\'] = $search_term;
endif;
if ( $search_tags != \'\' ) :
$args[\'tax_query\'][\'product_tag\'] = array(
\'taxonomy\' => \'product_tag\',
\'field\' => \'slug\',
\'terms\' => array($search_tags),
);
if (strpos($search_tags, \', \') !== false) {
$args[\'tax_query\'][\'product_tag\'][\'relation\'] = $search_relation;
}
endif;
if ( $search_categories != \'\' ) :
$args[\'tax_query\'][\'product_cat\'] = array(
\'taxonomy\' => \'product_cat\',
\'field\' => \'slug\',
\'terms\' => array($search_categories),
);
if (strpos($search_categories, \', \') !== false) {
$args[\'tax_query\'][\'product_cat\'][\'relation\'] = $search_relation;
}
endif;
if ( $search_tags != \'\' && $search_categories != \'\' ) :
$args[\'tax_query\'][\'relation\'] = $search_relation;
endif;
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
因此,我尽最大努力使其在搜索词上具有“OR”的关系(请注意“if($search\\u term!=“”)):“;以及对$args[\'tax\\u query\'][\'relation\']=$搜索\\u关系"E;IF语句):
$paged = !empty($_POST[\'page\']) ? $_POST[\'page\'] : 1;
$display_count = !empty($_POST[\'display_count\']) ? $_POST[\'display_count\'] : 9;
$direction = !empty($_POST[\'direction\']) ? $_POST[\'direction\'] : \'\';
$search_term = !empty($_POST[\'search_term\']) ? $_POST[\'search_term\'] : \'\';
$search_tags = !empty($_POST[\'search_tags\']) ? $_POST[\'search_tags\'] : \'\';
$search_categories = !empty($_POST[\'search_categories\']) ? $_POST[\'search_categories\'] : \'\';
$search_relation = !empty($_POST[\'search_relation\']) ? $_POST[\'search_relation\'] : \'AND\';
$offset_modifier = 0;
if ($direction === \'prev\') :
$offset_modifier = $paged - 2;
elseif ($direction === \'next\') :
$offset_modifier = $paged;
elseif ($direction === \'last\') :
$offset_modifier = $paged - 1;
endif;
$offsetcalc = $offset_modifier * $display_count;
$args = array(
\'post_type\' => \'product\',
\'post_status\' => \'publish\',
\'orderby\' => \'menu_order\',
\'order\' => \'ASC\',
\'posts_per_page\' => $display_count,
\'page\' => $paged,
\'offset\' => $offsetcalc,
\'tax_query\' => array()
);
if ( $search_term != \'\' ) :
$args[\'tax_query\'][\'product_tit\'] = array(
\'taxonomy\' => \'product_tit\',
\'field\' => \'slug\',
\'terms\' => $search_term,
);
endif;
if ( $search_tags != \'\' ) :
$args[\'tax_query\'][\'product_tag\'] = array(
\'taxonomy\' => \'product_tag\',
\'field\' => \'slug\',
\'terms\' => array($search_tags),
);
if (strpos($search_tags, \', \') !== false) {
$args[\'tax_query\'][\'product_tag\'][\'relation\'] = $search_relation;
}
endif;
if ( $search_categories != \'\' ) :
$args[\'tax_query\'][\'product_cat\'] = array(
\'taxonomy\' => \'product_cat\',
\'field\' => \'slug\',
\'terms\' => array($search_categories),
);
if (strpos($search_categories, \', \') !== false) {
$args[\'tax_query\'][\'product_cat\'][\'relation\'] = $search_relation;
}
endif;
if ((isset($search_term) && isset($search_tags)) || (isset($search_term) && isset($search_categories)) || (isset($search_tags) && isset($search_categories))) :
$args[\'tax_query\'][\'relation\'] = $search_relation;
endif;
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
我的更改不允许搜索词参数工作,我想我使用了错误的方法或错误的分类名称“product\\u tit”。。。
Please help me create the search term as a parameter with the \'OR\' relation and ensure it is narrowed down to the products title only
有人能帮忙吗?
非常感谢贡献者Jason。
编辑:不使用“或”关系的最新代码。
// PRODUCT PAGINATION AJAX FUNCTION
function load_products_by_ajax_callback() {
$paged = !empty($_POST[\'page\']) ? $_POST[\'page\'] : 1;
$display_count = !empty($_POST[\'display_count\']) ? $_POST[\'display_count\'] : 9;
$direction = !empty($_POST[\'direction\']) ? $_POST[\'direction\'] : \'\';
$search_term = !empty($_POST[\'search_term\']) ? $_POST[\'search_term\'] : \'\';
$search_tags = !empty($_POST[\'search_tags\']) ? $_POST[\'search_tags\'] : \'\';
$search_categories = !empty($_POST[\'search_categories\']) ? $_POST[\'search_categories\'] : \'\';
$search_relation = !empty($_POST[\'search_relation\']) ? $_POST[\'search_relation\'] : \'AND\';
$offset_modifier = 0;
if ($direction === \'prev\') :
$offset_modifier = $paged - 2;
elseif ($direction === \'next\') :
$offset_modifier = $paged;
elseif ($direction === \'last\') :
$offset_modifier = $paged - 1;
endif;
$offsetcalc = $offset_modifier * $display_count;
$args = array(
\'post_type\' => \'product\',
\'post_status\' => \'publish\',
\'orderby\' => \'menu_order\',
\'order\' => \'ASC\',
\'posts_per_page\' => $display_count,
\'page\' => $paged,
\'offset\' => $offsetcalc >= 1 ? $offsetcalc : \'\',
\'tax_query\' => array()
);
// Parse the search tags/categories list into an array.
$tags = strlen( $search_tags ) ? wp_parse_slug_list( $search_tags ) : \'\';
$cats = strlen( $search_categories ) ? wp_parse_slug_list( $search_categories ) : \'\';
$has_search_term = ( strlen( $search_term ) > 0 );
$relation = strtoupper( trim( $search_relation ) ); // normalize it into all caps
// We don\'t use $args[\'s\']. Instead, we write our own custom SQL for searching
// in the post title only. We also don\'t use the tax_query parameter (anymore).
// This is basically $args[\'tax_query\'], except that we *don\'t* add it to $args.
$tax_query = array();
if ( ! empty( $search_tags ) ) {
$tax_query[] = array(
\'taxonomy\' => \'product_tag\',
\'terms\' => wp_parse_slug_list( $search_tags ),
\'field\' => \'slug\',
\'operator\' => $search_relation,
);
}
if ( ! empty( $search_categories ) ) {
$tax_query[] = array(
\'taxonomy\' => \'product_cat\',
\'terms\' => wp_parse_slug_list( $search_categories ),
\'field\' => \'slug\',
\'operator\' => $search_relation,
);
}
if ( ! empty( $tax_query ) ) { // if empty, don\'t set the relation
$tax_query[\'relation\'] = $search_relation;
}
$_filter = true; // a (private) var for the closure below
add_filter( \'posts_clauses\',
function ( $clauses ) use ( &$_filter, $search_term, $tax_query ) {
if ( ! $_filter ) {
return $clauses;
}
global $wpdb;
$search_where = \'\';
if ( $search_term ) {
$like = \'%\' . $wpdb->esc_like( $search_term ) . \'%\';
$search_where = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $like );
}
if ( ! empty( $tax_query ) ) {
$tax_query = new WP_Tax_Query( $tax_query );
$is_and = ( \'AND\' === $tax_query->relation );
$tax_query = $tax_query->get_sql( $wpdb->posts, \'ID\' );
if ( empty( $tax_query[\'where\'] ) ) { // just in case..
if ( $search_where ) {
$clauses[\'where\'] .= " AND ( $search_where )";
}
return $clauses;
}
$clauses[\'join\'] .= $tax_query[\'join\'];
if ( $is_and ) {
$clauses[\'where\'] .= $search_where ?
" AND ( $search_where ) {$tax_query[\'where\']}" :
$tax_query[\'where\'];
} else {
$where = preg_replace( \'/^ *AND\\b/\', \'\', $tax_query[\'where\'] );
$clauses[\'where\'] .= $search_where ?
" AND ( ( $search_where ) OR{$where} )" :
$tax_query[\'where\'];
}
$clauses[\'groupby\'] = "$wpdb->posts.ID";
} elseif ( $search_where ) {
$clauses[\'where\'] .= " AND ( $search_where )";
}
return $clauses;
} );
$the_query = new WP_Query( $args );
$_filter = false;
if ( $the_query->have_posts() ) :
woocommerce_product_loop_start();
echo \'<div id="product-list" class="product-list">\';
while ( $the_query->have_posts() ) :
$the_query->the_post();
wc_get_template_part( \'content\', \'productloop\' );
endwhile;
echo \'</div>\';
woocommerce_product_loop_end();
else :
echo \'<div class="no-search-results">This search returned no results, please refine your parameters!</div>\';
endif;
$product_loop_count = $the_query->found_posts;
echo \'<div class="product-list-count">\';
echo \'<div class="product-loop-count-text">Total product count: </div><div id="product-loop-count">\' . $product_loop_count . \'</div>\';
echo \'</div>\';
wp_die();
}
add_action(\'wp_ajax_load_products_by_ajax\', \'load_products_by_ajax_callback\');
add_action(\'wp_ajax_nopriv_load_products_by_ajax\', \'load_products_by_ajax_callback\');
// END PRODUCT PAGINATION AJAX FUNCTION
最合适的回答,由SO网友:Sally CJ 整理而成
(Revised on March 25 2020 UTC)
在这个修改后的答案中,我将从代码开始:
定义变量:(我故意只包括$args
零件)
// define POSTed/submitted variables here like $paged, $display_count and $direction
// define the offset/\'direction\' stuff here
// then define your $args array
$args = array(
\'post_type\' => \'product\',
\'post_status\' => \'publish\',
\'orderby\' => \'menu_order\',
\'order\' => \'ASC\',
\'posts_per_page\' => $display_count,
// You should use \'paged\' and not \'page\'.
\'paged\' => $paged,
\'offset\' => $offsetcalc >= 1 ? $offsetcalc : \'\',
\'tax_query\' => array(),
);
这里是“搜索词或”的主代码:
// This is basically $args[\'tax_query\'], except that we *don\'t* add it to $args.
$tax_query = array();
if ( ! empty( $search_tags ) ) {
$tax_query[] = array(
\'taxonomy\' => \'product_tag\',
\'terms\' => wp_parse_slug_list( $search_tags ),
\'field\' => \'slug\',
);
}
if ( ! empty( $search_categories ) ) {
$tax_query[] = array(
\'taxonomy\' => \'product_cat\',
\'terms\' => wp_parse_slug_list( $search_categories ),
\'field\' => \'slug\',
);
}
if ( ! empty( $tax_query ) ) { // if empty, don\'t set the relation
$tax_query[\'relation\'] = $search_relation;
}
$_filter = true; // a (private) var for the closure below
add_filter( \'posts_clauses\',
function ( $clauses ) use ( &$_filter, $search_term, $tax_query ) {
if ( ! $_filter ) {
return $clauses;
}
global $wpdb;
$search_where = \'\';
if ( $search_term ) {
$like = \'%\' . $wpdb->esc_like( $search_term ) . \'%\';
$search_where = $wpdb->prepare( "$wpdb->posts.post_title LIKE %s", $like );
}
if ( ! empty( $tax_query ) ) {
$tax_query = new WP_Tax_Query( $tax_query );
$is_and = ( \'AND\' === $tax_query->relation );
$tax_query = $tax_query->get_sql( $wpdb->posts, \'ID\' );
if ( empty( $tax_query[\'where\'] ) ) { // just in case..
if ( $search_where ) {
$clauses[\'where\'] .= " AND ( $search_where )";
}
return $clauses;
}
$clauses[\'join\'] .= $tax_query[\'join\'];
if ( $is_and ) {
$clauses[\'where\'] .= $search_where ?
" AND ( $search_where ) {$tax_query[\'where\']}" :
$tax_query[\'where\'];
} else {
$where = preg_replace( \'/^ *AND\\b/\', \'\', $tax_query[\'where\'] );
$clauses[\'where\'] .= $search_where ?
" AND ( ( $search_where ) OR{$where} )" :
$tax_query[\'where\'];
}
$clauses[\'groupby\'] = "$wpdb->posts.ID";
} elseif ( $search_where ) {
$clauses[\'where\'] .= " AND ( $search_where )";
}
return $clauses;
} );
$the_query = new WP_Query( $args );
$_filter = false; // disable the filter, to avoid issues with other WP_Query calls
一点解释(对于上面的代码#2)
您要找的是
WHERE
类似以下内容的子句:
(还有其他条件/变化,但这是主要条件)
WHERE post_type = \'product\' AND (
( post_title LIKE \'%<search term>%\' ) # Find posts that matched the search term,
OR ( product_tag IN (<ids/slugs>) ) # ..or those that are in the specified tags
OR ( product_cat IN (<ids/slugs>) ) # ..or categories.
)
在上面的代码#2中,我使用
posts_clauses
hook 补充一下
WHERE
子句(并做其他相关的事情),但是为了为分类法(标记/类别)查询生成适当的SQL子句,我使用
WP_Tax_Query
(这是什么
WP_Query
使用,顺便说一句)。
我正在使用的其他注释wp_parse_slug_list()
将(逗号分隔的)标记和类别解析为一个slug数组。您还应该使用它来确保我们有一个有效的数组,因为该函数运行良好
记住如果offset
是0
, 然后在$args
, 这个offset
应设置为\'\'
(即空字符串)而不是0
, 确保$paged
按预期工作。只是一张个人便条。。。对不起,我忘了使用WP_Tax_Query
之前。;)