Modificar las caracterísricas de un post type registrado por otro plugin WordPress
La versión WordPress 4.4 introdujo un nuevo filtro, el register_post_type_args
, que permite modificar los argumentos de registro de un post type. Hasta ese momento se podía hacer por varios rodeos:
- Modificando la global
$wp_post_types
, con sus limitaciones y con la gran antipatía que las globales suelen generar. - Utilizando el action
registered_post_type
que, por llegar después de que el post type se haya registrado, requiere rehacer el trabajo hecho previamente por register_post_type(). - Utilizando funciones específicas, como add_post_type_support(), que permiten modificar características concretas del post type.
Pero con el filtro register_post_type_args
se pueden interceptar todos los argumentos antes de que el registro del post type tenga lugar. No hay limitaciones en las características a modificar ni trabajo que rehacer.
Entre los casos de uso discutidos en el ticket en el que se propuso este filtro (#17447), algunos de los más «evidentes» son la modificación de los labels o de las reglas de reescritura. Pero uno de los que más me llamó la atención, por buen ejemplo de la flexibilidad que aporta, fue la modificación de las capacidades asociadas a un post type.
Imaginaos que hay un plugin que utiliza un custom post type y que hace exactamente lo que necesitas. Es el plugin perfecto. Pero resulta que utiliza el argumento capability_type
en su valor predeterminado: post
. Y en tu web los que escriben posts en el blog y los que gestionan este post type son personal separado y se quiere impedir el acceso de unos y otros.
No tienes por qué hacer un fork del plugin y mantenerlo tú, tampoco tienes por qué modificar la global $wp_post_types
y probablemente varios hooks para algo tan delicado como las capacidades de creación, modificación y eliminación de contenido. El filtro register_post_type_args
lo soluciona del tirón.
Por ejemplo, podemos crear un pequeño plugin que modifique el capability_type
y que asigne los capacidades adecuadas a cada grupo de usuarios según necesitemos. Por ejemplo:
// Filtramos los argumentos para añadir
// nuestro capability_type
add_filter( 'register_post_type_args' , 'cyb_register_post_type_args', 10, 2 );
funcion cyb_register_post_type_args( $args, $post_type ) {
if( 'mi_post_type' == $post_type ) {
$args['capability_type'] = 'cap';
}
return $args;
}
// Añadimos las capacidades personalizadas, correspondientes
// al capability_type utilizado anteriormente, a los
// roles/usuarios que deseemos al activar el plugin
register_activation_hook( __FILE__, function () {
// Some custom role
$manager = get_role('manager');
// Admin role
$administrator = get_role('administrator');
$manager_and_admin_caps = cyb_get_capabilities_map();
foreach( $manager_and_admin_caps as $cap ) {
$manager->add_cap( $cap );
$administrator->add_cap( $cap );
}
} );
// Retiramos las capacidades personalizadas de los
// roles/usuarios al desactivar el plugin
register_deactivation_hook( __FILE__, function () {
$manager = get_role('manager');
$administrator = get_role('administrator');
$manager_and_admin_caps = cyb_get_capabilities_map();
foreach( $manager_and_admin_caps as $cap ) {
$manager->remove_cap( $cap );
$administrator->remove_cap( $cap );
}
} );
// Tan solo una función auxiliar de ejemplo
function cyb_get_capabilities_map() {
return array(
'delete_caps',
'delete_others_caps',
'delete_private_caps',
'delete_published_caps',
'edit_caps',
'edit_others_caps',
'edit_private_caps',
'edit_published_caps',
'publish_caps',
'read_private_caps'
);
}
Pero como digo, este es tan sólo un ejemplo de la flexibilidad que aporta este filtro. ¿Algún otro caso de uso que os resulte interesante y queráis compartir?