Как мне создать пользовательскую функцию роли?

26

Я хочу создать пользовательскую возможность доступа к интерфейсу моего плагина.

  • Должен ли плагин управлять добавлением этой возможности ко всем учетным записям администратора при активации?
  • Если да: удается ли WordPress добавить возможность всем администраторам суб-блогов и супер-администраторам в мультисайтовых установках, или эта функция должна обрабатываться плагином?
rsman
источник
Подробный блог: goo.gl/xNuafH
Суреш Камруши

Ответы:

11

Удалить то, что вы добавляете

Во-первых, убедитесь, что все, что вы добавляете при активации, также удаляется при удалении . Я получил краткое руководство, включая пример кода для вас.

Тест с небольшим плагином:

Я действительно мало знаю о 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.

кайзер
источник
17

Для плагина, над которым я сейчас работаю, я хотел предоставить / ограничить доступ к настройкам плагина (то есть соответствующим страницам меню администратора) для каждой роли .
Поэтому мне пришлось добавить новый плагин, специфичный capabilityдляuser roles .

К сожалению, ответ kaiser, похоже, больше не работает, поэтому я потратил некоторое время, пытаясь выяснить, как включить вышеупомянутую функциональность.


Расписание

Прежде чем я поделюсь с вами своим кодом, вот что это такое, в виде простого текста:

  1. При активации плагина добавьте новую возможность THE_NEW_CAPк ролям, имеющим определенную встроенную возможность BUILT_IN_CAP(в моем случае:) edit_pages.
  2. На каждой загрузке страницы выполните 1. (т. Е. Снова добавьте возможность). Это необходимо, только если вы хотите учесть возможные новые роли, которые были созданы после активации плагина. Следовательно, эти новые роли не имеют специфической для плагина возможности, даже если они имеют требуемую встроенную возможность.
  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');
            }
        }
    }

}

Примечание. Пожалуйста, не используйте заглавные буквы. Это только для удобства чтения.

tfrommen
источник
1
Всегда используйте get_editable_roles()для получения ролей, которые вы хотите редактировать. Вы будете ломать плагин иначе.
fuxia
1
@toscho Ну, ладно, я полагаю , что одна из этих функций даже Кодекс об этом не знает ...;) Конечно, эта функция имеет свое право на существование, однако, я не вижу , с использованием глобальной WP_Roles массива ломки любые плагины в моем случае.
13
2
Некоторые плагины создают специализированные пользовательские роли и полагаются на точный набор возможностей. В некоторых случаях одна возможность исключает использование другой в логике программы. Вы не можете знать, когда это так.
fuxia
0

Это работает для меня:

    add_action('admin_init', 'add_custom_cap');
    function add_custom_cap()
    {
        $custom_cap = 'test_cap';
        $min_cap    = 'read';
        $grant      = true;
        $to_role = 'your_user_role';
        $role = 'user_role';

        foreach ( $GLOBALS['wp_roles'] as $role_obj )
        {
            if (is_object($role_obj[$role])) {
                if (!$role_obj[$role]->has_cap( $custom_cap ) && $role_obj[$role]->has_cap( $min_cap )) {
                    $role_obj[$role]->add_cap( $custom_cap, $grant );
                }
            }
        }
    }
Виталий Конурин
источник
Никогда не изменяйте глобалы ролей! Никогда. Не надо! Вы не будете запускать какие-либо перехватчики, запрещать фильтры и делать ваш код движущейся целью. Никто никогда не узнает, когда и где вы зарегистрировали эту роль (вы этого не сделали, вы просто ее где-то вставили, когда-нибудь, как-нибудь). Пожалуйста: никогда не делай этого. Особенно не с ролями.
Кайзер