diff -r c7c34916027a -r 177826044cd9 wp/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php Mon Oct 14 18:28:13 2019 +0200 @@ -0,0 +1,178 @@ +namespace = 'wp/v2'; + $this->rest_base = 'block-renderer'; + } + + /** + * Registers the necessary REST API routes, one for each dynamic block. + * + * @since 5.0.0 + */ + public function register_routes() { + $block_types = WP_Block_Type_Registry::get_instance()->get_all_registered(); + + foreach ( $block_types as $block_type ) { + if ( ! $block_type->is_dynamic() ) { + continue; + } + + 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', + ), + ), + 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' ), + ) + ); + } + } + + /** + * Checks if a given request has access to read blocks. + * + * @since 5.0.0 + * + * @param WP_REST_Request $request Request. + * @return true|WP_Error True if the request has read access, WP_Error object otherwise. + */ + public function get_item_permissions_check( $request ) { + global $post; + + $post_id = isset( $request['post_id'] ) ? intval( $request['post_id'] ) : 0; + + if ( 0 < $post_id ) { + $post = get_post( $post_id ); + + if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) { + return new WP_Error( + 'block_cannot_read', + __( 'Sorry, you are not allowed to read blocks of this post.' ), + array( + 'status' => rest_authorization_required_code(), + ) + ); + } + } else { + if ( ! current_user_can( 'edit_posts' ) ) { + return new WP_Error( + 'block_cannot_read', + __( 'Sorry, you are not allowed to read blocks as this user.' ), + array( + 'status' => rest_authorization_required_code(), + ) + ); + } + } + + return true; + } + + /** + * Returns block output from block's registered render_callback. + * + * @since 5.0.0 + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. + */ + public function get_item( $request ) { + global $post; + + $post_id = isset( $request['post_id'] ) ? intval( $request['post_id'] ) : 0; + + if ( 0 < $post_id ) { + $post = get_post( $post_id ); + + // 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 ) { + return new WP_Error( + 'block_invalid', + __( 'Invalid block.' ), + array( + 'status' => 404, + ) + ); + } + + $data = array( + 'rendered' => $block->render( $request->get_param( 'attributes' ) ), + ); + return rest_ensure_response( $data ); + } + + /** + * Retrieves block's output schema, conforming to JSON Schema. + * + * @since 5.0.0 + * + * @return array Item schema data. + */ + public function get_item_schema() { + return array( + '$schema' => 'http://json-schema.org/schema#', + 'title' => 'rendered-block', + 'type' => 'object', + 'properties' => array( + 'rendered' => array( + 'description' => __( 'The rendered block.' ), + 'type' => 'string', + 'required' => true, + 'context' => array( 'edit' ), + ), + ), + ); + } +}