问题描述

我希望创建一个访问我的插件界面的自定义功能。

  • 插件管理员是否会在激活时将所有管理员帐户添加此功能?

  • 如果是这样:WordPress 是否管理员在多站点安装中向子博客和超级管理员的所有管理员添加该功能,还是该插件需要处理该功能?

最佳解决方案

删除你添加的内容

首先,请确保您在激活时添加的所有内容在卸载时都会被删除。我得到了 a short tutorial including example code

用一个小插件测试:

我真的不太了解 MU,但据我所知,角色对象在所有博客中都是全球性的。只要尝试这个小插件,看看你可以得到什么:

<?php
/*
Plugin Name:    MU Roles check
Plugin URI:     https://github.com/franz-josef-kaiser/
Description:    Check roles during viewing a blog
Author:     Franz Josef Kaiser
Author URI:     https://plus.google.com/u/0/107110219316412982437
Version:        0.1
Text Domain:    murc
License:        GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/

/**
 * Show the blog data and the role names in this blog
 * Also shows if the custom capability was successfully added, or displays n/a for the role
 * 
 * @return void
 */
function wpse35165_role_check()
{
    $blog = get_current_site();
    $custom_cap = 'name_of_your_custom_capability';

    $html = "<hr /><table>";
    $html .= "<caption>List roles in (Blog) {$blog->site_name} / ID#{$blog->id}</caption>"
    $html .= "<thead><tr><th>Role Name</th><th>Capabilties</th></tr></thead><tbody>";
    foreach ( $GLOBALS['wp_roles'] as $name => $role_obj )
    {
        $cap = in_array( $custom_cap, $role_obj->caps ) ? $custom_cap : 'n/a';
        $cap = $cap OR in_array( $custom_cap, $role_obj->allcaps ) ? $custom_cap : 'n/a';
        $html .= "<tr><td>{$name}</td><td>{$cap}</td></tr>";
    }
    $html .= '</tbody></table>';

    print $html;
}
add_action( 'shutdown', 'wpse35165_role_check' );

添加功能

/**
 * Add the capability to the role objects
 * Should be in your activation function and done before you inspect with your plugin
 * 
 * @return void
 */
function wpse35165_add_cap()
{
    $custom_cap = 'name_of_your_custom_capability';
    $min_cap    = 'the_minimum_required_built_in_cap'; // Check "Roles and objects table in codex!
    $grant      = true; 

    foreach ( $GLOBALS['wp_roles'] as $role_obj )
    {
        if ( 
            ! $role_obj->has_cap( $custom_cap ) 
            AND $role_obj->has_cap( $min_cap )
        )
            $role_obj->add_cap( $custom_cap, $grant );
    }
}

注意:您可以将角色添加到角色,而无需授予对其的访问权限 – 只需设置第二个参数 $grant = false; 即可。这允许通过简单地将包含最后一个参数的上限添加为 true 来将单个用户列入白名单。

次佳解决方案

对于我目前正在开发的插件,我想在每个角色基础上授予/限制对插件设置 (即相应的管理菜单页) 的访问。因此,我不得不向 user roles 添加一个新的 plugin-specific capability

不幸的是,kaiser’s answer 似乎没有工作,所以我花了一些时间试图找出如何允许上述功能。


日程安排

在与我分享我的代码之前,以下是纯文本:

  1. 在插件激活时,将新功能 THE_NEW_CAP 添加到具有特定内置功能的角色 BUILT_IN_CAP(在我的情况下为 edit_pages) 。

  2. 在每个页面加载时,执行 1.(即,再次添加功能) 。这只有在您想要考虑在激活插件后创建的新角色时才需要。因此,即使具有所需的内置功能,这些新角色也不具备 plugin-specific 功能。

  3. 使用新的功能,无论你想要什么。如前所述,我使用它来授予/限制对插件的管理菜单页的访问,所以这是如何在下面的代码示例中完成的。

  4. 在插件停用时,删除该功能。当然,您也可以在卸载插件时执行此操作。无论如何,最终做到这一点。


代码

这里是上面列表转换成代码:

» 设置它

class WPSE35165Plugin {

    public function __construct() {
        // Register hooks
        register_activation_hook(__FILE__, array(__CLASS__, 'activation'));
        register_deactivation_hook(__FILE__, array(__CLASS__, 'deactivation'));

        // Add actions
        add_action('admin_menu', array(__CLASS__, 'admin_menu'));
    }

    public function activation() {
        self::add_cap();
    }

    // Add the new capability to all roles having a certain built-in capability
    private static function add_cap() {
        $roles = get_editable_roles();
        foreach ($GLOBALS['wp_roles']->role_objects as $key => $role) {
            if (isset($roles[$key]) && $role->has_cap('BUILT_IN_CAP')) {
                $role->add_cap('THE_NEW_CAP');
            }
        }
    }

「 使用它

    // Add plugin menu pages to admin menu
    public function admin_menu() {
        // Remove the following line if you don't care about new roles
        // that have been created after plugin activation
        self::add_cap();

        // Set up the plugin admin menu
        add_menu_page('Menu', 'Menu', 'THE_NEW_CAP', …);
        add_submenu_page('wpse35165', 'Submenu', 'Submenu', 'THE_NEW_CAP', ...);
    }

» 清理它

    public function deactivation() {
        self::remove_cap();
    }

    // Remove the plugin-specific custom capability
    private static function remove_cap() {
        $roles = get_editable_roles();
        foreach ($GLOBALS['wp_roles']->role_objects as $key => $role) {
            if (isset($roles[$key]) && $role->has_cap('THE_NEW_CAP')) {
                $role->remove_cap('THE_NEW_CAP');
            }
        }
    }

}

注意:请勿使用大写功能。这只是为了可读性。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。