[wp-trac] [WordPress Trac] #46081: get_admin_page_title() returns nothing
WordPress Trac
noreply at wordpress.org
Wed Jan 23 14:32:48 UTC 2019
#46081: get_admin_page_title() returns nothing
----------------------------+-----------------------------
Reporter: grapestain | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Administration | Version: 5.0.3
Severity: minor | Keywords:
Focuses: administration |
----------------------------+-----------------------------
The function `get_admin_page_title()` returns nothing in case a menu page
is registered using `add_menu_page()` and accessed with an url such as
.../wp-admin/**options.php**?page=my_page_slug
Normally one should access the custom admin page using .../wp-
admin/**admin.php**?page=my_page_slug, so it's not really that big of an
issue. Actually, I've encountered this, because I've been using some old
code samples, which pointed me to the options.php link. I didn't notice
the difference, only that sometimes I have a title (from
`get_admin_page_title()`) and sometimes not.
While debugging the issue, I found this:
On .../wp-admin/**admin.php**?page=my_page_slug the `$title` global
already have the title populated at the time `get_admin_page_title()` is
called, so it just returns that, all is good.
On .../wp-admin/**options.php**?page=my_page_slug however the `$title`
global is empty, so the `get_admin_page_title()` function tries to
determine the title from the `$menu` global, which contains all registered
menu entries. Nice.
{{{#!php
foreach ( (array)$menu as $menu_array ) {
if ( isset( $menu_array[3] ) ) {
if ( $menu_array[2] == $pagenow ) {
$title = $menu_array[3];
return $menu_array[3];
} elseif ( isset( $plugin_page ) && ($plugin_page ==
$menu_array[2] ) && ($hook == $menu_array[3] ) ) {
$title = $menu_array[3];
return $menu_array[3];
}
/*...*/
}
/*...*/
}
}}}
(from https://core.trac.wordpress.org/browser/tags/5.0.3/src/wp-
admin/includes/plugin.php#L1608)
The problem, however, is that when it loops over the `$menu` array, it
first compares `$pagenow` to `$menu_array[2]` (which contains the
menu_slug), but as `$pagenow` is "options.php" this check fails, so then
it moves on to another check.
Now this is the part I think the implementation has a mistake. The check
consist of 3 parts:
- `isset( $plugin_page )` -> true, as this variable contains the page_slug
(as well).
- `($plugin_page == $menu_array[2] )` -> true, when the for loop is at the
right menu entry, because `$menu_array[2]` has the page_slug too.
- `$hook == $menu_array[3]` -> **false, but it should be true**. See the
`$hook` contains the actual page hook, however the menu array does not
store the page hooks under index 3, but index 5. Index 3 is actually the
Title, we are trying to find out, as it is visible from being the element
of the `$menu_array` being set as the global `$title` var and returned in
the next line.
You can confirm this by looking at the `add_menu_page()` function, whihc
defines the same array referenced above as `$menu_array` as:
{{{#!php
$new_menu = array( $menu_title, $capability, $menu_slug, $page_title,
'menu-top ' . $icon_class . $hookname, $hookname, $icon_url );
}}}
(https://core.trac.wordpress.org/browser/tags/5.0.3/src/wp-
admin/includes/plugin.php#L1112)
`$hookname` is the 6th element of the array, not the 4th as assumed in the
check above.
Now, please note, that I'm not trying to say WordPress should support
loading admin pages on the options.php the same way as admin.php, however:
- The main thing is that L1612 above compares potatoes to apples when
comparing `$hook == $menu_array[3]`, so regardless of what special cases
this code should run other than trying to load an admin page using
options.php, it cannot be good. Either the whole criteria is pointless, or
it should be `$hook == $menu_array[5]` instead, because in it's current
form it'd not evaluate to true. (Or if it does, that indicates something
else is being broken, and should be fixed too!)
- If accessing an admin page over options.php is not adequate, maybe
WordPress should make a warning or notice about it, or simply refuse to
render the page. Normally I'd not suggest WordPress should be responsible
for enforcing admin pages to be properly implemented, however, this is
very misleading to be able to render an admin page almost correctly, in an
incorrect way. I have `WP_DEBUG` on, but I saw no other symptoms of using
a wrong URL, other than the missing Title. Everything else worked as
expected.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/46081>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list