WordPress.org

Make WordPress Core

Ticket #22993: 22993.4.diff

File 22993.4.diff, 9.9 KB (added by johnbillion, 4 years ago)
  • src/wp-includes/user-functions.php

     
    735735 * Using $strategy = 'memory' this is memory-intensive and should handle around 10^5 users, but see WP Bug #12257.
    736736 *
    737737 * @since 3.0.0
     738 * @since 4.4.0 The number of users with no role is now included in the `none` element.
    738739 *
    739740 * @global wpdb $wpdb
    740741 *
     
    775776                // Get the meta_value index from the end of the result set.
    776777                $total_users = (int) $row[$col];
    777778
     779                $role_counts['none'] = ( $total_users - array_sum( $role_counts ) );
     780
    778781                $result['total_users'] = $total_users;
    779782                $result['avail_roles'] =& $role_counts;
    780783        } else {
    781                 $avail_roles = array();
     784                $avail_roles = array(
     785                        'none' => 0,
     786                );
    782787
    783788                $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" );
    784789
     
    786791                        $b_roles = maybe_unserialize($caps_meta);
    787792                        if ( ! is_array( $b_roles ) )
    788793                                continue;
     794                        if ( empty( $b_roles ) ) {
     795                                $avail_roles['none']++;
     796                        }
    789797                        foreach ( $b_roles as $b_role => $val ) {
    790798                                if ( isset($avail_roles[$b_role]) ) {
    791799                                        $avail_roles[$b_role]++;
     
    799807                $result['avail_roles'] =& $avail_roles;
    800808        }
    801809
     810        if ( is_multisite() ) {
     811                $result['avail_roles']['none'] = 0;
     812        }
     813
    802814        return $result;
    803815}
    804816
     
    22312243        $manager = WP_Session_Tokens::get_instance( get_current_user_id() );
    22322244        $manager->destroy_all();
    22332245}
     2246
     2247/**
     2248 * Get the user IDs of all users with no role on this site.
     2249 *
     2250 * This function returns an empty array when used on Multisite.
     2251 *
     2252 * @since 4.4.0
     2253 *
     2254 * @return array Array of user IDs.
     2255 */
     2256function wp_get_users_with_no_role() {
     2257        global $wpdb;
     2258
     2259        if ( is_multisite() ) {
     2260                return array();
     2261        }
     2262
     2263        $prefix = $wpdb->get_blog_prefix();
     2264        $regex  = implode( '|', wp_roles()->get_names() );
     2265        $regex  = preg_replace( '/[^a-zA-Z_\|-]/', '', $regex );
     2266        $users  = $wpdb->get_col( $wpdb->prepare( "
     2267                SELECT user_id
     2268                FROM $wpdb->usermeta
     2269                WHERE meta_key = '{$prefix}capabilities'
     2270                AND meta_value NOT REGEXP %s
     2271        ", $regex ) );
     2272
     2273        return $users;
     2274}
  • src/wp-admin/includes/class-wp-users-list-table.php

     
    8787
    8888                $paged = $this->get_pagenum();
    8989
    90                 $args = array(
    91                         'number' => $users_per_page,
    92                         'offset' => ( $paged-1 ) * $users_per_page,
    93                         'role' => $role,
    94                         'search' => $usersearch,
    95                         'fields' => 'all_with_meta'
    96                 );
     90                if ( 'none' === $role ) {
     91                        $args = array(
     92                                'number' => $users_per_page,
     93                                'offset' => ( $paged-1 ) * $users_per_page,
     94                                'include' => wp_get_users_with_no_role(),
     95                                'search' => $usersearch,
     96                                'fields' => 'all_with_meta'
     97                        );
     98                } else {
     99                        $args = array(
     100                                'number' => $users_per_page,
     101                                'offset' => ( $paged-1 ) * $users_per_page,
     102                                'role' => $role,
     103                                'search' => $usersearch,
     104                                'fields' => 'all_with_meta'
     105                        );
     106                }
    97107
    98108                if ( '' !== $args['search'] )
    99109                        $args['search'] = '*' . $args['search'] . '*';
     
    166176                        $url = 'users.php';
    167177                        $users_of_blog = count_users();
    168178                }
     179
    169180                $total_users = $users_of_blog['total_users'];
    170181                $avail_roles =& $users_of_blog['avail_roles'];
    171182                unset($users_of_blog);
     
    189200                        $role_links[$this_role] = "<a href='" . esc_url( add_query_arg( 'role', $this_role, $url ) ) . "'$class>$name</a>";
    190201                }
    191202
     203                if ( ! empty( $avail_roles['none' ] ) ) {
     204
     205                        $class = '';
     206
     207                        if ( 'none' === $role ) {
     208                                $class = ' class="current"';
     209                        }
     210
     211                        $name = __( 'No role' );
     212                        /* translators: User role name with count */
     213                        $name = sprintf( __('%1$s <span class="count">(%2$s)</span>'), $name, number_format_i18n( $avail_roles['none' ] ) );
     214                        $role_links['none'] = "<a href='" . esc_url( add_query_arg( 'role', 'none', $url ) ) . "'$class>$name</a>";
     215
     216                }
     217
    192218                return $role_links;
    193219        }
    194220
  • tests/phpunit/tests/user/countUsers.php

     
     1<?php
     2
     3/**
     4 * @group user
     5 */
     6class Tests_User_CountUsers extends WP_UnitTestCase {
     7
     8        /**
     9         * @ticket 22993
     10         *
     11         * @dataProvider data_count_users_strategies
     12         */
     13        public function test_count_users_is_accurate( $strategy ) {
     14
     15                if ( is_multisite() ) {
     16                        $this->markTestSkipped( 'Test does not run on multisite' );
     17                }
     18
     19                // Setup users
     20                $admin = $this->factory->user->create( array(
     21                        'role' => 'administrator',
     22                ) );
     23                $editor = $this->factory->user->create( array(
     24                        'role' => 'editor',
     25                ) );
     26                $author = $this->factory->user->create( array(
     27                        'role' => 'author',
     28                ) );
     29                $contributor = $this->factory->user->create( array(
     30                        'role' => 'contributor',
     31                ) );
     32                $subscriber = $this->factory->user->create( array(
     33                        'role' => 'subscriber',
     34                ) );
     35                $none = $this->factory->user->create( array(
     36                        'role' => '',
     37                ) );
     38                $nobody = $this->factory->user->create( array(
     39                        'role' => '',
     40                ) );
     41
     42                // Test user counts
     43                $count = count_users( $strategy );
     44
     45                $this->assertEquals( 8, $count['total_users'] );
     46                $this->assertEquals( array(
     47                        'administrator' => 2,
     48                        'editor'        => 1,
     49                        'author'        => 1,
     50                        'contributor'   => 1,
     51                        'subscriber'    => 1,
     52                        'none'          => 2,
     53                ), $count['avail_roles'] );
     54
     55        }
     56
     57        /**
     58         * @ticket 22993
     59         * @group multisite
     60         *
     61         * @dataProvider data_count_users_strategies
     62         */
     63        public function test_count_users_multisite_is_accurate( $strategy ) {
     64
     65                if ( ! is_multisite() ) {
     66                        $this->markTestSkipped( 'Test requires multisite' );
     67                }
     68
     69                // Setup users
     70                $admin = $this->factory->user->create( array(
     71                        'role' => 'administrator',
     72                ) );
     73                $editor = $this->factory->user->create( array(
     74                        'role' => 'editor',
     75                ) );
     76                $author = $this->factory->user->create( array(
     77                        'role' => 'author',
     78                ) );
     79                $contributor = $this->factory->user->create( array(
     80                        'role' => 'contributor',
     81                ) );
     82                $subscriber = $this->factory->user->create( array(
     83                        'role' => 'subscriber',
     84                ) );
     85                $none = $this->factory->user->create( array(
     86                        'role' => '',
     87                ) );
     88                $nobody = $this->factory->user->create( array(
     89                        'role' => '',
     90                ) );
     91
     92                // Setup blogs
     93                $blog_1 = (int) $this->factory->blog->create( array(
     94                        'user_id' => $editor,
     95                ) );
     96                $blog_2 = (int) $this->factory->blog->create( array(
     97                        'user_id' => $author,
     98                ) );
     99
     100                // Add users to blogs
     101                add_user_to_blog( $blog_1, $subscriber, 'editor' );
     102                add_user_to_blog( $blog_2, $none, 'contributor' );
     103
     104                // Test users counts on root site
     105                $count = count_users( $strategy );
     106
     107                $this->assertEquals( 8, $count['total_users'] );
     108                $this->assertEquals( array(
     109                        'administrator' => 2,
     110                        'editor'        => 1,
     111                        'author'        => 1,
     112                        'contributor'   => 1,
     113                        'subscriber'    => 1,
     114                        'none'          => 0,
     115                ), $count['avail_roles'] );
     116
     117                // Test users counts on blog 1
     118                switch_to_blog( $blog_1 );
     119                $count = count_users( $strategy );
     120                restore_current_blog();
     121
     122                $this->assertEquals( 2, $count['total_users'] );
     123                $this->assertEquals( array(
     124                        'administrator' => 1,
     125                        'editor'        => 1,
     126                        'none'          => 0,
     127                ), $count['avail_roles'] );
     128
     129                // Test users counts on blog 2
     130                switch_to_blog( $blog_2 );
     131                $count = count_users( $strategy );
     132                restore_current_blog();
     133
     134                $this->assertEquals( 2, $count['total_users'] );
     135                $this->assertEquals( array(
     136                        'administrator' => 1,
     137                        'contributor'   => 1,
     138                        'none'          => 0,
     139                ), $count['avail_roles'] );
     140
     141        }
     142
     143        function data_count_users_strategies() {
     144                return array(
     145                        array(
     146                                'time',
     147                        ),
     148                        array(
     149                                'memory',
     150                        ),
     151                );
     152        }
     153
     154}
  • tests/phpunit/tests/user/wpGetUsersWithNoRole.php

     
     1<?php
     2
     3/**
     4 * @group user
     5 */
     6class Tests_User_GetUsersWithNoRole extends WP_UnitTestCase {
     7
     8        /**
     9         * @ticket 22993
     10         */
     11        public function test_get_users_with_no_role_is_accurate() {
     12
     13                if ( is_multisite() ) {
     14                        $this->markTestSkipped( 'Test does not run on multisite' );
     15                }
     16
     17                // Setup users
     18                $admin = $this->factory->user->create( array(
     19                        'role' => 'administrator',
     20                ) );
     21                $editor = $this->factory->user->create( array(
     22                        'role' => 'editor',
     23                ) );
     24                $nobody = $this->factory->user->create( array(
     25                        'role' => '',
     26                ) );
     27                $nobody_else = $this->factory->user->create( array(
     28                        'role' => '',
     29                ) );
     30
     31                // Test users
     32                $users = wp_get_users_with_no_role();
     33
     34                $this->assertEquals( array(
     35                        $nobody,
     36                        $nobody_else,
     37                ), $users );
     38
     39        }
     40
     41        /**
     42         * @ticket 22993
     43         * @group multisite
     44         */
     45        public function test_get_users_with_no_role_multisite_is_accurate() {
     46
     47                if ( ! is_multisite() ) {
     48                        $this->markTestSkipped( 'Test requires multisite' );
     49                }
     50
     51                // Setup users
     52                $admin = $this->factory->user->create( array(
     53                        'role' => 'administrator',
     54                ) );
     55                $editor = $this->factory->user->create( array(
     56                        'role' => 'editor',
     57                ) );
     58                $nobody = $this->factory->user->create( array(
     59                        'role' => '',
     60                ) );
     61
     62                // Setup blogs
     63                $blog_1 = (int) $this->factory->blog->create( array(
     64                        'user_id' => $editor,
     65                ) );
     66
     67                // Add users to blogs
     68                add_user_to_blog( $blog_1, $editor, 'editor' );
     69
     70                // Test users on root site
     71                $users = wp_get_users_with_no_role();
     72                $this->assertSame( array(), $users );
     73
     74                // Test users counts on blog 1
     75                switch_to_blog( $blog_1 );
     76                $users = wp_get_users_with_no_role();
     77                restore_current_blog();
     78
     79                // Test users on root site
     80                $this->assertSame( array(), $users );
     81
     82        }
     83
     84}