I want to display the total count of categories in a set of search results.
For example, “10 posts found in 3 categories.” (Assuming that each post has only 1 category.)
Right now, my solution is to run through the loop, capture each post’s category in an array, then count the unique values:
<?php
$categories_in_search_results = array();
if (have_posts()) :
while (have_posts()) : the_post();
array_push($categories_in_search_results, get_the_category()[0]->name);
endwhile;
endif;
wp_reset_postdata();
$total_categories_in_search_results = count(array_unique($categories_in_search_results));
?>
Does WordPress provide a cleaner way to do this or is there a more efficient approach?
I’m afraid there is no function in WP core that will get number of unique categories based on given list of posts…
So let’s take a look at your code first… There are some problems in it…
-
There is no need to use typical loop in here – it causes many operations in background (setting global variables and so on). It would be more efficient to use foreach instead.
-
It can return incorrect results if there are multiple categories with the same name (and different parent for example).
And is there any more efficient way to do this? Yes, there is (especially, if there are many posts returned) – you can use custom SQL to obtain the categories count with only one query… Here’s how:
global $wp_query;
global $wpdb;
$post_ids = implode( ',', wp_list_pluck( $wp_query->posts, 'ID' ) );
$total_categories_in_search_results = $wpdb->get_var( "
SELECT COUNT(DISTINCT tt.term_taxonomy_id) FROM
{$wpdb->term_taxonomy} tt
INNER JOIN {$wpdb->term_relationships} tr ON ( tt.term_taxonomy_id = tr.term_taxonomy_id )
WHERE
tt.taxonomy = 'category'
AND tr.object_id IN ({$post_ids})
" );