From f09a40ab655f90e3e4d1600063cd9a81a3016f67 Mon Sep 17 00:00:00 2001 From: Ben Dwyer Date: Fri, 26 Jun 2026 21:34:58 +0100 Subject: [PATCH] Fix rich-text block attribute validation --- src/wp-includes/class-wp-block-type.php | 14 ++++++ tests/phpunit/tests/blocks/wpBlockType.php | 55 ++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/wp-includes/class-wp-block-type.php b/src/wp-includes/class-wp-block-type.php index 86f0ea21a2a3c..18170104cb9c5 100644 --- a/src/wp-includes/class-wp-block-type.php +++ b/src/wp-includes/class-wp-block-type.php @@ -510,6 +510,20 @@ public function prepare_attributes_for_render( $attributes ) { $schema = $this->attributes[ $attribute_name ]; + // Block metadata supports "rich-text" for editor attributes, but + // REST validation expects a valid JSON Schema type. + if ( isset( $schema['type'] ) ) { + if ( 'rich-text' === $schema['type'] ) { + $schema['type'] = 'string'; + } elseif ( is_array( $schema['type'] ) ) { + foreach ( $schema['type'] as $type_index => $type ) { + if ( 'rich-text' === $type ) { + $schema['type'][ $type_index ] = 'string'; + } + } + } + } + // 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 diff --git a/tests/phpunit/tests/blocks/wpBlockType.php b/tests/phpunit/tests/blocks/wpBlockType.php index a73efa8ce8a7d..bb35b672c3dfc 100644 --- a/tests/phpunit/tests/blocks/wpBlockType.php +++ b/tests/phpunit/tests/blocks/wpBlockType.php @@ -254,6 +254,61 @@ public function test_prepare_attributes() { ); } + /** + * @ticket 61406 + */ + public function test_prepare_attributes_validates_rich_text_attributes_as_strings() { + $doing_it_wrong = array(); + $callback = static function ( $function_name ) use ( &$doing_it_wrong ) { + if ( 'rest_validate_value_from_schema' === $function_name ) { + $doing_it_wrong[] = $function_name; + } + }; + + add_action( 'doing_it_wrong_run', $callback ); + + try { + $block_type = new WP_Block_Type( + 'core/fake', + array( + 'attributes' => array( + 'content' => array( + 'type' => 'rich-text', + ), + 'caption' => array( + 'type' => 'rich-text', + 'default' => 'Default caption', + ), + 'nullableContent' => array( + 'type' => array( 'rich-text', 'null' ), + ), + ), + ) + ); + + $prepared_attributes = $block_type->prepare_attributes_for_render( + array( + 'content' => 'include', + 'caption' => 5, + 'nullableContent' => 'nullable include', + ) + ); + } finally { + remove_action( 'doing_it_wrong_run', $callback ); + } + + $this->assertSame( 'include', $prepared_attributes['content'] ); + $this->assertSame( 'Default caption', $prepared_attributes['caption'] ); + $this->assertSame( 'nullable include', $prepared_attributes['nullableContent'] ); + $this->assertSame( + array(), + $doing_it_wrong, + 'rest_validate_value_from_schema() should not emit _doing_it_wrong() for rich-text attributes.' + ); + $this->assertSame( 'rich-text', $block_type->attributes['content']['type'] ); + $this->assertSame( array( 'rich-text', 'null' ), $block_type->attributes['nullableContent']['type'] ); + } + /** * @ticket 45145 */