Como registrar roles y capacidades personalizados en PHP en WordPress

Contents

Introducción

En este artículo se explica con todo lujo de detalles cómo registrar roles y capacidades (capabilities) personalizados en WordPress usando PHP. Verás desde la teoría básica sobre roles y capacidades hasta ejemplos prácticos listos para usar dentro de un plugin, buenas prácticas, consideraciones de seguridad y cómo integrarlo con tipos de contenido personalizados (custom post types) y la API REST.

Conceptos básicos: ¿rol o capacidad?

Rol: conjunto de capacidades que se asigna a un usuario. Ejemplos nativos: administrator, editor, author.

Capacidad: permiso granular que representa una acción (por ejemplo, edit_posts, publish_posts, delete_users). Los roles sirven para agrupar capacidades.

Reglas y buenas prácticas

  • Usa prefijos únicos para evitar colisiones entre plugins/themes (ejemplo: mi_plugin_).
  • Registra roles y capacidades en la activación del plugin y revísalos o límpialos en la desactivación/desinstalación.
  • Añade solo las capacidades estrictamente necesarias.
  • No modifiques permanentemente capacidades de roles centrales (ej. administrator) sin una buena razón y sin documentarlo.
  • En entorno multisite, piensa si las capacidades deben aplicarse a la red completa o por sitio.

Funciones clave de WordPress

  • add_role( role, display_name, capabilities ): crea un rol nuevo.
  • remove_role( role ): elimina un rol.
  • get_role( role ): obtiene un objeto WP_Role para modificar sus capacidades.
  • WP_Role::add_cap( cap ) y WP_Role::remove_cap( cap ): añaden o quitan capacidades a un rol existente.
  • current_user_can( cap ): comprueba si el usuario actual tiene una capacidad.
  • map_meta_cap (filtro): permite mapear capacidades a lógica personalizada (uso avanzado).

Ejemplo práctico: plugin mínimo que registra roles y capacidades

Este ejemplo muestra cómo crear un rol personalizado mi_plugin_manager con capacidades para gestionar un CPT book. El código está pensado para colocarse en el archivo principal de un plugin.

 true,
        MP_PLUGIN_SLUG . _read_book => true,
        MP_PLUGIN_SLUG . _edit_book => true,
        MP_PLUGIN_SLUG . _edit_books => true,
        MP_PLUGIN_SLUG . _edit_others_books => true,
        MP_PLUGIN_SLUG . _publish_books => true,
        MP_PLUGIN_SLUG . _delete_books => true,
    )

    add_role( MP_PLUGIN_SLUG . _manager, Mi Plugin Manager, caps )

    // Añadir capacidades a roles existentes (ejemplo: editor)
    role = get_role( editor )
    if ( role ) {
        role->add_cap( MP_PLUGIN_SLUG . _read_book )
        role->add_cap( MP_PLUGIN_SLUG . _edit_books )
    }
}
register_activation_hook( __FILE__, mp_activate_plugin )

/
  Desactivación: opcionalmente eliminar roles y capacidades.
  En muchos casos es preferible eliminar sólo el rol creado y no tocar los roles nativos.
 /
function mp_deactivate_plugin() {
    // Eliminar el rol personalizado
    remove_role( MP_PLUGIN_SLUG . _manager )

    // Quitar capacidades añadidas a roles existentes (si se añadieron)
    role = get_role( editor )
    if ( role ) {
        role->remove_cap( MP_PLUGIN_SLUG . _read_book )
        role->remove_cap( MP_PLUGIN_SLUG . _edit_books )
    }
}
register_deactivation_hook( __FILE__, mp_deactivate_plugin )

/
  Registrar CPT book con capacidades personalizadas.
 /
function mp_register_book_cpt() {
    labels = array(
        name => Books,
        singular_name => Book,
    )

    capability_type = array( book, books )
    capabilities = array(
        edit_post          => MP_PLUGIN_SLUG . _edit_book,
        read_post          => MP_PLUGIN_SLUG . _read_book,
        delete_post        => MP_PLUGIN_SLUG . _delete_book,
        edit_posts         => MP_PLUGIN_SLUG . _edit_books,
        edit_others_posts  => MP_PLUGIN_SLUG . _edit_others_books,
        publish_posts      => MP_PLUGIN_SLUG . _publish_books,
        read_private_posts => MP_PLUGIN_SLUG . _read_private_books,
    )

    args = array(
        labels => labels,
        public => true,
        has_archive => true,
        capability_type => capability_type,
        capabilities => capabilities,
        map_meta_cap => true, // importante para que WP use map_meta_cap
        supports => array( title, editor ),
    )

    register_post_type( book, args )
}
add_action( init, mp_register_book_cpt )
?>

Notas sobre el ejemplo

  • Usamos map_meta_cap => true en el CPT para que WP convierta las capacidades genéricas (edit_post) a las específicas que definimos.
  • Siempre prefija tus capacidades (aquí MP_PLUGIN_SLUG) para evitar choque con otros plugins o temas.
  • En la activación añadimos capacidades al rol editor como ejemplo en la desactivación las removemos.

Modificar capacidades de roles existentes

Para modificar un rol concreto (por ejemplo, añadir o quitar una capacidad) se utiliza get_role y luego add_cap/remove_cap. Ejemplo rápido:

add_cap( mi_plugin_ability )
}

// Quitarla
if ( role ) {
    role->remove_cap( mi_plugin_ability )
}
?>

Uso de current_user_can y comprobaciones en código

Para comprobar permisos en plantillas, endpoints REST, metaboxes o acciones, usa current_user_can con la capacidad adecuada. Ejemplos:

  • En plantillas: if ( current_user_can( mi_plugin_edit_books ) ) { / mostrar UI / }
  • En endpoints REST: retorna permissions_callback que evalúe current_user_can.

Mapeo avanzado: filtro map_meta_cap

Si necesitas lógica más compleja para decidir si un usuario puede editar un post (p. ej. solo si es autor o pertenece a un grupo), usa el filtro map_meta_cap. Ejemplo que permite a los autores editar sólo sus propios book aunque no tengan la capacidad general:

post_type === book ) {
            // Si el usuario es el autor, permitir con una capacidad personalizada
            if ( post->post_author == user_id ) {
                // Sustituir por nuestra capacidad personalizada
                caps = array( MP_PLUGIN_SLUG . _edit_own_books )
            } else {
                // Otros usuarios requieren capacidad de editar otros
                caps = array( MP_PLUGIN_SLUG . _edit_others_books )
            }
        }
    }
    return caps
}
?>

Consideraciones multisite

  1. En una red multisitio, register_activation_hook en un plugin activado en la red no siempre debe aplicar roles en todas las subsites directamente. Puedes iterar sobre sitios con get_sites() y usar switch_to_blog() para aplicar cambios por sitio.
  2. Alternativamente, aplica cambios sólo en sitios donde el plugin está activado.

Buenas prácticas adicionales y seguridad

  • Versiona cambios de capacidades: guarda en la opción del plugin una versión y al actualizar compara para aplicar nuevos cambios sin romper permisos existentes.
  • No elimines capacidades o roles sin confirmar que no hay usuarios afectados considera ofrecer una pantalla de administración donde el administrador decida quitar capacidades.
  • Respeta el principio de mínimo privilegio: concede solo lo necesario.
  • Documenta las capacidades que tu plugin crea para que otros desarrolladores o administradores las identifiquen fácilmente.

Comprobaciones y depuración

  • Usa la clase WP_Roles para inspeccionar todos los roles: global wp_roles var_export( wp_roles->roles )
  • Revisa la tabla wp_options (opción wp_user_roles) si necesitas ver el estado guardado de roles en la base de datos (cuidado al editar directamente).
  • WP-CLI puede ser útil: wp role list, wp role get, wp role create, wp cap add, wp cap remove.

Ejemplo: añadir y eliminar capacidades con WP-CLI

Comandos útiles (ejemplos):

  • Listar roles: wp role list
  • Añadir capacidad: wp cap add editor mi_plugin_edit_books
  • Quitar capacidad: wp cap remove editor mi_plugin_edit_books

Resumen y checklist antes de lanzar

  1. Prefija capacidades y roles para evitar conflictos.
  2. Registra roles/capacidades en la activación del plugin y límpialos opcionalmente en la desactivación o desinstalación.
  3. Asigna capacidades a roles existentes con get_role()->add_cap / remove_cap con cuidado.
  4. Usa map_meta_cap para lógica avanzada por post/ownership.
  5. Documenta las capacidades que crea tu plugin y proporciona una interfaz administrativa si tu plugin modifica roles de forma no trivial.
  6. Considera multisite y WP-CLI para gestión y automatización.

Recursos útiles

Con estos conceptos y ejemplos puedes diseñar una estrategia segura y fiable para registrar y gestionar roles y capacidades personalizados en WordPress. Implementa cambios en un entorno de pruebas antes de aplicar en producción y documenta cualquier modificación para los administradores del sitio.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *