Make WordPress Core

Changeset 61037


Ignore:
Timestamp:
10/21/2025 03:23:43 PM (4 months ago)
Author:
jorbin
Message:

Users: Revert Lazy load user capabilities in WP_User object.

The change from public to protected broke tests for extenders and this also broke WP_User::to_array().

Reverts [60915].

Props davidbaumwald, ellatrix, timothyblynjacobs, welcher, spacedmonkey, bradshawtm, peterwilsoncc, jorbin.
See #58001.

Location:
trunk
Files:
4 edited

Legend:

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

    r60915 r61037  
    3838 * @property string $syntax_highlighting
    3939 * @property string $use_ssl
    40  * @property array<string, bool> $caps
    41  * @property string[] $roles
    42  * @property array<string, bool> $allcaps
    4340 */
    4441#[AllowDynamicProperties]
     
    6461     *
    6562     * @since 2.0.0
    66      * @var array<string, bool>|null Array of key/value pairs where keys represent a capability name
    67      *                               and boolean values represent whether the user has that capability.
    68      */
    69     protected $caps = null;
     63     * @var bool[] Array of key/value pairs where keys represent a capability name
     64     *             and boolean values represent whether the user has that capability.
     65     */
     66    public $caps = array();
    7067
    7168    /**
     
    8380     * @var string[]
    8481     */
    85     protected $roles = array();
     82    public $roles = array();
    8683
    8784    /**
     
    8986     *
    9087     * @since 2.0.0
    91      * @var array<string, bool> Array of key/value pairs where keys represent a capability name
    92      *                          and boolean values represent whether the user has that capability.
    93      */
    94     protected $allcaps = array();
     88     * @var bool[] Array of key/value pairs where keys represent a capability name
     89     *             and boolean values represent whether the user has that capability.
     90     */
     91    public $allcaps = array();
    9592
    9693    /**
     
    292289        }
    293290
    294         if ( in_array( $key, array( 'caps', 'allcaps', 'roles' ), true ) ) {
    295             return true;
    296         }
    297 
    298291        if ( isset( $this->data->$key ) ) {
    299292            return true;
     
    327320            );
    328321            return $this->ID;
    329         }
    330 
    331         if ( in_array( $key, array( 'caps', 'allcaps', 'roles' ), true ) ) {
    332             $this->load_capability_data();
    333             return $this->$key;
    334322        }
    335323
     
    376364        }
    377365
    378         // Ensure capability data is loaded before setting related properties.
    379         if ( in_array( $key, array( 'caps', 'allcaps', 'roles' ), true ) ) {
    380             $this->load_capability_data();
    381             $this->$key = $value;
    382             return;
    383         }
    384 
    385366        $this->data->$key = $value;
    386367    }
     
    406387        }
    407388
    408         if ( in_array( $key, array( 'caps', 'allcaps', 'roles' ), true ) ) {
    409             $this->$key = null;
    410         }
    411 
    412389        if ( isset( $this->data->$key ) ) {
    413390            unset( $this->data->$key );
     
    538515
    539516        $wp_roles = wp_roles();
    540 
    541         // Edge case: In case someone calls this method before lazy initialization, we need to initialize on demand.
    542         if ( ! isset( $this->caps ) ) {
    543             $this->caps = $this->get_caps_data();
    544         }
    545517
    546518        // Filter out caps that are not role names and assign to $this->roles.
     
    577549            return;
    578550        }
    579         $this->load_capability_data();
    580551
    581552        if ( in_array( $role, $this->roles, true ) ) {
     
    607578     */
    608579    public function remove_role( $role ) {
    609         $this->load_capability_data();
    610580        if ( ! in_array( $role, $this->roles, true ) ) {
    611581            return;
     
    640610     */
    641611    public function set_role( $role ) {
    642         $this->load_capability_data();
    643612        if ( 1 === count( $this->roles ) && current( $this->roles ) === $role ) {
    644613            return;
     
    742711     */
    743712    public function add_cap( $cap, $grant = true ) {
    744         $this->load_capability_data();
    745713        $this->caps[ $cap ] = $grant;
    746714        update_user_meta( $this->ID, $this->cap_key, $this->caps );
     
    757725     */
    758726    public function remove_cap( $cap ) {
    759         $this->load_capability_data();
    760727        if ( ! isset( $this->caps[ $cap ] ) ) {
    761728            return;
     
    776743    public function remove_all_caps() {
    777744        global $wpdb;
    778         $this->caps = null;
     745        $this->caps = array();
    779746        delete_user_meta( $this->ID, $this->cap_key );
    780747        delete_user_meta( $this->ID, $wpdb->get_blog_prefix() . 'user_level' );
    781         $this->load_capability_data();
     748        $this->get_role_caps();
    782749    }
    783750
     
    810777     */
    811778    public function has_cap( $cap, ...$args ) {
    812         $this->load_capability_data();
    813 
    814779        if ( is_numeric( $cap ) ) {
    815780            _deprecated_argument( __FUNCTION__, '2.0.0', __( 'Usage of user levels is deprecated. Use capabilities instead.' ) );
     
    913878
    914879        $this->cap_key = $wpdb->get_blog_prefix( $this->site_id ) . 'capabilities';
    915         $this->caps    = null;
     880
     881        $this->caps = $this->get_caps_data();
     882
     883        $this->get_role_caps();
    916884    }
    917885
     
    944912        return $caps;
    945913    }
    946 
    947     /**
    948      * Loads capability data if it has not been loaded yet.
    949      *
    950      * @since 6.9.0
    951      */
    952     private function load_capability_data() {
    953         if ( isset( $this->caps ) ) {
    954             return;
    955         }
    956         $this->caps = $this->get_caps_data();
    957         $this->get_role_caps();
    958     }
    959914}
  • trunk/tests/phpunit/tests/user/capabilities.php

    r60915 r61037  
    994994
    995995    /**
    996      * Test adding capabilities, roles, and allcaps manually to a user.
    997      *
    998      * @ticket 58001
    999      *
    1000      * @dataProvider data_add_user_properties_manually
    1001      *
    1002      * @param string $property_name  The property name to set.
    1003      * @param array  $property_value The property value to set.
    1004      * @param bool   $check_null     Whether to check that the property is null after unsetting it.
    1005      */
    1006     public function test_add_user_properties_manually( $property_name, $property_value, $check_null ) {
    1007         $id                     = self::factory()->user->create();
    1008         $user                   = new WP_User( $id );
    1009         $user->{$property_name} = $property_value;
    1010 
    1011         $this->assertSameSets( $property_value, $user->{$property_name}, "User property {$property_name} was not set correctly." );
    1012         unset( $user->{$property_name} );
    1013         if ( $check_null ) {
    1014             $this->assertNull( $user->{$property_name}, "User property {$property_name} should be null after unsetting it." );
    1015         }
    1016     }
    1017 
    1018     /**
    1019      * Data provider for test_add_user_properties_manually.
    1020      *
    1021      * @return array<string, array{0:string,1:array}>
    1022      */
    1023     public function data_add_user_properties_manually() {
    1024         return array(
    1025             'caps'    => array( 'caps', array( 'foo' => true ), false ),
    1026             'roles'   => array( 'roles', array( 'foo' => true ), true ),
    1027             'allcaps' => array( 'allcaps', array( 'foo' => true ), true ),
    1028         );
    1029     }
    1030 
    1031     /**
    1032996     * Test add_role with implied capabilities grant successfully grants capabilities.
    1033997     *
     
    11351099        $this->flush_roles();
    11361100        $this->assertFalse( $wp_roles->is_role( $role_name ) );
    1137     }
    1138 
    1139     /**
    1140      * @ticket 58001
    1141      */
    1142     public function test_get_role_caps() {
    1143         $id_1   = self::$users['contributor']->ID;
    1144         $user_1 = new WP_User( $id_1 );
    1145 
    1146         $role_caps = $user_1->get_role_caps();
    1147         $this->assertIsArray( $role_caps, 'User role capabilities should be an array' );
    1148         $this->assertArrayHasKey( 'edit_posts', $role_caps, 'User role capabilities should contain the edit_posts capability' );
    1149     }
    1150 
    1151     /**
    1152      * @ticket 58001
    1153      */
    1154     public function test_user_lazy_capabilities() {
    1155         $id_1   = self::$users['contributor']->ID;
    1156         $user_1 = new WP_User( $id_1 );
    1157 
    1158         $this->assertTrue( isset( $user_1->roles ), 'User roles should be set' );
    1159         $this->assertTrue( isset( $user_1->allcaps ), 'User all capabilities should be set' );
    1160         $this->assertTrue( isset( $user_1->caps ), 'User capabilities should be set' );
    1161         $this->assertIsArray( $user_1->roles, 'User roles should be an array' );
    1162         $this->assertSame( array( 'contributor' ), $user_1->roles, 'User roles should match' );
    1163         $this->assertIsArray( $user_1->allcaps, 'User allcaps should be an array' );
    1164         $this->assertIsArray( $user_1->caps, 'User caps should be an array' );
    1165 
    1166         $caps = $this->getAllCapsAndRoles();
    1167         foreach ( $caps as $cap => $roles ) {
    1168             if ( in_array( 'contributor', $roles, true ) ) {
    1169                 $this->assertTrue( $user_1->has_cap( $cap ), "User should have the {$cap} capability" );
    1170             }
    1171         }
    11721101    }
    11731102
  • trunk/tests/phpunit/tests/user/multisite.php

    r60977 r61037  
    370370        switch_to_blog( $site_id );
    371371        $user = get_user_by( 'id', $user_id );
    372         $this->assertContains( 'subscriber', $user->roles, 'User should have subscriber role' );
    373372        restore_current_blog();
    374373
     
    376375        wpmu_delete_user( $user_id );
    377376
    378         $this->assertContains( 'subscriber', $user->roles, 'User should still have subscriber role' );
     377        $this->assertContains( 'subscriber', $user->roles );
    379378    }
    380379
  • trunk/tests/phpunit/tests/user/query.php

    r60915 r61037  
    163163        add_filter( 'update_user_metadata_cache', array( $filter, 'filter' ), 10, 2 );
    164164
    165         $query = new WP_User_Query(
     165        new WP_User_Query(
    166166            array(
    167167                'include' => self::$author_ids,
     
    169169            )
    170170        );
    171 
    172         $users = $query->get_results();
    173         foreach ( $users as $user ) {
    174             $this->assertIsArray( $user->roles );
    175             foreach ( $user->roles as $role ) {
    176                 $this->assertIsString( $role );
    177             }
    178         }
    179171
    180172        $args      = $filter->get_args();
Note: See TracChangeset for help on using the changeset viewer.