wp/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
--- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php	Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php	Tue Dec 15 13:49:49 2020 +0100
@@ -30,49 +30,72 @@
 	 * Registers the necessary REST API routes, one for each dynamic block.
 	 *
 	 * @since 5.0.0
+	 *
+	 * @see register_rest_route()
 	 */
 	public function register_routes() {
-		$block_types = WP_Block_Type_Registry::get_instance()->get_all_registered();
+		register_rest_route(
+			$this->namespace,
+			'/' . $this->rest_base . '/(?P<name>[a-z0-9-]+/[a-z0-9-]+)',
+			array(
+				'args'   => array(
+					'name' => array(
+						'description' => __( 'Unique registered name for the block.' ),
+						'type'        => 'string',
+					),
+				),
+				array(
+					'methods'             => array( WP_REST_Server::READABLE, WP_REST_Server::CREATABLE ),
+					'callback'            => array( $this, 'get_item' ),
+					'permission_callback' => array( $this, 'get_item_permissions_check' ),
+					'args'                => array(
+						'context'    => $this->get_context_param( array( 'default' => 'view' ) ),
+						'attributes' => array(
+							'description'       => __( 'Attributes for the block' ),
+							'type'              => 'object',
+							'default'           => array(),
+							'validate_callback' => static function ( $value, $request ) {
+								$block = WP_Block_Type_Registry::get_instance()->get_registered( $request['name'] );
 
-		foreach ( $block_types as $block_type ) {
-			if ( ! $block_type->is_dynamic() ) {
-				continue;
-			}
+								if ( ! $block ) {
+									// This will get rejected in ::get_item().
+									return true;
+								}
 
-			register_rest_route(
-				$this->namespace,
-				'/' . $this->rest_base . '/(?P<name>' . $block_type->name . ')',
-				array(
-					'args'   => array(
-						'name' => array(
-							'description' => __( 'Unique registered name for the block.' ),
-							'type'        => 'string',
+								$schema = array(
+									'type'                 => 'object',
+									'properties'           => $block->get_attributes(),
+									'additionalProperties' => false,
+								);
+
+								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.' ),
+							'type'        => 'integer',
 						),
 					),
-					array(
-						'methods'             => WP_REST_Server::READABLE,
-						'callback'            => array( $this, 'get_item' ),
-						'permission_callback' => array( $this, 'get_item_permissions_check' ),
-						'args'                => array(
-							'context'    => $this->get_context_param( array( 'default' => 'view' ) ),
-							'attributes' => array(
-								/* translators: %s is the name of the block */
-								'description'          => sprintf( __( 'Attributes for %s block' ), $block_type->name ),
-								'type'                 => 'object',
-								'additionalProperties' => false,
-								'properties'           => $block_type->get_attributes(),
-								'default'              => array(),
-							),
-							'post_id'    => array(
-								'description' => __( 'ID of the post context.' ),
-								'type'        => 'integer',
-							),
-						),
-					),
-					'schema' => array( $this, 'get_public_item_schema' ),
-				)
-			);
-		}
+				),
+				'schema' => array( $this, 'get_public_item_schema' ),
+			)
+		);
 	}
 
 	/**
@@ -134,10 +157,11 @@
 			// Set up postdata since this will be needed if post_id was set.
 			setup_postdata( $post );
 		}
-		$registry = WP_Block_Type_Registry::get_instance();
-		$block    = $registry->get_registered( $request['name'] );
 
-		if ( null === $block ) {
+		$registry   = WP_Block_Type_Registry::get_instance();
+		$registered = $registry->get_registered( $request['name'] );
+
+		if ( null === $registered || ! $registered->is_dynamic() ) {
 			return new WP_Error(
 				'block_invalid',
 				__( 'Invalid block.' ),
@@ -147,9 +171,21 @@
 			);
 		}
 
+		$attributes = $request->get_param( 'attributes' );
+
+		// Create an array representation simulating the output of parse_blocks.
+		$block = array(
+			'blockName'    => $request['name'],
+			'attrs'        => $attributes,
+			'innerHTML'    => '',
+			'innerContent' => array(),
+		);
+
+		// Render using render_block to ensure all relevant filters are used.
 		$data = array(
-			'rendered' => $block->render( $request->get_param( 'attributes' ) ),
+			'rendered' => render_block( $block ),
 		);
+
 		return rest_ensure_response( $data );
 	}
 
@@ -161,7 +197,11 @@
 	 * @return array Item schema data.
 	 */
 	public function get_item_schema() {
-		return array(
+		if ( $this->schema ) {
+			return $this->schema;
+		}
+
+		$this->schema = array(
 			'$schema'    => 'http://json-schema.org/schema#',
 			'title'      => 'rendered-block',
 			'type'       => 'object',
@@ -174,5 +214,7 @@
 				),
 			),
 		);
+
+		return $this->schema;
 	}
 }