From 6b781c682340b4b3096ec5d1aa53a431661d3504 Mon Sep 17 00:00:00 2001 From: danielbachhuber Date: Wed, 21 Nov 2018 14:44:48 +0000 Subject: [PATCH] REST API: Preserve unknown, respect `null` in server-side block rendering. * Skips validation where there is no attribute definition, but keeps the attribute value. Previously, the attribute would be omitted from the attributes passed to `render_callback`. Notably, this resolves an issue where `render_callback` cannot receive a block's `align` and `customClassName` attribute values, since these are defined as a client-side filter. * Validates `null` as a proper value in its own right. Previously, a client implementation of a block could track `{"attribute":null}` as an explicitly empty value, and the server would wrongly initiate defaulting behavior. The new behavior will now only populate a default value if the attribute is not defined at all, including when unset in its being invalid per the attribute schema. Props aduth, noisysocks, youknowriad. See #45145 for the patch, #45098 for the original ticket. Built from https://develop.svn.wordpress.org/branches/5.0@43918 git-svn-id: http://core.svn.wordpress.org/branches/5.0@43750 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-block-type.php | 43 ++++++++++++------- ...lass-wp-rest-block-renderer-controller.php | 1 + wp-includes/version.php | 2 +- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/wp-includes/class-wp-block-type.php b/wp-includes/class-wp-block-type.php index 4247cccffa..6ffda95b4e 100644 --- a/wp-includes/class-wp-block-type.php +++ b/wp-includes/class-wp-block-type.php @@ -123,7 +123,7 @@ class WP_Block_Type { /** * Validates attributes against the current block schema, populating - * defaulted and missing values, and omitting unknown attributes. + * defaulted and missing values. * * @since 5.0.0 * @@ -131,30 +131,41 @@ class WP_Block_Type { * @return array Prepared block attributes. */ public function prepare_attributes_for_render( $attributes ) { + // If there are no attribute definitions for the block type, skip + // processing and return vebatim. if ( ! isset( $this->attributes ) ) { return $attributes; } - $prepared_attributes = array(); - - foreach ( $this->attributes as $attribute_name => $schema ) { - $value = null; - - if ( isset( $attributes[ $attribute_name ] ) ) { - $is_valid = rest_validate_value_from_schema( $attributes[ $attribute_name ], $schema ); - if ( ! is_wp_error( $is_valid ) ) { - $value = rest_sanitize_value_from_schema( $attributes[ $attribute_name ], $schema ); - } + foreach ( $attributes as $attribute_name => $value ) { + // If the attribute is not defined by the block type, it cannot be + // validated. + if ( ! isset( $this->attributes[ $attribute_name ] ) ) { + continue; } - if ( is_null( $value ) && isset( $schema['default'] ) ) { - $value = $schema['default']; - } + $schema = $this->attributes[ $attribute_name ]; - $prepared_attributes[ $attribute_name ] = $value; + // Validate value by JSON schema. An invalid value should revert to + // its default, if one exists. This occurs by virtue of the missing + // attributes loop immediately following. If there is not a default + // assigned, the attribute value should remain unset. + $is_valid = rest_validate_value_from_schema( $value, $schema ); + if ( is_wp_error( $is_valid ) ) { + unset( $attributes[ $attribute_name ] ); + } } - return $prepared_attributes; + // Populate values of any missing attributes for which the block type + // defines a default. + $missing_schema_attributes = array_diff_key( $this->attributes, $attributes ); + foreach ( $missing_schema_attributes as $attribute_name => $schema ) { + if ( isset( $schema['default'] ) ) { + $attributes[ $attribute_name ] = $schema['default']; + } + } + + return $attributes; } /** diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php index f0e1e7db47..681e519313 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php @@ -61,6 +61,7 @@ class WP_REST_Block_Renderer_Controller extends WP_REST_Controller { 'type' => 'object', 'additionalProperties' => false, 'properties' => $block_type->get_attributes(), + 'default' => array(), ), 'post_id' => array( 'description' => __( 'ID of the post context.' ), diff --git a/wp-includes/version.php b/wp-includes/version.php index c6f8cbeb5f..859faf3a80 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '5.0-beta5-43917'; +$wp_version = '5.0-beta5-43918'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.