問題描述

我希望建立一個訪問我的外掛介面的自定義功能。

  • 外掛管理員是否會在啟用時將所有管理員帳戶新增此功能?

  • 如果是這樣: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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。