1

This question already has an answer here:

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

marked as duplicate by birgire, fuxia Aug 21 at 13:57

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

0

It'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.com/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 theargsarray passed toWP_Query()`

Not the answer you're looking for? Browse other questions tagged or ask your own question.