0

Have a widget that's currently filtering a set of categories, and need to make it support more than one set of categories.

Right now the code is something like this:

$query_args = array(
            'post_type' => 'product',
            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'product_cat',
                    'field' => 'slug',
                    'terms' => $categories,
                    'operator' => 'AND',
                ),
            ),
        );

So, basically, it's filtering products that have x, y and z categories. Now I need it to filter products that have x and y, OR x and z. I've sketched this:

        $query_args = array(
            'post_type' => 'product',
            'tax_query' => array(
                'relation' => 'AND'
            ),
        );

        if(is_array($tags)){
            $query_args['tax_query']['relation'] = 'OR';
            foreach($tags as $tagGroup){
                array_push($query_args['tax_query'], array(
                    'taxonomy' => 'product_cat',
                    'field' => 'slug',
                    'terms' => implode(',', $tagGroup),
                    'operator' => 'AND'
                ));
            }
        }else{
            array_push($query_args['tax_query'], array(
                'taxonomy' => 'product_cat',
                'field' => 'slug',
                'terms' => $categories,
                'operator' => 'AND',
            ));
        }

But it's still not filtering products as I need. What am I doing wrong?

2 Answers 2

1

You can nest your tax queries. Just make sure you use OR as the first relation and AND relation on the nested tax queries.

$filter_group_a = array(
  'relation' => 'AND',
  array(
    'taxonomy' => 'product_cat',
    'field'    => 'slug',
    'terms'    => $term_a,
  ),
  array(
    'taxonomy' => 'product_cat',
    'field'    => 'slug',
    'terms'    => $term_b,
  ),
);

$filter_group_b = array(
  'relation' => 'AND',
  array(
    'taxonomy' => 'product_cat',
    'field'    => 'slug',
    'terms'    => $term_a,
  ),
  array(
    'taxonomy' => 'product_cat',
    'field'    => 'slug',
    'terms'    => $term_c,
  ),
)

$query_args = array(
  'tax_query' => array(
    'relation' => 'OR',
    $filter_group_a,
    $filter_group_b,
  )
);

You could write some fancy loop that builds the $filter_groups and pushes them to the $query_args['tax_query'] array.

0

you can nest multiple tax queries like so:

$query_args = array(
        'post_type' => 'product',
        'tax_query' => [
            'relation' => 'OR',
            [
                [
                    'taxonomy' => 'product_cat',
                    'field' => 'slug',
                    'terms' => $x_y,
                    'operator' => 'AND',
                ],
            ],
            [
                'relation' => 'AND',
                [
                    'taxonomy' => 'product_cat',
                    'field' => 'slug',
                    'terms' => $x_z,
                    'operator' => 'AND',
                ],
                [
                    'taxonomy' => 'something_something',
                    'field' => 'slug',
                    'terms' => $z,
                    'operator' => 'AND',
                ]
            ],

        ],
    );

i took your example code, so not sure about all the values you have there, but basically you can combine AND and OR.. more info here

3
  • There is no such 'operator' parameter value like 'AND'.
    – Max Yudin
    Commented Jul 10, 2019 at 16:44
  • the operator IN means "has one of the values from the terms table", the operator AND means "has all the values from the terms table"
    – nmr
    Commented Jul 11, 2019 at 5:20
  • @MaxYudin if would read, you would know better: first off, i say, that i'm not sure about the parameters that the questioner is using, i'm just copying his stuff. second i link to the docs, and yeah, the operator does exist.. <3
    – honk31
    Commented Jul 11, 2019 at 9:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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