diff --git a/wp-includes/post.php b/wp-includes/post.php index 8e70573518..302d2210d5 100644 --- a/wp-includes/post.php +++ b/wp-includes/post.php @@ -238,6 +238,9 @@ function create_initial_post_types() { 'show_ui' => true, 'show_in_menu' => false, 'rewrite' => false, + 'show_in_rest' => true, + 'rest_base' => 'blocks', + 'rest_controller_class' => 'WP_REST_Blocks_Controller', 'capability_type' => 'block', 'capabilities' => array( // You need to be able to edit posts, in order to read blocks in their raw form. diff --git a/wp-includes/rest-api.php b/wp-includes/rest-api.php index ebc3d9a053..e1d8919c8d 100644 --- a/wp-includes/rest-api.php +++ b/wp-includes/rest-api.php @@ -250,6 +250,10 @@ function create_initial_rest_routes() { $controller = new WP_REST_Search_Controller( $search_handlers ); $controller->register_routes(); + // Block Renderer. + $controller = new WP_REST_Block_Renderer_Controller; + $controller->register_routes(); + // Settings. $controller = new WP_REST_Settings_Controller; $controller->register_routes(); @@ -257,6 +261,7 @@ function create_initial_rest_routes() { // Themes. $controller = new WP_REST_Themes_Controller; $controller->register_routes(); + } /** diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php new file mode 100644 index 0000000000..a4f17283c5 --- /dev/null +++ b/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php @@ -0,0 +1,177 @@ +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(), + ), + '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' ), + ), + ), + ); + } +} diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php new file mode 100644 index 0000000000..66a2e7adad --- /dev/null +++ b/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php @@ -0,0 +1,39 @@ +post_type ); + if ( ! current_user_can( $post_type->cap->read_post, $post->ID ) ) { + return false; + } + + return parent::check_read_permission( $post ); + } +} diff --git a/wp-includes/version.php b/wp-includes/version.php index d5e523a146..72fce4fbae 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '5.0-alpha-43804'; +$wp_version = '5.0-alpha-43805'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. diff --git a/wp-settings.php b/wp-settings.php index f711b9167b..efefa1b214 100644 --- a/wp-settings.php +++ b/wp-settings.php @@ -235,6 +235,8 @@ require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-terms-controller.p require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-users-controller.php' ); require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-comments-controller.php' ); require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-search-controller.php' ); +require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-blocks-controller.php' ); +require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-renderer-controller.php' ); require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-settings-controller.php' ); require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-themes-controller.php' ); require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php' );