[wp-trac] [WordPress Trac] #29213: Introduce capability for access to nav-menus.php
WordPress Trac
noreply at wordpress.org
Mon Aug 18 19:52:12 UTC 2014
#29213: Introduce capability for access to nav-menus.php
-------------------------+------------------------------
Reporter: westonruter | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Menus | Version: 3.0
Severity: normal | Resolution:
Keywords: needs-patch | Focuses: administration
-------------------------+------------------------------
Comment (by jesin):
I created patch **29213.diff** as a starting point based on changesheet
[29170] and added `edit_nav_menus` capability through the `map_meta_cap`
filter. However accessing **wp-admin/nav-menus.php** displayed the
following error:
> **You do not have sufficient permissions to access this page.**
This was because `user_can_access_admin_page()` was returning `false`.
Digging deeper I found that `$_wp_menu_nopriv` contained the following
value:
{{{
$_wp_menu_nopriv["nav-menus.php"] = true;
}}}
To test how `customize` worked I used the same filter and printed
`$_wp_menu_nopriv`. This is what I saw:
{{{
$_wp_menu_nopriv["customize.php?return=%2Fwp-admin%2Fcustomize.php"] =
true;
}}}
But **wp-admin/customize.php** was accessible, so I narrowed down to the
`user_can_access_admin_page()` function's following lines:
{{{
if ( isset( $_wp_menu_nopriv[$pagenow] ) )
return false;
}}}
The `$pagenow` variable only contains the filename without query strings
so when `customize` was used this line checked for `isset(
$_wp_menu_nopriv["customize.php"] )` which obviously caused this `if` loop
to be skipped with `user_can_access_admin_page()` returning `true`.
Now the question is why did **customize.php** and **nav-menus.php** end up
in the `$_wp_menu_nopriv` list when appropriate capabilities were being
used.
The answer is in **lines 93 - 117** of file **wp-
admin/includes/menu.php**. Specifically the following lines:
{{{
if ( $new_parent != $old_parent ) {
$_wp_real_parent_file[$old_parent] = $new_parent;
$menu[$id][2] = $new_parent;
}}}
This piece of code replaces the parent menu's filename with the filename
of its child menu. This results in the following values:
{{{
Array
(
[0] => Appearance
[1] => edit_theme_options
[2] => nav-menus.php
[3] =>
[4] => menu-top menu-icon-appearance
[5] => menu-appearance
[6] => dashicons-admin-appearance
)
}}}
Notice how this menu got its parent's capability requirement. This causes
**nav-menus.php** (or **customize.php?return=%2Fwp-
admin%2Fcustomize.php**) to be added to the `$_wp_menu_nopriv` list.
So when filenames are being replaced we should also replace their
capability requirement.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/29213#comment:2>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list