只能编辑微件而不能编辑其他主题选项的角色

时间:2012-08-06 作者:Justas Butkus

如何让特定角色访问widgets管理菜单(wp admin/widgets.php),但是not 访问其他theme administration 菜单元素。

我已经做到了Appearance 菜单链接到小部件。通过绑定到_admin_menu 事件和修改全局变量$子菜单。尽管这显然不起作用,正如我在wp admin/widgets中看到的代码。php本身:

    if ( ! current_user_can(\'edit_theme_options\') )
            wp_die( __( \'Cheatin’ uh?\' ));
很清楚,除非您明确edit_theme_options 能力。但是,如果我不希望此功能的其他元素(除了小部件)可由当前用户(角色)修改,该怎么办?

很容易从菜单中“隐藏”其他选项。但这让那个些知道WP如何工作(至少理解寻址)的用户可以自由访问它们,而我显然希望避免这样做。

感谢您提前提供的任何帮助。

3 个回复
SO网友:kaiser

确认(&H)

是的,目前没有办法修改管理菜单页面的访问参数。唯一可以通过公共wp API修改的是“注释”菜单项。所有其他都是手工注册的。

但是有人来帮忙@scribu (read more at the trac ticket) 迄今为止,世卫组织已经付出了大量努力,为core带来了更有用的东西。

解释

当深入查看核心时,您将看到函数wp_widgets_add_menu() 在…内~/wp-includes/functions.php. 这一个基本上添加了子菜单项,因为WP 2.2…

function wp_widgets_add_menu() {
    global $submenu;
    $submenu[\'themes.php\'][7] = array( __( \'Widgets\' ), \'edit_theme_options\', \'widgets.php\' );
    ksort( $submenu[\'themes.php\'], SORT_NUMERIC );
}
此函数将添加到_admin_menu 采取的行动wp_maybe_load_widgets() 作用

菜单项的中间解决方法;widgets页面当前是加载默认小部件并注册子菜单项(即wp_maybe_load_widgets) 在plugins_loaded 挂钩优先级为0.

这使得用普通插件注销它变得很困难。因此,您需要在mu-plugins 文件夹

<?php
/* Plugin Name: »Kaisers« Deny Widgets page access */
! defined( \'ABSPATH\' ) AND exit;

// Init the plugin
add_action( \'muplugins_loaded\', array( \'wpse6106_deny_widgets\', \'init\' ), 0 );

class wpse6106_deny_widgets
{
    static public $instance;

    public $required_cap = \'SET_CUSTOM_CAP_HERE\';

    /**
     * Get the instance of the plugin
     * @since  2012-08-07.1505
     * @return void
     */
    static function init()
    {
        null === self :: $instance AND self :: $instance = new self;
        return self :: $instance;
    }

    /**
     * Setup
     * Removes the default function that registers the widgets.php sub menu item.
     * @since  2012-08-07.1505
     * @return void
     */
    function __construct()
    {
        // remove core function...
        remove_action( \'plugins_loaded\', \'wp_maybe_load_widgets\', 0 );

        // ...and add our own
        add_action( \'admin_head\', array( $this, \'widgets_menu_access\' ), 0 );

        // Then abort any attempt to access the widgets page
        add_action( \'load-widgets.php\', array( $this, \'widgets_page_access\' ), 0 );
    }

    /**
     * Adds an action, that re-registers the sub menu item with a custom capability.
     * @since  2012-08-07.1505
     * @return void
     */
    function widgets_menu_access()
    {
        global $submenu;

        // Call default widgets file
        require_once( ABSPATH . WPINC . \'/default-widgets.php\' );

        $submenu[\'themes.php\'][7] = array( 
             __( \'Widgets\' )
            ,$this->required_cap
            ,\'widgets.php\'
        );
        ksort( $submenu[\'themes.php\'], SORT_NUMERIC );
    }

    /**
     * Does a second check if someone without the custom cap entered the widgets page and dies.
     * @since  2012-08-07.1505
     * @return void
     */
    function widgets_page_access()
    {
        get_currentuserinfo();
        global $current_user;

        if ( ! current_user_can( $this->required_cap ) )
            wp_die( __( \'Cheatin&#8217; uh?\' ) );
    }
}
只需将其放入您的MU插件文件夹,调整SET_CUSTOM_CAP_HERE 插件内的字符串(顶部的类变量↑) 你已经准备好了。确保您使用的是某种角色管理器(如Members, 这允许您将此角色仅授予那些打算访问widgets页面的人。或者使用一些自己的/自定义插件手动添加它。

还要确保用户没有一些遗留的功能。如果它不起作用,请停用所有插件,切换回二十/十一,并使用如下插件重置本地数据库»WordPress Reset«.

经验证的结果

enter image description here

注意:插件已经过测试,可以在普通安装中使用

禁用默认窗口小部件和子菜单项注意:这仅适用于以后的读者,他们希望将其全部删除

如果您想完全摆脱所有默认小部件,那么有一个简单的过滤器,您可以调用它,它停止包含~/wp-includes/default-widgets.php 文件并禁用页面注册:

add_filter( \'load_default_widgets\', \'__return_false\' );

SO网友:Chris Lemke

OVERVIEW

虽然问题是关于限制编辑器角色仅访问小部件,但下面的示例显示了如何限制对菜单的访问。然而,正如您将看到的,它可以很容易地更改为只允许小部件或更多!

我添加了步骤#3,因为我忘记了管理栏。哎呀!因此,现在无论是登录仪表板还是登录WP网站,您都可以完全控制“edit\\u theme\\u Capability”子菜单的编辑器可用内容。

If you don\'t have a Roles & Capabilities Plugin installed, you can do this:

(如果是,请跳过#1,转到#2,然后转到#3)

(1) Add this to your theme\'s functions.php:

// Add all Editors the privilege to edit Themes, Widgets, Menus, Backgrounds

// get the the role object - editor, author, etc. (or those specially created)
$role_object = get_role( \'editor\' );

// add $cap capability to this role object
// \'edit_theme_options\' enables Dashboard APPEARANCE sub-menus
// for Themes, Widgets, Menus, and Backgrounds for users with that role
$role_object->add_cap( \'edit_theme_options\' );

(2) Add this to admin-footer.php : (位于wp admin目录中)
这样做是为了允许您选择希望编辑器在其仪表板上具有的选项
READ THIS 有关jQuery代码段作者的更多信息。

<?php
  //  Using jQuery: How to allow Editors to edit only Menus (or more!)
  //  Placed in admin-footer.php as Dashboard comes from the wp-admin files

  if ( is_user_logged_in() ) { // This IF may be redundant, but safe is better than sorry...
    if ( current_user_can(\'edit_theme_options\') && !current_user_can(\'manage_options\') ) { // Check if non-Admin
?>
      <script>
    jQuery.noConflict();
    jQuery(document).ready(function() {
      //  Comment out the line you WANT to enable, so it displays (is NOT removed).
      //  For example, the jQuery line for MENUS is commented out below so it\'s not removed.

      // THEMES:  If you want to allow THEMES, also comment out APPEARANCE if you want it to display Themes when clicked. (Default behaviour)
      jQuery(\'li#menu-appearance.wp-has-submenu li a[href="themes.php"]\').remove();
      jQuery(\'li#menu-appearance.wp-has-submenu a.wp-has-submenu\').removeAttr("href");

      // WIDGETS:
      jQuery(\'li#menu-appearance.wp-has-submenu li a[href="widgets.php"]\').remove();

      // MENUS:
      // jQuery(\'li#menu-appearance.wp-has-submenu li a[href="nav-menus.php"]\').remove();

      // BACKGROUND:
      jQuery(\'li#menu-appearance.wp-has-submenu li a[href="themes.php?page=custom-background"]\').remove();
    });
      </script>
<?php
    } // End IF current_user_can...
  } // End IF is_user_logged_in...
?>

(3) Add this to the Theme\'s footer.php :
这样做的目的是允许您选择希望编辑器在其管理栏上具有的选项

<?php
  //  Using jQuery: How to allow Editors to edit only Menus (or more!)
  //  Placed in THEME\'s footer.php as the Admin Bar is added when a user is logged in

  if ( is_user_logged_in() ) { // This IF may be redundant, but safe is better than sorry...
    if ( current_user_can(\'edit_theme_options\') && !current_user_can(\'manage_options\') ) { // Check if non-Admin
?>
      <script>
    jQuery.noConflict();
    jQuery(document).ready(function() {
      //  Comment out the line you WANT to enable, so it displays (is NOT removed).
      //  For example, the jQuery line for MENUS is commented out below so it\'s not removed.

      // THEMES:
      jQuery(\'li#wp-admin-bar-themes\').remove();

      // CUSTOMIZE:
      jQuery(\'li#wp-admin-bar-customize\').remove();

      // WIDGETS:
      jQuery(\'li#wp-admin-bar-widgets\').remove();

      // MENUS:
      // jQuery(\'li#wp-admin-bar-menus\').remove();

      // BACKGROUND:
      jQuery(\'li#wp-admin-bar-background\').remove();
    });
      </script>
<?php
    } // End IF current_user_can...
  } // End IF is_user_logged_in...
?>

SO网友:Justas Butkus

我找到了一个部分的解决方法。

绑定操作

我将延迟(优先级=10)方法添加到user_has_cap 行动在绑定方法中,我检查访问的页面(确保wp-admin/widgets.php) 如果是这样的话,正在检查的权限是edit_theme_options - 我同意return $all_caps + array(\'edit_theme_options\' => true);.

此外,我很晚(优先级=999)将方法绑定到admin_menu 行动考虑到当前用户拥有我自己定义的只访问小部件菜单的能力(没有意义-可能是user_can_customize_themes_widgets_only) 我遍历与外观相关的全局$子菜单数组部分($submenu[\'themes.php\']) 并删除任何没有“小部件”的元素。php’作为path元素(path的索引为2). 最后我再加上widgets.php 以防丢失。

要考虑的事情为什么我说它是片面的?

因为这是一种变通方法。我授予用户edit_theme_options 是的,即使在短时间内并且在确保用户访问widgets.php 而不是任何其他页面。

而且-我不能依靠它来处理WP的未来版本,因为我正在修改全局变量$submenu, 这可能会在任何时候以任何方式发生变化。

有鉴于此,实现解决方案很容易,但无论如何都不好。

结束

相关推荐

Admin menus and submenus

我为管理员创建了一个选项页面,并将其显示为顶级菜单->add_menu_page($themename, $themename, \'administrator\', basename(__FILE__), \'mytheme_admin\');我想在我创建的顶级菜单下添加一个子菜单,以显示完全相同的页面(显示为子菜单,但当用户单击顶级菜单时也会打开此页面)。此外,我不知道如何在这个顶级菜单下添加我创建的另一个主题页面。在这里询问之前,我已经阅读了wordpress文档,但无法完成。非常感谢。