WordPress как на ладони
Прибыльная монетизация. Выгодно. Безопасно. Стабильно.

user_has_capхук-фильтрWP 2.0.0

Позволяет удалить/добавить новые права (возможности) отдельному пользователю.

Этот хук также будет работать и для неавторизованных пользователей. Права проверяются и для них, только по умолчанию в списке прав неавторизованных пользователей пусто, но мы можем и им разрешить выполнять какие-то действия. Кейс когда это может пригодиться см. в примере.

Использование

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)
Объект юзера, права которого фильтруются.

Примеры

0

#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 === $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 'Право есть.';
}

0

#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.

Где вызывается хук

WP_User::has_cap()
user_has_cap
wp-includes/class-wp-user.php 809
$capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this );

Где используется хук в WordPress

wp-includes/default-filters.php 678
add_filter( 'user_has_cap', 'wp_maybe_grant_install_languages_cap', 1 );
wp-includes/default-filters.php 679
add_filter( 'user_has_cap', 'wp_maybe_grant_resume_extensions_caps', 1 );
wp-includes/default-filters.php 680
add_filter( 'user_has_cap', 'wp_maybe_grant_site_health_caps', 1, 4 );
campusboy 4173youtube.com/c/wpplus
Создатель YouTube канала wp-plus, на котором делюсь своим опытом. Активный пользователь wp-kama.ru. WordPress-разработчик. Разработка сайтов и лендингов. Доработка существующих проектов. Сопровождение ресурсов.
Редакторы: Kama 9026
1 комментарий
    Войти