From 2e389fef98d2091e46e70ae5af6b201f56ea12f4 Mon Sep 17 00:00:00 2001 From: Sainath Poojary Date: Mon, 23 Jun 2025 15:49:30 +0530 Subject: [PATCH 1/5] Post: Fix `wp_list_pages()` to correctly honor `exclude` with `depth` parameter --- src/wp-includes/class-wp-walker.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/class-wp-walker.php b/src/wp-includes/class-wp-walker.php index df67921c2746c..0d91c82e2bd16 100644 --- a/src/wp-includes/class-wp-walker.php +++ b/src/wp-includes/class-wp-walker.php @@ -253,14 +253,17 @@ public function walk( $elements, $max_depth, ...$args ) { } /* - * If we are displaying all levels, and remaining children_elements is not empty, - * then we got orphans, which should be displayed regardless. - */ - if ( ( 0 === $max_depth ) && count( $children_elements ) > 0 ) { - $empty_array = array(); - foreach ( $children_elements as $orphans ) { - foreach ( $orphans as $op ) { - $this->display_element( $op, $empty_array, 1, 0, $args, $output ); + * If we are displaying all levels (depth=0), + * OR if specific parents were excluded with limited depth, + * we may have got orphans, which should be displayed regardless. + */ + if ( 0 === $max_depth || ( $max_depth > 0 && ! empty( $args[0]['exclude'] ) ) ) { + if ( count( $children_elements ) > 0 ) { + $empty_array = array(); + foreach ( $children_elements as $orphans ) { + foreach ( $orphans as $op ) { + $this->display_element( $op, $empty_array, 1, 0, $args, $output ); + } } } } From c9a0da66798ffeba18e79f5e47dcccbe1a3c2821 Mon Sep 17 00:00:00 2001 From: Sainath Poojary Date: Mon, 23 Jun 2025 17:45:24 +0530 Subject: [PATCH 2/5] Tests: Add unit test for `wp_list_pages()` with `exclude` and `depth` --- tests/phpunit/tests/post/wpListPages.php | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/phpunit/tests/post/wpListPages.php b/tests/phpunit/tests/post/wpListPages.php index f059591219b1a..e81b8a5138a50 100644 --- a/tests/phpunit/tests/post/wpListPages.php +++ b/tests/phpunit/tests/post/wpListPages.php @@ -540,4 +540,36 @@ public function test_wp_list_pages_classes_with_hierarchical_cpt() { 'The output should contain exactly one "current_page_item" class.' ); } + + /** + * @ticket 27326 + */ + public function test_wp_list_page_combo_exclude_depth() { + $args = array( + 'echo' => false, + 'exclude' => self::$parent_3, + 'depth' => 3, + ); + + $expected = ''; + + $this->assertSameIgnoreEOL( $expected, wp_list_pages( $args ) ); + } } From 1808a3286405931d54036cea117c920725fcfbe6 Mon Sep 17 00:00:00 2001 From: Sainath Poojary Date: Tue, 24 Jun 2025 13:23:23 +0530 Subject: [PATCH 3/5] Canonical: Fix failing unit test --- src/wp-includes/class-wp-walker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-walker.php b/src/wp-includes/class-wp-walker.php index 0d91c82e2bd16..7578dea43f1da 100644 --- a/src/wp-includes/class-wp-walker.php +++ b/src/wp-includes/class-wp-walker.php @@ -257,7 +257,7 @@ public function walk( $elements, $max_depth, ...$args ) { * OR if specific parents were excluded with limited depth, * we may have got orphans, which should be displayed regardless. */ - if ( 0 === $max_depth || ( $max_depth > 0 && ! empty( $args[0]['exclude'] ) ) ) { + if ( 0 === $max_depth || ( $max_depth > 0 && ! empty( $args[0]->exclude ) ) ) { if ( count( $children_elements ) > 0 ) { $empty_array = array(); foreach ( $children_elements as $orphans ) { From e056a06edd5778efb2489e2ec6a800ce35afa7eb Mon Sep 17 00:00:00 2001 From: Sainath Poojary Date: Tue, 24 Jun 2025 13:39:11 +0530 Subject: [PATCH 4/5] Canonical: Fix failing unit test --- src/wp-includes/class-wp-walker.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/class-wp-walker.php b/src/wp-includes/class-wp-walker.php index 7578dea43f1da..13ffd9f2e8fc8 100644 --- a/src/wp-includes/class-wp-walker.php +++ b/src/wp-includes/class-wp-walker.php @@ -252,13 +252,23 @@ public function walk( $elements, $max_depth, ...$args ) { $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output ); } + $has_excluded_parents = false; + + if ( $max_depth > 0 ) { + if ( is_array( $args[0] ) && ! empty( $args[0]['exclude'] ) ) { + $has_excluded_parents = true; + } elseif ( is_object( $args[0] ) && ! empty( $args[0]->exclude ) ) { + $has_excluded_parents = true; + } + } + /* - * If we are displaying all levels (depth=0), + * If we are displaying all levels (depth = 0), * OR if specific parents were excluded with limited depth, * we may have got orphans, which should be displayed regardless. */ - if ( 0 === $max_depth || ( $max_depth > 0 && ! empty( $args[0]->exclude ) ) ) { - if ( count( $children_elements ) > 0 ) { + if ( 0 === $max_depth || $has_excluded_parents ) { + if ( ! empty( $children_elements ) ) { $empty_array = array(); foreach ( $children_elements as $orphans ) { foreach ( $orphans as $op ) { From e0d1c8aeea4929bf84a0c883e115af2c5d0d84a9 Mon Sep 17 00:00:00 2001 From: Sainath Poojary Date: Tue, 24 Jun 2025 15:22:48 +0530 Subject: [PATCH 5/5] Post: Fix condition to check for excluded parents in Walker class --- src/wp-includes/class-wp-walker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-walker.php b/src/wp-includes/class-wp-walker.php index 13ffd9f2e8fc8..01f47c1f7962b 100644 --- a/src/wp-includes/class-wp-walker.php +++ b/src/wp-includes/class-wp-walker.php @@ -254,7 +254,7 @@ public function walk( $elements, $max_depth, ...$args ) { $has_excluded_parents = false; - if ( $max_depth > 0 ) { + if ( $max_depth > 0 && isset( $args[0] ) ) { if ( is_array( $args[0] ) && ! empty( $args[0]['exclude'] ) ) { $has_excluded_parents = true; } elseif ( is_object( $args[0] ) && ! empty( $args[0]->exclude ) ) {