Skip to navigation | Skip to content



Get WordPress users by role

Please note that as of WordPress 3.1, this code is pretty much redundant. Check out get_users!

There’s a few posts around that reveal a nifty use of the WP_User_Search class that’s part of WordPress’ core code, in order to select all users that have a specific role (the trick seems to have originated with John Kolbert).

But… WP_User_Search is only loaded when you’re inside the WP admin area. What about front-end template code?

I decided to track down the SQL that WP_User_Search comes up with for the search (using $wpdb->queries), and write a custom function wrapper which will work the same way wherever.

I’m not quite sure if there’s any advantage to including the use of WP_User_Search as well as the back-up SQL, as they pretty much do the same thing. I dunno.

Anyway, here’s the code. This is for pasting into your theme’s functions.php file. It’ll return an array of user IDs.

function getUsersByRole( $role ) {
	if ( class_exists( 'WP_User_Search' ) ) {
		$wp_user_search = new WP_User_Search( '', '', $role );
		$userIDs = $wp_user_search->get_results();
	} else {
		global $wpdb;
		$userIDs = $wpdb->get_col('
			SELECT ID
			FROM '.$wpdb->users.' INNER JOIN '.$wpdb->usermeta.'
			ON '.$wpdb->users.'.ID = '.$wpdb->usermeta.'.user_id
			WHERE '.$wpdb->usermeta.'.meta_key = \''.$wpdb->prefix.'capabilities\'
			AND '.$wpdb->usermeta.'.meta_value LIKE \'%"'.$role.'"%\'
		');
	}
	return $userIDs;
}

UPDATE 4/9/10: By popular request, here’s another version, which will accept an array (or comma-delimited list) of roles to select by. I’ve pasted it in from a custom project—do let me know if it works in your themes!

UPDATE 7/11/10: Thanks to Acebone, a corrected version that uses array_walk properly.

function getUsersByRole( $roles ) {
	global $wpdb;
	if ( ! is_array( $roles ) ) {
		$roles = explode( ",", $roles );
		array_walk( $roles, 'trim' );
	}
	$sql = '
		SELECT	ID, display_name
		FROM		' . $wpdb->users . ' INNER JOIN ' . $wpdb->usermeta . '
		ON		' . $wpdb->users . '.ID				=		' . $wpdb->usermeta . '.user_id
		WHERE	' . $wpdb->usermeta . '.meta_key		=		\'' . $wpdb->prefix . 'capabilities\'
		AND		(
	';
	$i = 1;
	foreach ( $roles as $role ) {
		$sql .= ' ' . $wpdb->usermeta . '.meta_value	LIKE	\'%"' . $role . '"%\' ';
		if ( $i < count( $roles ) ) $sql .= ' OR ';
		$i++;
	}
	$sql .= ' ) ';
	$sql .= ' ORDER BY display_name ';
	$userIDs = $wpdb->get_col( $sql );
	return $userIDs;
}

20 comments

  1. Ian (25th June 2010)

    You can also just include the WP_User_Search class from your template:

    require_once(WP_CONTENT_DIR . ‘/../wp-admin/includes/user.php’);

  2. Dwaynne (16th August 2010)

    Ok, so how do you use this in a template function, since that’s where the rubber hits the road in displaying it to end-users?

  3. Steve Taylor (17th August 2010)

    Hi Dwaynne, not sure if you’re asking me or Ian – I should get threaded comments sorted out here!

    As to how to use getUsersByRole, how about:

    $subscriberIDs = getUsersByRole( 'subscriber' );

    Then… depends what you want to do really.

  4. Flick (4th September 2010)

    Thanks for this code! I found out about it through CogDogBlog, and was wondering if multiple roles could be used in the getUsersByRole() bracket?

    This is because I would like to be able to display a list of users. e.g. all users excluding ‘subscriber’; or just display ‘editors’ and ‘authors’ together.

    At present I can only seem to search for ‘one’ role only.

    Thanks in advance! :)

  5. Steve Taylor (4th September 2010)

    Hi Flick, check the updated post. I developed the alternate version for a project I worked on and never posted it. Hope it helps!

  6. Jeff King (7th September 2010)

    Steve,

    Thanks for this post, it was very helpful.

    However, your update does not accept an array of roles, it accepts a comma separated string of roles (without any whitespace). A simple edit will allow comma separated strings (with or without whitespace) and arrays of roles. I replaced


    $roles = explode( ",", $roles );

    with


    if( !is_Array( $roles ) ) {
    $roles = array_walk(explode( ",", $roles ), 'trim');
    }

  7. Steve Taylor (7th September 2010)

    Jeff, many thanks for that – I’ve updated the update. (Memo to self: never edit public code in a hurry!)

  8. Acebone (7th November 2010)

    Hi!

    Your updated ‘array’ version of the function won’t work.

    array_walk does NOT return an array, it returns an error-value where 1 = true = everything went OK and 0 = false = something went wrong

    array_walk works directly on the array that you pass it (and you are passing it a temporary variable created by ‘explode’), so you need to change line 4.

    Here is a working version of your function:

    function getUsersByRole( $roles ) {
    global $wpdb;

    if ( !is_array( $roles ) ) {
    $roles = explode( ",", $roles );
    array_walk( $roles, 'trim' );
    }

    $sql = '
    SELECT ID, display_name
    FROM ' . $wpdb->users . ' INNER JOIN ' . $wpdb->usermeta . '
    ON ' . $wpdb->users . '.ID = ' . $wpdb->usermeta . '.user_id
    WHERE ' . $wpdb->usermeta . '.meta_key = \'' . $wpdb->prefix . 'capabilities\'
    AND (
    ';

    $i = 1;
    foreach ( $roles as $role ) {
    $sql .= ' ' . $wpdb->usermeta . '.meta_value LIKE \'%"' . $role . '"%\' ';
    if ( $i get_col( $sql );

    return $userIDs;
    }

    A quick test seems to confirm that this function works, haven’t tested in depth though,

  9. Steve Taylor (7th November 2010)

    Thanks Acebone, that was a bit of a dumb mistake!

  10. Acebone (7th November 2010)

    Cool!
    That kind of thing happens.

    The SQL part itself, did you use it and can confirm that it works with no bugs?

    It seems to work, but I haven’t the time right now for proper testing.

    Another thing:

    WP_User_Search will return users with AT LEAST the specified role – so if you search ‘editors’ you get editors AND admins

    Your function seems to go directly for the specified user-role and nothing else, eg: editors but NOT admins

    If that’s true – I like your function better :)

  11. Steve Taylor (7th November 2010)

    I can confirm that the SQL in the first example works fine. The second variant seems pretty straightforward, but I don’t have time for extensive testing, so let me know if it trips up anywhere.

    As for WP_User_Search, for me it only returns users in the specified role. Looking at the source, this does seem to be how it works. Let me know if you can confirm a situation where this isn’t the case.

    Interestingly, it seem that WP_User_Search has been deprecated for the next version of WP. I’ve not looked into how its replacement works.

  12. Jim (18th November 2010)

    Really cool Steve been trying to write code similar to this myself (but not trying too hard) luckily found you could while doing my research and now I can get to bed early! You’re a prince!

  13. Mat_ (9th January 2011)

    Thanks for this code! I haven’t tested it yet but i’m sure it works.
    It saves me a lot of time!
    Many Thanks

  14. John Franks (3rd April 2011)

    You don’t know how much time you saved me. I had a site up that used basically the same code that you wrote. It would select all users in a role.

    Anyways the site got infected with a virus and I decided to scratch it and start over. Unfortunately I didn’t have a backup and lost the code.

    I was really dreading to have to rewrite it. But thankfully, I found your site now I don’t have to.

  15. Brent Shepherd (13th April 2011)

    With WordPress 3.1 and newer, we can use the get_users function: http://codex.wordpress.org/Function_Reference/get_users

  16. Steve Taylor (13th April 2011)

    Indeed, thanks Brent! I’ve just been updating my plugins to use this new function.

  17. rayne (14th April 2011)

    Thanks for this script! I found it while I was looking for a way to “gray out” inactive authors – I want a list of authors where every author who hasn’t posted anything in the last 6 or 12 months is applied an extra CSS class (eg. gray font color or 50% opacity). Would that be easy to implement into your script? My PHP skills are too crappy to figure it out myself :/

  18. Steve Taylor (14th April 2011)

    Hi rayne, sounds like you need some custom SQL querying. Or, if you don’t mind the extra database hits (or you have a caching plugin working and it doesn’t matter), just grab the most recent post for each author in the loop as you output them, and test the date. HTH.

  19. Kexin Li (18th June 2011)

    Hi Steve,

    Thanks for sharing the plugin. Can you please tell me how I can call this function on my template? For example I want to list all administrators

  20. Steve Taylor (19th June 2011)

    Kexin, this code is out of date. Use get_users.

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Want to show me some code? Don't paste long code here, link to a post at pastebin.ca or a similar site. Thanks.

Recent posts

View complete archives »