Introduce the ability to filter the Users admin listing screen by users with no role, if such users exist.

Fixes #22993
Props spmlucas, johnbillion


git-svn-id: https://develop.svn.wordpress.org/trunk@34965 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
John Blackbourn
2015-10-08 22:06:46 +00:00
parent 6fe7598cff
commit bc043c51e8
4 changed files with 313 additions and 8 deletions
@@ -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] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$class>$name</a>";
}
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 <span class="count">(%2$s)</span>'), $name, number_format_i18n( $avail_roles['none' ] ) );
$role_links['none'] = "<a href='" . esc_url( add_query_arg( 'role', 'none', $url ) ) . "'$class>$name</a>";
}
return $role_links;
}
+42 -1
View File
@@ -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;
}
+154
View File
@@ -0,0 +1,154 @@
<?php
/**
* @group user
*/
class Tests_User_CountUsers extends WP_UnitTestCase {
/**
* @ticket 22993
*
* @dataProvider data_count_users_strategies
*/
public function test_count_users_is_accurate( $strategy ) {
if ( is_multisite() ) {
$this->markTestSkipped( 'Test does not run on multisite' );
}
// Setup users
$admin = $this->factory->user->create( array(
'role' => 'administrator',
) );
$editor = $this->factory->user->create( array(
'role' => 'editor',
) );
$author = $this->factory->user->create( array(
'role' => 'author',
) );
$contributor = $this->factory->user->create( array(
'role' => 'contributor',
) );
$subscriber = $this->factory->user->create( array(
'role' => 'subscriber',
) );
$none = $this->factory->user->create( array(
'role' => '',
) );
$nobody = $this->factory->user->create( array(
'role' => '',
) );
// Test user counts
$count = count_users( $strategy );
$this->assertEquals( 8, $count['total_users'] );
$this->assertEquals( array(
'administrator' => 2,
'editor' => 1,
'author' => 1,
'contributor' => 1,
'subscriber' => 1,
'none' => 2,
), $count['avail_roles'] );
}
/**
* @ticket 22993
* @group multisite
*
* @dataProvider data_count_users_strategies
*/
public function test_count_users_multisite_is_accurate( $strategy ) {
if ( ! is_multisite() ) {
$this->markTestSkipped( 'Test requires multisite' );
}
// Setup users
$admin = $this->factory->user->create( array(
'role' => 'administrator',
) );
$editor = $this->factory->user->create( array(
'role' => 'editor',
) );
$author = $this->factory->user->create( array(
'role' => 'author',
) );
$contributor = $this->factory->user->create( array(
'role' => 'contributor',
) );
$subscriber = $this->factory->user->create( array(
'role' => 'subscriber',
) );
$none = $this->factory->user->create( array(
'role' => '',
) );
$nobody = $this->factory->user->create( array(
'role' => '',
) );
// Setup blogs
$blog_1 = (int) $this->factory->blog->create( array(
'user_id' => $editor,
) );
$blog_2 = (int) $this->factory->blog->create( array(
'user_id' => $author,
) );
// Add users to blogs
add_user_to_blog( $blog_1, $subscriber, 'editor' );
add_user_to_blog( $blog_2, $none, 'contributor' );
// Test users counts on root site
$count = count_users( $strategy );
$this->assertEquals( 8, $count['total_users'] );
$this->assertEquals( array(
'administrator' => 2,
'editor' => 1,
'author' => 1,
'contributor' => 1,
'subscriber' => 1,
'none' => 0,
), $count['avail_roles'] );
// Test users counts on blog 1
switch_to_blog( $blog_1 );
$count = count_users( $strategy );
restore_current_blog();
$this->assertEquals( 2, $count['total_users'] );
$this->assertEquals( array(
'administrator' => 1,
'editor' => 1,
'none' => 0,
), $count['avail_roles'] );
// Test users counts on blog 2
switch_to_blog( $blog_2 );
$count = count_users( $strategy );
restore_current_blog();
$this->assertEquals( 2, $count['total_users'] );
$this->assertEquals( array(
'administrator' => 1,
'contributor' => 1,
'none' => 0,
), $count['avail_roles'] );
}
function data_count_users_strategies() {
return array(
array(
'time',
),
array(
'memory',
),
);
}
}
@@ -0,0 +1,84 @@
<?php
/**
* @group user
*/
class Tests_User_GetUsersWithNoRole extends WP_UnitTestCase {
/**
* @ticket 22993
*/
public function test_get_users_with_no_role_is_accurate() {
if ( is_multisite() ) {
$this->markTestSkipped( 'Test does not run on multisite' );
}
// Setup users
$admin = $this->factory->user->create( array(
'role' => 'administrator',
) );
$editor = $this->factory->user->create( array(
'role' => 'editor',
) );
$nobody = $this->factory->user->create( array(
'role' => '',
) );
$nobody_else = $this->factory->user->create( array(
'role' => '',
) );
// Test users
$users = wp_get_users_with_no_role();
$this->assertEquals( array(
$nobody,
$nobody_else,
), $users );
}
/**
* @ticket 22993
* @group multisite
*/
public function test_get_users_with_no_role_multisite_is_accurate() {
if ( ! is_multisite() ) {
$this->markTestSkipped( 'Test requires multisite' );
}
// Setup users
$admin = $this->factory->user->create( array(
'role' => 'administrator',
) );
$editor = $this->factory->user->create( array(
'role' => 'editor',
) );
$nobody = $this->factory->user->create( array(
'role' => '',
) );
// Setup blogs
$blog_1 = (int) $this->factory->blog->create( array(
'user_id' => $editor,
) );
// Add users to blogs
add_user_to_blog( $blog_1, $editor, 'editor' );
// Test users on root site
$users = wp_get_users_with_no_role();
$this->assertSame( array(), $users );
// Test users counts on blog 1
switch_to_blog( $blog_1 );
$users = wp_get_users_with_no_role();
restore_current_blog();
// Test users on root site
$this->assertSame( array(), $users );
}
}