user_has_cap
Позволяет удалить/добавить новые права (возможности) отдельному пользователю.
Этот хук также будет работать и для неавторизованных пользователей. Права проверяются и для них, только по умолчанию в списке прав неавторизованных пользователей пусто, но мы можем и им разрешить выполнять какие-то действия. Кейс когда это может пригодиться см. в примере.
Использование
add_filter( 'user_has_cap', 'wp_kama_user_has_cap_filter', 10, 4 ); /** * Function for `user_has_cap` filter-hook. * * @param bool[] $allcaps Array of key/value pairs where keys represent a capability name and boolean values represent whether the user has that capability. * @param string[] $caps Required primitive capabilities for the requested capability. * @param array $args Arguments that accompany the requested capability check. * @param WP_User $user The user object. * * @return bool[] */ function wp_kama_user_has_cap_filter( $allcaps, $caps, $args, $user ){ // filter... return $allcaps; }
- $allcaps(массив)
Массив всех возможностей пользователя.
Массив пар
ключ => значение
, где ключи представляют имя возможности, а значение логическое true/false показывает, имеет ли пользователь эту возможность.- $caps(массив)
- Примитивные права для запрашиваемой возможности. То, что возвращает map_meta_cap().
- $args(массив)
- Дополнительные параметры переданные в current_user_can() или WP_User::has_cap(), обычно это ID объекта (поста/коммента/юзера).
- $user(WP_User)
- Объект юзера, права которого фильтруются.
Примеры
#1 Добавим названия прав в список прав пользователей на лету
Обычно права ролям выставляются при регистрации роли, а дополнительные права отдельным пользователям можно добавить с помощью плагина User Role Editor. Однако в этом случае данные добавляются в Базу данных, а это не всегда удобно - иногда нужна динамика.
Иногда удобнее выставлять права для роли налету. Например на новом проекте где права постоянно добавляются/удаляются по мере роста проекта и обновлять права в базе неудобно. А тут, внёс правки в код и сразу результат.
Рассмотрим как это сделать через хук user_has_cap на простом примере. Он показывает, как добавить право some_capability
пользователю с ID 5:
add_filter( 'user_has_cap', 'maybe_grant_some_capability_cap', 1, 4 ); function maybe_grant_some_capability_cap( $allcaps, $caps, $args, $user ){ if ( 5 === (int) $user->ID ) { $allcaps['some_capability'] = true; } return $allcaps; }
Рассмотрим еще один пример посложнее. Этот пример проверят роль текущего пользователя и тут же добавляет новые права (возможности) в список прав юзера, в зависимости от текущей роли пользователя (название роли пользователя хранится в общем списке прав пользователя).
add_filter( 'user_has_cap', 'kama_user_has_cap', 10, 4 ); /** * Меняет возможности ролей "на лету". * * @param array $allcaps * @param array $caps * @param array $args * @param WP_User $user * * @return array */ function kama_user_has_cap( $allcaps, $caps, $args, $user ) { // Трекер (неподтверждённый) $role = 'project_tracker_fake'; if ( ! empty( $allcaps[ $role ] ) ) { // WordPress $allcaps['read'] = true; } // Руководитель $role = 'project_leader'; if ( ! empty( $allcaps[ $role ] ) ) { // WordPress $allcaps['read'] = true; $allcaps['edit_posts'] = true; $allcaps['edit_published_posts'] = true; // + Эксперт $allcaps['view_expert_note'] = true; // Видеть метабокс Эксперта $allcaps['view_expert_comment'] = true; // Видеть комментарий Эксперта // + Модератор $allcaps['view_moderator_note'] = true; // Видеть метабокс Модератора } // Трекер $role = 'project_tracker'; if ( ! empty( $allcaps[ $role ] ) ) { // WordPress $allcaps['read'] = true; $allcaps['edit_posts'] = true; $allcaps['edit_published_posts'] = true; // Общее $allcaps['view_post_contacts'] = true; // Видеть метабокс с Контактами // + Эксперт $allcaps['view_expert_note'] = true; // Видеть метабокс Эксперта $allcaps['view_expert_comment'] = true; // Видеть комментарий Эксперта $allcaps['view_expert_rating'] = true; // Видеть оценку Эксперта // + Модератор $allcaps['view_moderator_note'] = true; // Видеть метабокс Модератора } // Эксперт $role = 'project_expert'; if ( ! empty( $allcaps[ $role ] ) ) { // WordPress $allcaps['read'] = true; $allcaps['edit_posts'] = true; $allcaps['delete_others_posts'] = false; $allcaps['edit_others_posts'] = true; // Общее $allcaps['view_post_contacts'] = true; // Видеть метабокс с Контактами // + Модератор $allcaps['view_moderator_note'] = true; // Видеть метабокс Модератора // Личное $allcaps['view_expert_note'] = true; // Видеть метабокс Эксперта $allcaps['view_expert_comment'] = true; // Видеть комментарий Эксперта $allcaps['view_expert_rating'] = true; // Видеть оценку Эксперта $allcaps['add_expert_note'] = true; // Изменять метабокс Эксперта $allcaps['add_expert_comment'] = true; // Изменять комментарий Эксперта $allcaps['add_expert_rating'] = true; // Изменять оценку Эксперта } return $allcaps; }
Теперь можно проверить, например возможность add_expert_rating
у юзера так:
if( current_user_can( 'add_expert_rating' ) ){ echo 'Право есть.'; }
#2 Разрешим обновлять пост не авторизованному пользователю {#allows-for-unauthorized}
Допустим, у нас такой случай, что на фронте неавторизованные пользователи могут обновлять какие-то конкретные данные поста, например добавлять метки к нему. Для обновления поста мы используем функцию wp_update_post().
По умолчанию ВП не разрешит это сделать неавторизованному пользователю, но нам нужно дать такое право. Для этого вешаем функцию на хук user_has_cap
и в функции добавляем право редактировать пост.
Мы не боимся что, юзер как-то сможет навредить, потому что мы сами устанавливаем поля которые нужно обновить для поста и предварительно их очищаем.
Например, на аякс запросе мы принимаем название элемента таксономии и хотим добавить его для поста:
// ... тут код получения GET/POST данных // разрешаем любому пользователю обновлять любые посты (в частности наш) add_filter( 'user_has_cap', 'add_editor_cap_for_unauthorizes_user' ); function add_editor_cap_hb( $allcaps ){ $allcaps['edit_posts'] = true; return $allcaps; } $post_data = [ 'ID' => 654, 'tax_input' = [ 'tax_name' => [ 'Term Name' ], ], ]; // обновляем wp_update_post( wp_slash( $post_data ) ); // отменяем разрешение remove_filter( 'user_has_cap', 'add_editor_cap_for_unauthorizes_user' ); // ... какой-то еще код
Список изменений
С версии 2.0.0 | Введена. |
С версии 3.7.0 | Added the $user parameter. |
Где вызывается хук
$capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this );
Где используется хук в WordPress
add_filter( 'user_has_cap', 'wp_maybe_grant_install_languages_cap', 1 );
add_filter( 'user_has_cap', 'wp_maybe_grant_resume_extensions_caps', 1 );
add_filter( 'user_has_cap', 'wp_maybe_grant_site_health_caps', 1, 4 );