Make WordPress Core

Changeset 58869


Ignore:
Timestamp:
08/08/2024 11:28:30 AM (2 years ago)
Author:
luisherranz
Message:

Interactivity API: Allow server derived state to appear in non-final position

In some cases, derived state returns an associative array. Directives may wish to continue to access properties of the associative array, when using the syntax state.arrayReturnedByClosure.property. This patch continues evaluating the path after the associative array has been returned by the Closure.

Reviewed by adamsilverstein and gziolo.
Merges [58825] to the 6.6 branch.

Props jonsurrell, luisherranz, adamsilverstein, gziolo.

Fixes #61741.

Location:
branches/6.6
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/6.6

  • branches/6.6/src/wp-includes/interactivity-api/class-wp-interactivity-api.php

    r58327 r58869  
    522522         * @since 6.6.0 The function now adds a warning when the namespace is null, falsy, or the directive value is empty.
    523523         * @since 6.6.0 Removed `default_namespace` and `context` arguments.
     524         * @since 6.6.0 Add support for derived state.
    524525         *
    525526         * @param string|true $directive_value The directive attribute value string or `true` when it's a boolean attribute.
     
    558559                                return null;
    559560                        }
    560                 }
    561 
    562                 if ( $current instanceof Closure ) {
    563                         /*
    564                          * This state getter's namespace is added to the stack so that
    565                          * `state()` or `get_config()` read that namespace when called
    566                          * without specifying one.
    567                          */
    568                         array_push( $this->namespace_stack, $ns );
    569                         try {
    570                                 $current = $current();
    571                         } catch ( Throwable $e ) {
    572                                 _doing_it_wrong(
    573                                         __METHOD__,
    574                                         sprintf(
    575                                                 /* translators: 1: Path pointing to an Interactivity API state property, 2: Namespace for an Interactivity API store. */
    576                                                 __( 'Uncaught error executing a derived state callback with path "%1$s" and namespace "%2$s".' ),
    577                                                 $path,
    578                                                 $ns
    579                                         ),
    580                                         '6.6.0'
    581                                 );
    582                                 return null;
    583                         } finally {
    584                                 // Remove the property's namespace from the stack.
    585                                 array_pop( $this->namespace_stack );
     561
     562                        if ( $current instanceof Closure ) {
     563                                /*
     564                                 * This state getter's namespace is added to the stack so that
     565                                 * `state()` or `get_config()` read that namespace when called
     566                                 * without specifying one.
     567                                 */
     568                                array_push( $this->namespace_stack, $ns );
     569                                try {
     570                                        $current = $current();
     571                                } catch ( Throwable $e ) {
     572                                        _doing_it_wrong(
     573                                                __METHOD__,
     574                                                sprintf(
     575                                                        /* translators: 1: Path pointing to an Interactivity API state property, 2: Namespace for an Interactivity API store. */
     576                                                        __( 'Uncaught error executing a derived state callback with path "%1$s" and namespace "%2$s".' ),
     577                                                        $path,
     578                                                        $ns
     579                                                ),
     580                                                '6.6.0'
     581                                        );
     582                                        return null;
     583                                } finally {
     584                                        // Remove the property's namespace from the stack.
     585                                        array_pop( $this->namespace_stack );
     586                                }
    586587                        }
    587588                }
  • branches/6.6/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php

    r58327 r58869  
    14001400        }
    14011401
    1402 
    14031402        /**
    14041403         * Tests the `evaluate` method for derived state functions that throw.
     
    14231422                $result = $this->evaluate( 'state.derivedThatThrows' );
    14241423                $this->assertNull( $result );
     1424        }
     1425
     1426        /**
     1427         * Tests the `evaluate` method for derived state intermediate values.
     1428         *
     1429         * @ticket 61741
     1430         *
     1431         * @covers ::evaluate
     1432         */
     1433        public function test_evaluate_derived_state_intermediate() {
     1434                $this->interactivity->state(
     1435                        'myPlugin',
     1436                        array(
     1437                                'derivedState' => function () {
     1438                                        return array( 'property' => 'value' );
     1439                                },
     1440                        )
     1441                );
     1442                $this->set_internal_context_stack();
     1443                $this->set_internal_namespace_stack( 'myPlugin' );
     1444
     1445                $result = $this->evaluate( 'state.derivedState.property' );
     1446                $this->assertSame( 'value', $result );
    14251447        }
    14261448
Note: See TracChangeset for help on using the changeset viewer.