current_user_can()
Перевіряє права поточного користувача, здійснювати вказану дію.
За замовчуванням в 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()
(дуже повільно) | 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;
Приклади
#1 Перевіримо адміністратор користувач чи ні:
// Перевіримо можливість if( current_user_can('manage_options') ){ echo "Користувач має право змінювати налаштування"; }
#2 Використовуємо user_can() , щоб перевірити права користувача:
// Визначаємо користувача глобально global $user; if( user_can($user->ID, 'manage_options') ){ // робимо щось, що може користувач з цими правами };
manage_options – права адміністратора
#3 Приклад використання другого аргументу $args :
if( current_user_can('edit_post', 123) ) { echo 'Поточний користувач може редагувати пост 123'. }
#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>'; }
#5 Перевірка більше двох ролей
Якщо ви хочете перевірити більше двох ролей, ви можете перевірити, чи є роль поточного користувача всередині масиву ролей, наприклад:
$user = wp_get_current_user(); $allowed_roles = array( 'editor', 'administrator', 'author' ); if ( array_intersect( $allowed_roles, $user->roles ) ) { // Stuff here for allowed roles }
#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)
#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'; }
нотатки
- Дивіться: WP_User::has_cap()
- Дивіться: map_meta_cap()
список змін
З версії 2.0.0 | Введено. |
З версії 5.3.0 | Formalizated 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 ); }