[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * REST API: WP_REST_Block_Patterns_Controller class 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 6.0.0 8 */ 9 10 /** 11 * Core class used to access block patterns via the REST API. 12 * 13 * @since 6.0.0 14 * 15 * @see WP_REST_Controller 16 */ 17 class WP_REST_Block_Patterns_Controller extends WP_REST_Controller { 18 19 /** 20 * Defines whether remote patterns should be loaded. 21 * 22 * @since 6.0.0 23 * @var bool 24 */ 25 private $remote_patterns_loaded; 26 27 /** 28 * An array that maps old categories names to new ones. 29 * 30 * @since 6.2.0 31 * @var array 32 */ 33 protected static $categories_migration = array( 34 'buttons' => 'call-to-action', 35 'columns' => 'text', 36 'query' => 'posts', 37 ); 38 39 /** 40 * Constructs the controller. 41 * 42 * @since 6.0.0 43 */ 44 public function __construct() { 45 $this->namespace = 'wp/v2'; 46 $this->rest_base = 'block-patterns/patterns'; 47 } 48 49 /** 50 * Registers the routes for the objects of the controller. 51 * 52 * @since 6.0.0 53 */ 54 public function register_routes() { 55 register_rest_route( 56 $this->namespace, 57 '/' . $this->rest_base, 58 array( 59 array( 60 'methods' => WP_REST_Server::READABLE, 61 'callback' => array( $this, 'get_items' ), 62 'permission_callback' => array( $this, 'get_items_permissions_check' ), 63 ), 64 'schema' => array( $this, 'get_public_item_schema' ), 65 ) 66 ); 67 } 68 69 /** 70 * Checks whether a given request has permission to read block patterns. 71 * 72 * @since 6.0.0 73 * 74 * @param WP_REST_Request $request Full details about the request. 75 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. 76 */ 77 public function get_items_permissions_check( $request ) { 78 if ( current_user_can( 'edit_posts' ) ) { 79 return true; 80 } 81 82 foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { 83 if ( current_user_can( $post_type->cap->edit_posts ) ) { 84 return true; 85 } 86 } 87 88 return new WP_Error( 89 'rest_cannot_view', 90 __( 'Sorry, you are not allowed to view the registered block patterns.' ), 91 array( 'status' => rest_authorization_required_code() ) 92 ); 93 } 94 95 /** 96 * Retrieves all block patterns. 97 * 98 * @since 6.0.0 99 * @since 6.2.0 Added migration for old core pattern categories to the new ones. 100 * 101 * @param WP_REST_Request $request Full details about the request. 102 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 103 */ 104 public function get_items( $request ) { 105 if ( ! $this->remote_patterns_loaded ) { 106 // Load block patterns from w.org. 107 _load_remote_block_patterns(); // Patterns with the `core` keyword. 108 _load_remote_featured_patterns(); // Patterns in the `featured` category. 109 _register_remote_theme_patterns(); // Patterns requested by current theme. 110 111 $this->remote_patterns_loaded = true; 112 } 113 114 $response = array(); 115 $patterns = WP_Block_Patterns_Registry::get_instance()->get_all_registered(); 116 foreach ( $patterns as $pattern ) { 117 $migrated_pattern = $this->migrate_pattern_categories( $pattern ); 118 $prepared_pattern = $this->prepare_item_for_response( $migrated_pattern, $request ); 119 $response[] = $this->prepare_response_for_collection( $prepared_pattern ); 120 } 121 return rest_ensure_response( $response ); 122 } 123 124 /** 125 * Migrates old core pattern categories to the new categories. 126 * 127 * Core pattern categories are revamped. Migration is needed to ensure 128 * backwards compatibility. 129 * 130 * @since 6.2.0 131 * 132 * @param array $pattern Raw pattern as registered, before applying any changes. 133 * @return array Migrated pattern. 134 */ 135 protected function migrate_pattern_categories( $pattern ) { 136 // No categories to migrate. 137 if ( 138 ! isset( $pattern['categories'] ) || 139 ! is_array( $pattern['categories'] ) 140 ) { 141 return $pattern; 142 } 143 144 foreach ( $pattern['categories'] as $index => $category ) { 145 // If the category exists as a key, then it needs migration. 146 if ( isset( static::$categories_migration[ $category ] ) ) { 147 $pattern['categories'][ $index ] = static::$categories_migration[ $category ]; 148 } 149 } 150 151 return $pattern; 152 } 153 154 /** 155 * Prepare a raw block pattern before it gets output in a REST API response. 156 * 157 * @since 6.0.0 158 * @since 6.3.0 Added `source` property. 159 * 160 * @param array $item Raw pattern as registered, before any changes. 161 * @param WP_REST_Request $request Request object. 162 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 163 */ 164 public function prepare_item_for_response( $item, $request ) { 165 // Resolve pattern blocks so they don't need to be resolved client-side 166 // in the editor, improving performance. 167 $blocks = parse_blocks( $item['content'] ); 168 $blocks = resolve_pattern_blocks( $blocks ); 169 $item['content'] = serialize_blocks( $blocks ); 170 171 $fields = $this->get_fields_for_response( $request ); 172 $keys = array( 173 'name' => 'name', 174 'title' => 'title', 175 'content' => 'content', 176 'description' => 'description', 177 'viewportWidth' => 'viewport_width', 178 'inserter' => 'inserter', 179 'categories' => 'categories', 180 'keywords' => 'keywords', 181 'blockTypes' => 'block_types', 182 'postTypes' => 'post_types', 183 'templateTypes' => 'template_types', 184 'source' => 'source', 185 ); 186 $data = array(); 187 foreach ( $keys as $item_key => $rest_key ) { 188 if ( isset( $item[ $item_key ] ) && rest_is_field_included( $rest_key, $fields ) ) { 189 $data[ $rest_key ] = $item[ $item_key ]; 190 } 191 } 192 193 $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; 194 $data = $this->add_additional_fields_to_object( $data, $request ); 195 $data = $this->filter_response_by_context( $data, $context ); 196 return rest_ensure_response( $data ); 197 } 198 199 /** 200 * Retrieves the block pattern schema, conforming to JSON Schema. 201 * 202 * @since 6.0.0 203 * @since 6.3.0 Added `source` property. 204 * 205 * @return array Item schema data. 206 */ 207 public function get_item_schema() { 208 if ( $this->schema ) { 209 return $this->add_additional_fields_schema( $this->schema ); 210 } 211 212 $schema = array( 213 '$schema' => 'http://json-schema.org/draft-04/schema#', 214 'title' => 'block-pattern', 215 'type' => 'object', 216 'properties' => array( 217 'name' => array( 218 'description' => __( 'The pattern name.' ), 219 'type' => 'string', 220 'readonly' => true, 221 'context' => array( 'view', 'edit', 'embed' ), 222 ), 223 'title' => array( 224 'description' => __( 'The pattern title, in human readable format.' ), 225 'type' => 'string', 226 'readonly' => true, 227 'context' => array( 'view', 'edit', 'embed' ), 228 ), 229 'content' => array( 230 'description' => __( 'The pattern content.' ), 231 'type' => 'string', 232 'readonly' => true, 233 'context' => array( 'view', 'edit', 'embed' ), 234 ), 235 'description' => array( 236 'description' => __( 'The pattern detailed description.' ), 237 'type' => 'string', 238 'readonly' => true, 239 'context' => array( 'view', 'edit', 'embed' ), 240 ), 241 'viewport_width' => array( 242 'description' => __( 'The pattern viewport width for inserter preview.' ), 243 'type' => 'number', 244 'readonly' => true, 245 'context' => array( 'view', 'edit', 'embed' ), 246 ), 247 'inserter' => array( 248 'description' => __( 'Determines whether the pattern is visible in inserter.' ), 249 'type' => 'boolean', 250 'readonly' => true, 251 'context' => array( 'view', 'edit', 'embed' ), 252 ), 253 'categories' => array( 254 'description' => __( 'The pattern category slugs.' ), 255 'type' => 'array', 256 'readonly' => true, 257 'context' => array( 'view', 'edit', 'embed' ), 258 ), 259 'keywords' => array( 260 'description' => __( 'The pattern keywords.' ), 261 'type' => 'array', 262 'readonly' => true, 263 'context' => array( 'view', 'edit', 'embed' ), 264 ), 265 'block_types' => array( 266 'description' => __( 'Block types that the pattern is intended to be used with.' ), 267 'type' => 'array', 268 'readonly' => true, 269 'context' => array( 'view', 'edit', 'embed' ), 270 ), 271 'post_types' => array( 272 'description' => __( 'An array of post types that the pattern is restricted to be used with.' ), 273 'type' => 'array', 274 'readonly' => true, 275 'context' => array( 'view', 'edit', 'embed' ), 276 ), 277 'template_types' => array( 278 'description' => __( 'An array of template types where the pattern fits.' ), 279 'type' => 'array', 280 'readonly' => true, 281 'context' => array( 'view', 'edit', 'embed' ), 282 ), 283 'source' => array( 284 'description' => __( 'Where the pattern comes from e.g. core' ), 285 'type' => 'string', 286 'readonly' => true, 287 'context' => array( 'view', 'edit', 'embed' ), 288 'enum' => array( 289 'core', 290 'plugin', 291 'theme', 292 'pattern-directory/core', 293 'pattern-directory/theme', 294 'pattern-directory/featured', 295 ), 296 ), 297 ), 298 ); 299 300 $this->schema = $schema; 301 302 return $this->add_additional_fields_schema( $this->schema ); 303 } 304 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |