current_user_can() WP 2.0.0

Перевіряє права поточного користувача, здійснювати вказану дію.

За замовчуванням в WP поточний користувач встановлюється на подію plugins_loaded .

Супер-Адміни в мережі мультисайт завжди мають усі права (повертає true), якщо право, яке перевіряється, спеціально не заборонено. WP_User ::has_cap() .

Єдиний спосіб явно заборонити право супер адміністраторів – використовувати фільтр map_meta_cap де повернути do_not_allowдля можливості. Варіант заборони: $user->add_cap( 'capability', false )не працюватиме!

Якщо потрібно перевірити право вказаного користувача, а не поточного користувача, використовуйте user_can() .

Працює на основі:
WP_User::has_cap()
Основа для:
get_edit_post_link()
1 раз – 0.0034041 сек
(дуже повільно) | 50000 разів – 3.84 сек
(швидко) |
PHP 7.4.8, WP 5.6

Хуків немає.

Повертає

true|false. true – є права, false – немає прав.


Використання

if( current_user_can( $capability, $args ) ){
	// є право...
}
$capability
(рядок) (обов’язковий)
Назва можливості чи ролі. Список можливостей та ролей
дивіться тут .
…$args
(змішаний)

Додаткові аргументи, які буде використано для перевірки права. Наприклад, ID посту.

Деякі перевірки потребують таких аргументів. Наприклад, edit_postпотрібно вказати ID запису для якого перевіряється доступ.


Базовий список прав

За промовчанням у WordPress 6 ролей:

Super AdminСупер-адміністратор. Має права керувати мережею сайтів. Ця роль з’являється тільки при мультисайті установки .
administratorАдміністратор сайту (окремого сайту в мережі мультисайт).
editorРедактор. Має доступ до всіх постів, сторінок, коментарів, категорій, тегів та посилань.
authorАвтор. Може писати, завантажувати фотографії, редагувати та публікувати свої пости.
contributorУчасник Може писати пости, які потім публікує редактор чи адмін.
subscriberПередплатник. Не може нічого, крім редагування профілю.

Яку роль отримує новий користувач вказується у Настройки > Общие. Дані зберігаються в опції: default_role :


Список прав за ролями

Список примітивних (фундаментальних) прав користувача. Це можливості, які за замовчуванням є у зазначених ролей (користувачів). Цей список прав задається один раз, при встановленні WordPress – він зберігається в таблицю БД wp_optionsв опцію wp_user_roles.

ПравоСупер-АдмінАдмінРедакторАвторУчасникПередплатник
readтактактактактактак
delete_postsтактактактактак
edit_postsтактактактактак
delete_published_postsтактактактак
edit_published_postsтактактактак
publish_postsтактактактак
upload_filesтактактактак
delete_others_pagesтактактак
delete_others_postsтактактак
delete_pagesтактактак
delete_private_pagesтактактак
delete_private_postsтактактак
delete_published_pagesтактактак
edit_others_pagesтактактак
edit_others_postsтактактак
edit_pagesтактактак
edit_private_pagesтактактак
edit_private_postsтактактак
edit_published_pagesтактактак
manage_categoriesтактактак
manage_linksтактактак
moderate_commentsтактактак
publish_pagesтактактак
read_private_pagesтактактак
read_private_postsтактактак
unfiltered_htmlтактак ¹так ¹
activate_pluginsтактак ²
create_usersтактак ¹
deactivate_pluginsтактак
delete_pluginsтактак ¹
delete_themesтактак ¹
delete_usersтактак ¹
edit_dashboardтактак
edit_filesтактак ¹
edit_pluginsтактак ¹
edit_theme_optionsтактак
edit_themesтактак ¹
edit_usersтактак ¹
exportтактак
importтактак
install_languagesтактак ¹
install_pluginsтактак ¹
install_themesтактак ¹
list_usersтактак
manage_optionsтактак
promote_usersтактак
remove_usersтактак
switch_themesтактак
update_coreтактак ¹
update_languagesтактак ¹
update_pluginsтактак ¹
update_themesтактак ¹
unfiltered_uploadтак ³так ³
manage_network_optionsтак
manage_network_pluginsтак
manage_network_themesтак
manage_network_usersтак
manage_networkтак
manage_sitesтак
setup_networkтак
upgrade_networkтак
  • ¹коли один сайт (не мультисайт).
  • ²коли один сайт (не мультисайт). Або вмикається у налаштуваннях мережі.
  • ³– Це право потрібно включати окремо, докладніше нижче .


Мета права

Вище перераховано перелік примітивних (фундаментальних) прав. Але ще є так звані мета-права. Вони ніде не зберігаються, а обчислюються «нальоту» й у результаті перетворюються на примітивне право.

Список мета-прав:

activate_plugin
activate_plugins
add_comment_meta
add_post_meta
add_term_meta
add_user_meta
add_users
assign_categories
assign_post_tags
assign_term
create_app_password
create_sites
create_users
customize
deactivate_plugin
deactivate_plugins
delete_app_password
delete_app_passwords
delete_categories
delete_comment_meta
delete_page
delete_page
delete_plugins
delete_post
delete_post
delete_post_meta
delete_post_tags
delete_site
delete_sites
delete_term
delete_term_meta
delete_themes
delete_user
delete_user
delete_user_meta
delete_users
edit_app_password
edit_categories
edit_comment
edit_comment
edit_comment_meta
edit_css
edit_files
edit_page
edit_page
edit_plugins
edit_post
edit_post
edit_post_meta
edit_post_tags
edit_term
edit_term_meta
edit_themes
edit_user
edit_user
edit_user_meta
edit_users
erase_others_personal_data
export_others_personal_data
install_languages
install_plugins
install_themes
list_app_passwords
manage_links
manage_network
manage_network_options
manage_network_plugins
manage_network_themes
manage_network_users
manage_post_tags
manage_privacy_options
manage_sites
promote_user
promote_user
publish_post
read_app_password
read_page
read_page
read_post
read_post
remove_user
remove_user
resume_plugin
resume_theme
setup_network
unfiltered_html
unfiltered_upload
update_core
update_https
update_languages
update_php
update_plugins
update_themes
upgrade_network
upload_plugins
upload_themes

edit_term - WP 4.7 - Не перевірять хто створив термін - тільки перевіряє наявність зазначеного терміну та таксономії.
delete_term - WP 4.7 -
assign_term - WP 4.7 -
activate_plugin - WP 4.9 - current_user_can( 'activate_plugin', 'my-plugin/my-plugin.php' )
deactivate_plugin - WP 4.9 - current_user_can( 'deactivate_plugin', 'my-plugin/my-plugin.php' )

export_others_personal_data - WP 4.9.6 - is_multisite() ? 'manage_network' : 'manage_options'
erase_others_personal_data - WP 4.9.6 - is_multisite() ? 'manage_network' : 'manage_options'
manage_privacy_options - WP 4.9.6 - is_multisite() ? 'manage_network' : 'manage_options'

update_php - WP 5.0 - is_multisite() ? is_super_admin() : update_core
update_https - WP 5.7 - is_multisite() ? is_super_admin() : manage_options | update_core

create_app_password - WP 5.7 - map_meta_cap( 'edit_user', $user_id )
list_app_passwords - WP 5.7 - map_meta_cap( 'edit_user', $user_id )
read_app_password - WP 5.7 - map_meta_cap( 'edit_user', $user_id )
edit_app_password - WP 5.7 - map_meta_cap( 'edit_user', $user_id )
delete_app_passwords - WP 5.7 - map_meta_cap( 'edit_user', $user_id )
delete_app_password - WP 5.7 - map_meta_cap( 'edit_user', $user_id )

Для перевірки таких прав потрібно передавати додаткові параметри, наприклад ID запису, для якої потрібно перевірити, чи може користувач її редагувати. Наприклад:

if( current_user_can( 'edit_post', 123 ) ){
	 echo 'Поточний користувач може редагувати пост 123';
}

У цьому випадку WP нальоту перевіряє, чи є користувач автором цієї посади, або у нього є примітивне право редагувати всі пости. У результаті, якщо перевірку пройдено, це мета право перетворюється на аналогічне примітивне право, яке дозволяє виконувати дію.

Докладніше про мета права читайте в описі map_meta_cap() .


unfiltered_upload

За замовчуванням можливість unfiltered_upload є у адміністратора . Проте це за замовчуванням заблоковано, тобто. ролі не пройдуть перевірку if( current_user_can('unfiltered_upload') ), незважаючи на наявність у них такого права.

Щоб право unfiltered_upload почало працювати як очікується, потрібно у файлі wp-config.php “включити” константу:

define( 'ALLOW_UNFILTERED_UPLOADS', true );

З визначенням цієї константи ролі, що мають право unfiltered_upload, зможуть завантажувати файли з будь-яким розширенням (без перевірки типу файлу).

Для мультисайту складання право unfiltered_uploadє тільки у Супер Адміністратора. Якщо інша роль має право unfiltered_upload, воно просто ігноруватися. Докладніше дивіться перевірку мета-права в map_meta_cap() :

case 'unfiltered_upload':
	if ( defined( 'ALLOW_UNFILTERED_UPLOADS' ) && ALLOW_UNFILTERED_UPLOADS && ( ! is_multisite() || is_super_admin( $user_id ) ) ) {
		$caps[] = $cap;
	} else {
		$caps[] = 'do_not_allow';
	}
	break;


Приклади

0

#1 Перевіримо адміністратор користувач чи ні:

// Перевіримо можливість
if( current_user_can('manage_options') ){
	echo "Користувач має право змінювати налаштування";
}
0

#2 Використовуємо user_can() , щоб перевірити права користувача:

// Визначаємо користувача глобально
global $user;
if( user_can($user->ID, 'manage_options') ){
	// робимо щось, що може користувач з цими правами
};

manage_options – права адміністратора

0

#3 Приклад використання другого аргументу $args :

if( current_user_can('edit_post', 123) ) {
	 echo 'Поточний користувач може редагувати пост 123'.
}
0

#4 Перевірка прав для окремого елемента таксономії

З версії 4.7. Стало можливим перевіряти права окремого терміна. Для цього потрібно використовувати права: edit_term , delete_term , assign_term .

Наприклад, давайте виведемо посилання на редагування елемента таксономії, тільки якщо поточний користувач має таке право.

if( current_user_can('edit_term', $term_id) ){
	echo '<a href="'. get_edit_term_link( $term_id ) .'">Редакт.</a>';
}
0

#5 Перевірка більше двох ролей

Якщо ви хочете перевірити більше двох ролей, ви можете перевірити, чи є роль поточного користувача всередині масиву ролей, наприклад:

$user = wp_get_current_user();
$allowed_roles = array( 'editor', 'administrator', 'author' );

if ( array_intersect( $allowed_roles, $user->roles ) ) {
   // Stuff here for allowed roles
}
0

#6 Перевірка ролі поточного користувача

Не рекомендується використовувати назву ролі в current_user_can(), тому що код може працювати неправильно.

Приклад, як робити не слід:

// якщо поточний користувач редактор (editor), функція поверне:
current_user_can('administrator') // false
current_user_can('editor') // true
current_user_can('contributor') // false
current_user_can('subscriber') // false

Чому так писати не варто? Наприклад, ми використовуємо перевірку current_user_can('editor'), яка дозволяє редактору робити що-небудь, начебто все добре і користувач з роллю ‘editor’ проходить перевірку, але користувач з роллю ‘administrator’, який також повинен проходити перевірку, її не пройде!

Хак для можливості використовувати імена ролей у перевірці права користувача

Якщо вставити цей хук у файлі теми functions.php, то до списку прав користувача, що перевіряється будуть додаватися всі ролі які вважаються нижче за рівнем доступу, наприклад для користувача за участю автор будуть додані також ролі contributor і subscriber. Таким чином, перевірку current_user_can( 'contributor' )буде також пройдено для будь-якої ролі вище зазначеної – це author > editor > administrator.

add_filter( 'user_has_cap', 'user_lower_roles_to_allcaps', 10, 4);

/**
 * Додайте низку клацань до списку всіх дзвінків поточної перевірки користувача.
 *
 * @param bool[] $allcaps Array of key/value pairs where keys являють собою capability name and
 * boolean values ​​represent whether the user has that capability.
 * @param string[] $caps Потрібні 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 user_lower_roles_to_allcaps( $allcaps, $caps, $args, $user ){

	$roles_chain = ' > administrator > editor > author > contributor > subscriber > ';

	// do nothing if no need
	if( false === strpos( $roles_chain, $args[0] ) ){
		return $allcaps;
	}

	$low_roles = '';
	foreach( $user->roles as $role ){

		$pos = strpos( $roles_chain, " > $role > " );

		if( false === $pos ){
			continue;
		}

		$_low_roles = substr($roles_chain, $pos);

		if( strlen( $_low_roles ) > strlen( $low_roles ) ){
			$low_roles = $_low_roles;
		}
	}

	// add top roles to all caps
	$low_roles = explode('>', trim($low_roles, '>'));
	foreach( $low_roles as $lowrole ){
		$allcaps[ $lowrole ] = 1;
	}

	return $allcaps;
}

Перевіримо як працює хак:

$ user = get_userdata( 141 ); // editor
var_dump( user_can( $user, 'administrator' ) ); // bool (false)
var_dump( user_can( $user, 'contributor' ) ); // bool (true)
echo "---n";

$user = get_userdata(3); // author
var_dump( user_can( $user, 'administrator' ) ); // bool (false)
var_dump( user_can( $user, 'contributor' ) ); // bool (true)
echo "---n";

$ user = get_userdata (1220); // contributor
var_dump( user_can( $user, 'administrator' ) ); // bool (false)
var_dump( user_can( $user, 'contributor' ) ); // bool (true)
var_dump( user_can( $user, 'subscriber' ) ); // bool (true)
echo "---n";

$ user = get_userdata (2486); // subscriber
var_dump( user_can( $user, 'administrator' ) ); // bool (false)
var_dump( user_can( $user, 'contributor' ) ); // bool (false)
var_dump( user_can( $user, 'subscriber' ) ); // bool (true)
0

#7 Функція перевірки кількох ролей користувача

Щоб мати можливість надійно перевіряти права точно за ролями, було б зручно перераховувати їх у масиві, але ми не можемо написати так – це викличе нотиси:

current_user_can( [ 'administrator', 'author' ] );

Для такої перевірки я іноді використовую таку функцію:

/**
 * Checks if the specified role is in the roles of the current/specified user.
 *
 * @param string|array $roles Назви role ви збираєтеся за допомогою поточного користувача.
 * @param empty|int|WP_User $user Default: current user
 *
 * @return bool
 */
function is_user_role_in( $roles, $user = false ) {

	$user || $user = wp_get_current_user();

	if( is_numeric( $user ) ){
		$ user = get_userdata ($ user);
	}

	if( empty( $user->ID ) ){
		return false;
	}

	foreach( (array) $roles as $role ){
		if( isset( $user->caps[ $role ] ) || in_array( $role, $user->roles, true ) ){
			return true;
		}
	}

	return false;
}

Приклад використання:

if( is_user_role_in( [ 'new_role','new_role2' ] ) ){
	echo 'Роль поточного користувача new_role або new_role2';
}

if( is_user_role_in( [ 'new_role','new_role2' ], 5 ) ){
	echo 'Роль користувача 5 new_role або new_role2';
}

нотатки

список змін

З версії 2.0.0Введено.
З версії 5.3.0Formalizated existing and already documented …$args parameter by adding it до функції signature.
З версії 5.8.0Перевірено, щоб розвантажити функцію user_can () .

current user can WP 6.0.2

function current_user_can( $capability, ...$args ) {
	return user_can( wp_get_current_user(), $capability, ...$args );
}

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *