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:

  1. Modificando la global $wp_post_types, con sus limitaciones y con la gran antipatía que las globales suelen generar.
  2. 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().
  3. 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?

  • Esa incorporación fue de la más útiles que vi en años, haha! ¿Sabes la de problemas que me ha ahorrado? Hasta la fecha era un engorro añadir un simple “support” para cualquier metabox de otro plugin. Muy buena explicación, como siempre 🙂

    • Si es que es muy difícil que WordPress cierre alguna puerta a la flexibilidad. 🙂