In my WP_Query I'd like to have a tax query and a meta query, but I want the results to include results that match the tax query AND/OR the meta query - if I do it like the below, then it only returns posts that match both the tax qury and meta query.
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $product_cats_to_show,
'include_children' => true
),
),
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'color',
'value' => 'red',
'compare' => '!=',
)
)
);
The above returns products that have a color
of red
AND products of those categories. I want it to be AND/OR, not just AND. I.E. I want the query to return all products with color
of red
and all products that are in the categories specified in the tax query.
Is this possible using WP_Query args? Or do I need to build a custom query?
Thanks
This question already has an answer here: WP_Query to show post from a category OR custom field (1 answer) Closed 5 years ago.In my WP_Query I'd like to have a tax query and a meta query, but I want the results to include results that match the tax query AND/OR the meta query - if I do it like the below, then it only returns posts that match both the tax qury and meta query.
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $product_cats_to_show,
'include_children' => true
),
),
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'color',
'value' => 'red',
'compare' => '!=',
)
)
);
The above returns products that have a color
of red
AND products of those categories. I want it to be AND/OR, not just AND. I.E. I want the query to return all products with color
of red
and all products that are in the categories specified in the tax query.
Is this possible using WP_Query args? Or do I need to build a custom query?
Thanks
Share Improve this question asked Dec 22, 2017 at 10:33 Dan.Dan. 8561 gold badge7 silver badges10 bronze badges 01 Answer
Reset to default 0It's not possible without a more custom query/filter.
I have achieved it with a filter (code taken from this guy on this gist - https://gist.github/elvismdev/61f8509eff8abcc21ef84154b74fbf56)
function f1_egpaf_meta_or_tax( $where, \WP_Query $q ) {
// Get query vars.
$tax_args = isset( $q->query_vars['tax_query'] ) ? $q->query_vars['tax_query'] : null;
$meta_args = isset( $q->query_vars['meta_query'] ) ? $q->query_vars['meta_query'] : null;
$meta_or_tax = isset( $q->query_vars['_meta_or_tax'] ) ? wp_validate_boolean( $q->query_vars['_meta_or_tax'] ) : false;
// Construct the "tax OR meta" query.
if ( $meta_or_tax && is_array( $tax_args ) && is_array( $meta_args ) ) {
global $wpdb;
// Primary id column.
$field = 'ID';
// Tax query.
$sql_tax = get_tax_sql( $tax_args, $wpdb->posts, $field );
// Meta query.
$sql_meta = get_meta_sql( $meta_args, 'post', $wpdb->posts, $field );
// Modify the 'where' part.
if ( isset( $sql_meta['where'] ) && isset( $sql_tax['where'] ) ) {
$where = str_replace(
[ $sql_meta['where'], $sql_tax['where'] ],
'',
$where
);
$where .= sprintf(
' AND ( %s OR %s ) ',
substr( trim( $sql_meta['where'] ), 4 ),
substr( trim( $sql_tax['where'] ), 4 )
);
}
}
return $where;
}
add_filter( 'posts_where', 'f1_egpaf_meta_or_tax', PHP_INT_MAX, 2 );
Then, just add '_meta_or_tax'
=>trueto the
argsarray passed to
WP_Query()`