Make WordPress Core

Changeset 58825


Ignore:
Timestamp:
07/29/2024 11:08:18 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.

Props jonsurrell, luisherranz.

Fixes #61741.

Location:
trunk
Files:
2 edited

Legend:

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

    r58729 r58825  
    495495         * @since 6.6.0 The function now adds a warning when the namespace is null, falsy, or the directive value is empty.
    496496         * @since 6.6.0 Removed `default_namespace` and `context` arguments.
     497         * @since 6.6.0 Add support for derived state.
    497498         *
    498499         * @param string|true $directive_value The directive attribute value string or `true` when it's a boolean attribute.
    … …  
    531532                                return null;
    532533                        }
    533                 }
    534 
    535                 if ( $current instanceof Closure ) {
    536                         /*
    537                          * This state getter's namespace is added to the stack so that
    538                          * `state()` or `get_config()` read that namespace when called
    539                          * without specifying one.
    540                          */
    541                         array_push( $this->namespace_stack, $ns );
    542                         try {
    543                                 $current = $current();
    544                         } catch ( Throwable $e ) {
    545                                 _doing_it_wrong(
    546                                         __METHOD__,
    547                                         sprintf(
    548                                                 /* translators: 1: Path pointing to an Interactivity API state property, 2: Namespace for an Interactivity API store. */
    549                                                 __( 'Uncaught error executing a derived state callback with path "%1$s" and namespace "%2$s".' ),
    550                                                 $path,
    551                                                 $ns
    552                                         ),
    553                                         '6.6.0'
    554                                 );
    555                                 return null;
    556                         } finally {
    557                                 // Remove the property's namespace from the stack.
    558                                 array_pop( $this->namespace_stack );
     534
     535                        if ( $current instanceof Closure ) {
     536                                /*
     537                                 * This state getter's namespace is added to the stack so that
     538                                 * `state()` or `get_config()` read that namespace when called
     539                                 * without specifying one.
     540                                 */
     541                                array_push( $this->namespace_stack, $ns );
     542                                try {
     543                                        $current = $current();
     544                                } catch ( Throwable $e ) {
     545                                        _doing_it_wrong(
     546                                                __METHOD__,
     547                                                sprintf(
     548                                                        /* translators: 1: Path pointing to an Interactivity API state property, 2: Namespace for an Interactivity API store. */
     549                                                        __( 'Uncaught error executing a derived state callback with path "%1$s" and namespace "%2$s".' ),
     550                                                        $path,
     551                                                        $ns
     552                                                ),
     553                                                '6.6.0'
     554                                        );
     555                                        return null;
     556                                } finally {
     557                                        // Remove the property's namespace from the stack.
     558                                        array_pop( $this->namespace_stack );
     559                                }
    559560                        }
    560561                }
  • trunk/tests/phpunit/tests/interactivity-api/wpInteractivityAPI.php

    r58729 r58825  
    12981298        }
    12991299
    1300 
    13011300        /**
    13021301         * Tests the `evaluate` method for derived state functions that throw.
    … …  
    13211320                $result = $this->evaluate( 'state.derivedThatThrows' );
    13221321                $this->assertNull( $result );
     1322        }
     1323
     1324        /**
     1325         * Tests the `evaluate` method for derived state intermediate values.
     1326         *
     1327         * @ticket 61741
     1328         *
     1329         * @covers ::evaluate
     1330         */
     1331        public function test_evaluate_derived_state_intermediate() {
     1332                $this->interactivity->state(
     1333                        'myPlugin',
     1334                        array(
     1335                                'derivedState' => function () {
     1336                                        return array( 'property' => 'value' );
     1337                                },
     1338                        )
     1339                );
     1340                $this->set_internal_context_stack();
     1341                $this->set_internal_namespace_stack( 'myPlugin' );
     1342
     1343                $result = $this->evaluate( 'state.derivedState.property' );
     1344                $this->assertSame( 'value', $result );
    13231345        }
    13241346
Note: See TracChangeset for help on using the changeset viewer.