12

I've got some code like this:

$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;

I want to get more roles and also include contributor, author and some custom roles I created with the Role Scoper plugin e.g. Manager, etc. Any ideas how I can do this with get_users?

Thanks

9 Answers 9

30

Fast forward to WordPress 4.4 - it will support the role__in attribute!

It looks like WordPress 4.4 is our lucky version number, because it will support both the role__in and role__not_in attributes of the WP_User_Query class.

So to include the subscriber, contributor and author roles, we can simply use:

$users = get_users( [ 'role__in' => [ 'subscriber', 'contributor', 'author' ] ] );

Check out the ticket #22212 for the whole story!

1
  • 2
    You have been officially dubbed birgireV4.4, the new and improved version ;-) Commented Nov 23, 2015 at 15:54
19

You can also do this via a single call to get_users or using a single WP_User_Query by making use of the meta_query argument:

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'
        )
    )
) );

The meta_query is pulled from how WP_User_Query handles the role parameter, if you're interested.

4
  • @Andy-Adams Thanks for sharing. This only seems to display all the roles for me. Is this still working for you? Commented Jul 25, 2013 at 16:41
  • @helgatheviking What roles are you comparing, specifically? It could depend on what the role names are.
    – Andy Adams
    Commented Jul 25, 2013 at 18:32
  • @AndyAdams I'm trying to work this into my Simple User Listing plugin, so I'm trying to make it work for any combination of roles. On my local site, I've tried administrator and editor, but looping through the results all the other roles are still included. Commented Jul 25, 2013 at 20:03
  • I might recommend using the Debug Queries plugin to see what SQL query is being generated. A lot of times this helps me figure out why I'm getting unexpected results. wordpress.org/plugins/debug-queries
    – Andy Adams
    Commented Jul 26, 2013 at 1:06
13

I managed to solve this by using this function:

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;
}

Then in my theme I can do this:

$users_array = get_clients();
2
  • 1
    This is the best option I have come across. Thanks.
    – Jake
    Commented Oct 12, 2012 at 18:44
  • @blogjunkie Curious, but how well does this sort? Commented Jul 25, 2013 at 15:28
4
$users = array_merge( get_users('role=subscriber'), get_users('role=contributor') );

Since get_users() returns an array of users that match the query string given as a param. Just run the get_users() query for every role you want separately and merge the results. You can then loop through $users the same way you would have otherwise.

3
  • 1
    Can you please provide more information explaining why this solves the problem?
    – GhostToast
    Commented Aug 29, 2013 at 18:33
  • I edited the original answer to better explain why it works.
    – ksloan
    Commented Aug 31, 2013 at 5:34
  • I used this as $users = array_merge( get_users( array('role' => 'RoleOne' ,'fields' => 'ID') ), get_users( array('role' => 'RoleTwo' ,'fields' => 'ID') ));, and it worked a treat. Thanks!
    – Guit4eva
    Commented Sep 2, 2015 at 13:45
3

The problem with using array_merge is that you can't use pagination. I really like @Andy Adams's solution, but if you're searching on many roles, using his meta query will result in a very slow query (internally it does a new INNER JOIN for each meta query).

My solution is to use a regular expression meta query:

<?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)
));

?>

This generates a query that looks something like:

array(
    'meta_query' => array(
        array(
            'key' => 'wp_capabilities'
            'value' => '"(editor|administrator)"'
            'compare' => 'REGEXP'
        )
    )
);
1

You could simply merge more user query results. Let's say you want to include both Author and Editor roles. Define the query for each case then use array_merge to consolidate into a single array.

$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);

// further on you might want to do some sorting 
// of the resulting array of objects before looping through it:

if (!empty( $mergedRoles->results ) ) {
 foreach ( $mergedRoles->results as $user ) { 
        echo $user->display_name;
      }
 else echo "nada, no users found";
1

Hi you can use this easy way

$admins = get_users( array(
    'role__in'     => array('administrator', 'editor', 'author'),
    'fields' => array( 'ID' ),
) );
$admins_ids = wp_list_pluck( $admins, 'ID' );

$users = get_users(array(
    'exclude' => $admins_ids,
    'fields' => array( 'ID' ),
    ) );
$users_ids = wp_list_pluck( $users, 'ID' );
0

All the parameters from the function get_users are optional. If you specify nothing you will get an array that contains objects corresponding to each and every user of the current blog, including ones with custom roles.

0
<?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,$xuser_query->results);

// further on you might want to do some sorting 
// of the resulting array of objects before looping through it:

if (!empty( $mergedRoles) ) {

    foreach ( $mergedRoles as $user ) { 
        echo $user->display_name;
    }

} else {
    echo "nada, no users found";
}
?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.