Make WordPress Core

Changeset 40560


Ignore:
Timestamp:
04/30/2017 01:02:50 PM (7 years ago)
Author:
johnbillion
Message:

Users: Ensure user counts remain accurate if users are added to or removed from the users table without corresponding usermeta entries being added or removed.

This has a slight performance impact on sites with a large number of users when the time strategy is used for counting users. Hopefully this impact will be negated by enhancements proposed in #38741.

Props psoluch, dots, boonebgorges, ptbello, tharsheblows

Fixes #29785

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/user.php

    r40387 r40560  
    858858
    859859        // Add the meta_value index to the selection list, then run the query.
    860         $row = $wpdb->get_row( "SELECT $select_count, COUNT(*) FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'", ARRAY_N );
     860        $row = $wpdb->get_row( "
     861            SELECT {$select_count}, COUNT(*)
     862            FROM {$wpdb->usermeta}
     863            INNER JOIN {$wpdb->users} ON user_id = ID
     864            WHERE meta_key = '{$blog_prefix}capabilities'
     865        ", ARRAY_N );
    861866
    862867        // Run the previous loop again to associate results with role names.
     
    882887        );
    883888
    884         $users_of_blog = $wpdb->get_col( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = '{$blog_prefix}capabilities'" );
     889        $users_of_blog = $wpdb->get_col( "
     890            SELECT meta_value
     891            FROM {$wpdb->usermeta}
     892            INNER JOIN {$wpdb->users} ON user_id = ID
     893            WHERE meta_key = '{$blog_prefix}capabilities'
     894        " );
    885895
    886896        foreach ( $users_of_blog as $caps_meta ) {
  • trunk/tests/phpunit/tests/user/countUsers.php

    r40543 r40560  
    170170        ), $count['avail_roles'] );
    171171
     172    }
     173
     174    /**
     175     * @ticket 29785
     176     *
     177     * @dataProvider data_count_users_strategies
     178     */
     179    public function test_count_users_should_not_count_users_who_are_not_in_posts_table( $strategy ) {
     180        global $wpdb;
     181
     182        // Get a 'before' count for comparison.
     183        $count = count_users( $strategy );
     184
     185        $u = self::factory()->user->create( array(
     186            'role' => 'editor',
     187        ) );
     188
     189        // Manually delete the user, but leave the capabilities usermeta.
     190        $wpdb->delete( $wpdb->users, array(
     191            'ID' => $u,
     192        ) );
     193
     194        $count2 = count_users( $strategy );
     195
     196        $this->assertEqualSets( $count, $count2 );
    172197    }
    173198
Note: See TracChangeset for help on using the changeset viewer.