I’ve covered WP_User_Query in a previous post. In short, WP_User_Query is the preferred method for retrieving user information from the database when working with custom queries.
One of the shortcomings of this API method is that it doesn’t allow you to query across multiple roles. So, for example, if you want to retrieve users that meet a certain criteria but may span across multiple roles – say editors and administrators – the API doesn’t support it.
That said, there is a simple strategy that can be used with WP_User_Query to retrieve users across multiple roles.
A Real World Scenario
Before setting up the query, we need to define a scenario in which this may be useful. In one of my recent projects, all users accounts had a piece of meta data associated with them.
Specifically, users had a meta key of ‘featured’ and a value of ‘yes’ or a value of ‘no.’ In code, it worked something like this:
add_user_meta( $user_id, 'featured', 'yes' );
From there, users could either be set as administrators or as editors and I needed to pull back five featured users from each role and then render their display name on the frontend.
Ultimately, the final loop looked something like this:
foreach( $users as $user ) {
echo $user->display_name;
} // end foreach
Simple, right? But there’s a bit that actually goes into collecting all of the users into that single array.
WP_User_Query and Multiple Roles
Given the state of some of the other API methods, I think that it’s a reasonable assumption that you could setup a call to WP_User_Query like this:
$editor_query = new WP_User_Query( array( 'role' => array( 'editor', 'administrator' ), 'meta_key' => 'featured', 'meta_value' => 'yes', 'meta_compare' => '=', 'number' => 5 ) );
But that’s not the case. The role parameter actually only accepts a single string, not an array.
Instead, you have to actually setup two separate queries and then merge the results into a single array:
// get the featured editors $editor_query = new WP_User_Query( array( 'role' => 'editor', 'meta_key' => 'featured', 'meta_value' => 'yes', 'meta_compare' => '=', 'number' => 5 ) ); $editors = $editor_query->get_results(); // get the featured admins $administrator_query = new WP_User_Query( array( 'role' => 'administrator', 'meta_key' => 'featured', 'meta_value' => 'yes', 'meta_compare' => '=', 'number' => 5 ) ); $admins = $administrator_query->get_results(); // store them all as users $users = array_merge( $admins, $editors );
Obviously, it’s not the most elegant solution since you have to setup several independent queries, but it does provide a straightforward way of querying users across multiple roles, and then accessing them all from a single, independent query.
As usual, I’m always interested in how others address this issue especially if there’s a more optimal solution so let me know in the comments.









it just so happens I was after this very thing recently, in the end I used get_users and removed admins with jquery, this is a much better solution thanks Tom.
Of course, Elliot – glad to help!
When it comes to stuff like this, I generally think it’s better to do as much work on the server side since any clever end user that’s comfortable with a debug console could end up displaying some information that you intended to hide.
In your case, it’s nothing too drastic though, so maybe I’m being a bit facetious
.
I found this solution by Andy Adams on the wordpress stackexchange site. It uses a meta query to pull users by their associated capabilities from the usermeta table. I think it works quite well for this task.
global $wpdb;
$user_query = new WP_User_Query( array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => $wpdb->prefix . 'capabilities',
'value' => 'role_one',
'compare' => 'like'
),
array(
'key' => $wpdb->prefix . 'capabilities',
'value' => 'role_two',
'compare' => 'like'
)
)
) );
Andy’s a great developer so thanks for sharing this. Love having a couple of different ways to perform the same task.
The only thing with the code above is that I dislike the concatenation of the
.
$wpdb->prefixwith the string in the array. Honestly, it’s not that big of a deal – it’s a matter purely of personal preference. I’m picky like thatNonetheless, I do appreciate you sharing this snippet as it does provide a bit of a more concise way of doing exactly this.
Thanks a lot for this method! It was really helpful to me. Also, I tried both your method and Andy’s: yours is way faster.
Thanks for sharing this Julien!
I can’t necessarily say why it’s faster without digging deeper and benchmarking, but I suspect that it has to do with the query optimization that comes with using
WP_Querywhere as Andy’s method is using a combination of that and the$wpdbobject.My general rule of thumb is to avoid
$wpdbunlessWP_QueryorWP_User_Queryabsolutely cannot perform what I need.