How to update incorrect post count in taxonomy?

It only took 3.5-years for someone to be put into the position of @robert-andrews to chase down the post count problem. While having the same problem (and misinterpretation), I ran across your post yesterday in my search for answers. Nothing good really turned up. So, I was forced to trace the code and take the long way home in figuring out what’s going on. (Though there are other related posts here and here that touch on this subject, there is no “good” answer on the StackExchange family of sites or StackOverflow.)

You’ll notice taxonomies generally appear under the admin menu of the post type to which they have been registered. That’s important to note because wp-admin/edit-tags.php only shows post counts of the type under which the page is nested. (Hint: look in the URL, and you’ll see the slug of that post type.)

Next, my tracing took me a private function _update_post_term_count(). What I found is that the count is stored in the database, not calculated dynamically. In other words, no results will be seen simply by doing a bit of coding and refreshing the page: a post associated with the taxonomy must be saved in order to manifest any results. (What a silly thing to do considering the limited number of times the count is accessed and the fact that post counts are dynamic in the admin table view counts.)

Anyway, back to _update_post_term_count(): it will only save posts of the specific post type that have published status. This was particularly distressing to me because I have a custom post status for a custom post type that is categorized by a custom taxonomy. Well, the update_post_term_count_statuses hook is what solves that problem. Here’s a bit of shorthand of how I solved my problem of counting posts appearing in my CPT admin table “All” view:

add_filter('update_post_term_count_statuses', function($post_statuses, $taxonomy) {
    // Intercept
    if($taxonomy->name === 'mort-custom-taxonomy') {
        foreach(array(
            // Some post statuses to be included in the count ...
            'mort-custom-post-status',
            'draft',
            'pending',
            'private'
        ) as $v) {
            // Check to ensure another call hasn't already added the status.
            if(!in_array($v, $post_statuses)) {
                $post_statuses[] = $v;
            }
        }
    }
    // Return
    return $post_statuses;
}, 10, 2);

Here’s how the filter above would be called: _update_post_term_count() is executed by wp_update_term_count_now() when wp_update_term_count() is put into effect by wp_set_object_terms() and _update_term_count_on_transition_post_status() at the time a post is created/updated/published.

One final important note so you don’t drive yourself crazy. After implementing the filter, the count of a term will not be updated until (as you might have guessed) a post related to that term is created/updated/published.

Leave a Comment