Зачем нужна иерархия пользователей в WordPress с REST API
В стандартном WordPress пользователи распределены по ролям, но часто возникает необходимость построить более сложную иерархическую структуру, где один пользователь может быть "начальником" или "родителем" для других. Это полезно для корпоративных сайтов, образовательных платформ и проектов с распределённым администрированием.
Добавление поддержки REST API к такой иерархии позволяет создавать, изменять и получать данные о пользователях и их отношениях через API, что важно для интеграции с внешними сервисами, мобильными приложениями и фронтенд-решениями на React, Vue или Angular.
В этой статье мы подробно разберём, как реализовать такую иерархию, используя кастомные мета-поля и расширение REST API WordPress.
Создание иерархии пользователей через пользовательские метаполя
Для начала нам нужно в базе данных хранить информацию о "родителе" для каждого пользователя. Для этого используем метаполе parent_user_id.
Добавим функцию для сохранения этой информации при обновлении профиля пользователя.
function wphierarchy_update_parent_user_id($user_id) {
if (!current_user_can('edit_user', $user_id)) {
return false;
}
if (isset($_POST['parent_user_id'])) {
$parent_user_id = intval($_POST['parent_user_id']);
if ($parent_user_id === $user_id) {
// Запретить указание самого себя как родителя
return;
}
update_user_meta($user_id, 'parent_user_id', $parent_user_id);
}
}
add_action('edit_user_profile_update', 'wphierarchy_update_parent_user_id');
add_action('personal_options_update', 'wphierarchy_update_parent_user_id');Далее добавим поле ввода для администратора в профиль пользователя:
function wphierarchy_show_parent_user_field($user) {
if (!current_user_can('edit_users')) {
return;
}
$parent_user_id = get_user_meta($user->ID, 'parent_user_id', true);
$users = get_users(array('exclude' => array($user->ID)));
?>
<h3>Иерархия пользователя</h3>
<table class="form-table">
<tr>
<th><label for="parent_user_id">Родительский пользователь</label></th>
<td>
<select name="parent_user_id" id="parent_user_id">
<option value="0">Нет</option>
<?php foreach ($users as $u) : ?>
<option value="<?php echo $u->ID; ?>" <?php selected($parent_user_id, $u->ID); ?>><?php echo esc_html($u->user_login); ?></option>
<?php endforeach; ?>
</select>
<p class="description">Выберите родительского пользователя для текущего.</p>
</td>
</tr>
</table>
<?php
}
add_action('show_user_profile', 'wphierarchy_show_parent_user_field');
add_action('edit_user_profile', 'wphierarchy_show_parent_user_field');Так мы создадим базу для иерархии пользователей.
Расширение REST API для работы с иерархией
По умолчанию REST API WordPress не возвращает кастомные метаполя пользователей. Чтобы работать с нашим полем parent_user_id, нужно расширить REST API.
Добавим регистрацию поля в REST API:
function wphierarchy_register_parent_user_id_rest_field() {
register_rest_field('user', 'parent_user_id', array(
'get_callback' => function($user) {
return get_user_meta($user['id'], 'parent_user_id', true);
},
'update_callback' => function($value, $user) {
if (!current_user_can('edit_user', $user->ID)) {
return new WP_Error('rest_forbidden', 'Нет прав для редактирования пользователя', array('status' => 403));
}
$parent_user_id = intval($value);
if ($parent_user_id === $user->ID) {
return new WP_Error('rest_invalid', 'Нельзя назначить самого себя родителем', array('status' => 400));
}
update_user_meta($user->ID, 'parent_user_id', $parent_user_id);
return true;
},
'schema' => array(
'description' => 'ID родительского пользователя',
'type' => 'integer',
'context' => array('view', 'edit'),
),
));
}
add_action('rest_api_init', 'wphierarchy_register_parent_user_id_rest_field');Теперь при запросе пользователей через REST API поле parent_user_id будет доступно.
Получение иерархии пользователей через REST API: пример запроса и обработки
Создадим функцию, которая по REST API вернёт дерево иерархии пользователей. Для этого в PHP сформируем структуру, которую потом можно отдать через отдельный endpoint.
function wphierarchy_get_users_hierarchy() {
$users = get_users(array('fields' => array('ID', 'user_login')));
$tree = array();
$lookup = array();
// Инициализация узлов
foreach ($users as $user) {
$lookup[$user->ID] = array(
'ID' => $user->ID,
'user_login' => $user->user_login,
'children' => array(),
);
}
// Построение дерева
foreach ($lookup as $user_id => &$node) {
$parent_id = get_user_meta($user_id, 'parent_user_id', true);
if ($parent_id && isset($lookup[$parent_id])) {
$lookup[$parent_id]['children'][] = &$node;
} else {
$tree[] = &$node;
}
}
return $tree;
}
function wphierarchy_register_hierarchy_endpoint() {
register_rest_route('wphierarchy/v1', '/users-hierarchy', array(
'methods' => 'GET',
'callback' => 'wphierarchy_get_users_hierarchy',
'permission_callback' => function() {
return current_user_can('list_users');
}
));
}
add_action('rest_api_init', 'wphierarchy_register_hierarchy_endpoint');Теперь по адресу /wp-json/wphierarchy/v1/users-hierarchy можно получить JSON-структуру иерархии пользователей. Это удобно для фронтенд-приложений или аналитики.
Практическое использование и рекомендации
Такую иерархию удобно использовать для:
- Организации управления на корпоративных порталах;
- Построения систем наставничества или кураторства;
- Реализации многоуровневой поддержки или ответственных;
- Интеграции с системами CRM или ERP через REST API.
Для улучшения UX можно разработать админский интерфейс с помощью React и REST API, где легко менять иерархию drag-and-drop.
Если нужно более сложное построение ролей и иерархий, советуем рассмотреть плагин Clearfy Pro (ссылка на Clearfy Pro), который умеет гибко управлять ролями и правами с поддержкой API.
Безопасность и производительность
Обязательно проверяйте права доступа при редактировании и выводе данных через REST API. Не давайте лишних прав неподготовленным пользователям.
Для сайтов с большим количеством пользователей кешируйте дерево иерархии, чтобы не нагружать базу лишними запросами. Можно использовать Transients API.
Заключение к технической части
Реализовать иерархию пользователей с поддержкой REST API в WordPress несложно, если использовать стандартные возможности метаполей и расширения REST API. Это открывает большие возможности для кастомизации и интеграции.