Funciones y capacidades de WordPress un ejemplo de la vida real

Este es un tutorial de cuatro partes que cubre el tema de usuarios, roles y capacidades de WordPress. La serie cubrirá la arquitectura y el diseño de roles de usuario en WordPress; resalte las funciones más importantes para interactuar con los usuarios y administrar roles y capacidades; y en el último tutorial, vamos a construir un ejemplo de la vida real que demuestra la utilidad de esta API..


Introducción

Este tutorial se centrará en la creación de una solución práctica utilizando el sistema de funciones y capacidades de WordPress. Si te has perdido los dos últimos tutoriales, te sugiero que los revises. La primera parte, "Funciones y capacidades de WordPress: Lo básico" explica el diseño de este sistema; mientras que la segunda parte "Funciones y capacidades de WordPress: Funciones de nota" se centra en las funciones y clases que ofrece WordPress para interactuar con el sistema.

La solución propuesta en este tutorial es la misma que estoy usando para uno de mis complementos de WordPress premium. Lo he elegido después de probar diferentes enfoques. Es simple, corto y encapsulado en una clase. Puedes adaptarlo fácilmente para tu propio plugin. El código está disponible en GitHub; y no tiene licencia. También viene sin garantías, y usted es libre de usarlo y licenciarlo como desee..


Paso 1 El Escenario

Estamos creando un complemento de WordPress que tiene un panel de administración de cliente especial. Este panel de administración debe ser accesible solo para un conjunto limitado de usuarios. Estos usuarios pueden ser seleccionados por el administrador del blog. Puede habilitar diferentes roles, usuarios o todos ellos para acceder al panel de administración del cliente o funciones.

Aparte de eso, necesitamos tener un acceso restringido a la Biblioteca de medios para usuarios con acceso al Panel de clientes. WordPress tiene una capacidad especial para acceder y subir archivos a la biblioteca multimedia: "subir archivos". Sin embargo, esto le da al usuario (o rol) acceso completo a la Biblioteca de Medios. Esto no es bueno, especialmente porque las fotos (o archivos) no se pueden jerarquizar en diferentes categorías donde puede restringir el acceso para cada uno..

Necesitamos restringir el acceso a la biblioteca de medios solo a los archivos que el usuario ha cargado. No debería tener acceso a las subidas de otros usuarios. Esta restricción debe aplicarse solo a los usuarios que no tienen la "subir archivos"capacidad. A otros usuarios y roles no les preocupa esta restricción, ya que ya tienen acceso completo a la Biblioteca de medios.

Nuestro blog tendrá estas cuatro categorías de usuarios:

Los primeros dos grupos de usuarios son los que no tendrán acceso al Panel de Clientes del complemento. He resaltado el hecho de que hay usuarios que tienen acceso a la Biblioteca de medios, y un conjunto que no lo tiene. Es esencial que nuestra solución no afecte las dos primeras categorías y deje sus capacidades intactas.

Con eso en mente, nuestra clase debería hacer dos cosas:

  • Establezca los permisos correctos para el tercer y cuarto conjunto de usuarios.
  • Habilitar un acceso restringido a la biblioteca de medios a la cuarta categoría. Debe asegurarse de que después de deshabilitar el complemento o de cambiar los derechos de los usuarios, esta categoría de usuarios recupere sus permisos originales.

Paso 2 La interfaz del plugin

Antes de crear nuestra clase, tengamos una idea más profunda acerca del complemento. El plugin tiene una estructura bastante simple. Se compone de dos menús diferentes: uno para el administrador y sirve como panel administrativo, accesible solo para usuarios con una capacidad de "opciones de gestión". El segundo menú es para clientes y da acceso al panel de clientes. Este panel requiere una"wptuts_client_page"capacidad.

Esta capacidad no existe en WordPress; necesitamos agregarlo y asignarlo a los usuarios o roles especificados. Pero antes de eso, echemos un vistazo al plugin..

 / * Nombre del complemento: WordPress Roles Plugin URI del complemento: https://github.com/omarabid/WordPress-Roles-Plugin Descripción: Un complemento de los roles de WordPress Autor: Abid Omar Autor URI: http://omarabid.com Versión: 1.0 * / // Agregar un menú de usuario de administrador a WordPress Dashboard add_action ('admin_menu', 'wptuts_admin_menu'); función wptuts_admin_menu () add_menu_page ('Admin Access', 'Admin Access', 'manage_options', 'wptuts-admin', 'wptuts_admin_page');  función wptuts_admin_page () echo 'Admin Page';  // Agregar un menú de usuario del cliente a WordPress Dashboard add_action ('admin_menu', 'wptuts_client_menu'); función wptuts_client_menu () add_menu_page ('Client Access', 'Client Access', 'wptuts_client', 'wptuts-client', 'wptuts_client_page');  función wptuts_client_page () echo 'Página de cliente'; 

Tenemos dos "admin_menu"ganchos de acción que agregan el menú de administración tanto para el administrador como para el cliente. Podemos acortarlo a solo un gancho que agrega a ambos; pero prefiero separar los dos. Cada uno"add_menu_page"la función se engancha a otra función que mostrará el contenido de la página.

A continuación, necesitamos inicializar nuestra clase de roles. El código de clase se coloca en otro archivo; y el proceso de inicialización se realiza durante el "en eso"gancho que asegura que WordPress ha terminado de cargar.

La función constructora acepta tres parámetros:

  • $ todos Booleano (opcional) Si desea que el cliente tenga acceso a todos los usuarios del blog, puede configurarlo en verdadero e ignorar los parámetros restantes.
  • $ roles Array (opcional) Una matriz con los identificadores de roles que tendrán acceso al panel del cliente.
  • $ usuarios Array (opcional) Una matriz con los nombres de usuario de los usuarios que tendrán acceso al panel del cliente.
 // Carga e inicializa la clase de roles add_action ('init', 'wptuts_start_plugin'); función wptuts_start_plugin () require_once ('roles_class.php'); $ all = falso; $ roles = array ('suscriptor'); $ usuarios = matriz (3); nuevos wpttuts_roles ($ todos, $ roles, $ usuarios); 

Paso 3 La clase de roles

Las propiedades

La clase tiene solo 3 propiedades: $ todos, $ roles y $ usuarios. Estas son las mismas variables que pasas a la función de constructor. El valor de las variables no se cambia en nuestro ejemplo; pero en un caso práctico real, es posible que desee fusionarse con otra fuente. Para esto, tienes la set_entities función. Puedes acomodarlo a tus propias necesidades..

 / ** * @var boolean * / private $ all; / ** * @var array * / private $ roles; / ** * @var array * / private $ users; / ** * Establecer las entidades de permisos * * @param boolean $ all * @param array $ roles * @param array $ users * / private function set_entities ($ all, $ roles, $ users) $ this-> all = $ todos; $ this-> roles = $ roles; $ this-> users = $ users; 

La función constructora

En un primer paso, la función constructora inicializa $ todos, $ roles y $ usuarios variables usando el set_entitites () función. Luego, llama a una función privada para configurar las capacidades, y otra para la restricción de la Biblioteca de medios. Estos son exactamente los pasos que definimos en nuestro escenario..

 / ** * Crea una nueva instancia de la clase de roles * * @param boolean $ all * @param array $ roles * @param array $ users * / function __construct ($ all = false, $ roles = array (), $ users = array ()) // Establezca las entidades permitidas $ this-> set_entities ($ all, $ roles, $ usuarios); // Establecer el permiso de acceso de usuario $ this-> set_permissions (); // Filtro de biblioteca de medios $ this-> media_filter (); 

Funciones estáticas

Las funciones estáticas no requieren inicialización de clase. Son similares a las funciones independientes, pero simplemente están vinculadas a la clase especificada. Decidí mantener algunas funciones estáticas porque se pueden usar de forma independiente; y podrías encontrarlos útiles en otro contexto.

Estas funciones son filter_roles () y filter_users (); que están asociadas con otras dos funciones role_has_caps () y user_has_caps (). Las funciones juegan la parte de un filtro. Filtran roles (o usuarios) en función de las capacidades que tienen y no tienen.

Ambas funciones aceptan dos argumentos:

  • $ incluye Formación Un conjunto de capacidades que tiene el rol..
  • $ excluir Formación Un conjunto de capacidades que el rol no tiene.
 / ** * Filtra todos los roles del blog según las capacidades * * @static * @param array $ incluye una matriz de capacidades para incluir * @param array $ exclude Una matriz de capacidades para excluir * @return array * / static function filter_roles ($ incluye, $ exclude) $ filter_roles = array (); $ wp_roles globales; $ roles = $ wp_roles-> get_names (); foreach ($ roles como $ role_id => $ role_name) $ role = get_role ($ role_id); if (self :: role_has_caps ($ role, $ include) &&! self :: role_has_caps ($ role, $ exclude)) $ filter_roles [] = $ role_id;  devolver $ filter_roles;  / ** * Filtra a todos los usuarios del blog según las capacidades * * @static * @param array $ incluye la matriz de capacidades para incluir * @param array $ exclude la matriz de capacidades para excluir * @return array * / static function filter_users ( $ incluye, $ excluye) $ filter_users = array (); $ users = get_users (); foreach ($ users como $ user) $ user = new WP_User ($ user-> ID); if (self :: user_has_caps ($ user, $ include) &&! self :: user_has_caps ($ user, $ exclude)) $ filter_users [] = $ user-> ID;  devolver $ filter_users; 

Las funciones recorren todos los roles y usuarios en la base de datos. Para cada rol (o usuario), verifica si tiene las capacidades requeridas y no tiene las capacidades para excluir. Este control se realiza con la role_has_caps () y user_has_caps () funciones.

Estas dos funciones (role_has_caps () y user_has_caps ()) acepta dos argumentos:

  • $ rol (o $ usuario) Cuerda El ID de rol o el ID de usuario.
  • $ caps Formación Un conjunto de capacidades para contrastar.

Si el rol (o usuario) tiene las capacidades especificadas en el $ caps array, la función devuelve true. En el otro caso, la función devuelve falso. La función básicamente recorre cada capacidad y verifica que el rol (o usuario) tenga la capacidad especificada.

 / ** * Devuelve verdadero si un rol tiene las capacidades en la matriz pasada * * @static * @param $ role * @param $ caps * @return bool * / static function role_has_caps ($ role, $ caps) foreach ($ los límites como $ cap) if (! $ role-> has_cap ($ cap)) return false;  devuelve true;  / ** * Devuelve verdadero si un usuario tiene las capacidades en la matriz pasada * * @static * @param $ user * @param $ caps * @return bool * / static function user_has_caps ($ user, $ caps) foreach ( $ caps as $ cap) if (! $ user-> has_cap ($ cap)) return false;  devuelve true; 

Agregando Permisos

Este es el primer paso para imponer la ley de nuestro complemento. He distribuido la funcionalidad en 3 funciones: una para establecer permisos para todos los usuarios, una para configurar permisos para los roles y otra para configurar permisos para los usuarios especificados. La función principal simplemente decide qué funciones llamar..

 / ** * Establezca los permisos de acceso a Menú y Páginas * / función privada set_permissions () $ this-> set_all_permissions (); if (! $ this-> all) $ this-> set_roles_permissions (); $ this-> set_users_permissions (); 

los set_all_permissions () La función recorre todos los usuarios del blog y agrega (o elimina) el "wptuts_client"capacidad dependiendo del valor del $ todos variable. Obtenemos la lista completa de usuarios usando el get_users () función; e inicializa un nuevo WP_User objeto para acceder a la add_cap () y quite la tapa() funciones.

 / ** * Establezca los permisos para TODOS los usuarios * / función privada set_all_permissions () $ users = get_users (); foreach ($ users como $ user) $ user = new WP_User ($ user-> ID); if ($ this-> all) $ user-> add_cap ('wptuts_client');  else $ user-> remove_cap ('wptuts_client'); 

los set_roles_permissions () La función recorre todos los roles en el blog y elimina el "wptuts_client"capacidad. Después de eso, recorre los roles en el $ roles matriz y agrega el "wptuts_client"capacidad. El primer paso fue garantizar que limpiemos la capacidad de los roles que puede haber tenido anteriormente.

 / ** * Establezca los permisos para Roles * / private function set_roles_permissions () global $ wp_roles; $ roles = $ wp_roles-> get_names (); foreach ($ roles como $ role_id => $ role_name) $ role = get_role ($ role_id); $ role-> remove_cap ('wptuts_client');  if (! empty ($ this-> roles)) foreach ($ this-> roles as $ role_id) $ role = get_role ($ role_id); $ role-> add_cap ('wptuts_client'); 

los set_users_permissions () La función hace lo mismo que la última función. La única diferencia es que se dirige a usuarios en lugar de roles.

 / ** * Establezca los permisos para Usuarios específicos * / función privada set_users_permissions () $ users = get_users (); foreach ($ users como $ user) $ user = new WP_User ($ user-> ID); $ usuario-> remove_cap ('wptuts_client');  if (! empty ($ this-> users)) foreach ($ this-> users as $ user_id) $ user = new WP_User ($ user_id); $ usuario-> add_cap ('wptuts_client'); 

Filtro de la biblioteca de medios

Ahora hemos establecido los permisos correctos para las entidades correctas. (Ya sea un usuario o un rol) También tenemos que restringir el acceso a la Biblioteca de medios para la cuarta categoría que distinguimos en el escenario.

Esta categoría de roles (o usuarios) tiene el "wptuts_client"capacidad, pero no tiene la"subir archivos"capacidad. Y ahí es donde entran en juego nuestras funciones de filtro. Nos ayudarán a filtrar y devolver esta categoría de roles (o usuarios).

Para esta categoría, agregaremos dos capacidades "subir archivos"y"remove_upload_files". Los "subir archivos"dará acceso completo a la Biblioteca de medios; y la otra capacidad se usará para filtrar las publicaciones de la Biblioteca de medios, y también se usará para eliminar el"subir archivos"capacidad una vez que el"wptuts_client"la capacidad también se elimina.

 / ** * Restringir acceso a medios * / función privada media_filter () // Aplicar el filtro de medios para Clientes actuales $ roles = self :: filter_roles (array ('wptuts_client'), array ('upload_files')); $ users = self :: filter_users (array ('wptuts_client'), array ('upload_files')); $ this-> roles_add_cap ($ roles, 'upload_files'); $ this-> roles_add_cap ($ roles, 'remove_upload_files'); $ this-> users_add_cap ($ users, 'upload_files'); $ this-> users_add_cap ($ users, 'remove_upload_files'); // Restringir el acceso a la biblioteca de medios add_filter ('parse_query', array (& $ this, 'restrict_media_library')); // Para fines de limpieza $ clean_roles = self :: filter_roles (array ('remove_upload_files'), array ('wptuts_client')); $ clean_users = self :: filter_users (array ('remove_upload_files'), array ('wptuts_client')); $ this-> roles_remove_cap ($ clean_roles, 'upload_files'); $ this-> roles_remove_cap ($ clean_roles, 'remove_upload_files'); $ this-> users_remove_cap ($ clean_users, 'upload_files'); $ this-> users_remove_cap ($ clean_users, 'remove_upload_files'); 

Después de establecer las capacidades en esta categoría, nos conectamos a la "parse_query"filtro. Este filtro nos permite cambiar las publicaciones devueltas por WP_Query. En nuestro caso, vamos a establecer el "autor"variable de consulta. Esto resulta en devolver solo las publicaciones creadas por el autor especificado.

 / ** * Restringir el acceso a la biblioteca de medios * * @param $ wp_query * / public function restrict_media_library ($ wp_query) if (strpos ($ _ SERVER ['REQUEST_URI'], '/wp-admin/upload.php')) if (current_user_can ('remove_upload_files')) global $ current_user; $ wp_query-> set ('author', $ current_user-> ID);  else else if (strpos ($ _ SERVER ['REQUEST_URI'], '/wp-admin/media-upload.php')) if (current_user_can ('remove_upload_files')) global $ current_user; $ wp_query-> set ('author', $ current_user-> ID); 

El codigo completo

 if (! class_exists ('wpttuts_roles')) class wpttuts_roles / ** * Determina si todos los usuarios tendrán los permisos necesarios * * @var boolean * / private $ all; / ** * Una matriz con los roles que tienen los permisos necesarios * * @var array * / private $ roles; / ** * Una matriz con los nombres de usuario que tienen los permisos necesarios * * @var array * / private $ users; / ** * Crea una nueva instancia de la clase de roles * * @param boolean $ all * @param array $ roles * @param array $ users * / function __construct ($ all = false, $ roles = array (), $ users = array ()) // Establezca las entidades permitidas $ this-> set_entities ($ all, $ roles, $ usuarios); // Establecer el permiso de acceso de usuario $ this-> set_permissions (); // Filtro de biblioteca de medios $ this-> media_filter ();  / ** * Establecer las entidades de permisos * * @param boolean $ all * @param array $ roles * @param array $ users * / private function set_entities ($ all, $ roles, $ users) $ this-> all = $ todos; $ this-> roles = $ roles; $ this-> users = $ users;  / ** * Establezca los permisos de acceso a Menú y Páginas * / private function set_permissions () $ this-> set_all_permissions (); if (! $ this-> all) $ this-> set_roles_permissions (); $ this-> set_users_permissions ();  / ** * Establezca los permisos para TODOS los usuarios * / función privada set_all_permissions () $ users = get_users (); foreach ($ users como $ user) $ user = new WP_User ($ user-> ID); if ($ this-> all) $ user-> add_cap ('wptuts_client');  else $ user-> remove_cap ('wptuts_client');  / ** * Establezca los permisos para Roles * / private function set_roles_permissions () global $ wp_roles; $ roles = $ wp_roles-> get_names (); foreach ($ roles como $ role_id => $ role_name) $ role = get_role ($ role_id); $ role-> remove_cap ('wptuts_client');  if (! empty ($ this-> roles)) foreach ($ this-> roles as $ role_id) $ role = get_role ($ role_id); $ role-> add_cap ('wptuts_client');  / ** * Configure los permisos para Usuarios específicos * / función privada set_users_permissions () $ users = get_users (); foreach ($ users como $ user) $ user = new WP_User ($ user-> ID); $ usuario-> remove_cap ('wptuts_client');  if (! empty ($ this-> users)) foreach ($ this-> users as $ user_id) $ user = new WP_User ($ user_id); $ usuario-> add_cap ('wptuts_client');  / ** * Restringir el acceso a los medios * / private function media_filter () // Aplicar el filtro de medios para los clientes de AdPress de currenct $ roles = self :: filter_roles (array ('wptuts_client'), array ('upload_files')) ; $ users = self :: filter_users (array ('wptuts_client'), array ('upload_files')); $ this-> roles_add_cap ($ roles, 'upload_files'); $ this-> roles_add_cap ($ roles, 'remove_upload_files'); $ this-> users_add_cap ($ users, 'upload_files'); $ this-> users_add_cap ($ users, 'remove_upload_files'); // Restringir el acceso a la biblioteca de medios add_filter ('parse_query', array (& $ this, 'restrict_media_library')); // Para fines de limpieza $ clean_roles = self :: filter_roles (array ('remove_upload_files'), array ('wptuts_client')); $ clean_users = self :: filter_users (array ('remove_upload_files'), array ('wptuts_client')); $ this-> roles_remove_cap ($ clean_roles, 'upload_files'); $ this-> roles_remove_cap ($ clean_roles, 'remove_upload_files'); $ this-> users_remove_cap ($ clean_users, 'upload_files'); $ this-> users_remove_cap ($ clean_users, 'remove_upload_files');  / ** * Agregar una capacidad a una matriz de roles * * @param $ roles * @param $ cap * / private function roles_add_cap ($ roles, $ cap) foreach ($ roles como $ role) $ role = get_role ($ rol); $ role-> add_cap ($ cap);  / ** * Agregar una capacidad a una matriz de usuarios * * @param $ users * @param $ cap * / private function users_add_cap ($ users, $ cap) foreach ($ users como $ user) $ user = nuevo WP_User ($ usuario); $ usuario-> add_cap ($ cap);  / ** * Eliminar una capacidad de una matriz de roles * * @param $ roles * @param $ cap * / private function roles_remove_cap ($ roles, $ cap) foreach ($ roles como $ role) $ role = get_role ($ role); $ role-> remove_cap ($ cap);  / ** * Eliminar una capacidad de una matriz de usuarios * * @param $ users * @param $ cap * / private function users_remove_cap ($ users, $ cap) foreach ($ users como $ user) $ user = nuevo WP_User ($ usuario); $ usuario-> remove_cap ($ cap);  / ** * Filtrar todos los roles del blog según las capacidades * * @static * @param array $ incluye una matriz de capacidades para incluir * @param array $ exclude Una matriz de capacidades para excluir * @return array * / static function filter_roles ($ include, $ exclude) $ filter_roles = array (); $ wp_roles globales; $ roles = $ wp_roles-> get_names (); foreach ($ roles como $ role_id => $ role_name) $ role = get_role ($ role_id); if (self :: role_has_caps ($ role, $ include) &&! self :: role_has_caps ($ role, $ exclude)) $ filter_roles [] = $ role_id;  devolver $ filter_roles;  / ** * Devuelve verdadero si un rol tiene las capacidades en la matriz pasada * * @static * @param $ role * @param $ caps * @return bool * / static function role_has_caps ($ role, $ caps) foreach ( $ caps as $ cap) if (! $ role-> has_cap ($ cap)) return false;  devuelve true;  / ** * Filtra a todos los usuarios del blog según las capacidades * * @static * @param array $ incluye la matriz de capacidades para incluir * @param array $ exclude la matriz de capacidades para excluir * @return array * / static function filter_users ( $ incluye, $ excluye) $ filter_users = array (); $ users = get_users (); foreach ($ users como $ user) $ user = new WP_User ($ user-> ID); if (self :: user_has_caps ($ user, $ include) &&! self :: user_has_caps ($ user, $ exclude)) $ filter_users [] = $ user-> ID;  devolver $ filter_users;  / ** * Devuelve verdadero si un usuario tiene las capacidades en la matriz pasada * * @static * @param $ user * @param $ caps * @return bool * / static function user_has_caps ($ user, $ caps) foreach ( $ caps as $ cap) if (! $ user-> has_cap ($ cap)) return false;  devuelve true;  / ** * Restringir el acceso a la biblioteca de medios * * @param $ wp_query * / public function restrict_media_library ($ wp_query) if (strpos ($ _ SERVER ['REQUEST_URI'], '/wp-admin/upload.php'))  if (current_user_can ('remove_upload_files')) global $ current_user; $ wp_query-> set ('author', $ current_user-> ID);  else else if (strpos ($ _ SERVER ['REQUEST_URI'], '/wp-admin/media-upload.php')) if (current_user_can ('remove_upload_files')) global $ current_user; $ wp_query-> set ('author', $ current_user-> ID); 

Conclusión

En este tutorial, traté de usar el material que aprendimos de las dos publicaciones anteriores para crear una solución personalizada para roles y capacidades. La solución se encapsuló en una clase que se puede personalizar para sus propias necesidades o complementos. Puedes encontrar el código en Github.

Si tiene alguna pregunta, sugerencia o mejora, no dude en publicarla en los comentarios..