Make WordPress Core

Opened 14 years ago

Closed 11 years ago

#14084 closed defect (bug) (invalid)

Custom taxonomy count includes draft & trashed posts

Reported by: lumpysimon's profile lumpysimon Owned by: garyc40's profile 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 13 years ago.
there's a patch for that
garyc40.14084.2.diff (4.0 KB) - added by garyc40 13 years ago.
use get_taxonomies() in get_object_taxonomies()

Download all attachments as: .zip

Change History (34)

#1 @scribu
14 years ago

Related: #14076

#2 @bunnykins
14 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.

#3 @kevinB
14 years ago

  • Cc kevinB added

#4 @lumpysimon
14 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' ).

#5 @nacin
14 years ago

  • Milestone changed from Awaiting Review to Future Release

#6 @mfields
13 years ago

  • Cc michael@… added

#7 @mfields
13 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.

#8 @dd32
13 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 11 years ago by SergeyBiryukov (previous) (diff)

#9 @garyc40
13 years ago

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

@garyc40
13 years ago

there's a patch for that

#10 @garyc40
13 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.

#11 follow-up: @nacin
13 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.

#12 in reply to: ↑ 11 @garyc40
13 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?

#13 @nacin
13 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.

@garyc40
13 years ago

use get_taxonomies() in get_object_taxonomies()

#14 @garyc40
13 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().

#15 follow-up: @scribu
13 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.

#16 in reply to: ↑ 15 @garyc40
13 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' ) ) ) );
}

#18 @rfair404
13 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 11 years ago by SergeyBiryukov (previous) (diff)

#19 @danielbachhuber
13 years ago

  • Cc d@… added

#20 @sbressler
13 years ago

  • Cc sbressler@… added

#21 @scribu
13 years ago

Related: #19031

#22 @jazbek
12 years ago

  • Cc j.yzbek@… added

#23 @dglingren
12 years ago

  • Cc david@… added

#24 @wonderboymusic
11 years ago

  • Keywords needs-refresh added; needs-testing removed

#25 @wonderboymusic
11 years 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.

#26 @wonderboymusic
11 years ago

  • Component changed from Accessibility to Taxonomy

#27 @dglingren
11 years 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.

#28 @wonderboymusic
11 years ago

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

#29 @pbaylies
11 years 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 11 years ago by SergeyBiryukov (previous) (diff)

#30 @SergeyBiryukov
11 years ago

  • Milestone set to Awaiting Review

#31 follow-up: @jeremyclarke
11 years 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?

#32 in reply to: ↑ 31 @nacin
11 years 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.