From 99cf0b7b90fadffb339c6a945e80c3455c3b1fac Mon Sep 17 00:00:00 2001 From: Ryan Boren Date: Fri, 17 Feb 2006 00:57:10 +0000 Subject: [PATCH] Dynamic menu reparenting. fixes #2257 git-svn-id: https://develop.svn.wordpress.org/trunk@3536 602fd350-edb4-49c9-b593-d223f7449a82 --- wp-admin/admin-functions.php | 50 ++++++++++++++++++++++++------------ wp-admin/menu-header.php | 2 +- wp-admin/menu.php | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/wp-admin/admin-functions.php b/wp-admin/admin-functions.php index b6eb4bcdfc..440d69eb67 100644 --- a/wp-admin/admin-functions.php +++ b/wp-admin/admin-functions.php @@ -1231,32 +1231,37 @@ function user_can_access_admin_page() { global $pagenow; global $menu; global $submenu; + global $menu_nopriv; $parent = get_admin_page_parent(); + + if ( isset($menu_nopriv[$pagenow]) ) + return false; - foreach ($menu as $menu_array) { - //echo "parent array: " . $menu_array[2]; - if ($menu_array[2] == $parent) { - if (!current_user_can($menu_array[1])) { - return false; - } else { - break; - } - } - } + if ( empty($parent) ) + return true; if (isset ($submenu[$parent])) { foreach ($submenu[$parent] as $submenu_array) { if ($submenu_array[2] == $pagenow) { - if (!current_user_can($submenu_array[1])) { - return false; - } else { + if (current_user_can($submenu_array[1])) return true; - } + else + return false; } } } + foreach ($menu as $menu_array) { + //echo "parent array: " . $menu_array[2]; + if ($menu_array[2] == $parent) { + if (current_user_can($menu_array[1])) + return true; + else + return false; + } + } + return true; } @@ -1313,8 +1318,12 @@ function get_admin_page_parent() { global $submenu; global $pagenow; global $plugin_page; + global $real_parent_file; + + if ( !empty ($parent_file) ) { + if ( isset($real_parent_file[$parent_file]) ) + $parent_file = $real_parent_file[$parent_file]; - if (isset ($parent_file) && !empty ($parent_file)) { return $parent_file; } @@ -1322,13 +1331,18 @@ function get_admin_page_parent() { foreach ($menu as $parent_menu) { if ($parent_menu[2] == $plugin_page) { $parent_file = $plugin_page; - return $plugin_page; + if ( isset($real_parent_file[$parent_file]) ) + $parent_file = $real_parent_file[$parent_file]; + + return $parent_file; } } } foreach (array_keys($submenu) as $parent) { foreach ($submenu[$parent] as $submenu_array) { + if ( isset($real_parent_file[$parent]) ) + $parent = $real_parent_file[$parent]; if ($submenu_array[2] == $pagenow) { $parent_file = $parent; return $parent; @@ -1363,8 +1377,12 @@ function add_menu_page($page_title, $menu_title, $access_level, $file, $function function add_submenu_page($parent, $page_title, $menu_title, $access_level, $file, $function = '') { global $submenu; global $menu; + global $real_parent_file; $parent = plugin_basename($parent); + if ( isset($real_parent_file[$parent]) ) + $parent = $real_parent_file[$parent]; + $file = plugin_basename($file); // If the parent doesn't already have a submenu, add a link to the parent diff --git a/wp-admin/menu-header.php b/wp-admin/menu-header.php index d3ba3308b8..8adac684a7 100644 --- a/wp-admin/menu-header.php +++ b/wp-admin/menu-header.php @@ -11,7 +11,7 @@ foreach ($menu as $item) { // 0 = name, 1 = capability, 2 = file if (( strcmp($self, $item[2]) == 0 && empty($parent_file)) || ($parent_file && ($item[2] == $parent_file))) $class = ' class="current"'; - if ( current_user_can($item[1]) ) { + if ( !empty($submenu[$item[2]]) || current_user_can($item[1]) ) { if ( file_exists(ABSPATH . "wp-content/plugins/{$item[2]}") ) echo "\n\t
  • {$item[0]}
  • "; else diff --git a/wp-admin/menu.php b/wp-admin/menu.php index ed58186c2e..ac4d3642ed 100644 --- a/wp-admin/menu.php +++ b/wp-admin/menu.php @@ -49,6 +49,51 @@ $submenu['plugins.php'][10] = array(__('Plugin Editor'), 'edit_plugins', 'plugin $submenu['themes.php'][5] = array(__('Themes'), 'switch_themes', 'themes.php'); $submenu['themes.php'][10] = array(__('Theme Editor'), 'edit_themes', 'theme-editor.php'); +// Loop over submenus and remove pages for which the user does not have privs. +foreach ($submenu as $parent => $sub) { + foreach ($sub as $index => $data) { + if ( ! current_user_can($data[1]) ) { + $menu_nopriv[$data[2]] = true; + unset($submenu[$parent][$index]); + } + } + + if ( empty($submenu[$parent]) ) + unset($submenu[$parent]); +} + +// Loop over the top-level menu. +// Remove menus that have no accessible submenus and require privs that the user does not have. +// Menus for which the original parent is not acessible due to lack of privs will have the next +// submenu in line be assigned as the new menu parent. +foreach ( $menu as $id => $data ) { + // If submenu is empty... + if ( empty($submenu[$data[2]]) ) { + // And user doesn't have privs, remove menu. + if ( ! current_user_can($data[1]) ) { + $menu_nopriv[$data[2]] = true; + unset($menu[$id]); + } + } else { + $subs = $submenu[$data[2]]; + $first_sub = array_shift($subs); + $old_parent = $data[2]; + $new_parent = $first_sub[2]; + // If the first submenu is not the same as the assigned parent, + // make the first submenu the new parent. + if ( $new_parent != $old_parent ) { + $real_parent_file[$old_parent] = $new_parent; + $menu[$id][2] = $new_parent; + + foreach ($submenu[$old_parent] as $index => $data) { + $submenu[$new_parent][$index] = $submenu[$old_parent][$index]; + unset($submenu[$old_parent][$index]); + } + unset($submenu[$old_parent]); + } + } +} + // Create list of page plugin hook names. foreach ($menu as $menu_page) { $admin_page_hooks[$menu_page[2]] = sanitize_title($menu_page[0]);