Make WordPress Core

Changeset 58320


Ignore:
Timestamp:
06/04/2024 06:56:25 AM (2 years ago)
Author:
gziolo
Message:

Interactivity API: Some property access does not work well in server directives

Ensures property access in PHP works for object properties or associative array values correctly when processing Interactivity API directives.

Props narenin, cbravobernal, jonsurrell, gziolo, czapla.
Fixes #61039.

Location:
trunk
Files:
2 edited

Legend:

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

    r58159 r58320  
    424424                $current       = $store;
    425425                foreach ( $path_segments as $path_segment ) {
    426                         if ( isset( $current[ $path_segment ] ) ) {
     426                        if ( ( is_array( $current ) || $current instanceof ArrayAccess ) && isset( $current[ $path_segment ] ) ) {
    427427                                $current = $current[ $path_segment ];
     428                        } elseif ( is_object( $current ) && isset( $current->$path_segment ) ) {
     429                                $current = $current->$path_segment;
    428430                        } else {
    429431                                return null;
  • trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php

    r58159 r58320  
    817817        private function evaluate( $directive_value ) {
    818818                $generate_state = function ( $name ) {
     819                        $obj       = new stdClass();
     820                        $obj->prop = $name;
    819821                        return array(
    820                                 'key'    => $name,
    821                                 'nested' => array( 'key' => $name . '-nested' ),
     822                                'key'       => $name,
     823                                'nested'    => array( 'key' => $name . '-nested' ),
     824                                'obj'       => $obj,
     825                                'arrAccess' => new class() implements ArrayAccess {
     826                                        #[\ReturnTypeWillChange]
     827                                        public function offsetExists( $offset ) {
     828                                                return true;
     829                                        }
     830
     831                                        public function offsetGet( $offset ): string {
     832                                                return $offset;
     833                                        }
     834
     835                                        public function offsetSet( $offset, $value ): void {}
     836
     837                                        public function offsetUnset( $offset ): void {}
     838                                },
    822839                        );
    823840                };
     
    827844                        'myPlugin'    => $generate_state( 'myPlugin-context' ),
    828845                        'otherPlugin' => $generate_state( 'otherPlugin-context' ),
     846                        'obj'         => new stdClass(),
    829847                );
    830848                $evaluate = new ReflectionMethod( $this->interactivity, 'evaluate' );
     
    852870                $result = $this->evaluate( 'otherPlugin::context.key' );
    853871                $this->assertEquals( 'otherPlugin-context', $result );
     872
     873                $result = $this->evaluate( 'state.obj.prop' );
     874                $this->assertSame( 'myPlugin-state', $result );
     875
     876                $result = $this->evaluate( 'state.arrAccess.1' );
     877                $this->assertSame( '1', $result );
    854878        }
    855879
Note: See TracChangeset for help on using the changeset viewer.