Роли и права в WordPress: как добавить свои возможности
В WordPress можно не только назначать администраторами и редакторами, но и создавать собственные права: например, разрешить сотруднику видеть отчёты без доступа к настройкам сайта. Разбираем безопасную схему для WordPress 6.x.

В WordPress 6.x собственное право доступа можно добавить без выдачи пользователю роли администратора. Например, сотруднику разрешают управлять внутренними отчётами, но закрывают настройки сайта, плагины и редактор тем. Ошибка в этой схеме стоит дорого: меню можно скрыть, но забытая проверка capability1 оставит закрытые данные доступными по прямому URL.
Сначала разделите роли и возможности
Роль — набор прав, который назначают пользователю. Встроенные роли WordPress — administrator, editor, author, contributor и subscriber. Возможность — отдельное право вроде edit_posts, publish_posts или вашей собственной manage_partner_reports.
Пользователь может иметь одну роль, а роль — десятки возможностей. Проверять нужно не название роли, а конкретное право:
if ( current_user_can( 'manage_partner_reports' ) ) {
// Показываем отчёты и разрешаем работу с ними.
}
Проверка роли вроде «если пользователь — редактор» жёстко связывает код с текущей структурой сайта. Собственная capability позволяет позже дать то же право другой роли без переписывания интерфейса.
Скрытое меню — это удобство интерфейса, а не защита. Защищать нужно действие, данные и каждый endpoint, который их отдаёт.
Три способа настроить доступ
| Подход | Когда использовать | Цена решения |
|---|---|---|
| Добавить capability встроенной роли | Одно дополнительное право для редакторов или другой готовой роли | Быстро, но право получат все пользователи этой роли |
| Создать собственную роль | Для отдельного типа сотрудников с заранее известным набором действий | Нужно поддерживать состав прав и миграции при изменениях |
| Назначить capability для собственного типа записей | Когда доступ связан с CPT: например, «брифы» или «партнёры» | Больше настроек, зато можно разделить чтение, редактирование и публикацию |
Для небольшого проекта обычно достаточно первой схемы. Если право относится к отдельному бизнес-процессу, лучше создать собственную capability и назначить её нужной роли. Не добавляйте новые права каждому пользователю вручную: после удаления пользователя или смены команды такая настройка быстро теряется.
Добавляем своё право существующей роли
Ниже — фрагмент для основного файла собственного плагина, рассчитанный на WordPress 6.x. Право добавляется при активации плагина, а не при каждом открытии страницы.
<?php
register_activation_hook( __FILE__, function () {
$role = get_role( 'editor' );
if ( $role ) {
$role->add_cap( 'manage_partner_reports' );
}
} );
После активации все редакторы получат manage_partner_reports. В рабочем коде это право проверяют в каждом месте, где пользователь может получить или изменить отчёт:
if ( ! current_user_can( 'manage_partner_reports' ) ) {
wp_die( 'У вас нет доступа к отчётам.' );
}
Проверка должна стоять не только перед выводом страницы. Если отчёт отдаётся через AJAX, REST API или отдельный обработчик формы, там нужна такая же авторизация. Для nonce используется отдельная проверка: nonce подтверждает происхождение запроса, но не заменяет проверку capability.
Создаём собственную роль
Собственная роль полезна, когда сотруднику нужен предсказуемый набор прав: например, просмотр и редактирование внутренних брифов без публикации записей и доступа к настройкам.
<?php
register_activation_hook( __FILE__, function () {
add_role(
'brief_manager',
'Менеджер брифов',
array(
'read' => true,
'edit_briefs' => true,
'edit_others_briefs' => true,
'publish_briefs' => false,
'read_private_briefs' => true,
'delete_briefs' => false,
)
);
} );
Эта роль заработает только если такие возможности действительно зарегистрированы у типа записи. Значения вроде edit_briefs не становятся рабочими автоматически: WordPress должен встретить их в настройках custom post type, а роль — получить их через add_role() или add_cap().
Не вызывайте add_role() на каждой загрузке страницы. Функция сохраняет роль в базе, поэтому повторный вызов в init может перезаписывать состав прав после ручных изменений или усложнить миграции.
Связываем права с собственным типом записей
Если права относятся к отдельному типу записей, задайте для него собственный набор capability. Пример ниже регистрирует закрытый тип «брифы» и разделяет права на просмотр, редактирование и публикацию.
add_action( 'init', function () {
register_post_type(
'brief',
array(
'label' => 'Брифы',
'public' => false,
'show_ui' => true,
'show_in_menu' => true,
'supports' => array( 'title', 'editor' ),
'capability_type' => array( 'brief', 'briefs' ),
'map_meta_cap' => true,
'capabilities' => array(
'edit_post' => 'edit_brief',
'read_post' => 'read_brief',
'delete_post' => 'delete_brief',
'edit_posts' => 'edit_briefs',
'edit_others_posts' => 'edit_others_briefs',
'publish_posts' => 'publish_briefs',
'read_private_posts' => 'read_private_briefs',
'delete_posts' => 'delete_briefs',
'delete_others_posts' => 'delete_others_briefs',
'delete_private_posts' => 'delete_private_briefs',
'delete_published_posts'=> 'delete_published_briefs',
'edit_private_posts' => 'edit_private_briefs',
'edit_published_posts' => 'edit_published_briefs',
),
)
);
} );
После регистрации CPT нужные capability нужно выдать роли. Например, менеджеру брифов можно добавить edit_briefs, edit_others_briefs, read_private_briefs и права для конкретных записей edit_brief и read_brief. Публикацию и удаление оставьте выключенными, если они не нужны.
Параметр map_meta_cap важен для проверки доступа к конкретной записи. Он позволяет WordPress сопоставить действие над одной записью с базовыми правами пользователя. После изменения набора capability проверьте как собственные, так и чужие записи, а также опубликованные и приватные.
Когда выбирать каждый вариант
- Добавляйте capability редактору, если все редакторы должны выполнять одно новое действие.
- Создавайте роль, если у проекта появилась отдельная должность с самостоятельным набором прав.
- Настраивайте capability CPT, если нужно различать «создать», «изменить чужое», «опубликовать», «удалить» и «прочитать приватное».
- Проверяйте capability в коде, а не слаг роли: это упростит смену структуры команды.
Самый частый практический критерий — граница ответственности. Если менеджер должен работать только с брифами, не выдавайте ему общее edit_posts: оно может открыть редактирование обычных записей.
Что ломается чаще всего
Право добавили не той роли
После изменения кода проверьте пользователя с нужной ролью в новой сессии. У уже открытой страницы может сохраниться старый интерфейс, а у пользователя может быть несколько ролей и права от каждой из них.
Меню спрятали, но обработчик не защищён
remove_menu_page() и параметр show_in_menu меняют навигацию, но не дают полноценной авторизации. Перед изменением записи, экспортом и выдачей данных снова вызывайте current_user_can().
Право добавили на каждом запросе
Добавление capability в init иногда выглядит удобнее, но превращает структуру прав в скрытую миграцию на каждой странице. Для плагина используйте activation hook, а для обновлений — отдельную проверяемую версию миграции.
Удалили роль вместо права
remove_role() удаляет всю роль из базы. Если нужно отменить только собственную возможность, используйте remove_cap() у конкретной роли. Перед удалением проверьте, что право не требуется другому коду или роли.
REST и AJAX проверяются отдельно
Страница админки может быть закрыта, а endpoint — нет. Для REST задайте корректную проверку доступа в аргументах маршрута, для AJAX проверяйте nonce и capability в обработчике. Не считайте факт авторизации пользователя достаточным условием.
Что делать дальше
Составьте таблицу действий: кто видит запись, кто меняет свою, кто меняет чужую, кто публикует и кто удаляет. Для каждого действия назначьте отдельную capability, затем протестируйте четыре сценария: администратор, разрешённая роль, пользователь без права и неавторизованный посетитель.
После выкладки проверьте доступ не только через меню, но и по прямым URL, REST-запросам и формам. В журнале приложения полезно отслеживать отказы доступа и неожиданные изменения ролей. Настройка инвалидации кэша после изменения прав — отдельная задача: здесь рассматривается только модель ролей и capability.
1 Capability — именованное право WordPress, которое отвечает на вопрос, может ли пользователь выполнить конкретное действие.
Редактор изображений: Убрать лишнее, заменить фон, добавить объект, расширить кадр — на вашем изображении.
Спросить за 20 ₽Источники: Roles and Capabilities — WordPress Developer Resources, register_post_type() — WordPress Developer Resources
Частые вопросы
Можно ли добавить собственное право без создания плагина?
Почему пользователь видит меню, но получает отказ при открытии записи?
Как убрать добавленное право?
Можно ли дать право одному пользователю, а не всей роли?
Что будет, если забыть проверку capability в AJAX или REST?
Сработает ли этот код на старой версии WordPress?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.