Get users from all/specific blog by user_role and current_user role

I’ve been struggling to get this working properly for a few days but finally got it so I thought to share it so others might profit from it as well.

Create a file in you theme named user-list.php with a Template Name.

<?php
/**
 * Template Name: List Users
 */

Now create a page via the Admin Dashboard called user-list and select the page-template List Users.

Now that’s sorted, let’s make it interesting.

First, let’s determine if our current_user is allowed to retrieve this information. For this we need a few global variables WordPress has available to us. At the same time, we’ll also setup the first few statements and call a function that isn’t part of WordPress.

(user-list.php)
/* Get user info. */
global $current_user, $wpdb;
get_currentuserinfo();

/* Load the user file. */
require_once( ABSPATH . WPINC . '/user.php' );
$error = array();

/* Check if user is super-admin or a customer */
/* Values stored in variables for later use to limit DB requests */
$super_admin = is_super_admin();
$editor = check_user_role( 'editor' );
if( $super_admin || $editor ){

As you can see above, we’re setting up global variables for current_user(info) and wpdb(info). We’ll be needing those for this. Also, we’re calling a function called check_user_role(). I can’t take credit for the function, I found it. But add the function below to your functions.php file to be able to use it, it is very handy to have.

(functions.php)
/**
 * Checks if a particular user has a role.
 * Returns true if a match was found.
 *
 * @param string $role - Role name.
 * @param int $user_id - (Optional) The ID of a user. Defaults to the current user.
 * @return bool        - returns true/false
 */
function check_user_role( $role, $user_id = null ){
    if( is_numeric( $user_id ))
        $user = get_userdata( $user_id );
    else
        $user = wp_get_current_user();
    if( empty( $user ))
        return false;
    return in_array( $role, (array)$user->roles );
}

Now that we can check if a user, whom might be created with a custom user_role (info here and here).

If the user requesting this page gets through the first if statement, he’s either a super-admin or an editor. For the purpose of this example we’re working under the assumption an editor should be allowed to do this.

Let’s continue with our user-list.php file. We’ll be re-using the $super_admin and $editor variables here, which is why we created them as variables and not as part of the if-statement. This saves a few queries to the database. Next we need to setup the variables to use in the query so we get the users returned. Obviously an editor user_role shouldn’t get to see all of the same users and/or have the same options later on with the data. So let’s split that up before it we query for the data. Also, a super-admin has access to the data of the entire Multi-site, where as an editor shouldn’t.

I’ve added comments into the code as it’s really 1 part.

    (user-list.php continued)
    /* Setup variables to use in query to get users */
    $blog_id = '';
    $roles = array();

    /* Depending on logged in user, setup query vars differently */
    if( $super_admin ){
        $blog_id = '*';
        $roles = array();
    }
    elseif( $editor ){
        $blog_id = get_current_blog_id(); // In case of user on sub-domain

        // Select which user_roles the logged in user is allowed to see 
        $user_roles = array( 'subscriber', 'author', 'contributor' );
        // If more than 1 add to array 1 at a time
        if( $user_roles > 1 ){
            $roles[ 'relation' ] = 'OR' ;
            foreach( $user_roles as $role ){
                $roles[] = array(
                'key'       => 'wp_capabilities',
                'value'     => serialize(array($role=>true)), /* This value gets stored as: serialize(array(1){[$key]=>bool(true)) when it's created */
                'compare'   => '='
                );
            }
        } else {
            /* NOTE!: set $user_roles NOT as an array if only 1 role!!! Just: $user_roles="contributor"; */
            $roles[] = array(
                'key'       => 'wp_capabilities',
                'value'     => serialize(array($user_roles=>true)), /* This value gets stored as: serialize(array(1){[$key]=>bool(true)) when it's created */
                'compare'   => '='
            );
        }
    }
    /* Use the setup variables to query users to display */
    $args = array(
        'blog_id'           => $blog_id,
        'meta_query'        => $roles,
        'fields'            => 'all_with_meta'
    );

    $all_users = new WP_User_Query( $args );
    echo '<pre>';
    print_r( $all_users );
    echo '</pre>';
}

Source for 'value'.

Now all of the relevant users are stored in $all_users and you can do with them as you please. Hopefully someone will find this useful.