diff --git a/package-lock.json b/package-lock.json index 49acf29c3b..582ae772a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5939,7 +5939,8 @@ }, "kind-of": { "version": "6.0.2", - "resolved": "", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } @@ -10566,7 +10567,8 @@ }, "kind-of": { "version": "6.0.2", - "resolved": "", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } @@ -23584,7 +23586,8 @@ }, "kind-of": { "version": "6.0.2", - "resolved": "", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true } } diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php index 3388078d05..07a389e794 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php @@ -70,6 +70,22 @@ class WP_REST_Block_Renderer_Controller extends WP_REST_Controller { return rest_validate_value_from_schema( $value, $schema ); }, + 'sanitize_callback' => static function ( $value, $request ) { + $block = WP_Block_Type_Registry::get_instance()->get_registered( $request['name'] ); + + if ( ! $block ) { + // This will get rejected in ::get_item(). + return true; + } + + $schema = array( + 'type' => 'object', + 'properties' => $block->get_attributes(), + 'additionalProperties' => false, + ); + + return rest_sanitize_value_from_schema( $value, $schema ); + }, ), 'post_id' => array( 'description' => __( 'ID of the post context.' ), diff --git a/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php b/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php index 423d4a4947..94c7cf8103 100644 --- a/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php +++ b/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php @@ -55,6 +55,15 @@ class REST_Block_Renderer_Controller_Test extends WP_Test_REST_Controller_Testca */ protected static $non_dynamic_block_name = 'core/non-dynamic'; + /** + * Dynamic block with boolean attributes block name. + * + * @since 5.5.0 + * + * @var string + */ + protected static $dynamic_block_with_boolean_attributes_block_name = 'core/dynamic-block-with-boolean-attributes'; + /** * Test API user's ID. * @@ -127,6 +136,7 @@ class REST_Block_Renderer_Controller_Test extends WP_Test_REST_Controller_Testca $this->register_test_block(); $this->register_post_context_test_block(); $this->register_non_dynamic_block(); + $this->register_dynamic_block_with_boolean_attributes(); parent::setUp(); } @@ -139,6 +149,7 @@ class REST_Block_Renderer_Controller_Test extends WP_Test_REST_Controller_Testca WP_Block_Type_Registry::get_instance()->unregister( self::$block_name ); WP_Block_Type_Registry::get_instance()->unregister( self::$context_block_name ); WP_Block_Type_Registry::get_instance()->unregister( self::$non_dynamic_block_name ); + WP_Block_Type_Registry::get_instance()->unregister( self::$dynamic_block_with_boolean_attributes_block_name ); parent::tearDown(); } @@ -195,6 +206,30 @@ class REST_Block_Renderer_Controller_Test extends WP_Test_REST_Controller_Testca register_block_type( self::$non_dynamic_block_name ); } + /** + * Registers the dynamic with boolean attributes block name. + * + * @since 5.5.0 + */ + protected function register_dynamic_block_with_boolean_attributes() { + register_block_type( + self::$dynamic_block_with_boolean_attributes_block_name, + array( + 'attributes' => array( + 'boolean_true_attribute' => array( + 'type' => 'boolean', + 'default' => true, + ), + 'boolean_false_attribute' => array( + 'type' => 'boolean', + 'default' => false, + ), + ), + 'render_callback' => array( $this, 'render_test_block' ), + ) + ); + } + /** * Test render callback. * @@ -522,6 +557,33 @@ class REST_Block_Renderer_Controller_Test extends WP_Test_REST_Controller_Testca $this->assertErrorResponse( 'block_invalid', $response, 404 ); } + /** + * @ticket 50620 + */ + public function test_get_sanitized_attributes_for_dynamic_block_with_boolean_attributes() { + wp_set_current_user( self::$user_id ); + + $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$dynamic_block_with_boolean_attributes_block_name ); + + $attributes = array( + 'boolean_true_attribute' => 'true', + 'boolean_false_attribute' => 'false', + ); + + $expected = array( + 'boolean_true_attribute' => true, + 'boolean_false_attribute' => false, + ); + + $request->set_param( 'context', 'edit' ); + $request->set_param( 'attributes', $attributes ); + $response = rest_get_server()->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + + $this->assertSame( $expected, json_decode( $data['rendered'], true ) ); + } + /** * Get item schema. *