diff --git a/wp-admin/includes/class-wp-users-list-table.php b/wp-admin/includes/class-wp-users-list-table.php
index 852552c703..cf530057f0 100644
--- a/wp-admin/includes/class-wp-users-list-table.php
+++ b/wp-admin/includes/class-wp-users-list-table.php
@@ -87,13 +87,23 @@ class WP_Users_List_Table extends WP_List_Table {
$paged = $this->get_pagenum();
- $args = array(
- 'number' => $users_per_page,
- 'offset' => ( $paged-1 ) * $users_per_page,
- 'role' => $role,
- 'search' => $usersearch,
- 'fields' => 'all_with_meta'
- );
+ if ( 'none' === $role ) {
+ $args = array(
+ 'number' => $users_per_page,
+ 'offset' => ( $paged-1 ) * $users_per_page,
+ 'include' => wp_get_users_with_no_role(),
+ 'search' => $usersearch,
+ 'fields' => 'all_with_meta'
+ );
+ } else {
+ $args = array(
+ 'number' => $users_per_page,
+ 'offset' => ( $paged-1 ) * $users_per_page,
+ 'role' => $role,
+ 'search' => $usersearch,
+ 'fields' => 'all_with_meta'
+ );
+ }
if ( '' !== $args['search'] )
$args['search'] = '*' . $args['search'] . '*';
@@ -166,6 +176,7 @@ class WP_Users_List_Table extends WP_List_Table {
$url = 'users.php';
$users_of_blog = count_users();
}
+
$total_users = $users_of_blog['total_users'];
$avail_roles =& $users_of_blog['avail_roles'];
unset($users_of_blog);
@@ -189,6 +200,21 @@ class WP_Users_List_Table extends WP_List_Table {
$role_links[$this_role] = "$name";
}
+ if ( ! empty( $avail_roles['none' ] ) ) {
+
+ $class = '';
+
+ if ( 'none' === $role ) {
+ $class = ' class="current"';
+ }
+
+ $name = __( 'No role' );
+ /* translators: User role name with count */
+ $name = sprintf( __('%1$s (%2$s)'), $name, number_format_i18n( $avail_roles['none' ] ) );
+ $role_links['none'] = "$name";
+
+ }
+
return $role_links;
}
diff --git a/wp-includes/user-functions.php b/wp-includes/user-functions.php
index 3ec4cd856f..db87cd49a8 100644
--- a/wp-includes/user-functions.php
+++ b/wp-includes/user-functions.php
@@ -735,6 +735,7 @@ function update_user_meta($user_id, $meta_key, $meta_value, $prev_value = '') {
* 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
*
@@ -775,10 +776,14 @@ function count_users($strategy = 'time') {
// Get the meta_value index from the end of the result set.
$total_users = (int) $row[$col];
+ $role_counts['none'] = ( $total_users - array_sum( $role_counts ) );
+
$result['total_users'] = $total_users;
$result['avail_roles'] =& $role_counts;
} else {
- $avail_roles = array();
+ $avail_roles = array(
+ 'none' => 0,
+ );
$users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" );
@@ -786,6 +791,9 @@ function count_users($strategy = 'time') {
$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]++;
@@ -799,6 +807,10 @@ function count_users($strategy = 'time') {
$result['avail_roles'] =& $avail_roles;
}
+ if ( is_multisite() ) {
+ $result['avail_roles']['none'] = 0;
+ }
+
return $result;
}
@@ -2231,3 +2243,32 @@ function wp_destroy_all_sessions() {
$manager = WP_Session_Tokens::get_instance( get_current_user_id() );
$manager->destroy_all();
}
+
+/**
+ * Get the user IDs of all users with no role on this site.
+ *
+ * This function returns an empty array when used on Multisite.
+ *
+ * @since 4.4.0
+ *
+ * @return array Array of user IDs.
+ */
+function wp_get_users_with_no_role() {
+ global $wpdb;
+
+ if ( is_multisite() ) {
+ return array();
+ }
+
+ $prefix = $wpdb->get_blog_prefix();
+ $regex = implode( '|', wp_roles()->get_names() );
+ $regex = preg_replace( '/[^a-zA-Z_\|-]/', '', $regex );
+ $users = $wpdb->get_col( $wpdb->prepare( "
+ SELECT user_id
+ FROM $wpdb->usermeta
+ WHERE meta_key = '{$prefix}capabilities'
+ AND meta_value NOT REGEXP %s
+ ", $regex ) );
+
+ return $users;
+}
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 23e2c6fa24..f64a34c9d2 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
-$wp_version = '4.4-alpha-34964';
+$wp_version = '4.4-alpha-34965';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.