В WordPress часто возникает задача построить иерархию пользователей не просто по ролям, а на основе произвольных данных, которые хранятся в метаполях. Это позволяет создавать сложную структуру подчинения или группирования пользователей, например, для корпоративных сайтов, образовательных платформ или проектов с многоуровневой организацией.
Почему стандартных ролей WordPress недостаточно для иерархии пользователей
Стандартные роли WordPress (Администратор, Редактор, Автор, и т.д.) дают базовые права доступа, но не позволяют выстраивать сложные отношения между пользователями. Например, нельзя задать, что один пользователь является менеджером группы других пользователей или что у него есть определённые подчинённые.
Для таких задач нужно использовать пользовательские метаполя, в которых можно хранить ID руководителя, отдел, проект или другие параметры, по которым строится иерархия.
Такой подход гибкий и масштабируемый, но требует реализации логики вывода и навигации по иерархии через код или плагины.
Создание пользовательского метаполя для хранения иерархии
Первый шаг — добавить пользовательское поле, в котором будет храниться ID родительского пользователя или иные данные для иерархии. Для удобства можно использовать Advanced Custom Fields (ACF) или сделать вручную.
Пример создания метаполя вручную:
function wphierarchy_add_user_meta_field() {
add_action('show_user_profile', 'wphierarchy_show_extra_profile_fields');
add_action('edit_user_profile', 'wphierarchy_show_extra_profile_fields');
add_action('personal_options_update', 'wphierarchy_save_extra_profile_fields');
add_action('edit_user_profile_update', 'wphierarchy_save_extra_profile_fields');
}
function wphierarchy_show_extra_profile_fields($user) {
$manager_id = get_user_meta($user->ID, 'wphierarchy_manager_id', true);
?>
<h3>Иерархия пользователей</h3>
<table class="form-table">
<tr>
<th><label for="wphierarchy_manager_id">ID руководителя</label></th>
<td>
<input type="number" name="wphierarchy_manager_id" id="wphierarchy_manager_id" value="<?php echo esc_attr($manager_id); ?>" class="regular-text" />
<p class="description">Введите ID пользователя, который является руководителем этого пользователя.</p>
</td>
</tr>
</table>
<?php
}
function wphierarchy_save_extra_profile_fields($user_id) {
if (!current_user_can('edit_user', $user_id)) {
return false;
}
update_user_meta($user_id, 'wphierarchy_manager_id', intval($_POST['wphierarchy_manager_id']));
}
add_action('init', 'wphierarchy_add_user_meta_field');Этот код добавит поле "ID руководителя" в профиль пользователя в админке, где можно указать иерархическую принадлежность.
Вывод иерархии пользователей на сайте
После того как данные сохранены, нужно уметь выводить иерархическую структуру. Рассмотрим пример функции, которая выводит дерево подчинённых для заданного пользователя.
function wphierarchy_get_subordinates($user_id) {
$args = [
'meta_key' => 'wphierarchy_manager_id',
'meta_value' => $user_id,
'fields' => ['ID', 'display_name'],
'number' => -1
];
$user_query = new WP_User_Query($args);
return $user_query->get_results();
}
function wphierarchy_display_hierarchy($user_id, $level = 0) {
$subs = wphierarchy_get_subordinates($user_id);
if (empty($subs)) {
return;
}
echo '<ul style="margin-left:' . ($level * 20) . 'px;">';
foreach ($subs as $sub) {
echo '<li>' . esc_html($sub->display_name) . ' (ID: ' . $sub->ID . ')</li>';
wphierarchy_display_hierarchy($sub->ID, $level + 1);
}
echo '</ul>';
}Эта рекурсивная функция сначала получает всех пользователей, для которых текущий пользователь является руководителем, а затем выводит их в виде вложенного списка с отступами, отражающими уровень вложенности.
Вы можете вызвать wphierarchy_display_hierarchy($user_id), подставив ID пользователя, с которого хотите начать вывод иерархии.
Оптимизация и расширение функционала
Когда иерархия большая, рекурсивный вывод может быть тяжёлым для сервера. Для оптимизации стоит:
- Кэшировать результаты запросов с помощью Transients API.
- Использовать AJAX-подгрузку подчинённых при клике, чтобы не загружать сразу всю структуру.
- Реализовать пагинацию, если подчинённых слишком много.
Для AJAX можно использовать следующий пример обработчика:
add_action('wp_ajax_wphierarchy_load_subordinates', 'wphierarchy_ajax_load_subordinates');
function wphierarchy_ajax_load_subordinates() {
if (!current_user_can('list_users')) {
wp_send_json_error('Недостаточно прав');
}
$user_id = intval($_POST['user_id']);
if (!$user_id) {
wp_send_json_error('Некорректный ID пользователя');
}
ob_start();
wphierarchy_display_hierarchy($user_id, 0);
$html = ob_get_clean();
wp_send_json_success(['html' => $html]);
}
// Для фронтенда подключите JS, который будет отправлять запрос и подставлять ответ в нужное место.Плагины для работы с иерархией пользователей и метаполями
Для упрощения можно использовать плагины:
- Clearfy Pro — помогает оптимизировать и кастомизировать пользовательские роли и метаполя.
- WPRemark — для организации отзывов и рейтингов, может быть полезен, если иерархия связана с оценочными системами.
Но основной функционал иерархии на основе метаполей лучше реализовывать кастомно, чтобы максимально точно соответствовать бизнес-логике.
Заключение
Создание иерархии пользователей на основе метаполей в WordPress — мощный инструмент для построения сложных отношений между аккаунтами. Это помогает реализовать гибкое управление доступом, навигацию и отображение структур. При правильной организации метаданных и грамотном коде вы получите расширяемую и удобную систему.