隐藏主题选项和自定义管理菜单

时间:2018-11-15 作者:Randomer11

在外观管理菜单下,我通过主题添加了customizer,通过插件添加了主题选项。我使用这段代码来隐藏除了某个用户名之外的所有管理员的两个菜单(外观的子菜单)。

function hide_menu() {
    global $current_user;
    $current_user = wp_get_current_user();
    $user_name = $current_user->user_login; 

        //check condition for the user means show menu for this user
        if(is_admin() &&  $user_name != \'USERNAME\') {

         remove_submenu_page( \'themes.php\', \'customize\' );
         remove_submenu_page( \'themes.php\', \'core-settings\' );
   }
}
add_action(\'admin_head\', \'hide-menu\');
代码本身运行良好,我可以隐藏父菜单。但我似乎无法隐藏我要隐藏的两个子菜单。

这两个菜单指向URL:

domainname.com/wp-admin/customize.php

domainname.com/wp-admin/themes.php?page=core-settings
子菜单调试:

[6] => Array
                (
                    [0] => Customise
                    [1] => customize
                    [2] => customize.php?return=%2Fwp-admin%2Findex.php
                    [3] => 
                    [4] => hide-if-no-customize
                )
               [21] => Array
                (
                    [0] => Theme Settings
                    [1] => manage_options
                    [2] => core-settings
                    [3] => Theme Settings
                )
我已经看过dubug模式,但我不确定我在看什么,请有人给出一个解决方案和解释为什么它会工作。

2 个回复
最合适的回答,由SO网友:coolpasta 整理而成

直接回答:

add_action( \'admin_menu\', function() {
    global $current_user;
    $current_user = wp_get_current_user();
    $user_name = $current_user->user_login;

        //check condition for the user means show menu for this user
        if(is_admin() &&  $user_name != \'USERNAME\') {
            //We need this because the submenu\'s link (key from the array too) will always be generated with the current SERVER_URI in mind.
            $customizer_url = add_query_arg( \'return\', urlencode( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER[\'REQUEST_URI\'] ) ) ), \'customize.php\' );
            remove_submenu_page( \'themes.php\', $customizer_url );
   }
}, 999 );
您必须尊重完整的路径命名。

答案很长,这是:

add_action( \'admin_menu\', function() {
    $page = remove_submenu_page( \'themes.php\', \'customize.php\' );
}, 999 );
不起作用。但这个:

add_action( \'admin_menu\', function() {
    $page = remove_submenu_page( \'themes.php\', \'widgets.php\' );
}, 999 );
工作。如果我们只看链接,那么我们可以看到should work, 但看看这个。在里面wp-admin/menu.php, line 164, 我们有:

$submenu[\'themes.php\'][6] = array( __( \'Customize\' ), \'customize\', esc_url( $customize_url ), \'\', \'hide-if-no-customize\' );
如果我们对此进行评论,砰Customize 链接消失,但如果我们继续粘贴此代码并转到wp-admin/index.php, 我们可以看到没有customize.php 在阵列中:

add_action( \'admin_menu\', function() {
   global $submenu;
   var_dump( $submenu );
}, 999 );
其他人在这里。发生了什么事?如果我们把$submenu 创建完成后,我们可以看到它就在那里:

[themes.php] => Array
    (
        [5] => Array
            (
                [0] => Themes
                [1] => switch_themes
                [2] => themes.php
            )

        [6] => Array
            (
                [0] => Customize
                [1] => customize
                [2] => customize.php?return=%2Fwordpress%2Fwp-admin%2Findex.php
                [3] => 
                [4] => hide-if-no-customize
            )

        [10] => Array
            (
                [0] => Menus
                [1] => edit_theme_options
                [2] => nav-menus.php
            )

    )
。。。所以,在某个地方,它丢失了,or so you would think, 在这个文件的末尾,我们再次看到,我们包含了另一个文件:

require_once(ABSPATH . \'wp-admin/includes/menu.php\');
如果我们在这个文件的末尾转储$menu, 我们得到的是。。令人惊讶的是,菜单中没有“customizer”。但就在刚才。

令人惊讶的是,如果我们这样做:

add_action( \'admin_menu\', function() {
    global $submenu;
    var_dump( $submenu );
}, 999 );
很明显customize.php 是否有。。。除了它使用以下参数生成自身:customize.php?return=%2Fwordpress%2Fwp-admin%2Findex.php (这取决于您的站点)。

有趣,所以如果我们这样做:

add_action( \'admin_menu\', function() {
    remove_submenu_page( \'themes.php\', \'customize.php?return=%2Fwordpress%2Fwp-admin%2Findex.php\' );
}, 999 )
或者,在您的情况下:

add_action( \'admin_menu\', function() {
    remove_submenu_page( \'themes.php\', \'customize.php?return=%2Fwp-admin%2Findex.php\' );
}, 999 )
它起作用了。

那么我们今天学到了什么?WP Core是一个糟糕的废话,好吧,这是真的,但这是你的错误,你没有看到什么remove_submenu_page 查找。

function remove_submenu_page( $menu_slug, $submenu_slug ) {
    global $submenu;

    if ( !isset( $submenu[$menu_slug] ) )
        return false;

    foreach ( $submenu[$menu_slug] as $i => $item ) {
        if ( $submenu_slug == $item[2] ) {
            unset( $submenu[$menu_slug][$i] );
            return $item;
        }
    }

    return false;
}
在我们的例子中,它首先检查菜单是否存在themes.php 然后它会检查每个项目,Appearance, 每个元素本身都是一个数组,然后它会查找第三个元素,该元素对应于[2] => customize.php... 项目,所以,它当然不会找到我们的customize.php, 这就是为什么我们需要提供完整的链接。这只是一个简单的错误。

SO网友:FooBar

这在WordPress 5中适用

add_action( \'admin_menu\', function() {
    remove_submenu_page( \'themes.php\', \'customize.php?return=\' . urlencode($_SERVER[\'SCRIPT_NAME\']));
});

结束