count_users( string $strategy = 'time', int|null $site_id = null )
Counts number of users who have each of the user roles.
Description
Assumes there are neither duplicated nor orphaned capabilities meta_values.
Assumes role names are unique phrases. Same assumption made by WP_User_Query::prepare_query() Using $strategy = ‘time’ this is CPU-intensive and should handle around 10^7 users.
Using $strategy = ‘memory’ this is memory-intensive and should handle around 10^5 users, but see WP Bug #12257.
Parameters
- $strategy
-
(Optional) The computational strategy to use when counting the users.<br> Accepts either 'time' or 'memory'. Default 'time'.
Default value: 'time'
- $site_id
-
(Optional) The site ID to count users for. Defaults to the current site.
Default value: null
Return
(array) User counts.<br>
- 'total_users'
(int) Total number of users on the site.<br> - 'avail_roles'
(int[]) Array of user counts keyed by user role.<br>
Source
File: wp-includes/user.php
function count_users( $strategy = 'time', $site_id = null ) {
global $wpdb;
// Initialize
if ( ! $site_id ) {
$site_id = get_current_blog_id();
}
$blog_prefix = $wpdb->get_blog_prefix( $site_id );
$result = array();
if ( 'time' == $strategy ) {
if ( is_multisite() && $site_id != get_current_blog_id() ) {
switch_to_blog( $site_id );
$avail_roles = wp_roles()->get_names();
restore_current_blog();
} else {
$avail_roles = wp_roles()->get_names();
}
// Build a CPU-intensive query that will return concise information.
$select_count = array();
foreach ( $avail_roles as $this_role => $name ) {
$select_count[] = $wpdb->prepare( "COUNT(NULLIF(`meta_value` LIKE %s, false))", '%' . $wpdb->esc_like( '"' . $this_role . '"' ) . '%');
}
$select_count[] = "COUNT(NULLIF(`meta_value` = 'a:0:{}', false))";
$select_count = implode(', ', $select_count);
// Add the meta_value index to the selection list, then run the query.
$row = $wpdb->get_row( "
SELECT {$select_count}, COUNT(*)
FROM {$wpdb->usermeta}
INNER JOIN {$wpdb->users} ON user_id = ID
WHERE meta_key = '{$blog_prefix}capabilities'
", ARRAY_N );
// Run the previous loop again to associate results with role names.
$col = 0;
$role_counts = array();
foreach ( $avail_roles as $this_role => $name ) {
$count = (int) $row[$col++];
if ($count > 0) {
$role_counts[$this_role] = $count;
}
}
$role_counts['none'] = (int) $row[$col++];
// Get the meta_value index from the end of the result set.
$total_users = (int) $row[$col];
$result['total_users'] = $total_users;
$result['avail_roles'] =& $role_counts;
} else {
$avail_roles = array(
'none' => 0,
);
$users_of_blog = $wpdb->get_col( "
SELECT meta_value
FROM {$wpdb->usermeta}
INNER JOIN {$wpdb->users} ON user_id = ID
WHERE meta_key = '{$blog_prefix}capabilities'
" );
foreach ( $users_of_blog as $caps_meta ) {
$b_roles = maybe_unserialize($caps_meta);
if ( ! is_array( $b_roles ) )
continue;
if ( empty( $b_roles ) ) {
$avail_roles['none']++;
}
foreach ( $b_roles as $b_role => $val ) {
if ( isset($avail_roles[$b_role]) ) {
$avail_roles[$b_role]++;
} else {
$avail_roles[$b_role] = 1;
}
}
}
$result['total_users'] = count( $users_of_blog );
$result['avail_roles'] =& $avail_roles;
}
return $result;
}
Changelog
Version | Description |
---|---|
4.9.0 | The $site_id parameter was added to support multisite. |
4.4.0 | The number of users with no role is now included in the none element. |
3.0.0 | Introduced. |