Ограничение просмотра произвольного типа записей по роли пользователя
Я создал произвольный тип записей и несколько пользовательских ролей, и хочу иметь возможность ограничить просмотр этого типа записей на основе определенных ролей.
Есть ли простой способ настроить такое ограничение?
Каждая роль имеет свои возможности (capabilities).
Вот простой участник (contributor) нашего проекта: (он только пишет и редактирует)
add_role('contributor', 'Contributor', array(
'read' => true,
'edit_posts' => true,
'delete_posts' => false,
));
Теперь добавим ему новую возможность (он сможет редактировать записи других людей)
function add_capability()
{
$role = get_role('contributor');
$role->add_cap('edit_others_posts');
}
add_action('admin_init', 'add_capability');
Теперь добавим новые возможности для нашего нового типа записей. Сначала создадим тип записей:
function create_myposttype()
{
register_post_type(
'myposttype',
array(
'public' => true,
'capability_type' => 'myposttype',
'capabilities' => array(
'publish_posts' => 'publish_myposttypes',
'edit_posts' => 'edit_myposttypes',
'edit_others_posts' => 'edit_others_myposttypes',
'read_private_posts' => 'read_private_myposttypes',
'edit_post' => 'edit_myposttype',
'delete_post' => 'delete_myposttype',
'read_post' => 'read_myposttype',
),
)
);
}
add_action('init', 'create_myposttype');
Тип записей создан, но у участника нет прав для работы с ним. Дадим ему немного возможностей:
function add_capability()
{
$role = get_role('contributor');
$role->add_cap('read_myposttype');
$role->add_cap('edit_myposttypes');
$role->add_cap('delete_myposttype', false); // на всякий случай
}
add_action('admin_init', 'add_capability');
Возможность read_post и read_* гарантирует, что пользователь с этой ролью не сможет видеть и получать доступ к соответствующей области. Он получит стандартную ошибку WordPress:
У вас недостаточно прав для доступа к этой странице
И давайте сделаем так, чтобы авторы (стандартная роль) не могли видеть записи типа myposttype:
function remove_author_capability()
{
$role = get_role('author');
$role->add_cap('read_myposttype', false);
}
add_action('admin_init', 'remove_author_capability');
Не забываем про очистку:
function add_roles_on_activation() // добавляем роли при активации
{
add_role('contributor', 'Contributor', array(
'read' => true,
'edit_posts' => true,
'delete_posts' => false,
));
}
register_activation_hook(__FILE__, 'add_roles_on_activation');
function add_roles_removal() // очищаем за собой
{
remove_role('contributor');
}
register_deactivatin_hook(__FILE__, 'add_roles_removal');
Если вы просто хотите удалить элементы из меню (оставляя их доступными по прямой ссылке), вот как это сделать:
Из админ-бара (верхнего плавающего меню):
function my_edit_adminbar($wp_admin_bar)
{
if(current_user_can('read_myposttype'))
$wp_admin_bar->remove_node('new-myposttype');
}
add_action('admin_bar_menu', 'my_edit_adminbar');
Из основного меню:
function my_edit_menu()
{
if(current_user_can('read_myposttype'))
{
$slug = 'edit.php?post_type=myposttype';
remove_menu_page($slug);
}
}
add_action('admin_menu', 'my_edit_menu');

Хорошо... Я не вижу кода... поэтому не знаю, создали ли вы свой тип записи самостоятельно или использовали плагин. Предполагаю, что вы создали тип записи в functions.php. Там вы можете использовать условный оператор для проверки, есть ли у пользователя определенные права.
<?php current_user_can( $capability, $args ); ?>
Было бы очень полезно, если бы вы поделились кодом, чтобы я мог привести конкретный пример, как это сделать.
http://codex.wordpress.org/Function_Reference/current_user_can

В первую очередь, вот как мы можем получить текущую роль пользователя.
<?php
// Получаем ID текущего пользователя
$user_id = get_current_user_id();
// Получаем данные пользователя по этому ID
// возвращается в виде массива
$user_data = new WP_User( $user_id );
// Мы можем вывести первую роль из массива
// вот таким образом...
echo $user->roles[0];
// Или можем вывести весь
// массив вот так
print_r($user->roles);
?>
Теперь мы можем использовать эти данные для создания простого условного оператора в шаблонах. Это будет зависеть от того, чего вы пытаетесь достичь, но...
<?php
$user_roll = $user->roles[0];
if($user_roll =="administrator") {
// Код здесь будет выполнен только если текущий
// пользователь является администратором
}
?>
Вы поняли суть ;)

При регистрации пользовательского типа записи (Custom Post Type, CPT) мы используем хук действия init
:
add_action( 'init', 'my_custom_post_type_function', 0 );
Нам необходимо обернуть регистрацию этого конкретного CPT в условие проверки роли пользователя в два этапа:
1. Создать функцию для получения текущей роли пользователя в виде строки
function my_get_current_user_role() {
$user = wp_get_current_user();
$roles = (array)$user->roles;
return $roles[0];
}
2. Затем ограничить регистрацию
if(my_get_current_user_role() == 'administrator'){
add_action( 'init', 'my_custom_post_type_function', 0 );
}
