From f6267a04eee1bd82b4d283290e5ccb442eafb2ef Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sun, 6 Oct 2019 15:04:18 +0000 Subject: [PATCH] Menus: In `Walker_Nav_Menu`, `Walker_Category`, and `Walker_Page`, properly output link attributes having a legitimate "empty" value, for example an HTML data attribute with a value of zero (0). Props nevma, AkSDvP, greenshady, SergeyBiryukov. Fixes #47720. git-svn-id: https://develop.svn.wordpress.org/trunk@46413 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-walker-category.php | 2 +- src/wp-includes/class-walker-nav-menu.php | 2 +- src/wp-includes/class-walker-page.php | 2 +- .../phpunit/tests/category/walkerCategory.php | 92 +++++++++++++++++++ .../tests/menu/walker-nav-menu-edit.php | 2 +- tests/phpunit/tests/menu/walker-nav-menu.php | 88 +++++++++++++++++- tests/phpunit/tests/post/walkerPage.php | 87 ++++++++++++++++++ 7 files changed, 267 insertions(+), 8 deletions(-) create mode 100644 tests/phpunit/tests/category/walkerCategory.php create mode 100644 tests/phpunit/tests/post/walkerPage.php diff --git a/src/wp-includes/class-walker-category.php b/src/wp-includes/class-walker-category.php index 997993710a..16ad852e5b 100644 --- a/src/wp-includes/class-walker-category.php +++ b/src/wp-includes/class-walker-category.php @@ -139,7 +139,7 @@ class Walker_Category extends Walker { $attributes = ''; foreach ( $atts as $attr => $value ) { - if ( ! empty( $value ) ) { + if ( is_scalar( $value ) && '' !== $value && false !== $value ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } diff --git a/src/wp-includes/class-walker-nav-menu.php b/src/wp-includes/class-walker-nav-menu.php index 06070ed0c8..1d0fd714f7 100644 --- a/src/wp-includes/class-walker-nav-menu.php +++ b/src/wp-includes/class-walker-nav-menu.php @@ -203,7 +203,7 @@ class Walker_Nav_Menu extends Walker { $attributes = ''; foreach ( $atts as $attr => $value ) { - if ( ! empty( $value ) ) { + if ( is_scalar( $value ) && '' !== $value && false !== $value ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } diff --git a/src/wp-includes/class-walker-page.php b/src/wp-includes/class-walker-page.php index 27e06c9b5d..eac5a4f9fd 100644 --- a/src/wp-includes/class-walker-page.php +++ b/src/wp-includes/class-walker-page.php @@ -182,7 +182,7 @@ class Walker_Page extends Walker { $attributes = ''; foreach ( $atts as $attr => $value ) { - if ( ! empty( $value ) ) { + if ( is_scalar( $value ) && '' !== $value && false !== $value ) { $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value ); $attributes .= ' ' . $attr . '="' . $value . '"'; } diff --git a/tests/phpunit/tests/category/walkerCategory.php b/tests/phpunit/tests/category/walkerCategory.php new file mode 100644 index 0000000000..aec86e173a --- /dev/null +++ b/tests/phpunit/tests/category/walkerCategory.php @@ -0,0 +1,92 @@ +walker = new Walker_Category(); + } + + /** + * @ticket 47720 + * + * @dataProvider data_start_el_with_empty_attributes + */ + public function test_start_el_with_empty_attributes( $value, $expected ) { + $output = ''; + $category = $this->factory->category->create_and_get(); + $link = get_term_link( $category ); + + $args = array( + 'use_desc_for_title' => 0, + 'style' => 'list', + ); + + add_filter( + 'category_list_link_attributes', + function( $atts ) use ( $value ) { + $atts['data-test'] = $value; + return $atts; + } + ); + + $this->walker->start_el( $output, $category, 0, $args ); + + if ( '' !== $expected ) { + $expected = sprintf( ' data-test="%s"', $expected ); + } + + $this->assertSame( "
  • term_id}\">{$category->name}", trim( $output ) ); + } + + public function data_start_el_with_empty_attributes() { + return array( + array( + '', + '', + ), + array( + 0, + '0', + ), + array( + 0.0, + '0', + ), + array( + '0', + '0', + ), + array( + null, + '', + ), + array( + false, + '', + ), + array( + true, + '1', + ), + array( + array(), + '', + ), + ); + } +} diff --git a/tests/phpunit/tests/menu/walker-nav-menu-edit.php b/tests/phpunit/tests/menu/walker-nav-menu-edit.php index 6bf931608d..73982768e2 100644 --- a/tests/phpunit/tests/menu/walker-nav-menu-edit.php +++ b/tests/phpunit/tests/menu/walker-nav-menu-edit.php @@ -4,7 +4,7 @@ * @group navmenus * @group walker */ -class Tests_Walker_Nav_Menu_Edit extends WP_UnitTestCase { +class Tests_Menu_Walker_Nav_Menu_Edit extends WP_UnitTestCase { protected $_wp_nav_menu_max_depth; function setUp() { diff --git a/tests/phpunit/tests/menu/walker-nav-menu.php b/tests/phpunit/tests/menu/walker-nav-menu.php index e60a9550d4..a564b08545 100644 --- a/tests/phpunit/tests/menu/walker-nav-menu.php +++ b/tests/phpunit/tests/menu/walker-nav-menu.php @@ -3,7 +3,7 @@ * @group navmenus * @group walker */ -class Tests_Walker_Nav_Menu extends WP_UnitTestCase { +class Tests_Menu_Walker_Nav_Menu extends WP_UnitTestCase { /** * @var \Walker_Nav_Menu The instance of the walker. @@ -18,7 +18,7 @@ class Tests_Walker_Nav_Menu extends WP_UnitTestCase { parent::setUp(); - /** Walker_Nav_Menu_Edit class */ + /** Walker_Nav_Menu class */ require_once ABSPATH . 'wp-includes/class-walker-nav-menu.php'; $this->walker = new Walker_Nav_Menu(); @@ -37,9 +37,9 @@ class Tests_Walker_Nav_Menu extends WP_UnitTestCase { } /** - * Tests when an items target it _blank, that rel="'noopener noreferrer" is added. + * Tests when an item's target is _blank, that rel="noopener noreferrer" is added. * - * @ticket #43290 + * @ticket 43290 */ public function test_noopener_no_referrer_for_target_blank() { $expected = ''; @@ -66,4 +66,84 @@ class Tests_Walker_Nav_Menu extends WP_UnitTestCase { $this->assertSame( "
  • {$post_title}", $expected ); } + + /** + * @ticket 47720 + * + * @dataProvider data_start_el_with_empty_attributes + */ + public function test_start_el_with_empty_attributes( $value, $expected ) { + $output = ''; + $post_id = $this->factory->post->create(); + $post_title = get_the_title( $post_id ); + + $item = array( + 'ID' => $post_id, + 'object_id' => $post_id, + 'title' => $post_title, + 'target' => '', + 'xfn' => '', + 'current' => false, + ); + + $args = array( + 'before' => '', + 'after' => '', + 'link_before' => '', + 'link_after' => '', + ); + + add_filter( + 'nav_menu_link_attributes', + function( $atts ) use ( $value ) { + $atts['data-test'] = $value; + return $atts; + } + ); + + $this->walker->start_el( $output, (object) $item, 0, (object) $args ); + + if ( '' !== $expected ) { + $expected = sprintf( ' data-test="%s"', $expected ); + } + + $this->assertSame( "
  • {$post_title}", $output ); + } + + public function data_start_el_with_empty_attributes() { + return array( + array( + '', + '', + ), + array( + 0, + '0', + ), + array( + 0.0, + '0', + ), + array( + '0', + '0', + ), + array( + null, + '', + ), + array( + false, + '', + ), + array( + true, + '1', + ), + array( + array(), + '', + ), + ); + } } diff --git a/tests/phpunit/tests/post/walkerPage.php b/tests/phpunit/tests/post/walkerPage.php new file mode 100644 index 0000000000..14963e9b32 --- /dev/null +++ b/tests/phpunit/tests/post/walkerPage.php @@ -0,0 +1,87 @@ +walker = new Walker_Page(); + } + + /** + * @ticket 47720 + * + * @dataProvider data_start_el_with_empty_attributes + */ + public function test_start_el_with_empty_attributes( $value, $expected ) { + $output = ''; + $page = $this->factory->post->create_and_get( array( 'post_type' => 'page' ) ); + $link = get_permalink( $page ); + + add_filter( + 'page_menu_link_attributes', + function( $atts ) use ( $value ) { + $atts['data-test'] = $value; + return $atts; + } + ); + + $this->walker->start_el( $output, $page, 0 ); + + if ( '' !== $expected ) { + $expected = sprintf( ' data-test="%s"', $expected ); + } + + $this->assertSame( "
  • ID}\">{$page->post_title}", $output ); + } + + public function data_start_el_with_empty_attributes() { + return array( + array( + '', + '', + ), + array( + 0, + '0', + ), + array( + 0.0, + '0', + ), + array( + '0', + '0', + ), + array( + null, + '', + ), + array( + false, + '', + ), + array( + true, + '1', + ), + array( + array(), + '', + ), + ); + } +}