Возможности и Пользовательские Типы Записей

30 июл. 2013 г., 17:20:27
Просмотры: 78.9K
Голосов: 38

У меня есть пользовательский тип записи, для которого я хочу ограничить доступ определенным ролям, однако я уже добавил контент, используя этот пользовательский тип записи, и теперь мне нужно сделать его ограниченным. Тип возможностей был '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');
0
Все ответы на вопрос 4
2
56

После короткого обсуждения с 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 является вторым аргументом.

30 июл. 2013 г. 23:24:54
Комментарии

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

d79 d79
13 апр. 2015 г. 13:42:45

Отлично! Я предпочитаю использовать WP CLI для добавления возможностей, если сайт полностью кастомный/уникальный, так как это действие нужно выполнить всего один раз.

squarecandy squarecandy
1 дек. 2017 г. 03:56:31
2
12

Добавьте:

map_meta_cap => true

в ваш массив $args. Подробнее смотрите здесь.

Надеюсь, это поможет!

30 июл. 2013 г. 20:39:24
Комментарии

Я тоже так думал, но не совсем так.

erichmond erichmond
30 июл. 2013 г. 22:47:51

Это сработало у меня

Shikyo Shikyo
27 мар. 2018 г. 17:20:39
0

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;
        }
    }

Это покажет вам, какими возможностями вы действительно обладаете.

31 июл. 2013 г. 00:56:25
2

Для пользовательских типов записей я НЕ рекомендую использовать хук:

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" ) 
   ...
}
21 апр. 2019 г. 00:58:52
Комментарии

предложение хорошее, но оно не отвечает на вопрос.

Aurovrata Aurovrata
11 нояб. 2019 г. 10:06:13

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

TonyG TonyG
14 окт. 2021 г. 02:58:04