From 81679ef45370fb6077911687522825a39e789d4d Mon Sep 17 00:00:00 2001 From: Scott Taylor Date: Fri, 7 Feb 2014 19:53:01 +0000 Subject: [PATCH] When a `term_id` matches in `_get_term_children()`, recurse through its children until there is no more depth in the hierarchy. Since `get_terms()` return terms with a `count` of `0` when their children are not empty, we must return all children so that `get_terms()` can check their count. In [27108], #26903 was fixed, but only because we were using the example in the ticket, leaving out infinite depth for hierarchical taxonomies. Adds unit tests, including `Tests_Term_getTerms::test_get_terms_seven_levels_deep()`. Fixes #26903. Again. git-svn-id: https://develop.svn.wordpress.org/trunk@27125 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/taxonomy.php | 15 ++++++---- tests/phpunit/tests/term/getTerms.php | 40 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index 34f7900426..5df7789a9b 100644 --- a/src/wp-includes/taxonomy.php +++ b/src/wp-includes/taxonomy.php @@ -3004,12 +3004,17 @@ function _get_term_children($term_id, $terms, $taxonomy) { if ( $term->term_id == $term_id ) { if ( isset( $has_children[$term_id] ) ) { - foreach ( $has_children[$term_id] as $t_id ) { - if ( $use_id ) { - $term_list[] = $t_id; - } else { - $term_list[] = get_term( $t_id, $taxonomy ); + $current_id = $term_id; + while ( $current_id > 0 ) { + foreach ( $has_children[$current_id] as $t_id ) { + if ( $use_id ) { + $term_list[] = $t_id; + } else { + $term_list[] = get_term( $t_id, $taxonomy ); + } } + + $current_id = isset( $has_children[$t_id] ) ? $t_id : 0; } } continue; diff --git a/tests/phpunit/tests/term/getTerms.php b/tests/phpunit/tests/term/getTerms.php index c232d4fd93..06e9aacb71 100644 --- a/tests/phpunit/tests/term/getTerms.php +++ b/tests/phpunit/tests/term/getTerms.php @@ -273,4 +273,44 @@ class Tests_Term_getTerms extends WP_UnitTestCase { $this->assertNotEmpty( $terms ); $this->assertEquals( wp_list_pluck( $terms, 'name' ), array( 'Cheese', 'Crackers' ) ); } + + function test_get_terms_grandparent_zero() { + $tax = 'food'; + register_taxonomy( $tax, 'post', array( 'hierarchical' => true ) ); + + $cheese = $this->factory->term->create( array( 'name' => 'Cheese', 'taxonomy' => $tax ) ); + $cheddar = $this->factory->term->create( array( 'name' => 'Cheddar', 'parent' => $cheese, 'taxonomy' => $tax ) ); + $spread = $this->factory->term->create( array( 'name' => 'Spread', 'parent' => $cheddar, 'taxonomy' => $tax ) ); + $post_id = $this->factory->post->create(); + wp_set_post_terms( $post_id, $spread, $tax ); + $term = get_term( $spread, $tax ); + $this->assertEquals( 1, $term->count ); + + $terms = get_terms( $tax, array( 'parent' => 0, 'cache_domain' => $tax ) ); + $this->assertNotEmpty( $terms ); + $this->assertEquals( array( 'Cheese' ), wp_list_pluck( $terms, 'name' ) ); + + _unregister_taxonomy( $tax ); + } + + function test_get_terms_seven_levels_deep() { + $tax = 'deep'; + register_taxonomy( $tax, 'post', array( 'hierarchical' => true ) ); + $parent = 0; + $t = array(); + foreach ( range( 1, 7 ) as $depth ) { + $t[$depth] = $this->factory->term->create( array( 'name' => 'term' . $depth, 'taxonomy' => $tax, 'parent' => $parent ) ); + $parent = $t[$depth]; + } + $post_id = $this->factory->post->create(); + wp_set_post_terms( $post_id, $t[7], $tax ); + $term = get_term( $t[7], $tax ); + $this->assertEquals( 1, $term->count ); + + $terms = get_terms( $tax, array( 'parent' => 0, 'cache_domain' => $tax ) ); + $this->assertNotEmpty( $terms ); + $this->assertEquals( array( 'term1' ), wp_list_pluck( $terms, 'name' ) ); + + _unregister_taxonomy( $tax ); + } }