Interactivity API: Support length property on strings and arrays on the server

The Interactivity API tries to align client and server rendering so that the behavior is the same. Adds missing handling for `.length` to directives processing on the server on strings and numeric arrays which is inherently supported through JavaScript language on the client.

Props jonsurrell, gziolo, luisherranz.
Fixes #62582.


Built from https://develop.svn.wordpress.org/trunk@59477


git-svn-id: http://core.svn.wordpress.org/trunk@58863 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
gziolo 2024-12-02 08:10:17 +00:00
parent 8f8ffaab84
commit 369a675488
2 changed files with 31 additions and 1 deletions

View File

@ -579,6 +579,36 @@ final class WP_Interactivity_API {
$path_segments = explode( '.', $path ); $path_segments = explode( '.', $path );
$current = $store; $current = $store;
foreach ( $path_segments as $path_segment ) { foreach ( $path_segments as $path_segment ) {
/*
* Special case for numeric arrays and strings. Add length
* property mimicking JavaScript behavior.
*
* @since 6.8.0
*/
if ( 'length' === $path_segment ) {
if ( is_array( $current ) && array_is_list( $current ) ) {
$current = count( $current );
break;
}
if ( is_string( $current ) ) {
/*
* Differences in encoding between PHP strings and
* JavaScript mean that it's complicated to calculate
* the string length JavaScript would see from PHP.
* `strlen` is a reasonable approximation.
*
* Users that desire a more precise length likely have
* more precise needs than "bytelength" and should
* implement their own length calculation in derived
* state taking into account encoding and their desired
* output (codepoints, graphemes, bytes, etc.).
*/
$current = strlen( $current );
break;
}
}
if ( ( is_array( $current ) || $current instanceof ArrayAccess ) && isset( $current[ $path_segment ] ) ) { if ( ( is_array( $current ) || $current instanceof ArrayAccess ) && isset( $current[ $path_segment ] ) ) {
$current = $current[ $path_segment ]; $current = $current[ $path_segment ];
} elseif ( is_object( $current ) && isset( $current->$path_segment ) ) { } elseif ( is_object( $current ) && isset( $current->$path_segment ) ) {

View File

@ -16,7 +16,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '6.8-alpha-59476'; $wp_version = '6.8-alpha-59477';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.