diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index dcd102623a..2bb4e0543e 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -857,7 +857,12 @@ function count_users($strategy = 'time') { $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 ); + $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; @@ -881,7 +886,12 @@ function count_users($strategy = 'time') { 'none' => 0, ); - $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" ); + $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); diff --git a/tests/phpunit/tests/user/countUsers.php b/tests/phpunit/tests/user/countUsers.php index 9d5f63d050..08e74e7a54 100644 --- a/tests/phpunit/tests/user/countUsers.php +++ b/tests/phpunit/tests/user/countUsers.php @@ -171,6 +171,31 @@ class Tests_User_CountUsers extends WP_UnitTestCase { } + /** + * @ticket 29785 + * + * @dataProvider data_count_users_strategies + */ + public function test_count_users_should_not_count_users_who_are_not_in_posts_table( $strategy ) { + global $wpdb; + + // Get a 'before' count for comparison. + $count = count_users( $strategy ); + + $u = self::factory()->user->create( array( + 'role' => 'editor', + ) ); + + // Manually delete the user, but leave the capabilities usermeta. + $wpdb->delete( $wpdb->users, array( + 'ID' => $u, + ) ); + + $count2 = count_users( $strategy ); + + $this->assertEqualSets( $count, $count2 ); + } + function data_count_users_strategies() { return array( array(