WordPress.org

Make WordPress Core

Opened 4 years ago

Closed 14 months ago

#14084 closed defect (bug) (invalid)

Custom taxonomy count includes draft & trashed posts

Reported by: lumpysimon Owned by: garyc40
Milestone: Priority: normal
Severity: normal Version: 3.0
Component: Taxonomy Keywords: has-patch 3.2-early dev-feedback needs-refresh
Focuses: Cc:

Description (last modified by dd32)

I have registered a custom post type and an associated non-hierarchical custom taxonomy.

The tag count, both on edit-tags.php?taxonomy=my_tag&post_type=my_post and when using wp_tag_cloud, includes draft & trashed posts in the count.

The count should only include published posts.

This error doesn't seem to occur for normal posts/tags, only for custom posts types/taxonomies.

--
Added by dd32: The count on the taxonomy page is currently global, It includes All post types regardless of the post status (ie. published vs trashed, published vs custom_status)

Attachments (2)

garyc40.14084.diff (3.6 KB) - added by garyc40 3 years ago.
there's a patch for that
garyc40.14084.2.diff (4.0 KB) - added by garyc40 3 years ago.
use get_taxonomies() in get_object_taxonomies()

Download all attachments as: .zip

Change History (34)

comment:1 scribu4 years ago

Related: #14076

comment:2 bunnykins4 years ago

I am a bit confused here how is this bug related to mine?
According to my bug report the count displayed next the the category is correct as I do have that many entries in that category. However those entries are in a different post type so when you click on that category it acts as if there is no entries at all in that category.
I did how ever find a work around and that is to create the entry in both the regular post type and in the new post type and make sure both entries have the same permlink and you should be able to see those entries when you click on that category or tag.

comment:3 kevinB4 years ago

  • Cc kevinB added

comment:4 lumpysimon4 years ago

  • Cc piemanek@… added

I've just noticed that this bug also affects the count for hierarchical taxonomies associated with custom post types, for instance when you use wp_list_categories( 'taxonomy=my_taxo&show_count=1' ).

comment:5 nacin3 years ago

  • Milestone changed from Awaiting Review to Future Release

comment:6 mfields3 years ago

  • Cc michael@… added

comment:7 mfields3 years ago

I have witnessed the behavior that lumpysimon has reported.

If the 'update_count_callback' argument is not defined when a custom taxonomy is registered it's value is set to empty and the post count will not be updated when post_status is changed, only when published. However, if a custom taxonomy's 'update_count_callback' argument is set to '_update_post_term_count', the count will be updated when post_status is changed from a value of 'publish', 'draft' or 'pending' to a value of 'publish', 'draft' or 'pending'.

I'm not sure whether or not it is a good idea to suggest that users set the value of 'update_count_callback' to a function marked as private in core. Would it be better to have register_taxonomy() set this function for the user instead of giving it an empty value?

In my tests I never witnessed the count being updated when a post's status was changed to or from 'trash'. I believe this to be a bug.

comment:8 dd323 years ago

  • Description modified (diff)

I've closed #14076 as a duplicate of this ticket.

The count on the taxonomy page is currently global, It includes All post types regardless of the post status (ie. published vs trashed, published vs custom_status)

Last edited 15 months ago by SergeyBiryukov (previous) (diff)

comment:9 garyc403 years ago

  • Owner set to garyc40
  • Status changed from new to assigned

garyc403 years ago

there's a patch for that

comment:10 garyc403 years ago

  • Keywords has-patch needs-testing 3.2-early added

My patch addresses the issues with term counts in taxonomy UI as well as wp_list_categories().

  • get_object_taxonomies() now accepts a third optional parameter, $exclude_builtin, which is used when you want to get a list of only custom taxonomies.
  • update_count_callback will automatically be set to _update_post_term_count when show_ui is true and update_count_callback is an empty string. The edge case is when the developer wants to show the UI, but don't want to call _update_post_term_count. In this case, update_count_callback => false can be used. However, _updating_post_term_count is the expected behavior when show_ui is true. I doubt that this change would affect current plugins and themes relying on custom taxonomies.
  • tax_input is properly generated in wp_get_single_post(). Without this, update_count_callback isn't called whenever a post with custom taxonomies is deleted.

comment:11 follow-up: nacin3 years ago

Let's make get_object_taxonomies() either take an array of args, or we should use wp_filter_object_list for the argument so it works like get_taxonomies() and get_post_types(). I like the latter.

comment:12 in reply to: ↑ 11 garyc403 years ago

Replying to nacin:

Let's make get_object_taxonomies() either take an array of args, or we should use wp_filter_object_list for the argument so it works like get_taxonomies() and get_post_types(). I like the latter.

I notice that originally in get_object_taxonomies($object, $output = 'names'), $object can be an array of taxonomy object types. How should I match this with wp_filter_object_list() ?

For example, will something like this work?

wp_filter_object_list( $wp_taxonomies, array( 'object_type' => array( 'post_type_1', 'post_type_2' ), $output );

As far as I know, wp_filter_object_list() can't filter an array of acceptable values for a single key, right?

comment:13 nacin3 years ago

I meant get_object_taxonomies( $object, $output = 'names', $args ), where $args then goes through wp_filter_object_list. It can then be passed straight through to get_taxonomies(), which would need to replace the raw $wp_taxonomies call.

Then you can call get_object_taxonomies( 'post', 'names', array( '_builtin' => false ) ).

get_attachment_taxonomies() will probably need similar treatment to make everything consistent.

garyc403 years ago

use get_taxonomies() in get_object_taxonomies()

comment:14 garyc403 years ago

Sorry, attached the wrong 16118.2.diff patch. You should look at 14084.2.diff (the latest one) instead.

Using wp_filter_object_list() makes me realize that this function only filter superficially. Let's say if I want to:

wp_filter_object_list( array_values( $wp_taxonomies ), array( 'object_type' => array( 'post' ) ) );

This will return all sorts of taxonomies, even those that have object_type == array( 'nav_menu_item' ) .

In other words, wp_filter_object_list() doesn't filter deep enough. What do you think? Should we enhance wp_filter_object_list() to also filter inside properties of the list item?

If we enhance that function, we might be able to get rid of the foreach loop inside get_object_taxonomies().

comment:15 follow-up: scribu3 years ago

This will return all sorts of taxonomies, even those that have object_type == array( 'nav_menu_item' ) .

I don't see how that could happen. It looks for an exact match.

Should we enhance wp_filter_object_list() to also filter inside properties of the list item?

I don't think that's a good idea. It could cause other problems.

comment:16 in reply to: ↑ 15 garyc403 years ago

Replying to scribu:

I don't see how that could happen. It looks for an exact match.

Try this:

add_action('admin_notices', 'test_admin_notices');
function test_admin_notices() {
	global $wp_taxonomies;
	var_dump( wp_filter_object_list( array_values( $wp_taxonomies ), array( 'object_type' => array( 'post' ) ) ) );
}

comment:17 scribu3 years ago

Indeed: #16137

comment:18 rfair4043 years ago

It also appears that a taxonomy that is registered to an array of post_types shows the count for all posts in the term on that specific post type taxonomy edit page. e.g.

  1. REGISTER a taxonomy (Tax) to two or more post type (Pt1 & Pt2)
  2. ADD one or more term (termA & termB) to Tax.
  3. Add one or more posts to Pt1 and Pt2, classify them as termA.
  4. Go to either of the edit-tags.php page that should exits as admin menu items for both Pt1 & Pt2.
  5. The post count shown for each existing term is for ALL posts regardless of type. Shouldn't this term count be just this post type?
Last edited 15 months ago by SergeyBiryukov (previous) (diff)

comment:19 danielbachhuber3 years ago

  • Cc d@… added

comment:20 sbressler3 years ago

  • Cc sbressler@… added

comment:21 scribu2 years ago

Related: #19031

comment:22 jazbek23 months ago

  • Cc j.yzbek@… added

comment:23 dglingren19 months ago

  • Cc david@… added

comment:24 wonderboymusic15 months ago

  • Keywords needs-refresh added; needs-testing removed

comment:25 wonderboymusic15 months ago

  • Component changed from Taxonomy to Accessibility
  • Milestone Future Release deleted
  • Resolution set to worksforme
  • Status changed from assigned to closed

The patch is way old and alters deprecated functions - I can't reproduce the issues described in this ticket. Count is always correct when trashing many flavors of post, custom post type, taxonomy, custom taxonomy, hierarchical, non-hierarchical, etc. If I'm wrong, please re-open.

comment:26 wonderboymusic15 months ago

  • Component changed from Accessibility to Taxonomy

comment:27 dglingren15 months ago

Have you done any testing with post_type = attachment? My site has numerous incorrect counts after registering the category and post_tags taxonomies for this type.

I discovered this some time back and have forgotton the cause of the problem, but I can do some investigation if it would help.

comment:28 wonderboymusic15 months ago

Feel free to reopen with reproducible steps - I was just testing the supplied patch against the supplied scenario

comment:29 pbaylies15 months ago

  • Cc pbaylies added
  • Resolution worksforme deleted
  • Status changed from closed to reopened

See rfair404's comment, those are the reproducible steps; I just ended up having to hack around this one myself (using hooks 'edit_term_count' and 'number_format_i18n', so not a pretty hack) to get a correct display of the term count for the given post type and taxonomy. Seeing as how tickets reporting this are getting closed as duplicates of this ticket, that should therefore be acknowledged in this ticket.

Last edited 15 months ago by SergeyBiryukov (previous) (diff)

comment:30 SergeyBiryukov15 months ago

  • Milestone set to Awaiting Review

comment:31 follow-up: jeremyclarke14 months ago

  • Cc jer@… added

I can confirm that the count of terms in custom taxonomies still includes draft posts.

Setting 'update_count_callback' => '_update_post_term_count' fixed the problem for me.

I see no reason why _update_post_term_count shouldn't be the default behavior. I don't think most people consider the mechanism that generates "term count", and would not expect it to behave differently between the built in taxonomies and a custom taxonomy with no update_count_callback specified.

My Details

We have posts that we are keeping as drafts and they had terms from our custom taxonomy. The tag cloud, because it looks at the term's ->count, was showing these terms even though the only post they were applied to was a draft. The site is new and has a term for every country on earth, many of which have no posts yet. The result was a tag cloud full of links to archive screens with zero posts, a terrible result.

After setting 'update_count_callback' => '_update_post_term_count' and resaving each draft post the tag cloud was fixed.

This is a very subtle bug because most of the time you would never notice. If there is at least one post in each term then their archives are never actually empty, so the mistake isn't as toxic when you get linked to zero-post screens. If you publish all posts in a timely manner there's no reason you'd ever notice the brief period where the tag from your draft was in the sidebar.

That said this bug probably affects the majority of people who use custom taxonomies, just by a small enough margin that it doesn't bother them. Why not fix it in the background? Anyone who really cares about how the term count is generated probably has their own callback for it right?

comment:32 in reply to: ↑ 31 nacin14 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from reopened to closed

Replying to jeremyclarke:

Why not fix it in the background?

We do. Check out wp_update_term_count_now(). If no update_count_callback is specified, then we use _update_post_term_count() as long as all attached object types are post types.

Note: See TracTickets for help on using tickets.