Если ваш плагин позволяет пользователям отправлять данные - будь то на Админ или на Публичной стороне - он должен проверить на User Capabilities (Возможности пользователя).
Роли пользователей и возможности
Самым важным шагом в создании эффективного уровня безопасности является наличие системы пользовательских разрешений. WordPress обеспечивает это в виде ролей пользователей и возможностей.
Каждому пользователю, авторизованному в WordPress, автоматически присваиваются конкретные возможности пользователя в зависимости от его роли.
Роли пользователей - это просто изящный способ сказать, к какой группе принадлежит пользователь. Каждая группа имеет определенный набор предопределенных возможностей.
Например, основной пользователь вашего веб-сайта будет иметь роль User (Пользователь) администратора, в то время как у других пользователей могут быть роли типа Editor (Редактор) или Author (Автор). Вы можете назначить более одного пользователя на одну роль, т.е. на сайте может быть два администратора.
Пользовательские возможности - это конкретные разрешения, которые вы назначаете каждому пользователю или его роли.
Например, администраторы имеют возможность "управлять_опциями" (manage_options), которая позволяет им просматривать, редактировать и сохранять опции сайта. Редакторы, с другой стороны, не имеют этой возможности, что препятствует их взаимодействию с опциями.
Эти возможности затем проверяются в различных точках Админа. В зависимости от возможностей, назначенных для той или иной роли, могут быть добавлены или удалены меню, функциональность и другие аспекты работы с WordPress.
При создании плагина убедитесь, что код запускается только тогда, когда текущий пользователь обладает необходимыми возможностями.
Иерархия
Чем выше роль пользователя, тем больше у него возможностей. Каждая пользовательская роль наследует предыдущие роли в иерархии.
Например, "Администратор" (Administrator), которая является самой высокой пользовательской ролью на одном автономном сайте, наследует следующие роли и их возможности: "Подписчик" (Subscriber), "Участник" (Contributor), "Автор" (Author) и "Редактор" (Editor).
Примеры
Нет ограничений
В примере, приведенном ниже, создается ссылка на фронтенде, которая дает возможность удалять статьи в корзину. Поскольку этот код не проверяет возможности пользователя, он позволяет любому посетителю удалять статьи!
<?php
/**
* создать ссылку Delete (удалить) на основе URL домашней страницы
*/
function wporg_generate_delete_link($content)
{
// запускать только для одного поста (single)
if (is_single() && in_the_loop() && is_main_query()) {
// добавить аргументы запроса: action, post
$url = add_query_arg(
[
'action' => 'wporg_frontend_delete',
'post' => get_the_ID(),
],
home_url()
);
return $content . ' <a href="' . esc_url($url) . '">' . esc_html__('Delete Post', 'wporg') . '</a>';
}
return null;
}
/**
* обработчик запросов
*/
function wporg_delete_post()
{
if (isset($_GET['action']) && $_GET['action'] === 'wporg_frontend_delete') {
// проверка на id поста
$post_id = (isset($_GET['post'])) ? ($_GET['post']) : (null);
// проверка наличия поста с таким номером
$post = get_post((int)$post_id);
if (empty($post)) {
return;
}
// удалить пост
wp_trash_post($post_id);
// перенаправление на страницу админа
$redirect = admin_url('edit.php');
wp_safe_redirect($redirect);
// готово
die;
}
}
/**
* добавить ссылку на удаление в конце статьи (content)
*/
add_filter('the_content', 'wporg_generate_delete_link');
/**
* зарегистрировать обработчик запроса с помощью хука init
*/
add_action('init', 'wporg_delete_post');
Ограничения с конкретными возможностями
Пример выше позволяет любому посетителю сайта нажать на ссылку "Удалить" (Delete) и удалить пост. Однако, мы хотим, чтобы только Редакторы и выше могли нажать на ссылку "Удалить".
Для этого мы проверим, что у текущего пользователя есть возможность редактирования постов edit_others_posts
, которая есть только у редакторов и выше:
<?php
/**
* создать ссылку Delete на основе URL домашней страницы
*/
function wporg_generate_delete_link($content)
{
// запускать только для одного поста
if (is_single() && in_the_loop() && is_main_query()) {
// добавлять аргументы запроса: action, post
$url = add_query_arg(
[
'action' => 'wporg_frontend_delete',
'post' => get_the_ID(),
],
home_url()
);
return $content . ' <a href="' . esc_url($url) . '">' . esc_html__('Delete Post', 'wporg') . '</a>';
}
return null;
}
/**
* обработчик запросов
*/
function wporg_delete_post()
{
if (isset($_GET['action']) && $_GET['action'] === 'wporg_frontend_delete') {
// проверьте, есть ли у нас id поста
$post_id = (isset($_GET['post'])) ? ($_GET['post']) : (null);
// проверить наличие поста с таким номером
$post = get_post((int)$post_id);
if (empty($post)) {
return;
}
// удалить пост
wp_trash_post($post_id);
// перенаправление на страницу Админа
$redirect = admin_url('edit.php');
wp_safe_redirect($redirect);
// готово
die;
}
}
if (current_user_can('edit_others_posts')) {
/**
* добавить ссылку на удаление в конце публикации
*/
add_filter('the_content', 'wporg_generate_delete_link');
/**
* зарегистрировать обработчик запроса с помощью хука init
*/
add_action('init', 'wporg_delete_post');
}