WordPress.org

Make WordPress Core

Opened 5 years ago

Last modified 4 months ago

#28145 new defect (bug)

wp_terms_checklist() returns all non-hierarchical terms even with $descendants_and_self parameter

Reported by: helgatheviking Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.9
Component: Posts, Post Types Keywords: has-patch needs-refresh
Focuses: Cc:
PR Number:

Description

Granted, I know that wp_terms_checklist() is meant for hierarchical terms, but I am also using it on non-hierarchical terms in my Radio Buttons for Taxonomies plugin. I was trying to use all core scripts/ajax-callbacks for the "add new term" feature in a posts taxonomy metabox, but it turns out that WP_Lists calls _wp_ajax_add_hierarchical_term via ajax which returns wp_terms_checklist() as part of the result.

For hierarchical terms the descendants_and_self parameter limits the size of the returned checklist. For non-hierarchical terms, however, I found that it simply returns *all* terms in addition to the new term.

wp_terms_checklist( $post_id, array('descendants_and_self' => $term_id ));

Obviously this isn't major, but it seems to me that if descendants_and_self is set, but there are no descendants... it should just return the single term.

I've gotten around this by unhooking that ajax callback for non-hierarchical terms and substituting my own that returns just a single input.

Here's the pertinent part of wp_terms_checklist():

if ( $descendants_and_self ) {
		$categories = (array) get_terms($taxonomy, array( 'child_of' => $descendants_and_self, 'hierarchical' => 0, 'hide_empty' => 0 ) );
		$self = get_term( $descendants_and_self, $taxonomy );
		array_unshift( $categories, $self );
	} else {
		$categories = (array) get_terms($taxonomy, array('get' => 'all'));
	}

I think if for non-hierarchical terms we skipped the get_terms() call we could limit the returned checklist to a single term.

if ( $descendants_and_self ) {
		$categories = is_taxonomy_hierarchical( $taxonomy ) ? (array) get_terms($taxonomy, array( 'child_of' => $descendants_and_self, 'hierarchical' => 0, 'hide_empty' => 0 ) ) : array();
		$self = get_term( $descendants_and_self, $taxonomy );
		array_unshift( $categories, $self );
	} else {
		$categories = (array) get_terms($taxonomy, array('get' => 'all'));
	}

Attachments (3)

28145.diff (1.6 KB) - added by MikeHansenMe 5 years ago.
patch based on suggestion, includes unit test
28145.2.diff (4.9 KB) - added by MikeHansenMe 5 years ago.
more tests
28145.3.diff (4.9 KB) - added by MikeHansenMe 4 years ago.

Download all attachments as: .zip

Change History (11)

@MikeHansenMe
5 years ago

patch based on suggestion, includes unit test

#1 @MikeHansenMe
5 years ago

  • Keywords has-patch added

#2 @boonebgorges
5 years ago

Thanks for the patch, MikeHansenMe. Can you provide a test that uses a non-hierarchical taxonomy? That's the change that really needs coverage here. (Ideally we'd keep the test you have here too, but add some real data so that we're returning more than just the Uncategorized category - maybe register a new hierarchical taxonomy so we don't have to deal with the quirks of 'category'.)

#3 @MikeHansenMe
5 years ago

Yea, I will work up a few other tests.

@MikeHansenMe
5 years ago

more tests

#4 @chriscct7
4 years ago

  • Keywords needs-refresh added

@MikeHansenMe
4 years ago

#5 @MikeHansenMe
4 years ago

  • Keywords needs-refresh removed

#6 @boonebgorges
4 years ago

Thanks @MikeHansenMe. Can we please move the fixture setup outside of setUp()? Putting it there adds lots of overhead for every test method in the class. It's fine to repeat it in both of the new tests. Also, we should be using self::factory()->term->create() instead of wp_insert_term() when setting up test fixtures.

Regarding the patch, the logic is somewhat convoluted. If the taxonomy is non-hierarchical, there's no point in doing the array_unshift() stuff at all - $categories should just be array( $term ). Can we simplify a bit?

#7 @MikeHansenMe
4 years ago

  • Keywords needs-refresh added

Hey @boonebgorges I will take a better look at what it is actually doing. I was just refreshing what already existed.

#8 @boonebgorges
4 years ago

@MikeHansenMe Thank you, sir!

Note: See TracTickets for help on using tickets.