Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to use the WP_Query class to filter some of my posts. The problem I facing now is handling the taxonomy query. Normally, the wp_query only handle one relationship for tax_query (either AND or OR), but what I need is mixed use of theses relationship on the tax_query, how can achieve it?
eg

'tax_query' => array(
        'relation' => 'AND',
        array(
            'taxonomy' => 'taxonomy1',
            'field' => 'slug',
            'terms' => array( $term)
        ),
        array(
            'taxonomy' => 'taxonomy3',
            'field' => 'slug',
            'terms' => 'terms' => array( $term3),
            'operator' => 'IN',
        )
       // below i want to use OR relationship
       'relation' => 'OR',
      array(
            'taxonomy' => 'taxonomy4',
            'field' => 'slug',
            'terms' => array( $term4)
        ),
        array(
            'taxonomy' => 'taxonomy2',
            'field' => 'slug',
            'terms' => 'terms' => array( $term2),
            'operator' => 'IN',
        )
    )  

I know the code above is not working, do I need to use wp_query filter to do it? Any idea?

share|improve this question

1 Answer 1

This can be done by using the term_taxonomy_id rather than the slug, which will effectively ignore whichever taxonomy is specified and just look at the unique term_taxonomy_id field. This will allow you to effectively be able to do a mixed relationship. You'd want to use an overall relation of AND and put all the terms that should be related OR in one item using the IN operator. You will need to map the terms desired to their term_taxonomy_ids first.

$taxes = array( 'taxonomy1', 'taxonomy2', 'taxonomy3', 'taxonomy4' );

foreach ( $taxes as $tax ) {
    $terms = get_terms( $tax );

    foreach ( $terms as $term )
        $tax_map[$tax][$term->slug] = $term->term_taxonomy_id;
}


$args['tax_query'] => array(
    'relation' => 'AND',
    array(
        'taxonomy' => 'taxonomy1',
        'field' => 'term_taxonomy_id',
        'terms' => array( $tax_map['taxonomy1'][$slug] )
        'operator' => 'IN',
    ),
    array(
        'taxonomy' => 'taxonomy3',
        'field' => 'term_taxonomy_id',
        'terms' => array( $tax_map['taxonomy3'][$slug] ),
        'operator' => 'IN',
    ),
    array(
        'taxonomy' => 'taxonomy4', // gets ignored
        'field' => 'term_taxonomy_id',
        'terms' => array( $tax_map['taxonomy4'][$slug], $tax_map['taxonomy2'][$slug] ),
        'operator' => 'IN',
    ),
);

Note that pre-3.5, you'd also need to specify 'include_children' => false. See this Trac ticket for more: https://core.trac.wordpress.org/ticket/21228

share|improve this answer
2  
By the way, please excuse and alert me to any mistakes/inaccuracies :) Typing all this one-handed with a baby in the other. –  helenhousandi Apr 18 '13 at 23:19
    
Where does $slug come from...? –  vancoder Apr 18 '13 at 23:45
1  
Just a placeholder in the code. I guess it was $term1 etc. in the original question. –  helenhousandi Apr 18 '13 at 23:47
    
You are right! This method seem to work. I will give it test, and come back to vote for this answer if it is working. Thanks –  ron_dev Apr 19 '13 at 3:22
    
It seem the 'taxonomy' => 'taxonomy4', // gets ignored cannot be ignored. If i put random text in this field, no result was found. Only when I assigned real taxonomy name, it give me the result. Any idea why? –  ron_dev Apr 19 '13 at 9:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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