same taxonomy for several post types: how to hide empty in a specific post type?

Thanks to this answer, I was able to see the light. Here is how to query taxonomy terms related to (woocommerce) products that are “in stock”. It uses both tax_query (to relate product to taxonomy) and meta_query (to filter out out-of-stock products).

$artists = get_terms_by_post_type( array('artist'), array('product'));

if( !empty($artists) && !is_wp_error( $artists )  ){

    // filter out out-of-stock products artists
    foreach($artists as $k=>$artist){
        $args = array(
            'post_type'     => 'product',
            'post_status'   => 'publish',
            'posts_per_page' => -1,
            'meta_query' =>array(
                'relation' => 'AND',
                array(
                    'key' => '_stock_status',
                    'value' => 'instock',
                    'compare' => '='
                )
                ,
                array(
                    'key' => '_stock',
                    'value' => '0',
                    'compare' => '>'
                )
                ,
                array(
                    'key' => '_stock',
                    'value' => '',
                    'compare' => '!='
                )
            ),
            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'artist',
                    'field' => 'id',
                    'terms' => array( $artist->term_id )
                ),


            )
        );

        $query = new WP_Query($args);

        if($query->post_count<1){
            unset($artists[$k]);
        }
    }
}

function get_terms_by_post_type( $taxonomies, $post_types ) {

    global $wpdb;

    $query = $wpdb->prepare(
        "SELECT t.*, COUNT(*) from $wpdb->terms AS t
        INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
        INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id
        INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id
        WHERE p.post_type IN('%s') AND tt.taxonomy IN('%s')
        GROUP BY t.term_id",
        join( "', '", $post_types ),
        join( "', '", $taxonomies )
    );

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

    return $results;

}

Leave a Comment