current_user_can()
Проверяет права текущего пользователя, совершать указанное действие.
По умолчанию в WP текущий юзер устанавливается на событии init. Поэтмоу эту функцию рекомендуется использовать не раньше этого события. Однако, она почти всегда работает правильно с события plugins_loaded .
Супер-Админы в сети мультисайт всегда имеют все права (возвращает true), если првоеряемое право специально не запрещено. См. WP_User::has_cap().
Единственный способ явно запретить право для супер администраторов - использовать фильтр map_meta_cap где вернуть do_not_allow
для возможности. Вариант запрета: $user->add_cap( 'capability', false )
работать не будет!
Когда нужно проверить право указанного, а не текущего пользователя, используйте user_can().
Хуков нет.
Возвращает
true|false
. true — есть права, false — нет прав.
Использование
if( current_user_can( $capability, $args ) ){ // есть право... }
- $capability(строка) (обязательный)
- Название возможности или роли. Список возможностей и ролей смотрите здесь.
- ...$args(смешанный)
Дополнительные аргументы, которые будут использованы для проверки права. Например, ID поста.
Некоторые проверки нуждаются в таких аргументах. Например,
edit_post
нужно указать ID записи для которой выполняется проверка доступа.
Базовый список прав
Build In PostПо умолчанию в WordPress 6 ролей:
Super Admin | Cупер-администратор. Имеет права для управления сетью сайтов. Эта роль появляется только при мультисайт установке. |
administrator | Aдминистратор сайта (отдельного сайта в сети мультисайт). |
editor | Редактор. Имеет доступ ко всем постам, страницам, комментариям, категориям, тегам и ссылкам. |
author | Автор. Может писать, загружать фотографии, редактировать и публиковать свои посты. |
contributor | Участник. Может писать посты, которые затем публикует редактор или админ. |
subscriber | Подписчик. Не может ничего, кроме редактирования профиля. |
Какую роль получает новый пользователь указывается в Настройки > Общие
. Данные сохраняются в опции: users_can_register и 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_plugins delete_post delete_post_meta delete_post_tags delete_site delete_sites delete_term delete_term_meta delete_themes delete_user delete_user_meta delete_users edit_app_password edit_categories edit_comment edit_comment_meta edit_css edit_files edit_page edit_plugins edit_post edit_post_meta edit_post_tags edit_term edit_term_meta edit_themes 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 publish_post read_app_password read_page read_post 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().
Динамические права
Это права которые не хранятся в БД, а вычисляются налету по определенным условиям. Делается такое вычисление на хуке user_has_cap.
install_languages — WP 4.9 — update_core || install_plugins || install_themes resume_plugins — WP 5.2 — activate_plugins resume_themes — WP 5.2 — switch_themes view_site_health_checks — WP 5.2 — install_plugins && is_super_admin (multisite)
См. wp_maybe_grant_install_languages_cap()
См. wp_maybe_grant_resume_extensions_caps()
См. wp_maybe_grant_site_health_caps()
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;
Примеры
#1 Проверка роли текущего пользователя
Не рекомендуется использовать название роли в 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 ); /** * Add lower roles to the list of all caps of current checking user. * * @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 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)
#2 Проверим администратор пользователь или нет:
// проверим возможность if( current_user_can('manage_options') ){ echo "У пользователя есть права изменять настройки"; }
#3 Используем user_can(), чтобы проверить права текущего пользователя:
// определяем пользователя глобально global $user; if( user_can($user->ID, 'manage_options') ){ // делаем что-то что может пользователь с этими правами };
manage_options - права администратора
#4 Пример использования второго аргумента $args:
if( current_user_can('edit_post', 123) ) { echo 'Текущий пользователь может редактировать пост 123'. }
#5 Проверка прав для отдельного элемента таксономии
C версии 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>'; }
#6 Проверка более двух ролей
Если вы хотите проверить более двух ролей, вы можете проверить, находится ли роль текущего пользователя внутри массива ролей, например:
$user = wp_get_current_user(); $allowed_roles = array( 'editor', 'administrator', 'author' ); if ( array_intersect( $allowed_roles, $user->roles ) ) { // Stuff here for allowed roles }
#7 Функция проверки нескольких ролей пользователя
Чтобы иметь возможность надежно проверять права точно по ролям, было бы удобно перечислять их в массиве, но мы не можем написать так - это вызовет нотисы:
current_user_can( [ 'administrator', 'author' ] );
Для такой проверки я иногда использую такую функцию:
/** * Checks if at least one of specified role is in the roles of the current/specified user. * * @param string|array $roles The name of the role you want to check with the current user. * @param empty|int|WP_User $user Default: current user */ function is_user_role_in( $roles, $user = false ): bool { $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'; }
Заметки
- Смотрите: WP_User::has_cap()
- Смотрите: map_meta_cap()
Список изменений
С версии 2.0.0 | Введена. |
С версии 5.3.0 | Formalized the existing and already documented ...$args parameter by adding it to the function signature. |
С версии 5.8.0 | Converted to wrapper for the user_can() function. |
Код current_user_can() current user can WP 6.6.2
function current_user_can( $capability, ...$args ) { return user_can( wp_get_current_user(), $capability, ...$args ); }