Capacidades y Tipos de Publicación Personalizados
Tengo un tipo de publicación personalizado al que me gustaría restringir el acceso a ciertos roles, sin embargo, ya he añadido contenido usando este tipo de publicación personalizado y ahora necesito restringirlos. El capability_type era 'post'
'capability_type' => 'post'
Lo cual está bien ya que el contenido se muestra en el backend, sin embargo, ahora tan pronto como añado cualquier capacidad, ¡el contenido desaparece del backend!
He intentado personalizar el tipo de capacidad para incluir definiciones plurales para construir el mío propio, pero tan pronto como elimino o cambio los tipos de capacidad, ¡desaparece!
código completo:
add_action( 'init', 'register_cpt_gallery' );
function register_cpt_gallery() {
$labels = array(
'name' => _x( 'Galleries', 'gallery' ),
'singular_name' => _x( 'Gallery', 'gallery' ),
'add_new' => _x( 'Add New', 'gallery' ),
'add_new_item' => _x( 'Add New Gallery', 'gallery' ),
'edit_item' => _x( 'Edit Gallery', 'gallery' ),
'new_item' => _x( 'New Gallery', 'gallery' ),
'view_item' => _x( 'View Gallery', 'gallery' ),
'search_items' => _x( 'Search Galleries', 'gallery' ),
'not_found' => _x( 'No galleries found', 'gallery' ),
'not_found_in_trash' => _x( 'No galleries found in Trash', 'gallery' ),
'parent_item_colon' => _x( 'Parent Gallery:', 'gallery' ),
'menu_name' => _x( 'Galleries', 'gallery' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'description' => 'Image galleries for teachers classes',
'supports' => array( 'title', 'editor', 'author'),
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_icon' => get_bloginfo('template_url') . '/images/imagegallery.png',
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'has_archive' => true,
'query_var' => true,
'can_export' => true,
'rewrite' => true,
'capability_type' => 'post',
'capabilities' => array(
'edit_post' => 'edit_gallery',
'edit_posts' => 'edit_galleries',
'edit_others_posts' => 'edit_other_galleries',
'publish_posts' => 'publish_galleries',
'read_post' => 'read_gallery',
'read_private_posts' => 'read_private_galleries',
'delete_post' => 'delete_gallery'
)
);
register_post_type( 'gallery', $args );
}
También he probado esto con un tipo de publicación personalizado completamente nuevo y, independientemente del tipo de capacidad, obtengo el mismo problema, por ejemplo, incluso si lo elimino y agrego el mío personalizado:
'capability_type' => array('movie','movies');

Después de una rápida conversación con Magicroundabout quien señaló un recurso útil de Justin Tadlock, resulta que las capacidades para tipos de contenido personalizados en realidad no existen a menos que uses add_cap para el rol, por ejemplo para el siguiente tipo de contenido personalizado:
add_action( 'init', 'register_cpt_gallery' );
function register_cpt_gallery() {
$labels = array(
'name' => __( 'Galerías', 'gallery' ),
'singular_name' => __( 'Galería', 'gallery' ),
'add_new' => __( 'Añadir nueva', 'gallery' ),
'add_new_item' => __( 'Añadir nueva galería', 'gallery' ),
'edit_item' => __( 'Editar galería', 'gallery' ),
'new_item' => __( 'Nueva galería', 'gallery' ),
'view_item' => __( 'Ver galería', 'gallery' ),
'search_items' => __( 'Buscar galerías', 'gallery' ),
'not_found' => __( 'No se encontraron galerías', 'gallery' ),
'not_found_in_trash' => __( 'No se encontraron galerías en la papelera', 'gallery' ),
'parent_item_colon' => __( 'Galería padre:', 'gallery' ),
'menu_name' => __( 'Galerías', 'gallery' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'description' => 'Galerías de imágenes para clases de profesores',
'supports' => array( 'title', 'editor', 'author'),
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_icon' => get_bloginfo('template_url') . '/images/imagegallery.png',
'show_in_nav_menus' => true,
'publicly_queryable' => true,
'exclude_from_search' => false,
'has_archive' => true,
'query_var' => true,
'can_export' => true,
'rewrite' => true,
'capabilities' => array(
'edit_post' => 'edit_gallery',
'edit_posts' => 'edit_galleries',
'edit_others_posts' => 'edit_other_galleries',
'publish_posts' => 'publish_galleries',
'read_post' => 'read_gallery',
'read_private_posts' => 'read_private_galleries',
'delete_post' => 'delete_gallery'
),
// como señaló iEmanuele, agregar map_meta_cap mapeará los meta correctamente
'map_meta_cap' => true
);
register_post_type( 'gallery', $args );
}
Las capacidades adicionales deben agregarse a un rol para que los permisos realmente funcionen en el backend, incluido el 'administrador' - por ejemplo:
function add_theme_caps() {
// obtiene el rol de administrador
$admins = get_role( 'administrator' );
$admins->add_cap( 'edit_gallery' );
$admins->add_cap( 'edit_galleries' );
$admins->add_cap( 'edit_other_galleries' );
$admins->add_cap( 'publish_galleries' );
$admins->add_cap( 'read_gallery' );
$admins->add_cap( 'read_private_galleries' );
$admins->add_cap( 'delete_gallery' );
}
add_action( 'admin_init', 'add_theme_caps');
Espero que esto sea útil para otros.
Adicionalmente, la función de traducción _x()
espera que el segundo argumento sea string $context
, que es una breve descripción, y el tercero sea string $domain
. Cuando no se proporciona una descripción, usa la función de traducción __()
que tiene string $domain
como segundo argumento.

add_theme_caps()
debe llamarse solo una vez, no cada vez que se carga una página de administración. Sería mejor usar switch_theme
como gancho para la activación del tema o register_activation_hook
en la activación del plugin.


En mi opinión, nunca debes mapear tus propias capacidades manualmente. Asegúrate de usar el plugin map meta cap para hacerlo. http://codex.wordpress.org/Function_Reference/map_meta_cap
Pasé días intentando mapear mis capacidades personalizadas manualmente con código. Simplemente instala ese plugin, mapea tus capacidades y desactívalo una vez que funcione. Si estás creando roles personalizados, NECESITARÁS el plugin Members.
La forma en que pruebo para ASEGURARME de que mi rol tiene esas capacidades (a veces juras que las tienes pero en realidad no) es crear una página de depuración con:
if( !function_exists( 'current_user_has_role' ) ){
function current_user_has_role( $role ){
$current_user = new WP_User( wp_get_current_user()->ID );
$user_roles = $current_user->roles;
$is_or_not = in_array( $role, $user_roles );
return $is_or_not;
}
}
Esto te mostrará qué capacidades tienes realmente.

Para Tipos de Entradas Personalizados (Custom Post Types), NO recomiendo usar el hook:
add_action( 'registered_post_type', 'your_func', 10, 2 );
en su lugar sugiero utilizar:
add_filter( 'register_post_type_args', 'your_func', 10, 2 );
function your_func( $args, $name )
{
if ( $name == "your_custom_post_name" )
...
}

Ni siquiera entiendo por qué es una buena sugerencia. Esa acción es llamada desde post.php al final de register_post_type, y pasa el tipo y el objeto de vuelta a cualquier código que quiera manejarlo. No parece haber nada malo con esto. Aunque nada en esta Q&A se refería a esta acción de todas formas. ;)
