$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>get_terms with posts that have a different taxonomy with term x|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

get_terms with posts that have a different taxonomy with term x

matteradmin9PV0评论

Here's the situation;

I am using get_terms to retrieve all terms from Tax 1 with posts associated with it. Using the following

$args = array(
            'hide_empty'    =>  0,
            'orderby'       =>  'name',
            'taxonomy'      =>  'tax_1'
        );

$terms  =   get_terms( $args );

Pretty simple. However that returns all terms, and does not consider the second taxonomy Tax 2 which I want to compare against term x

Ultimately I want to get all Tax 1 terms that have posts which also have Tax 2 term x

I could most likely to a query directly on posts and create an array of terms where the post has both of the above but that seems a bit messy, I am hoping there is a way to query this directly.

Thanks

Here's the situation;

I am using get_terms to retrieve all terms from Tax 1 with posts associated with it. Using the following

$args = array(
            'hide_empty'    =>  0,
            'orderby'       =>  'name',
            'taxonomy'      =>  'tax_1'
        );

$terms  =   get_terms( $args );

Pretty simple. However that returns all terms, and does not consider the second taxonomy Tax 2 which I want to compare against term x

Ultimately I want to get all Tax 1 terms that have posts which also have Tax 2 term x

I could most likely to a query directly on posts and create an array of terms where the post has both of the above but that seems a bit messy, I am hoping there is a way to query this directly.

Thanks

Share Improve this question asked Jan 30, 2019 at 12:47 epluribusunumepluribusunum 411 silver badge5 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 5

Just to start, you say "I am using get_terms to retrieve all terms from Tax 1 with posts associated with it", however your actual code gets all terms in that taxonomy regardless of whether or not they have posts. You need to set hide_empty to true.

So with that out of the way, the bad news: You won't be able to do this with get_terms(). That type of information doesn't exist without querying posts and comparing the terms. So the messy solution you wanted to avoid is unfortunately necessary.

Ultimately I think this is a situation where you might be better off just using SQL. This code will use $wpdb to get terms from Taxonomy A that have any posts of a given post type that have a specific term in Taxonomy B:

$post_type  = 'post';
$taxonomy_a = 'post_tag';
$taxonomy_b = 'category';
$term_b_id  = 12;

$query = $wpdb->prepare(
    "SELECT DISTINCT
        terms.*
    FROM
        `wp_terms` terms
    INNER JOIN
        `wp_term_taxonomy` tt1 ON
            tt1.term_id = terms.term_id
    INNER JOIN
        `wp_term_relationships` tr1 ON
            tr1.term_taxonomy_id = tt1.term_taxonomy_id
    INNER JOIN
        `wp_posts` p ON
            p.ID = tr1.object_id
    INNER JOIN 
        `wp_term_relationships` tr2 ON
            tr2.object_ID = p.ID
    INNER JOIN 
        `wp_term_taxonomy` tt2 ON
            tt2.term_taxonomy_id = tr2.term_taxonomy_id
    WHERE
        p.post_type = %s AND
        p.post_status = 'publish' AND
        tt1.taxonomy = %s AND
        tt2.taxonomy = %s AND
        tt2.term_id = %d",
    [
        $post_type,
        $taxonomy_a,
        $taxonomy_b,
        $term_b_id,
    ]
);

$results = $wpdb->get_results( $query );

if ( $results ) {
    $terms = array_map( 'get_term', $results );
}

So that code gets all Tags that have Posts that are assigned to the Category with the ID 12.

The last little bit with get_term() ensures that the final array contains the same WP_Term objects that you would get by running get_terms().

You could use the tax_query argument, for example:

'tax_query' => array(
    'relation' => 'AND',
    array(
        'taxonomy' => 'tax1',
        'field'    => 'slug',
        'terms'    => $terms,
    ),
    array(
        'taxonomy' => 'tax2',
        'field'    => 'slug',
        'terms'    => $terms,
    )
)

To get all posts which have both terms. You can then use get_terms and pass the object_ids as a parameter. See the WP_Term_Query documentation for more details.

Post a comment

comment list (0)

  1. No comments so far