Get multiple roles with get_users

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?

Read More

Thanks

Related posts

Leave a Reply

9 comments

  1. Fastforward 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', 'subscriber', 'author' ] ] );
    

    Check out the ticket #22212 for the whole story!

  2. 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.

  3. 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();
    
  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.

  5. 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'
            )
        )
    );
    
  6. 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";
    
  7. 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.

  8. <?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";
    }
    ?>
    
  9. 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' );