Get multiple users with meta value in one query and populate WP_User class

For anyone interested.

Got it solved using the get_user_metadata filter to short circuit the metaquery and cache loading.

Steps:

  • Run query
  • Store result data in the class property
  • Add get_user_metadata filter
  • Start foreach loop on results
  • Trigger new WP_User( $result_value ) for each result
  • Within the filter function, validate meta key on $wpdb->get_blog_prefix() . 'capabilities'.
  • Return the unserialized value from the capabilities meta data
  • After the loop, remove the get_user_metadata filter again
  • Done!

Full query (slightly modified)

SELECT {$wpdb->users}.*, {$wpdb->usermeta}.meta_value as roles FROM {$wpdb->users} 
LEFT JOIN {$wpdb->usermeta} ON {$wpdb->users}.ID = {$wpdb->usermeta}.user_id
WHERE {$wpdb->usermeta}.meta_key = '{$wpdb->get_blog_prefix()}capabilities'
ORDER BY {$wpdb->users}.display_name

This will return all the values from the users table + an extra column named roles with the meta_value for TABLEPREFIX_capabilities

There, one single query to load a bulk of users and their capabilities/roles.