In get_terms()
, check hierarchy for all $taxonomies
before bailing early from 'parent' or 'child_of'.
There is a pre-check in `get_terms()` that prevents an unnecessary database query if the 'parent' or 'child_of' parameter is not found in the cached term hierarchy (since a term without an index in the hierarchy cache has no descendants). Previously, only the first item in the `$taxonomies` array was being checked, with the result that an empty array was being erroneously returned in cases where the 'parent' or 'child_of' term is in a subsequent taxonomy. See #31118. git-svn-id: https://develop.svn.wordpress.org/trunk@31276 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
c67e5da8c9
commit
5bcee9e939
@ -1657,18 +1657,29 @@ function get_terms( $taxonomies, $args = '' ) {
|
||||
*/
|
||||
$args = apply_filters( 'get_terms_args', $args, $taxonomies );
|
||||
|
||||
// Avoid the query if the queried parent/child_of term has no descendants.
|
||||
$child_of = $args['child_of'];
|
||||
$parent = $args['parent'];
|
||||
|
||||
if ( $child_of ) {
|
||||
$hierarchy = _get_term_hierarchy( reset( $taxonomies ) );
|
||||
if ( ! isset( $hierarchy[ $child_of ] ) ) {
|
||||
return $empty_array;
|
||||
}
|
||||
$_parent = $child_of;
|
||||
} elseif ( $parent ) {
|
||||
$_parent = $parent;
|
||||
} else {
|
||||
$_parent = false;
|
||||
}
|
||||
|
||||
$parent = $args['parent'];
|
||||
if ( $parent ) {
|
||||
$hierarchy = _get_term_hierarchy( reset( $taxonomies ) );
|
||||
if ( ! isset( $hierarchy[ $parent ] ) ) {
|
||||
if ( $_parent ) {
|
||||
$in_hierarchy = false;
|
||||
foreach ( $taxonomies as $_tax ) {
|
||||
$hierarchy = _get_term_hierarchy( $_tax );
|
||||
|
||||
if ( isset( $hierarchy[ $_parent ] ) ) {
|
||||
$in_hierarchy = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $in_hierarchy ) {
|
||||
return $empty_array;
|
||||
}
|
||||
}
|
||||
@ -1942,9 +1953,11 @@ function get_terms( $taxonomies, $args = '' ) {
|
||||
}
|
||||
|
||||
if ( $child_of ) {
|
||||
$children = _get_term_hierarchy( reset( $taxonomies ) );
|
||||
if ( ! empty( $children ) ) {
|
||||
$terms = _get_term_children( $child_of, $terms, reset( $taxonomies ) );
|
||||
foreach ( $taxonomies as $_tax ) {
|
||||
$children = _get_term_hierarchy( $_tax );
|
||||
if ( ! empty( $children ) ) {
|
||||
$terms = _get_term_children( $child_of, $terms, $_tax );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,6 +376,47 @@ class Tests_Term_getTerms extends WP_UnitTestCase {
|
||||
$this->assertEquals( 1, count( $terms ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 31118
|
||||
*/
|
||||
public function test_child_of_should_skip_query_when_specified_parent_is_not_found_in_hierarchy_cache() {
|
||||
global $wpdb;
|
||||
|
||||
register_taxonomy( 'wptests_tax', 'post', array( 'hierarchical' => true, ) );
|
||||
|
||||
$terms = $this->factory->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
|
||||
|
||||
$num_queries = $wpdb->num_queries;
|
||||
|
||||
$found = get_terms( 'wptests_tax', array(
|
||||
'hide_empty' => false,
|
||||
'child_of' => $terms[0],
|
||||
) );
|
||||
|
||||
$this->assertEmpty( $found );
|
||||
$this->assertSame( $num_queries, $wpdb->num_queries );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 31118
|
||||
*/
|
||||
public function test_child_of_should_respect_multiple_taxonomies() {
|
||||
register_taxonomy( 'wptests_tax1', 'post', array( 'hierarchical' => true ) );
|
||||
register_taxonomy( 'wptests_tax2', 'post', array( 'hierarchical' => true ) );
|
||||
|
||||
$t1 = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax1' ) );
|
||||
$t2 = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax2' ) );
|
||||
$t3 = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax2', 'parent' => $t2 ) );
|
||||
|
||||
$found = get_terms( array( 'wptests_tax1', 'wptests_tax2' ), array(
|
||||
'fields' => 'ids',
|
||||
'hide_empty' => false,
|
||||
'child_of' => $t2,
|
||||
) );
|
||||
|
||||
$this->assertEqualSets( array( $t3 ), $found );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 27123
|
||||
*/
|
||||
@ -1156,6 +1197,47 @@ class Tests_Term_getTerms extends WP_UnitTestCase {
|
||||
$this->assertEqualSets( $expected, $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 31118
|
||||
*/
|
||||
public function test_parent_should_skip_query_when_specified_parent_is_not_found_in_hierarchy_cache() {
|
||||
global $wpdb;
|
||||
|
||||
register_taxonomy( 'wptests_tax', 'post', array( 'hierarchical' => true, ) );
|
||||
|
||||
$terms = $this->factory->term->create_many( 3, array( 'taxonomy' => 'wptests_tax' ) );
|
||||
|
||||
$num_queries = $wpdb->num_queries;
|
||||
|
||||
$found = get_terms( 'wptests_tax', array(
|
||||
'hide_empty' => false,
|
||||
'parent' => $terms[0],
|
||||
) );
|
||||
|
||||
$this->assertEmpty( $found );
|
||||
$this->assertSame( $num_queries, $wpdb->num_queries );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 31118
|
||||
*/
|
||||
public function test_parent_should_respect_multiple_taxonomies() {
|
||||
register_taxonomy( 'wptests_tax1', 'post', array( 'hierarchical' => true ) );
|
||||
register_taxonomy( 'wptests_tax2', 'post', array( 'hierarchical' => true ) );
|
||||
|
||||
$t1 = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax1' ) );
|
||||
$t2 = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax2' ) );
|
||||
$t3 = $this->factory->term->create( array( 'taxonomy' => 'wptests_tax2', 'parent' => $t2 ) );
|
||||
|
||||
$found = get_terms( array( 'wptests_tax1', 'wptests_tax2' ), array(
|
||||
'fields' => 'ids',
|
||||
'hide_empty' => false,
|
||||
'parent' => $t2,
|
||||
) );
|
||||
|
||||
$this->assertEqualSets( array( $t3 ), $found );
|
||||
}
|
||||
|
||||
public function test_hierarchical_false_parent_should_override_child_of() {
|
||||
$initial_terms = $this->create_hierarchical_terms();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user