Make WordPress Core

Opened 7 years ago

Last modified 6 years ago

#43995 new defect (bug)

wp_dropdown_categories(array( 'pad_counts' => true ) ) doesn't correctly pad counts on post_types with custom stati

Reported by: pbiron's profile pbiron Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Taxonomy Keywords:
Focuses: Cc:

Description

Suppose I have the following situation:

  • a custom post type (e.g., member)
  • post type member has custom post stati (e.g., subscribed and unsubscribed)
  • ALL posts of post type member have one of these custom stati (i.e., NONE have post_status publish).
  • a hierarchical taxonomy (e.g., membership-status) is registered on post type member
  • taxonomy membership-status looks like the following:
    • Membership
      • Current
      • Expired

and that the term Current has been assigned to 10 posts, Expired has been assigned to 5 posts and that Membership has been assigned to 0 posts.

If I then call

$args = array(
    'taxonomy' => 'membership-status',
    'show_counts' => true,
    'pad_counts' => true,
    ...
);
wp_dropdown_categories( $args );

I expect to get a dropdown that looks like:

  • Membership (15)
    • Current (10)
    • Expired (5)

Instead, I get the following:

  • Membership (0)
    • Current (10)
    • Expired (5)

which is, obviously, not correctly padding the count for Membership.

Related: #11847, #13176

Change History (6)

#1 @pbiron
7 years ago

The problem is in _pad_term_counts() (/wp-includes/taxonomy.php#L3537):

$results = $wpdb->get_results( "SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (" . implode( ',', array_keys( $term_ids ) ) . ") AND post_type IN ('" . implode( "', '", $object_types ) . "') AND post_status = 'publish'" );

which hardcodes ...AND post_status = 'publish' into the query.

My initial stab at a fix is to replace /wp-includes/taxonomy.php#L3537 with

$post_stati = apply_filters( 'pad_term_counts_post_stati', array( 'publish' ), $taxonomy, $object_types );
$results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (" . implode(',', array_keys($term_ids)) . ") AND post_type IN ('" . implode("', '", $object_types) . "') AND post_status IN ('" . implode("', '", $post_stati) . "')");

which would allow me to write:

add_filter( 'pad_term_counts_post_stati', 'my_pad_term_counts_post_stati' ), 10, 3 );
function my_pad_term_counts_post_stati( $post_stati, $taxonomy, $object_types ) {
        if ( in_array( 'member', $object_types ) && in_array( 'membership-status', (array) $taxonomy ) ) {
                $post_stati = array( 'subscribed', 'unsubscribed' );
        }

        return $post_stati;
}

The above would certainly solve my immediate need, but there might be other more generalized use cases that would require some other solution.

If others agree that the problem is real and that some fix is desired, I'll produce a patch and some unit tests that cover my immediate need.

#2 follow-up: @Venutius
7 years ago

This change would also be helpful to a few other plugins I can think of, one being my own BP Post Status, but also LH Logged in Post Status and WP_Statuses. Working around this is non trivial from what I can see.

#3 in reply to: ↑ 2 @pbiron
7 years ago

Replying to Venutius:

This change would also be helpful to a few other plugins I can think of, one being my own BP Post Status, but also LH Logged in Post Status and WP_Statuses. Working around this is non trivial from what I can see.

Thanx for the backup on the need for a change.

I am unfamiliar with the plugins you mention. From what you know, will my proposed fix above satisfy the requirements of those plugins?

#4 @Venutius
7 years ago

Yes I believe so, this problem is that we need a mechanism to add additional post statuses into the search for post categories, this seems to allow that in a very accessible way.

This ticket was mentioned in Slack in #core by pbiron. View the logs.


6 years ago

#6 @pento
6 years ago

  • Version trunk deleted
Note: See TracTickets for help on using tickets.