WordPress: Get taxonomies used in custom query result - php

I want to list a every taxonomy which is used in the output of a custom query.
For example:
I have a couple of cars listed on my site and a custom query to get all SUVs from that list. For that I'm using the following query args:
$args = array(
'post_type' => array( 'cars' ),
'posts_per_page' => '-1',
'tax_query' => array(
array(
'taxonomy' => 'car_type',
'field' => 'slug',
'terms' => 'suv',
),
),
);
$query = new WP_Query( $args );
$posts = $query->posts;
foreach ( $posts as $post ) {
$term_objects = get_the_terms( $post->ID, 'brand' );
foreach ( $term_objects as $term_object ) {
$terms_list[ $term_object->name ] = $term_object;
}
}
With this query I get a list of all SUVs within my cars.
Now I want to show a list of brands. The brand is a also a custom taxonomy.
So let's say there are 50 cars as a result from my query from 5 different brands.
How could I filter my query result and get the IDs of every brand (only once per brand) within the query results.

Related

WordPress: Get taxnomy terms which also uses a second taxonomy

Let's say I have a website which sells cars.
I'm using a custom taxonomy called brand for the manufacturer (like BMW, Audi, ...) and a custom taxonomy called type for the type of cars (like SUV, Coupe, ...).
For the cars itself I'm using a custom post type called models.
Now I want to show every car brand in the taxonomy archive for type (All brands with SUVs).
To do that, I'm trying to get all brands and filter them with all types.
As result there should be a list with all car brands that have SUVs.
Here's my current code to get a list of brands:
$taxonomies = get_terms( array(
'taxonomy' => 'brand',
'hide_empty' => false
) );
if ( !empty($taxonomies) ) :
$output = '<select>';
foreach( $taxonomies as $category ) {
if( $category->parent == 0 ) {
$output.= '<optgroup label="'. esc_attr( $category->name ) .'"></optgroup>';
}
}
$output.='</select>';
echo $output;
endif;
I couldn't find a way to add a second taxonomy to this snippet.
Is this the wrong approach?
Maybe I need to get the custom post types (models) first to check which one has both terms?
This article has a really helpful breakdown.
I needed to get the taxonomies that were part of another taxonomy for use in creating a dropdown (and some other uses.) This code allowed me to identify the "categories" that were part of a particular "destination".
$dest_slug = get_query_var('term');
$desination_ids = get_posts(array(
'post_type' => 'item',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'destinations',
'field' => 'slug',
'terms' => $dest_slug
)
),
'fields' => 'ids'
));
$categories = wp_get_object_terms($desination_ids, 'category');
I found a solution that works:
$productcat_id = get_queried_object_id();
$args = array(
'numberposts' => -1,
'post_type' => array('models'),
'tax_query' => array(
array(
'taxonomy' => 'brand',
'field' => 'term_id',
'terms' => $productcat_id,
),
),
);
$cat_posts = get_posts($args);
$my_post_ids = wp_list_pluck ($cat_posts, 'ID');
$my_terms = wp_get_object_terms ($my_post_ids, 'types');
if ( !empty($my_terms)) :
echo '<ul>';
foreach( $my_terms as $my_term ):
$brand_name = $my_term->name;
$brand_link = get_term_link($my_term);
echo '<li><a alt="'.$brand_name.'" href="'.esc_url( $brand_link ).'">'.$brand_name.'</a></li>';
endforeach;
echo '</ul>';
endif;

Display how many reviews there are for a CPT

I have two custom post types, 'product' and 'product_review'. The CPT 'product_review' has a taxonomy 'product_name' whose slug matches the CPT 'product'
An example 'Product A' is the product post. 'Product Review A' is the product_review post that has a 'product_name' taxonomy value of 'product_a'.
I need to show how many 'product_review' each 'product' has.
<?php
global $post;
$post_slug = $post->post_name;
//echo $post_slug;
//this outputs the name of the product, which I need
$terms = get_terms('product_review');
foreach ( $terms as $post_slug ) {
echo $term->count . 'Reviews';
?>
It doesn't show any count. I want it to show how many $terms(how many reviews) are tied to $post_slug(name of product). The 'product_review' slug matches the slug of the product.
You can use a custom WP_Query and the found_posts prop like below:
// example query args
$args = [
// look for reviews cpt
'post_type' => 'product_review',
// limit to posts that match our taxonomy product name
'tax_query' => [
[
'taxonomy' => 'product_name',
'field' => 'slug',
'terms' => [ 'product_a' ]
]
]
];
// run the query
$query = new WP_Query( $args );
// grab "total" found posts
$total = $query->found_posts;
// display the total
echo $total
// reset post data so we dont break the main loop
wp_reset_postdata();
#mikerojas answer got me close, but wasn't returning accurate data. Here is what I came up with that got me what I needed.
<?php
$review_args = array(
'post_type' => 'my_post_type',
'post_status' => 'publish',
'tax_query' => array(
array (
'taxonomy' => 'my_taxonomy',
'field' => 'slug',
//this is already inside a loop, making it dynamic to only grab the reviews whose tax value equals the post slut
'terms' => $post->post_name,
)
),
);
if($num = count( get_posts ( $review_args)) <= 1) {
echo 'Review ' . $num = count( get_posts( $review_args ) );
} else {
echo 'Reviews ' . $num = count( get_posts( $review_args ) );
}
wp_reset_postdata();
?>

How to query taxonomy for a post type then include another post type with no tax

How do I include these post types on a single query?
events -> all
guides -> all
page -> only topnews tax
This is the query I use to list posts from events and guides custom post type:
$args = array(
'post_type' => array('events', 'guides'),
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => 5,
'post_status' =>'publish',
);
$newlist = get_posts( $args );
Now, I want to add post type page with a tax_query of topnews on the $args. I already registered taxonomy called property for page post type, and topnews is one of its categories.
'tax_query' => array(
array (
'taxonomy' => 'property',
'field' => 'slug',
'terms' => 'topnews',
)
),
I want to include this on the query but the events and guides post types won't show any results. Only page with topnews tax is showing.
How do I include all of this on a single query?
use
$query1 = WP_Query(); // query without taxonomy
$query2 = WP_Query(); // query with taxonomy
$q1_posts = $query1->posts;
$q2_posts = $query2->posts;
$merged_posts = array_merge($q1_posts,$q2_posts);

Wordpress posts count with comman tags within specific category

i have two categories 'A' and 'B'. Both have 5 posts(each) with tag 'C'. How i can display the number of posts as 5 in Category 'A' or 'B' page. It showing total number of post with tag 'C' as 10. I need to show it as 5. How i can pass category variable to display exact count with tag within specific category. Here is my current code:
$tag = get_term_by('name', $tags,'post_tag');
$count = $tag->count;
reference: https://codex.wordpress.org/Function_Reference/get_term_by
This is not possible with the get_term_by() method.
Try this:
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND', // only posts that have both taxonomies will return.
array(
'taxonomy' => 'post_tag',
'field' => 'name',
'terms' => 'TAG_C', // you can also use an array with tags.
),
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'CATEGORY_B', // you can also use an array with categories.
),
),
);
$posts = get_posts($args);
$count = count($posts);
I haven't tested this code, but it should work. Ofcourse you do have
to set the correct terms.
UPDATE
When dealing with many posts I would create a $wpdb sql query that counts the rows, so only a number is returned and not all the posts. You can find an sql count example here.
You can use "found_posts" property of the WP_Query class object.
$args = array(
'posts_per_page' => 10,
'category_name' => 'aaa', // category slug
'tag' => 'ccc' // tag slug
);
$wp_query = new WP_Query( $args );
echo "Total posts count: ".$wp_query->found_posts;

related post by taxonomy custom plugin developement issue

I am facing issue with a custom plugin, which will show related post by taxonomy from a particular category(mobile). If there are no post matching taxonomy, it should display other posts from that particular category. First I fetched all taxonomies and terms for the current post(single.php). Then I prepare a query argument using loop. The code works for the below cases,
a) I have not added any post tag(current post), then it's showing other posts from the same category(mobile),
b) If I have added a post tag, and there are other post matching the terms of that post tag.
But, it's don't work when I have added a post tag, and there are no post matching those terms. But, here I want, if there are no matching post by the terms, then just display other posts irrespective of terms. I can do this, using a new query when have_posts fails, but I am thinking if there are any other way to do this withing the same query args, please help
I am placing the code which I am trying to develop.
$post_args = array();
$taxonomies = get_post_taxonomies( $post );
foreach ($taxonomies as $key => $taxonomy) {
# code...
if($taxonomy == 'category') continue;
$terms = wp_get_post_terms( get_the_ID(), $taxonomy );
$term_array = array();
if($terms){
foreach ($terms as $key => $value) {
array_push($term_array, $value->slug);
}
array_push($post_args,
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $term_array,
)
);
}
}
$tax_query = array();
$tax_query['relation'] = 'OR';
foreach ($post_args as $key => $value) {
# code...
array_push($tax_query, $value);
}
$args = array(
'post_type' => 'post',
// 'category_name' => 'mobiles',
'post__not_in' => array($curr_post_id),
'posts_per_page' => 10,
'orderby' => 'relevance',
'order' => 'ASC',
'tax_query' =>
array(
'relation' => 'AND',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'mobiles',
)
,
array($tax_query)
)
);
$the_query = new WP_Query( $args );
After trying a lot, I just decided to use another post loop. Say, if there are no result from first loop, just select random post from the category. If there are few posts(Max 10 posts) from the first loop, then user another loop to select random posts excluding the post ids we get from first loop.

Categories