Opened 4 years ago
Last modified 6 weeks ago
#52035 new defect (bug)
The `add_submenu_page()` position is ignored.
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | |
Component: | Administration | Keywords: | has-patch needs-testing |
Focuses: | administration | Cc: |
Description
Hello,
I'm not sure that the add_submenu_page()
position argument is being applied properly. See the below example:
<?php add_action( 'admin_menu', function() { add_submenu_page( 'edit.php', 'Foo', 'Foo', 'list_users', 'foo', function() { echo 'Hello Foo'; }, 200, ); add_submenu_page( 'edit.php', 'Bar', 'Bar', 'list_users', 'bar', function() { echo 'Hello Bar'; }, 100, ); } );
I would expect "Bar" to appear before "Foo" since it has a lower position number. What ends up happening is whichever add_submenu_page()
was called first, gets position priority.
Attachments (1)
Change History (15)
This ticket was mentioned in PR #816 on WordPress/wordpress-develop by mukeshpanchal27.
4 years ago
#2
- Keywords has-patch added
Trac ticket: https://core.trac.wordpress.org/ticket/52035
#4
@
3 years ago
Hi @mukesh27 ,
I just stumbled upon this bug and had a look at your patch.
It doesn't solve the problem if there are multiple submenus being registered because apparently array keys get reset and the last menu registered will always end up in the last position.
I suggest start by writing some tests so we can cover many different situations. I'm happy to help testing and giving feedback to move this ticket forward.
And in the meantime I'm going to look for a workaround to my problem :)
#5
@
3 years ago
Also, it just occurred to me that there would be a problem if 2 submenus are registered using the same position.
This ticket was mentioned in Slack in #core by im_niloy. View the logs.
9 months ago
This ticket was mentioned in PR #6971 on WordPress/wordpress-develop by @rajinsharwar.
8 months ago
#9
- Keywords has-patch added; needs-patch removed
Fix menu position for the add_submenu_page()
Trac ticket: https://core.trac.wordpress.org/ticket/52035
#10
@
8 months ago
- Keywords needs-testing needs-unit-tests added
I changed the position of the code from @im_niloy, and removed the count() check.
#11
@
8 months ago
- Keywords needs-unit-tests removed
So according to https://core.trac.wordpress.org/ticket/39776#comment:18, it says "If a number larger than the number of items is passed, it is appended to the end". So, if the number passed is greater than the number of sub-menus, it will be auto appended in the end.
I have modified my PR to change this. Now the Menu items will be added in the array pretty much with the key of it's position passed. So now the array with the menu items would look like:
[0] => Array ( [0] => My Custom Page [1] => manage_options [2] => my_top_level_slug [3] => My Custom Page ) [200] => Array ( [0] => My Custom Page - 1 [1] => manage_options [2] => my_top_level_slug [3] => My Custom Page - 1 ) [100] => Array ( [0] => My Custom Page - 2 [1] => manage_options [2] => my_top_level_slug [3] => My Custom Page - 2 )
Of course, after the ksort, the arrays are arranged in ascending. this solves the issue that whenever any higher value is passed, it still follows the same rule of priority. Modified the unit test as well, so I do not think any new unit tests are necessary.
Feel free to add your thoughts!
#12
@
8 months ago
@leogermani I have added a case for the one you mentioned in https://core.trac.wordpress.org/ticket/52035#comment:5.
Now if the menus have larger $position passed, then it adds float values to arrange accordingly. Like for below:
add_submenu_page( 'my_top_level_slug', 'My Custom Submenu Page - 1', 'My Custom Submenu Page - 1',
'manage_options', 'my-secondary-slug', '', 200 );
add_submenu_page( 'my_top_level_slug', 'My Custom Submenu Page - 2', 'My Custom Submenu Page - 2',
'manage_options', 'my-secondary-slug', '', 200 );
The output will be:
[0] => Array ( [0] => My Custom Page [1] => manage_options [2] => my_top_level_slug [3] => My Custom Page ) [200] => Array ( [0] => My Custom Submenu Page - 1 [1] => manage_options [2] => my-secondary-slug [3] => My Custom Submenu Page - 1 ) [200.1] => Array ( [0] => My Custom Submenu Page - 2 [1] => manage_options [2] => my-secondary-slug [3] => My Custom Submenu Page - 2 )
Let me know if we should add a unit test for this case.
#13
@
8 months ago
Hi @rajinsharwar, thank you so much for working on this!
Your patch works fine in my tests and solves all the issues.
I do think we could take this opportunity to add a few more tests though, it should be simple.
There are 2 things we are not testing:
- All the tests that use that data provider add only one submenu with a custom position, after adding several submenus with no position informed. One of the things we are fixing here is the addition of several submenus with custom positions, I think we should test that.
- Now that you have changed how the array keys are handled, I think we could have a better test to check if the menu fell in the right position.
The data provider you are passing on array( 123456, 123456 )
for example looks like a weak test to me. We are only testing that the key was preserved, but we are not testing whether ksort
produced the expected outcome.
Maybe we could add a test that resets the array keys, or loops through the submenus, and test the actual position of each item.
Lastly, I'm not sure if this deserves a Dev Note, since we are changing how menus are stored, no longer with sequential numeric keys.
(let me know and I can help writing tests if you want)
Thanks for the report!
Moving to the Administration component, as Menus is specifically for the Menus screen and nav menu functions.