count_users

The timeline below displays how wordpress function count_users has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.4

/**
 * Counts number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 * @since 4.9.0 The `$site_id` parameter was added to support multisite.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $strategy Optional. The computational strategy to use when counting the users.
 *                           Accepts either 'time' or 'memory'. Default 'time'.
 * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
 * @return array {
 *     User counts.
 *
 *     @type int   $total_users Total number of users on the site.
 *     @type int[] $avail_roles Array of user counts keyed by user role.
 * }
 */
function count_users($strategy = 'time', $site_id = null)
{
    global $wpdb;
    // Initialize.
    if (!$site_id) {
        $site_id = get_current_blog_id();
    }
    /**
     * Filters the user count before queries are run.
     *
     * Return a non-null value to cause count_users() to return early.
     *
     * @since 5.1.0
     *
     * @param null|array $result   The value to return instead. Default null to continue with the query.
     * @param string     $strategy Optional. The computational strategy to use when counting the users.
     *                             Accepts either 'time' or 'memory'. Default 'time'.
     * @param int        $site_id  The site ID to count users for.
     */
    $pre = apply_filters('pre_count_users', null, $strategy, $site_id);
    if (null !== $pre) {
        return $pre;
    }
    $blog_prefix = $wpdb->get_blog_prefix($site_id);
    $result = array();
    if ('time' === $strategy) {
        if (is_multisite() && get_current_blog_id() != $site_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("\n\t\t\tSELECT {$select_count}, COUNT(*)\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t", 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("\n\t\t\tSELECT meta_value\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t");
        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;
}

WordPress Version: 6.1

/**
 * Counts number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 * @since 4.9.0 The `$site_id` parameter was added to support multisite.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $strategy Optional. The computational strategy to use when counting the users.
 *                           Accepts either 'time' or 'memory'. Default 'time'.
 * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
 * @return array {
 *     User counts.
 *
 *     @type int   $total_users Total number of users on the site.
 *     @type int[] $avail_roles Array of user counts keyed by user role.
 * }
 */
function count_users($strategy = 'time', $site_id = null)
{
    global $wpdb;
    // Initialize.
    if (!$site_id) {
        $site_id = get_current_blog_id();
    }
    /**
     * Filters the user count before queries are run.
     *
     * Return a non-null value to cause count_users() to return early.
     *
     * @since 5.1.0
     *
     * @param null|array $result   The value to return instead. Default null to continue with the query.
     * @param string     $strategy Optional. The computational strategy to use when counting the users.
     *                             Accepts either 'time' or 'memory'. Default 'time'.
     * @param int        $site_id  The site ID to count users for.
     */
    $pre = apply_filters('pre_count_users', null, $strategy, $site_id);
    if (null !== $pre) {
        return $pre;
    }
    $blog_prefix = $wpdb->get_blog_prefix($site_id);
    $result = array();
    if ('time' === $strategy) {
        if (is_multisite() && get_current_blog_id() != $site_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("\n\t\t\tSELECT {$select_count}, COUNT(*)\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t", 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("\n\t\t\tSELECT meta_value\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t");
        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;
}

WordPress Version: 5.6

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 * @since 4.9.0 The `$site_id` parameter was added to support multisite.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $strategy Optional. The computational strategy to use when counting the users.
 *                           Accepts either 'time' or 'memory'. Default 'time'.
 * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
 * @return array {
 *     User counts.
 *
 *     @type int   $total_users Total number of users on the site.
 *     @type int[] $avail_roles Array of user counts keyed by user role.
 * }
 */
function count_users($strategy = 'time', $site_id = null)
{
    global $wpdb;
    // Initialize.
    if (!$site_id) {
        $site_id = get_current_blog_id();
    }
    /**
     * Filters the user count before queries are run.
     *
     * Return a non-null value to cause count_users() to return early.
     *
     * @since 5.1.0
     *
     * @param null|string $result   The value to return instead. Default null to continue with the query.
     * @param string      $strategy Optional. The computational strategy to use when counting the users.
     *                              Accepts either 'time' or 'memory'. Default 'time'.
     * @param int|null    $site_id  Optional. The site ID to count users for. Defaults to the current site.
     */
    $pre = apply_filters('pre_count_users', null, $strategy, $site_id);
    if (null !== $pre) {
        return $pre;
    }
    $blog_prefix = $wpdb->get_blog_prefix($site_id);
    $result = array();
    if ('time' === $strategy) {
        if (is_multisite() && get_current_blog_id() != $site_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("\n\t\t\tSELECT {$select_count}, COUNT(*)\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t", 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("\n\t\t\tSELECT meta_value\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t");
        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;
}

WordPress Version: 5.5

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 * @since 4.9.0 The `$site_id` parameter was added to support multisite.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $strategy Optional. The computational strategy to use when counting the users.
 *                           Accepts either 'time' or 'memory'. Default 'time'.
 * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
 * @return array {
 *     User counts.
 *
 *     @type int   $total_users Total number of users on the site.
 *     @type int[] $avail_roles Array of user counts keyed by user role.
 * }
 */
function count_users($strategy = 'time', $site_id = null)
{
    global $wpdb;
    // Initialize.
    if (!$site_id) {
        $site_id = get_current_blog_id();
    }
    /**
     * Filter the user count before queries are run. Return a non-null value to cause count_users()
     * to return early.
     *
     * @since 5.1.0
     *
     * @param null|string $result   The value to return instead. Default null to continue with the query.
     * @param string      $strategy Optional. The computational strategy to use when counting the users.
     *                              Accepts either 'time' or 'memory'. Default 'time'.
     * @param int|null    $site_id  Optional. The site ID to count users for. Defaults to the current site.
     */
    $pre = apply_filters('pre_count_users', null, $strategy, $site_id);
    if (null !== $pre) {
        return $pre;
    }
    $blog_prefix = $wpdb->get_blog_prefix($site_id);
    $result = array();
    if ('time' === $strategy) {
        if (is_multisite() && get_current_blog_id() != $site_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("\n\t\t\tSELECT {$select_count}, COUNT(*)\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t", 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("\n\t\t\tSELECT meta_value\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t");
        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;
}

WordPress Version: 5.4

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 * @since 4.9.0 The `$site_id` parameter was added to support multisite.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $strategy Optional. The computational strategy to use when counting the users.
 *                           Accepts either 'time' or 'memory'. Default 'time'.
 * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
 * @return array {
 *     User counts.
 *
 *     @type int   $total_users Total number of users on the site.
 *     @type int[] $avail_roles Array of user counts keyed by user role.
 * }
 */
function count_users($strategy = 'time', $site_id = null)
{
    global $wpdb;
    // Initialize.
    if (!$site_id) {
        $site_id = get_current_blog_id();
    }
    /**
     * Filter the user count before queries are run. Return a non-null value to cause count_users()
     * to return early.
     *
     * @since 5.1.0
     *
     * @param null|string $result   The value to return instead. Default null to continue with the query.
     * @param string      $strategy Optional. The computational strategy to use when counting the users.
     *                              Accepts either 'time' or 'memory'. Default 'time'.
     * @param int|null    $site_id  Optional. The site ID to count users for. Defaults to the current site.
     */
    $pre = apply_filters('pre_count_users', null, $strategy, $site_id);
    if (null !== $pre) {
        return $pre;
    }
    $blog_prefix = $wpdb->get_blog_prefix($site_id);
    $result = array();
    if ('time' == $strategy) {
        if (is_multisite() && get_current_blog_id() != $site_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("\n\t\t\tSELECT {$select_count}, COUNT(*)\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t", 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("\n\t\t\tSELECT meta_value\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t");
        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;
}

WordPress Version: 5.1

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 * @since 4.9.0 The `$site_id` parameter was added to support multisite.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $strategy Optional. The computational strategy to use when counting the users.
 *                           Accepts either 'time' or 'memory'. Default 'time'.
 * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
 * @return array Includes a grand total and an array of counts indexed by role strings.
 */
function count_users($strategy = 'time', $site_id = null)
{
    global $wpdb;
    // Initialize
    if (!$site_id) {
        $site_id = get_current_blog_id();
    }
    /**
     * Filter the user count before queries are run. Return a non-null value to cause count_users()
     * to return early.
     *
     * @since 5.1.0
     *
     * @param null|string $result   Default null.
     * @param string      $strategy Optional. The computational strategy to use when counting the users.
     *                              Accepts either 'time' or 'memory'. Default 'time'.
     * @param int|null    $site_id  Optional. The site ID to count users for. Defaults to the current site.
     */
    $pre = apply_filters('pre_count_users', null, $strategy, $site_id);
    if (null !== $pre) {
        return $pre;
    }
    $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("\n\t\t\tSELECT {$select_count}, COUNT(*)\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t", 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("\n\t\t\tSELECT meta_value\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t");
        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;
}

WordPress Version: 4.9

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 * @since 4.9.0 The `$site_id` parameter was added to support multisite.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $strategy Optional. The computational strategy to use when counting the users.
 *                           Accepts either 'time' or 'memory'. Default 'time'.
 * @param int|null $site_id  Optional. The site ID to count users for. Defaults to the current site.
 * @return array Includes a grand total and an array of counts indexed by role strings.
 */
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("\n\t\t\tSELECT {$select_count}, COUNT(*)\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t", 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("\n\t\t\tSELECT meta_value\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t");
        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;
}

WordPress Version: 4.8

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $strategy 'time' or 'memory'
 * @return array Includes a grand total and an array of counts indexed by role strings.
 */
function count_users($strategy = 'time')
{
    global $wpdb;
    // Initialize
    $id = get_current_blog_id();
    $blog_prefix = $wpdb->get_blog_prefix($id);
    $result = array();
    if ('time' == $strategy) {
        $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("\n\t\t\tSELECT {$select_count}, COUNT(*)\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t", 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("\n\t\t\tSELECT meta_value\n\t\t\tFROM {$wpdb->usermeta}\n\t\t\tINNER JOIN {$wpdb->users} ON user_id = ID\n\t\t\tWHERE meta_key = '{$blog_prefix}capabilities'\n\t\t");
        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;
    }
    if (is_multisite()) {
        $result['avail_roles']['none'] = 0;
    }
    return $result;
}

WordPress Version: 4.4

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @since 4.4.0 The number of users with no role is now included in the `none` element.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string $strategy 'time' or 'memory'
 * @return array Includes a grand total and an array of counts indexed by role strings.
 */
function count_users($strategy = 'time')
{
    global $wpdb;
    // Initialize
    $id = get_current_blog_id();
    $blog_prefix = $wpdb->get_blog_prefix($id);
    $result = array();
    if ('time' == $strategy) {
        $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} 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} 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;
    }
    if (is_multisite()) {
        $result['avail_roles']['none'] = 0;
    }
    return $result;
}

WordPress Version: 4.3

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 *
 * @global wpdb $wpdb
 *
 * @param string $strategy 'time' or 'memory'
 * @return array Includes a grand total and an array of counts indexed by role strings.
 */
function count_users($strategy = 'time')
{
    global $wpdb;
    // Initialize
    $id = get_current_blog_id();
    $blog_prefix = $wpdb->get_blog_prefix($id);
    $result = array();
    if ('time' == $strategy) {
        $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 = 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} 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;
            }
        }
        // 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();
        $users_of_blog = $wpdb->get_col("SELECT meta_value FROM {$wpdb->usermeta} 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;
            }
            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;
}

WordPress Version: 4.0

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @param string $strategy 'time' or 'memory'
 * @return array Includes a grand total and an array of counts indexed by role strings.
 */
function count_users($strategy = 'time')
{
    global $wpdb, $wp_roles;
    // Initialize
    $id = get_current_blog_id();
    $blog_prefix = $wpdb->get_blog_prefix($id);
    $result = array();
    if ('time' == $strategy) {
        global $wp_roles;
        if (!isset($wp_roles)) {
            $wp_roles = new WP_Roles();
        }
        $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 = 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} 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;
            }
        }
        // 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();
        $users_of_blog = $wpdb->get_col("SELECT meta_value FROM {$wpdb->usermeta} 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;
            }
            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;
}

WordPress Version: 3.7

/**
 * Count number of users who have each of the user roles.
 *
 * 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.
 *
 * @since 3.0.0
 * @param string $strategy 'time' or 'memory'
 * @return array Includes a grand total and an array of counts indexed by role strings.
 */
function count_users($strategy = 'time')
{
    global $wpdb, $wp_roles;
    // Initialize
    $id = get_current_blog_id();
    $blog_prefix = $wpdb->get_blog_prefix($id);
    $result = array();
    if ('time' == $strategy) {
        global $wp_roles;
        if (!isset($wp_roles)) {
            $wp_roles = new WP_Roles();
        }
        $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[] = "COUNT(NULLIF(`meta_value` LIKE '%\"" . like_escape($this_role) . "\"%', 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} 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;
            }
        }
        // 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();
        $users_of_blog = $wpdb->get_col("SELECT meta_value FROM {$wpdb->usermeta} 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;
            }
            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;
}