Получение нескольких ролей пользователей с помощью get_users
У меня есть такой код:
$query_args = array(); $query_args['fields'] = array( 'ID', 'display_name' ); $query_args['role'] = 'subscriber'; $users = get_users( $query_args ); foreach ($users as $user) $users_array[$user->ID] = $user->display_name;
Я хочу получить больше ролей и включить contributor
, author
и некоторые пользовательские роли, которые я создал с помощью плагина Role Scoper, например, Manager
и т.д. Есть идеи, как это можно сделать с помощью get_users
?
Спасибо

Перенесемся в WordPress 4.4 - он будет поддерживать атрибут role__in
!
Похоже, WordPress 4.4 - это наш счастливый номер версии, потому что он будет поддерживать оба атрибута role__in
и role__not_in
класса WP_User_Query
.
Таким образом, чтобы включить роли subscriber, contributor и author, мы можем просто использовать:
$users = get_users( [ 'role__in' => [ 'subscriber', 'contributor', 'author' ] ] );
Ознакомьтесь с тикетом #22212 для полной истории!

Вы также можете сделать это с помощью одного вызова get_users
или используя единый запрос WP_User_Query
, воспользовавшись аргументом meta_query
:
global $wpdb;
$blog_id = get_current_blog_id();
$user_query = new WP_User_Query( array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
'value' => 'role_one',
'compare' => 'like'
),
array(
'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities',
'value' => 'role_two',
'compare' => 'like'
)
)
) );
Аргумент meta_query
позаимствован из того, как WP_User_Query
обрабатывает параметр role
, если вам интересно.

@Andy-Adams Спасибо, что поделились. У меня это отображает только все роли. У вас это всё ещё работает?

@helgatheviking Какие именно роли вы сравниваете? Это может зависеть от названий ролей.

@AndyAdams Я пытаюсь интегрировать это в свой плагин Simple User Listing, поэтому хочу, чтобы это работало с любыми комбинациями ролей. На локальном сайте я пробовал администратора и редактора, но при переборе результатов все остальные роли всё равно включаются.

Я могу порекомендовать использовать плагин Debug Queries, чтобы увидеть, какой SQL-запрос генерируется. Часто это помогает мне понять, почему я получаю неожиданные результаты. http://wordpress.org/plugins/debug-queries/

Мне удалось решить эту проблему, используя следующую функцию:
function get_clients() {
$users = array();
$roles = array('subscriber', 'custom_role1', 'custom_role2');
foreach ($roles as $role) :
$users_query = new WP_User_Query( array(
'fields' => 'all_with_meta',
'role' => $role,
'orderby' => 'display_name'
) );
$results = $users_query->get_results();
if ($results) $users = array_merge($users, $results);
endforeach;
return $users;
}
Затем в моей теме я могу использовать это:
$users_array = get_clients();

$users = array_merge( get_users('role=subscriber'), get_users('role=contributor') );
Поскольку функция get_users()
возвращает массив пользователей, соответствующих переданному запросу, вы можете просто выполнить запрос get_users()
для каждой нужной роли отдельно и объединить результаты. Затем вы можете перебирать массив $users
так же, как делали бы это в других случаях.

Не могли бы вы предоставить больше информации, объясняющей, почему это решает проблему?

Я отредактировал исходный ответ, чтобы лучше объяснить, почему это работает.

Проблема с использованием array_merge
заключается в том, что вы не можете использовать пагинацию. Мне очень нравится решение @Andy Adams, но если вы ищете по многим ролям, использование его мета-запроса приведёт к очень медленному запросу (внутренне он создаёт новый INNER JOIN
для каждого мета-запроса).
Моё решение — использовать мета-запрос с регулярным выражением:
<?php
global $wpdb;
$blog_id = get_current_blog_id();
$roles = array('editor', 'administrator');
$meta_query = array(
'key' => $wpdb->get_blog_prefix($blog_id) . 'capabilities',
'value' => '"(' . implode('|', array_map('preg_quote', $roles)) . ')"',
'compare' => 'REGEXP'
);
$user_query = new WP_User_Query(array(
'meta_query' = array($meta_query)
));
?>
Это генерирует запрос, который выглядит примерно так:
array(
'meta_query' => array(
array(
'key' => 'wp_capabilities'
'value' => '"(editor|administrator)"'
'compare' => 'REGEXP'
)
)
);

Вы можете просто объединить результаты нескольких пользовательских запросов. Допустим, вы хотите включить как роли Author
, так и Editor
. Определите запрос для каждого случая, а затем используйте функцию array_merge для объединения в один массив.
$xuser_query = new WP_user_query(array( 'role' => 'Author'));
$yuser_query = new WP_user_query(array( 'role' => 'Editor'));
$mergedRoles=array_merge($xuser_query->results,$xuser_query->results);
// далее вы можете захотеть выполнить сортировку
// результирующего массива объектов перед перебором:
if (!empty( $mergedRoles->results ) ) {
foreach ( $mergedRoles->results as $user ) {
echo $user->display_name;
}
else echo "ничего, пользователи не найдены";

Привет, ты можешь использовать этот простой способ
$admins = get_users( array(
'role__in' => array('administrator', 'editor', 'author'), // Роли пользователей
'fields' => array( 'ID' ), // Получаем только ID
) );
$admins_ids = wp_list_pluck( $admins, 'ID' ); // Извлекаем ID администраторов
$users = get_users(array(
'exclude' => $admins_ids, // Исключаем администраторов
'fields' => array( 'ID' ), // Получаем только ID
) );
$users_ids = wp_list_pluck( $users, 'ID' ); // Извлекаем ID обычных пользователей

Все параметры функции get_users являются необязательными. Если вы ничего не укажете, вы получите массив, содержащий объекты, соответствующие каждому пользователю текущего блога, включая пользователей с пользовательскими ролями.

<?php
// Создаем запросы для пользователей с ролями Автор и Редактор
$xuser_query = new WP_user_query(array( 'role' => 'Author'));
$yuser_query = new WP_user_query(array( 'role' => 'Editor'));
// Объединяем результаты двух запросов
$mergedRoles = array_merge($xuser_query->results, $yuser_query->results);
// Дальше может потребоваться сортировка
// полученного массива объектов перед перебором:
if (!empty($mergedRoles)) {
// Выводим имена пользователей
foreach ($mergedRoles as $user) {
echo $user->display_name;
}
} else {
echo "Ничего не найдено, пользователей нет";
}
?>
