Make WordPress Core

Changeset 61210


Ignore:
Timestamp:
11/11/2025 12:51:01 PM (11 months ago)
Author:
SergeyBiryukov
Message:

Users: Initialize the WP_User::$roles property as a sequential array.

Previously, if any roles were filtered out via array_filter() when assigning the WP_User::$roles property in WP_User::get_role_caps(), the resulting array could contain non-sequential numeric keys, which would then cause it to be treated as an object when JSON-encoded, e.g. in wp_localize_script(), instead of a proper array, breaking client-side expectations.

This commit ensures that the WP_User::$roles property is always treated as an array.

Follow-up to [2703], [2793], [22118].

Props haruncpi, peterwilsoncc, SirLouen, getsyash, wildworks, johnjamesjacoby, SergeyBiryukov.
Fixes #63427.

Location:
trunk
Files:
2 edited

Legend:

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

    r61037 r61210  
    516516                $wp_roles = wp_roles();
    517517
    518                 // Filter out caps that are not role names and assign to $this->roles.
     518                // Select caps that are role names and assign to $this->roles.
    519519                if ( is_array( $this->caps ) ) {
    520                         $this->roles = array_filter( array_keys( $this->caps ), array( $wp_roles, 'is_role' ) );
     520                        $this->roles = array();
     521
     522                        foreach ( $this->caps as $key => $value ) {
     523                                if ( $wp_roles->is_role( $key ) ) {
     524                                        $this->roles[] = $key;
     525                                }
     526                        }
    521527                }
    522528
  • trunk/tests/phpunit/tests/user.php

    r60941 r61210  
    21592159
    21602160        /**
     2161         * Tests that the `WP_User::$roles` property is a sequential array.
     2162         *
     2163         * @ticket 63427
     2164         *
     2165         * @covers WP_User::get_role_caps
     2166         */
     2167        public function test_wp_user_roles_property_is_sequential_array() {
     2168                $user = new WP_User( self::$author_id );
     2169                $this->assertTrue( $this->is_sequential( $user->roles ), 'Initial roles array should be sequential.' );
     2170
     2171                $user->remove_role( 'author' );
     2172                $this->assertIsArray( $user->roles, 'After removing all roles, $user->roles should still be an array.' );
     2173                $this->assertSame( array(), $user->roles, 'After removing all roles, $user->roles should be an empty array.' );
     2174
     2175                $user->add_role( 'author' );
     2176                $user->add_role( 'subscriber' );
     2177                $this->assertSame( array( 'author', 'subscriber' ), $user->roles, 'After adding multiple roles, $user->roles should contain added roles.' );
     2178                $this->assertTrue( $this->is_sequential( $user->roles ), 'After adding multiple roles, $user->roles should still be sequential.' );
     2179        }
     2180
     2181        /**
     2182         * Determines whether an array has sequential numeric keys.
     2183         *
     2184         * @param array $arr The array to check.
     2185         * @return bool True if the array has sequential numeric keys, false otherwise.
     2186         */
     2187        private function is_sequential( array $arr ) {
     2188                return array_keys( $arr ) === range( 0, count( $arr ) - 1 );
     2189        }
     2190
     2191        /**
    21612192         * @ticket 42564
    21622193         */
Note: See TracChangeset for help on using the changeset viewer.