From 3b7187eade381d23ea221541796f026eeb6d5672 Mon Sep 17 00:00:00 2001 From: Boone Gorges Date: Tue, 29 Sep 2015 19:11:12 +0000 Subject: [PATCH] Fix 'exclude_tree' in `wp_list_categories()`. The 'exclude_tree' parameter must be compatible with 'hierarchical'; previously, 'hierarchical' canceled it out. This changeset also makes it so that 'exclude_tree' is compatible with 'exclude'. When both are passed, and 'hierarchical' is true, the descendant trees of terms in both parameters will be excluded from matched terms. Props tott, webord, MikeHansenMe. Fixes #12981. git-svn-id: https://develop.svn.wordpress.org/trunk@34696 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/category-template.php | 17 +++++++- .../tests/category/wpListCategories.php | 43 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/category-template.php b/src/wp-includes/category-template.php index 355b46b2e9..72b3e65d23 100644 --- a/src/wp-includes/category-template.php +++ b/src/wp-includes/category-template.php @@ -498,7 +498,9 @@ function wp_dropdown_categories( $args = '' ) { * @type string $feed_image URL of an image to use for the feed link. Default empty string. * @type int $child_of Term ID to retrieve child terms of. See {@link get_terms()}. Default 0. * @type array|string $exclude Array or comma/space-separated string of term IDs to exclude. - * See {@link get_terms()}. Default empty string. + * If `$hierarchical` is true, descendants of `$exclude` terms will also + * be excluded; see `$exclude_tree`. See {@link get_terms()}. + * Default empty string. * @type array|string $exclude_tree Array or comma/space-separated string of term IDs to exclude, along * with their descendants. See {@link get_terms()}. Default empty string. * @type bool|int $echo True to echo markup, false to return it. Default 1. @@ -536,8 +538,19 @@ function wp_list_categories( $args = '' ) { if ( !isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] ) $r['pad_counts'] = true; + // Descendants of exclusions should be excluded too. if ( true == $r['hierarchical'] ) { - $r['exclude_tree'] = $r['exclude']; + $exclude_tree = array(); + + if ( $r['exclude_tree'] ) { + $exclude_tree = array_merge( $exclude_tree, (array) $r['exclude_tree'] ); + } + + if ( $r['exclude'] ) { + $exclude_tree = array_merge( $exclude_tree, (array) $r['exclude'] ); + } + + $r['exclude_tree'] = $exclude_tree; $r['exclude'] = ''; } diff --git a/tests/phpunit/tests/category/wpListCategories.php b/tests/phpunit/tests/category/wpListCategories.php index 56ae395a9e..91031a667f 100644 --- a/tests/phpunit/tests/category/wpListCategories.php +++ b/tests/phpunit/tests/category/wpListCategories.php @@ -264,4 +264,47 @@ class Tests_Category_WpListCategories extends WP_UnitTestCase { $this->assertContains( '
  • Categories', $found ); } + + /** + * @ticket 12981 + */ + public function test_exclude_tree_should_be_respected() { + $c = $this->factory->category->create(); + $parent = $this->factory->category->create( array( 'name' => 'Parent', 'slug' => 'parent' ) ); + $child = $this->factory->category->create( array( 'name' => 'Child', 'slug' => 'child', 'parent' => $parent ) ); + + $args = array( 'echo' => 0, 'hide_empty' => 0, 'exclude_tree' => $parent ); + + $actual = wp_list_categories( $args ); + + $this->assertNotContains( '
  • ', $actual ); + + $this->assertNotContains( '
  • ', $actual ); + } + + /** + * @ticket 12981 + */ + public function test_exclude_tree_should_be_merged_with_exclude() { + $c = $this->factory->category->create(); + $parent = $this->factory->category->create( array( 'name' => 'Parent', 'slug' => 'parent' ) ); + $child = $this->factory->category->create( array( 'name' => 'Child', 'slug' => 'child', 'parent' => $parent ) ); + $parent2 = $this->factory->category->create( array( 'name' => 'Parent', 'slug' => 'parent2' ) ); + $child2 = $this->factory->category->create( array( 'name' => 'Child', 'slug' => 'child2', 'parent' => $parent2 ) ); + + $args = array( 'echo' => 0, 'hide_empty' => 0, 'exclude_tree' => $parent ); + + $actual = wp_list_categories( array( + 'echo' => 0, + 'hide_empty' => 0, + 'exclude' => $parent, + 'exclude_tree' => $parent2, + ) ); + + $this->assertNotContains( '
  • ', $actual ); + $this->assertNotContains( '
  • ', $actual ); + $this->assertNotContains( '
  • ', $actual ); + + $this->assertNotContains( '
  • ', $actual ); + } }