$a = $a[2]; $b = $b[2]; if (isset($menu_order[$a]) && !isset($menu_order[$b])) { return -1; } elseif (!isset($menu_order[$a]) && isset($menu_order[$b])) { return 1; } elseif (isset($menu_order[$a]) && isset($menu_order[$b])) { if ($menu_order[$a] == $menu_order[$b]) { return 0; } return $menu_order[$a] < $menu_order[$b] ? -1 : 1; } else { return $default_menu_order[$a] <= $default_menu_order[$b] ? -1 : 1; } } usort($menu, 'sort_menu'); unset($menu_order, $default_menu_order); } // Remove the last menu item if it is a separator. $last_menu_key = array_keys($menu); $last_menu_key = array_pop($last_menu_key); if (!empty($menu) && 'wp-menu-separator' == $menu[$last_menu_key][4]) { unset($menu[$last_menu_key]); } unset($last_menu_key); if (!user_can_access_admin_page()) { do_action('admin_page_access_denied'); wp_die(__('You do not have sufficient permissions to access this page.')); } $menu = add_menu_classes($menu);
/** * Filter a menu so that it can be handed to _wp_menu_output(). This method basically * emulates the filtering that WordPress does in /wp-admin/includes/menu.php, with a few * additions of our own. * * - Removes inaccessible items and superfluous separators. * * - Sets accessible items to a capability that the user is guaranteed to have to prevent * _wp_menu_output() from choking on plugin-specific capabilities like "cap1,cap2+not:cap3". * * - Adds position-dependent CSS classes. * * @param array $menu * @param array $submenu * @return array An array with two items - the filtered menu and submenu. */ private function filter_menu($menu, $submenu) { global $_wp_menu_nopriv; //Caution: Modifying this array could lead to unexpected consequences. //Remove sub-menus which the user shouldn't be able to access, //and ensure the rest are visible. foreach ($submenu as $parent => $items) { foreach ($items as $index => $data) { if (!$this->current_user_can($data[1])) { unset($submenu[$parent][$index]); $_wp_submenu_nopriv[$parent][$data[2]] = true; } else { //The menu might be set to some kind of special capability that is only valid //within this plugin and not WP in general. Ensure WP doesn't choke on it. //(This is safe - we'll double-check the caps when the user tries to access a page.) $submenu[$parent][$index][1] = 'exist'; //All users have the 'exist' cap. } } if (empty($submenu[$parent])) { unset($submenu[$parent]); } } //Remove menus that have no accessible sub-menus and require privileges that the user does not have. //Ensure the rest are visible. Run re-parent loop again. foreach ($menu as $id => $data) { if (!$this->current_user_can($data[1])) { $_wp_menu_nopriv[$data[2]] = true; } else { $menu[$id][1] = 'exist'; } //If there is only one submenu and it is has same destination as the parent, //remove the submenu. if (!empty($submenu[$data[2]]) && 1 == count($submenu[$data[2]])) { $subs = $submenu[$data[2]]; $first_sub = array_shift($subs); if ($data[2] == $first_sub[2]) { unset($submenu[$data[2]]); } } //If submenu is empty... if (empty($submenu[$data[2]])) { // And user doesn't have privs, remove menu. if (isset($_wp_menu_nopriv[$data[2]])) { unset($menu[$id]); } } } unset($id, $data, $subs, $first_sub); //Remove any duplicated separators $separator_found = false; foreach ($menu as $id => $data) { if (0 == strcmp('wp-menu-separator', $data[4])) { if ($separator_found) { unset($menu[$id]); } $separator_found = true; } else { $separator_found = false; } } unset($id, $data); //Remove the last menu item if it is a separator. $last_menu_key = array_keys($menu); $last_menu_key = array_pop($last_menu_key); if (!empty($menu) && 'wp-menu-separator' == $menu[$last_menu_key][4]) { unset($menu[$last_menu_key]); } unset($last_menu_key); //Add display-specific classes like "menu-top-first" and others. $menu = add_menu_classes($menu); return array($menu, $submenu); }