From e8a65ceb7aba5b064d2decd19e56fe60641f876e Mon Sep 17 00:00:00 2001 From: dan-zakirov Date: Mon, 2 Mar 2026 15:22:50 +0300 Subject: [PATCH 1/3] FIX: add default args to Walker_Comment methods to prevent PHP warnings Walker_Comment methods access $args keys (style, short_ping, format, avatar_size, max_depth) without checking if they exist. When called with an empty $args array, this produces PHP warnings on PHP 8.0+. Added wp_parse_args() with defaults matching wp_list_comments() at the top of each affected method: start_lvl, end_lvl, start_el, end_el, ping, comment, html5_comment. Added PHPUnit tests to verify no warnings are produced when Walker_Comment methods are called with an empty args array. Trac: https://core.trac.wordpress.org/ticket/56539 --- src/wp-includes/class-walker-comment.php | 54 +++++++++++++++++ tests/phpunit/tests/comment/walker.php | 75 ++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/src/wp-includes/class-walker-comment.php b/src/wp-includes/class-walker-comment.php index 3d2eb012e4903..31ff51edd6090 100644 --- a/src/wp-includes/class-walker-comment.php +++ b/src/wp-includes/class-walker-comment.php @@ -53,6 +53,13 @@ class Walker_Comment extends Walker { * @param array $args Optional. Uses 'style' argument for type of HTML list. Default empty array. */ public function start_lvl( &$output, $depth = 0, $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'style' => 'ul', + ) + ); + $GLOBALS['comment_depth'] = $depth + 1; switch ( $args['style'] ) { @@ -82,6 +89,13 @@ public function start_lvl( &$output, $depth = 0, $args = array() ) { * Default empty array. */ public function end_lvl( &$output, $depth = 0, $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'style' => 'ul', + ) + ); + $GLOBALS['comment_depth'] = $depth + 1; switch ( $args['style'] ) { @@ -171,6 +185,14 @@ public function display_element( $element, &$children_elements, $max_depth, $dep * @param int $current_object_id Optional. ID of the current comment. Default 0. */ public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) { + $args = wp_parse_args( + $args, + array( + 'short_ping' => false, + 'format' => 'xhtml', + ) + ); + // Restores the more descriptive, specific name for use within this method. $comment = $data_object; @@ -223,6 +245,13 @@ public function start_el( &$output, $data_object, $depth = 0, $args = array(), $ * @param array $args Optional. An array of arguments. Default empty array. */ public function end_el( &$output, $data_object, $depth = 0, $args = array() ) { + $args = wp_parse_args( + $args, + array( + 'style' => 'ul', + ) + ); + if ( ! empty( $args['end-callback'] ) ) { ob_start(); call_user_func( @@ -253,6 +282,13 @@ public function end_el( &$output, $data_object, $depth = 0, $args = array() ) { * @param array $args An array of arguments. */ protected function ping( $comment, $depth, $args ) { + $args = wp_parse_args( + $args, + array( + 'style' => 'ul', + ) + ); + $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> < id="comment-" > @@ -297,6 +333,15 @@ public function filter_comment_text( $comment_text, $comment ) { * @param array $args An array of arguments. */ protected function comment( $comment, $depth, $args ) { + $args = wp_parse_args( + $args, + array( + 'style' => 'ul', + 'avatar_size' => 32, + 'max_depth' => '', + ) + ); + if ( 'div' === $args['style'] ) { $tag = 'div'; $add_below = 'comment'; @@ -407,6 +452,15 @@ protected function comment( $comment, $depth, $args ) { * @param array $args An array of arguments. */ protected function html5_comment( $comment, $depth, $args ) { + $args = wp_parse_args( + $args, + array( + 'style' => 'ul', + 'avatar_size' => 32, + 'max_depth' => '', + ) + ); + $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; $commenter = wp_get_current_commenter(); diff --git a/tests/phpunit/tests/comment/walker.php b/tests/phpunit/tests/comment/walker.php index 504c5e3b0f2a9..8fa8da6defe54 100644 --- a/tests/phpunit/tests/comment/walker.php +++ b/tests/phpunit/tests/comment/walker.php @@ -54,6 +54,81 @@ public function test_has_children() { array( $comment_child, $comment_parent ) ); } + + /** + * @ticket 56539 + */ + public function test_start_lvl_with_empty_args_should_not_produce_warnings() { + $walker = new Walker_Comment(); + $output = ''; + + $walker->start_lvl( $output, 0, array() ); + + $this->assertStringContainsString( '', $output ); + } + + /** + * @ticket 56539 + */ + public function test_end_el_with_empty_args_should_not_produce_warnings() { + $comment_id = self::factory()->comment->create( array( 'comment_post_ID' => $this->post_id ) ); + $comment = get_comment( $comment_id ); + $walker = new Walker_Comment(); + $output = ''; + + $walker->end_el( $output, $comment, 0, array() ); + + $this->assertStringContainsString( '', $output ); + } + + /** + * @ticket 56539 + */ + public function test_start_el_with_empty_args_should_not_produce_warnings() { + $comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $this->post_id, + 'comment_type' => 'comment', + ) + ); + $comment = get_comment( $comment_id ); + $walker = new Walker_Comment(); + $output = ''; + + $walker->start_el( $output, $comment, 0, array() ); + + $this->assertNotEmpty( $output ); + } + + /** + * @ticket 56539 + */ + public function test_walk_with_empty_args_should_not_produce_warnings() { + $comment_id = self::factory()->comment->create( + array( + 'comment_post_ID' => $this->post_id, + 'comment_type' => 'comment', + ) + ); + $comments = array( get_comment( $comment_id ) ); + $walker = new Walker_Comment(); + + $output = $walker->walk( $comments, -1, array() ); + + $this->assertNotEmpty( $output ); + } } class Comment_Callback_Test_Helper { From 2b44eb0b225a6db319ee44043f4f28d1068a7bd2 Mon Sep 17 00:00:00 2001 From: dan-zakirov Date: Tue, 3 Mar 2026 11:54:35 +0300 Subject: [PATCH 2/3] REF: refactored Walker_Comment to use get_args() helper method - Replaced duplicated wp_parse_args() calls with a single get_args() helper - All 7 methods now use $this->get_args( $args ) for consistency - Single source of defaults: style, avatar_size, format, short_ping, max_depth Affected: src/wp-includes/class-walker-comment.php --- src/wp-includes/class-walker-comment.php | 75 +++++++++--------------- 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/src/wp-includes/class-walker-comment.php b/src/wp-includes/class-walker-comment.php index 31ff51edd6090..dad061003c427 100644 --- a/src/wp-includes/class-walker-comment.php +++ b/src/wp-includes/class-walker-comment.php @@ -40,6 +40,27 @@ class Walker_Comment extends Walker { 'id' => 'comment_ID', ); + /** + * Parses arguments with defaults. + * + * @since unreleased + * + * @param array $args Arguments to parse. + * @return array Parsed arguments. + */ + protected function get_args( array $args ): array { + return array_merge( + array( + 'style' => 'ul', + 'avatar_size' => 32, + 'format' => 'xhtml', + 'short_ping' => false, + 'max_depth' => '', + ), + $args + ); + } + /** * Starts the list before the elements are added. * @@ -53,12 +74,7 @@ class Walker_Comment extends Walker { * @param array $args Optional. Uses 'style' argument for type of HTML list. Default empty array. */ public function start_lvl( &$output, $depth = 0, $args = array() ) { - $args = wp_parse_args( - $args, - array( - 'style' => 'ul', - ) - ); + $args = $this->get_args( $args ); $GLOBALS['comment_depth'] = $depth + 1; @@ -89,12 +105,7 @@ public function start_lvl( &$output, $depth = 0, $args = array() ) { * Default empty array. */ public function end_lvl( &$output, $depth = 0, $args = array() ) { - $args = wp_parse_args( - $args, - array( - 'style' => 'ul', - ) - ); + $args = $this->get_args( $args ); $GLOBALS['comment_depth'] = $depth + 1; @@ -185,13 +196,7 @@ public function display_element( $element, &$children_elements, $max_depth, $dep * @param int $current_object_id Optional. ID of the current comment. Default 0. */ public function start_el( &$output, $data_object, $depth = 0, $args = array(), $current_object_id = 0 ) { - $args = wp_parse_args( - $args, - array( - 'short_ping' => false, - 'format' => 'xhtml', - ) - ); + $args = $this->get_args( $args ); // Restores the more descriptive, specific name for use within this method. $comment = $data_object; @@ -245,12 +250,7 @@ public function start_el( &$output, $data_object, $depth = 0, $args = array(), $ * @param array $args Optional. An array of arguments. Default empty array. */ public function end_el( &$output, $data_object, $depth = 0, $args = array() ) { - $args = wp_parse_args( - $args, - array( - 'style' => 'ul', - ) - ); + $args = $this->get_args( $args ); if ( ! empty( $args['end-callback'] ) ) { ob_start(); @@ -282,12 +282,7 @@ public function end_el( &$output, $data_object, $depth = 0, $args = array() ) { * @param array $args An array of arguments. */ protected function ping( $comment, $depth, $args ) { - $args = wp_parse_args( - $args, - array( - 'style' => 'ul', - ) - ); + $args = $this->get_args( $args ); $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> @@ -333,14 +328,7 @@ public function filter_comment_text( $comment_text, $comment ) { * @param array $args An array of arguments. */ protected function comment( $comment, $depth, $args ) { - $args = wp_parse_args( - $args, - array( - 'style' => 'ul', - 'avatar_size' => 32, - 'max_depth' => '', - ) - ); + $args = $this->get_args( $args ); if ( 'div' === $args['style'] ) { $tag = 'div'; @@ -452,14 +440,7 @@ protected function comment( $comment, $depth, $args ) { * @param array $args An array of arguments. */ protected function html5_comment( $comment, $depth, $args ) { - $args = wp_parse_args( - $args, - array( - 'style' => 'ul', - 'avatar_size' => 32, - 'max_depth' => '', - ) - ); + $args = $this->get_args( $args ); $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; From 778956340dde07f6db0a195aff8be7ea62f99feb Mon Sep 17 00:00:00 2001 From: dan-zakirov Date: Tue, 3 Mar 2026 23:26:21 +0300 Subject: [PATCH 3/3] FIX: use dynamic format default in get_args() to match wp_list_comments() - Replaced hardcoded 'xhtml' with current_theme_supports() check - Matches the format default logic used in wp_list_comments() Affected: src/wp-includes/class-walker-comment.php --- src/wp-includes/class-walker-comment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-walker-comment.php b/src/wp-includes/class-walker-comment.php index dad061003c427..3ce95692c0b45 100644 --- a/src/wp-includes/class-walker-comment.php +++ b/src/wp-includes/class-walker-comment.php @@ -53,7 +53,7 @@ protected function get_args( array $args ): array { array( 'style' => 'ul', 'avatar_size' => 32, - 'format' => 'xhtml', + 'format' => current_theme_supports( 'html5', 'comment-list' ) ? 'html5' : 'xhtml', 'short_ping' => false, 'max_depth' => '', ),