From aa47e83dee86eaeee4c90b9fdea64c06dc222aa2 Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 4 Mar 2010 00:15:55 +0000 Subject: [PATCH] Fix submenus for post types. Props TobiasBg. see #12453 git-svn-id: http://svn.automattic.com/wordpress/trunk@13579 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/admin.php | 22 +++++++++++++--------- wp-admin/includes/plugin.php | 9 ++++++++- wp-admin/includes/template.php | 2 -- wp-admin/menu-header.php | 24 ++++++++++++++---------- wp-admin/menu.php | 18 +++++++++++++++++- 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/wp-admin/admin.php b/wp-admin/admin.php index 719ab1e5d..89f492c08 100644 --- a/wp-admin/admin.php +++ b/wp-admin/admin.php @@ -72,17 +72,26 @@ wp_enqueue_script( 'jquery-color' ); $editing = false; -if (isset($_GET['page'])) { +if ( isset($_GET['page']) ) { $plugin_page = stripslashes($_GET['page']); $plugin_page = plugin_basename($plugin_page); } +if ( isset($_GET['post_type']) ) + $typenow = sanitize_user($_GET['post_type'], true); +else + $typenow = ''; + require(ABSPATH . 'wp-admin/menu.php'); do_action('admin_init'); -if (isset($plugin_page) ) { - if ( ! $page_hook = get_plugin_page_hook($plugin_page, $pagenow) ) { +if ( isset($plugin_page) ) { + if ( !empty($typenow) ) + $the_parent = $pagenow . '?post_type=' . $typenow; + else + $the_parent = $pagenow; + if ( ! $page_hook = get_plugin_page_hook($plugin_page, $the_parent) ) { $page_hook = get_plugin_page_hook($plugin_page, $plugin_page); // backwards compatibility for plugins using add_management_page if ( empty( $page_hook ) && 'edit.php' == $pagenow && '' != get_plugin_page_hook($plugin_page, 'tools.php') ) { @@ -95,6 +104,7 @@ if (isset($plugin_page) ) { exit; } } + unset($the_parent); } $hook_suffix = ''; @@ -105,12 +115,6 @@ else if ( isset($plugin_page) ) else if ( isset($pagenow) ) $hook_suffix = $pagenow; -if ( isset($_GET['post_type']) ) - $typenow = $_GET['post_type']; -else - $typenow = ''; -// @todo validate typenow against post types. - set_current_screen(); // Handle plugin admin pages. diff --git a/wp-admin/includes/plugin.php b/wp-admin/includes/plugin.php index 5e3eb5668..515742514 100644 --- a/wp-admin/includes/plugin.php +++ b/wp-admin/includes/plugin.php @@ -817,6 +817,7 @@ function add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $func $admin_page_hooks[$menu_slug] = sanitize_title( $menu_title ); $hookname = get_plugin_page_hookname( $menu_slug, '' ); + if (!empty ( $function ) && !empty ( $hookname ) && current_user_can( $capability ) ) add_action( $hookname, $function ); @@ -1167,6 +1168,7 @@ function get_admin_page_parent( $parent = '' ) { global $menu; global $submenu; global $pagenow; + global $typenow; global $plugin_page; global $_wp_real_parent_file; global $_wp_menu_nopriv; @@ -1215,7 +1217,10 @@ function get_admin_page_parent( $parent = '' ) { foreach ( $submenu[$parent] as $submenu_array ) { if ( isset( $_wp_real_parent_file[$parent] ) ) $parent = $_wp_real_parent_file[$parent]; - if ( $submenu_array[2] == $pagenow && ( empty($parent_file) || false === strpos($parent_file, '?') ) ) { + if ( !empty($typenow) && ($submenu_array[2] == "$pagenow?post_type=$typenow") ) { + $parent_file = $parent; + return $parent; + } elseif ( $submenu_array[2] == $pagenow && empty($typenow) && ( empty($parent_file) || false === strpos($parent_file, '?') ) ) { $parent_file = $parent; return $parent; } else @@ -1326,6 +1331,7 @@ function get_plugin_page_hookname( $plugin_page, $parent_page ) { $page_type = $admin_page_hooks[$parent]; } + $plugin_name = preg_replace( '!\.php!', '', $plugin_page ); return $page_type.'_page_'.$plugin_name; @@ -1350,6 +1356,7 @@ function user_can_access_admin_page() { return false; $hookname = get_plugin_page_hookname($plugin_page, $parent); + if ( !isset($_registered_pages[$hookname]) ) return false; } diff --git a/wp-admin/includes/template.php b/wp-admin/includes/template.php index 4b215128b..df00d2cfc 100644 --- a/wp-admin/includes/template.php +++ b/wp-admin/includes/template.php @@ -3947,8 +3947,6 @@ function set_current_screen( $id = '' ) { $typenow = 'post'; $current_screen->id = $typenow; $current_screen->post_type = $typenow; - } else { - $typenow = ''; } $current_screen = apply_filters('current_screen', $current_screen); diff --git a/wp-admin/menu-header.php b/wp-admin/menu-header.php index 1df52f078..358351494 100644 --- a/wp-admin/menu-header.php +++ b/wp-admin/menu-header.php @@ -33,7 +33,7 @@ get_admin_page_parent(); * @param bool $submenu_as_parent */ function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) { - global $self, $parent_file, $submenu_file, $plugin_page, $pagenow; + global $self, $parent_file, $submenu_file, $plugin_page, $pagenow, $typenow; $first = true; // 0 = name, 1 = capability, 2 = file, 3 = class, 4 = id, 5 = icon src @@ -47,7 +47,7 @@ function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) { if ( !empty($submenu[$item[2]]) ) $class[] = 'wp-has-submenu'; - if ( ( $parent_file && $item[2] == $parent_file ) || ( false === strpos($parent_file, '?') && strcmp($self, $item[2]) == 0 ) ) { + if ( ( $parent_file && $item[2] == $parent_file ) || ( false === strpos($parent_file, '?') && $self == $item[2] ) ) { if ( !empty($submenu[$item[2]]) ) $class[] = 'wp-has-current-submenu wp-menu-open'; else @@ -112,15 +112,22 @@ function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) { } $menu_file = $item[2]; + if ( false !== $pos = strpos($menu_file, '?') ) $menu_file = substr($menu_file, 0, $pos); + // Handle current for post_type=post|page|foo pages, which won't match $self. + if ( !empty($typenow) ) + $self_type = $self . '?post_type=' . $typenow; + else + $self_type = 'nothing'; + if ( isset($submenu_file) ) { if ( $submenu_file == $sub_item[2] ) $class[] = 'current'; // If plugin_page is set the parent must either match the current page or not physically exist. // This allows plugin pages with the same hook to exist under different parents. - } else if ( (isset($plugin_page) && $plugin_page == $sub_item[2] && (!file_exists($menu_file) || ($item[2] == $self))) || (!isset($plugin_page) && $self == $sub_item[2]) ) { + } else if ( (isset($plugin_page) && $plugin_page == $sub_item[2] && (!file_exists($menu_file) || ($item[2] == $self) || ($item[2] == $self_type))) || (!isset($plugin_page) && $self == $sub_item[2]) ) { $class[] = 'current'; } @@ -133,14 +140,11 @@ function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) { if ( ( ('index.php' != $sub_item[2]) && file_exists(WP_PLUGIN_DIR . "/$sub_file") ) || ! empty($menu_hook) ) { // If admin.php is the current page or if the parent exists as a file in the plugins or admin dir - - $parent_exists = (!$admin_is_parent && file_exists(WP_PLUGIN_DIR . "/$menu_file") && !is_dir(WP_PLUGIN_DIR . "/{$item[2]}") ) || file_exists($menu_file); - if ( $parent_exists ) - echo "{$sub_item[0]}"; - elseif ( 'admin.php' == $pagenow || !$parent_exists ) - echo "{$sub_item[0]}"; + if ( (!$admin_is_parent && file_exists(WP_PLUGIN_DIR . "/$menu_file") && !is_dir(WP_PLUGIN_DIR . "/{$item[2]}")) || file_exists($menu_file) ) + $sub_item_url = add_query_arg( array('page' => $sub_item[2]), $item[2] ); else - echo "{$sub_item[0]}"; + $sub_item_url = add_query_arg( array('page' => $sub_item[2]), 'admin.php' ); + echo "{$sub_item[0]}"; } else { echo "{$sub_item[0]}"; } diff --git a/wp-admin/menu.php b/wp-admin/menu.php index ad41d2753..6c21390c7 100644 --- a/wp-admin/menu.php +++ b/wp-admin/menu.php @@ -177,15 +177,31 @@ do_action('_admin_menu'); // Create list of page plugin hook names. foreach ($menu as $menu_page) { - $hook_name = sanitize_title(basename($menu_page[2], '.php')); + if ( false !== $pos = strpos($menu_page[2], '?') ) { + // Handle post_type=post|page|foo pages. + $hook_name = substr($menu_page[2], 0, $pos); + $hook_args = substr($menu_page[2], $pos + 1); + wp_parse_str($hook_args, $hook_args); + // Set the hook name to be the post type. + if ( isset($hook_args['post_type']) ) + $hook_name = $hook_args['post_type']; + else + $hook_name = basename($hook_name, '.php'); + unset($hook_args); + } else { + $hook_name = basename($menu_page[2], '.php'); + } + $hook_name = sanitize_title($hook_name); // ensure we're backwards compatible $compat = array( 'index' => 'dashboard', 'edit' => 'posts', + 'post' => 'posts', 'upload' => 'media', 'link-manager' => 'links', 'edit-pages' => 'pages', + 'page' => 'pages', 'edit-comments' => 'comments', 'options-general' => 'settings', 'themes' => 'appearance',