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
- 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.
- 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
- Prefija capacidades y roles para evitar conflictos.
- Registra roles/capacidades en la activación del plugin y límpialos opcionalmente en la desactivación o desinstalación.
- Asigna capacidades a roles existentes con get_role()->add_cap / remove_cap con cuidado.
- Usa map_meta_cap para lógica avanzada por post/ownership.
- Documenta las capacidades que crea tu plugin y proporciona una interfaz administrativa si tu plugin modifica roles de forma no trivial.
- 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 🙂 |