diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php --- 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[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' . $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; } }