[wp-trac] [WordPress Trac] #57122: `wp_nav_menu()` throws undefined offset if a menu item's parent has a higher ID.

WordPress Trac noreply at wordpress.org
Wed Nov 16 03:34:18 UTC 2022


#57122: `wp_nav_menu()` throws undefined offset if a menu item's parent has a
higher ID.
---------------------------+-----------------------------
 Reporter:  peterwilsoncc  |      Owner:  (none)
     Type:  defect (bug)   |     Status:  new
 Priority:  normal         |  Milestone:  Awaiting Review
Component:  Menus          |    Version:  6.1
 Severity:  normal         |   Keywords:
  Focuses:                 |
---------------------------+-----------------------------
 Following [54478] for #28620, it's possible for `wp_nav_menu()` to throw
 an undefined offset notice if a menu item has a lower post `ID` than its
 parent.

 This can occur if the menu items are created and then restructured/re-
 parented after they are initially created.

 The following test demonstrates the problem.

 {{{#!php
 <?php

 // Add to tests/phpunit/tests/menu/wp-nav-menu.php

 public function test_parent_with_higher_id_should_not_error() {
         // Create a new level zero menu item.
         $new_lvl0_menu_item = wp_update_nav_menu_item(
                 self::$menu_id,
                 0,
                 array(
                         'menu-item-title'  => 'Root menu item with high
 ID',
                         'menu-item-url'    => '#',
                         'menu-item-status' => 'publish',
                 )
         );

         // Reparent level 1 menu item to the new level zero menu item.
         self::$lvl1_menu_item = wp_update_nav_menu_item(
                 self::$menu_id,
                 self::$lvl1_menu_item,
                 array(
                         'menu-item-parent-id' => $new_lvl0_menu_item,
                 )
         );

         // Delete the old level zero menu item.
         wp_delete_post( self::$lvl0_menu_item, true );

         // Render the menu.
         $menu_html = wp_nav_menu(
                 array(
                         'menu' => self::$menu_id,
                         'echo' => false,
                 )
         );

         $this->assertStringContainsString(
                 sprintf(
                         '<ul id="menu-test" class="menu"><li id="menu-
 item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom
 menu-item-has-children menu-item-%1$d">',
                         $new_lvl0_menu_item
                 ),
                 $menu_html,
                 'The level zero menu item should appear as the first menu
 item.'
         );

 }

 }}}


 Note: `wp_get_nav_menu_items()` queries by `menu_order`, so the sorting
 for items with a matching `menu_order` is somewhat undefined. Results may
 differ depending on the DB engine/version/phase of the moon.

 This is the result on my local environment:

 {{{
 $ phpunit --filter test_parent_with_higher_id_should_not_throw
 Installing...
 Running as single site... To run multisite, use -c
 tests/phpunit/multisite.xml
 Not running ajax tests. To execute these, use --group ajax.
 Not running ms-files tests. To execute these, use --group ms-files.
 Not running external-http tests. To execute these, use --group external-
 http.
 PHPUnit 7.5.20 by Sebastian Bergmann and contributors.

 E                                                                   1 / 1
 (100%)

 Time: 12.79 seconds, Memory: 242.05 MB

 There was 1 error:

 1) Tests_Menu_wpNavMenu::test_parent_with_higher_id_should_not_throw
 Undefined offset: 5

 /vagrant/wordpress-develop/src/wp-includes/nav-menu-template.php:210
 /vagrant/wordpress-develop/tests/phpunit/tests/menu/wp-nav-menu.php:300
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/57122>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list