¿Cómo creo una capacidad de rol personalizada?

26

Deseo crear una capacidad personalizada para acceder a la interfaz de mi complemento.

  • ¿Debería el complemento administrar agregar esta capacidad a todas las cuentas de administrador en la activación?
  • Si es así: ¿WordPress logra agregar la capacidad a todos los administradores de subblogs y superadministradores en instalaciones de múltiples sitios, o esa función debe ser manejada por el complemento?
rsman
fuente
Un blog detallado: goo.gl/xNuafH
Suresh Kamrushi el

Respuestas:

11

Elimina lo que agregues

Primero, asegúrese de que todo lo que agregue en la activación también se elimine durante la desinstalación . Tengo un breve tutorial que incluye un código de ejemplo para ti.

Prueba con un pequeño complemento:

Realmente no sé mucho sobre MU, pero por lo que puedo decir, el objeto de roles es global en todos los blogs. Simplemente pruebe este pequeño complemento y vea qué puede obtener:

<?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' );

Agregar capacidades

/**
 * 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 );
    }
}

Nota: Puede agregar la capacidad al rol sin otorgarle acceso, solo configure el segundo argumento $grant = false;. Esto permite incluir en la lista blanca a usuarios individuales simplemente agregando el límite, incluido el último argumento como verdadero.

emperador
fuente
17

Para un complemento en el que estoy trabajando actualmente, quería otorgar / restringir el acceso a la configuración del complemento (es decir, las páginas correspondientes del menú de administración) en función de cada rol .
Por lo tanto, tuve que agregar un nuevo complemento específico capabilityparauser roles .

Desafortunadamente, la respuesta de Kaiser parece que ya no funciona, así que pasé un tiempo tratando de descubrir cómo permitir la funcionalidad mencionada anteriormente.


El horario

Antes de compartir mi código con usted, esto es de lo que se trata, en texto plano:

  1. En la activación del complemento, agregue la nueva capacidad THE_NEW_CAPa los roles que tienen una cierta capacidad incorporada BUILT_IN_CAP(en mi caso:) edit_pages.
  2. En cada carga de página, haga 1. (es decir, agregue la capacidad, nuevamente). Esto solo es necesario si desea dar cuenta de posibles roles nuevos que se han creado después de la activación del complemento. Por lo tanto, estos nuevos roles no tienen la capacidad específica del complemento, incluso si tienen la capacidad incorporada requerida.
  3. Use la nueva capacidad para lo que quiera. Como se explicó anteriormente, lo uso para otorgar / restringir el acceso a las páginas del menú de administración del complemento, así es como se hace en el siguiente ejemplo de código.
  4. En la desactivación del complemento, elimine la capacidad. Por supuesto, también puede hacer esto cuando se desinstala el complemento. De cualquier manera, hágalo eventualmente.

El código

Y aquí está la lista anterior convertida en código:

»Configurarlo

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');
            }
        }
    }

»Utilizándolo

    // 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', ...);
    }

»Limpiarlo

    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');
            }
        }
    }

}

Nota: no utilice las mayúsculas. Esto es solo para facilitar la lectura.

tfrommen
fuente
1
Utilice siempre get_editable_roles()para buscar roles que desea editar. Usted va a romper los plugins de otra manera.
fuxia
1
@toscho Bueno, está bien, supongo que es una de estas funciones incluso el Codex no sabe nada ...;) Por supuesto, esta función tiene su derecho a existir, sin embargo, no veo usando el WP_Roles matriz global de ruptura cualquier complemento en mi caso.
tfrommen
2
Algunos complementos crean roles de usuario especializados y dependen del conjunto exacto de capacidades. En algunos casos, una capacidad excluye el uso de otra en la lógica del programa. No puedes saber cuándo es el caso.
fuxia
0

Esto funciona para mi:

    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 );
                }
            }
        }
    }
Vitaly Konurin
fuente
¡Nunca modifiques los globales de los roles! Nunca. No lo hagas No activará ningún gancho y negará los filtros y hará que su código sea un objetivo en movimiento. Nadie sabrá cuándo y dónde registraste ese rol (no lo hiciste, simplemente lo metiste allí en algún lugar, de algún modo, de alguna manera). Por favor: nunca hagas eso. Especialmente no con roles.
Kaiser