File size: 5,834 Bytes
51345ad |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
<?php
/**
* Block Renderer REST API: WP_REST_Block_Renderer_Controller class
*
* @package WordPress
* @subpackage REST_API
* @since 5.0.0
*/
/**
* Controller which provides REST endpoint for rendering a block.
*
* @since 5.0.0
*
* @see WP_REST_Controller
*/
class WP_REST_Block_Renderer_Controller extends WP_REST_Controller {
/**
* Constructs the controller.
*
* @since 5.0.0
*/
public function __construct() {
$this->namespace = 'wp/v2';
$this->rest_base = 'block-renderer';
}
/**
* Registers the necessary REST API routes, one for each dynamic block.
*
* @since 5.0.0
*
* @see register_rest_route()
*/
public function register_routes() {
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'] );
if ( ! $block ) {
// This will get rejected in ::get_item().
return true;
}
$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',
),
),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
}
/**
* Checks if a given request has access to read blocks.
*
* @since 5.0.0
*
* @global WP_Post $post Global post object.
*
* @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'] ) ? (int) $request['post_id'] : 0;
if ( $post_id > 0 ) {
$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
*
* @global WP_Post $post Global post object.
*
* @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'] ) ? (int) $request['post_id'] : 0;
if ( $post_id > 0 ) {
$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();
$registered = $registry->get_registered( $request['name'] );
if ( null === $registered || ! $registered->is_dynamic() ) {
return new WP_Error(
'block_invalid',
__( 'Invalid block.' ),
array(
'status' => 404,
)
);
}
$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' => render_block( $block ),
);
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() {
if ( $this->schema ) {
return $this->schema;
}
$this->schema = 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' ),
),
),
);
return $this->schema;
}
}
|