Возможности и Пользовательские Типы Записей
У меня есть пользовательский тип записи, для которого я хочу ограничить доступ определенным ролям, однако я уже добавил контент, используя этот пользовательский тип записи, и теперь мне нужно сделать его ограниченным. Тип возможностей был 'post'
'capability_type' => 'post'
Это нормально, так как контент отображается в панели администратора, однако теперь, как только я добавляю какие-либо возможности, контент исчезает из панели администратора?
Я пытался настроить тип возможностей, включая множественные определения для создания собственных, но как только я удаляю или изменяю типы возможностей, он исчезает!
полный код:
add_action( 'init', 'register_cpt_gallery' );
function register_cpt_gallery() {
$labels = array(
'name' => _x( 'Галереи', 'gallery' ),
'singular_name' => _x( 'Галерея', 'gallery' ),
'add_new' => _x( 'Добавить новую', 'gallery' ),
'add_new_item' => _x( 'Добавить новую галерею', 'gallery' ),
'edit_item' => _x( 'Редактировать галерею', 'gallery' ),
'new_item' => _x( 'Новая галерея', 'gallery' ),
'view_item' => _x( 'Просмотреть галерею', 'gallery' ),
'search_items' => _x( 'Поиск галерей', 'gallery' ),
'not_found' => _x( 'Галереи не найдены', 'gallery' ),
'not_found_in_trash' => _x( 'Галереи не найдены в корзине', 'gallery' ),
'parent_item_colon' => _x( 'Родительская галерея:', 'gallery' ),
'menu_name' => _x( 'Галереи', 'gallery' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'description' => 'Галереи изображений для учительских классов',
'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 );
}
Я также протестировал это с совершенно новым пользовательским типом записи, и независимо от типа возможностей я получаю ту же проблему, например, даже если я удалю его и добавлю свой собственный:
'capability_type' => array('movie','movies');

После короткого обсуждения с Magicroundabout, который указал на полезный ресурс от Джастина Тэдлока, выяснилось, что возможности для произвольных типов записей на самом деле не существуют, если вы не используете add_cap для роли. Например, для следующего пользовательского типа записи:
add_action( 'init', 'register_cpt_gallery' );
function register_cpt_gallery() {
$labels = array(
'name' => __( 'Галереи', 'gallery' ),
'singular_name' => __( 'Галерея', 'gallery' ),
'add_new' => __( 'Добавить новую', 'gallery' ),
'add_new_item' => __( 'Добавить новую галерею', 'gallery' ),
'edit_item' => __( 'Редактировать галерею', 'gallery' ),
'new_item' => __( 'Новая галерея', 'gallery' ),
'view_item' => __( 'Просмотреть галерею', 'gallery' ),
'search_items' => __( 'Искать галереи', 'gallery' ),
'not_found' => __( 'Галереи не найдены', 'gallery' ),
'not_found_in_trash' => __( 'В корзине галерей не найдено', 'gallery' ),
'parent_item_colon' => __( 'Родительская галерея:', 'gallery' ),
'menu_name' => __( 'Галереи', 'gallery' ),
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'description' => 'Галереи изображений для занятий учителей',
'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'
),
// как отметил iEmanuele, добавление map_meta_cap правильно сопоставляет метаданные
'map_meta_cap' => true
);
register_post_type( 'gallery', $args );
}
Дополнительные возможности должны быть добавлены к роли, чтобы разрешения действительно работали в административной части, включая роль 'administrator' - например:
function add_theme_caps() {
// получаем роль администратора
$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');
Надеюсь, это будет полезно другим.
Дополнительно, функция перевода _x()
ожидает, что второй аргумент будет string $context
(короткое описание), а третий - string $domain
. Если описание не предоставляется, используйте вместо этого функцию перевода __()
, где string $domain
является вторым аргументом.

add_theme_caps()
следует вызывать только один раз, а не при каждой загрузке административной страницы. Лучше использовать хук switch_theme
для активации темы или register_activation_hook
для активации плагина.


IMO вы никогда не отображаете свои собственные возможности. Обязательно используйте плагин map meta cap для этого. http://codex.wordpress.org/Function_Reference/map_meta_cap
Я потратил дни, пытаясь вручную отобразить свои пользовательские возможности с помощью кода. Просто установите этот плагин, настройте ваши возможности и деактивируйте его после того, как все заработает. Если вы создаете пользовательские роли, вам ПОНАДОБИТСЯ плагин Members.
Способ, которым я проверяю, чтобы УБЕДИТЬСЯ, что моя роль имеет эти возможности (иногда кажется, что они есть, но на самом деле их нет) — создаю страницу для отладки с таким кодом:
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;
}
}
Это покажет вам, какими возможностями вы действительно обладаете.

Для пользовательских типов записей я НЕ рекомендую использовать хук:
add_action( 'registered_post_type', 'your_func', 10, 2 );
вместо этого я предлагаю использовать:
add_filter( 'register_post_type_args', 'your_func', 10, 2 );
function your_func( $args, $name )
{
if ( $name == "your_custom_post_name" )
...
}

Я даже не понимаю, почему это хорошее предложение. Это действие вызывается из post.php внизу register_post_type и передает тип и объект обратно любому коду, который хочет их обработать. В этом нет ничего плохого. Хотя ничто в этом вопросе и ответах не ссылалось на это действие в любом случае. ;)
