|
1 <?php |
|
2 /** |
|
3 * REST API: WP_REST_Global_Styles_Controller class |
|
4 * |
|
5 * @package WordPress |
|
6 * @subpackage REST_API |
|
7 * @since 5.9.0 |
|
8 */ |
|
9 |
|
10 /** |
|
11 * Base Global Styles REST API Controller. |
|
12 */ |
|
13 class WP_REST_Global_Styles_Controller extends WP_REST_Controller { |
|
14 |
|
15 /** |
|
16 * Post type. |
|
17 * |
|
18 * @since 5.9.0 |
|
19 * @var string |
|
20 */ |
|
21 protected $post_type; |
|
22 |
|
23 /** |
|
24 * Constructor. |
|
25 * @since 5.9.0 |
|
26 */ |
|
27 public function __construct() { |
|
28 $this->namespace = 'wp/v2'; |
|
29 $this->rest_base = 'global-styles'; |
|
30 $this->post_type = 'wp_global_styles'; |
|
31 } |
|
32 |
|
33 /** |
|
34 * Registers the controllers routes. |
|
35 * |
|
36 * @since 5.9.0 |
|
37 * |
|
38 * @return void |
|
39 */ |
|
40 public function register_routes() { |
|
41 register_rest_route( |
|
42 $this->namespace, |
|
43 '/' . $this->rest_base . '/themes/(?P<stylesheet>[\/\s%\w\.\(\)\[\]\@_\-]+)/variations', |
|
44 array( |
|
45 array( |
|
46 'methods' => WP_REST_Server::READABLE, |
|
47 'callback' => array( $this, 'get_theme_items' ), |
|
48 'permission_callback' => array( $this, 'get_theme_items_permissions_check' ), |
|
49 'args' => array( |
|
50 'stylesheet' => array( |
|
51 'description' => __( 'The theme identifier' ), |
|
52 'type' => 'string', |
|
53 ), |
|
54 ), |
|
55 ), |
|
56 ) |
|
57 ); |
|
58 |
|
59 // List themes global styles. |
|
60 register_rest_route( |
|
61 $this->namespace, |
|
62 // The route. |
|
63 sprintf( |
|
64 '/%s/themes/(?P<stylesheet>%s)', |
|
65 $this->rest_base, |
|
66 // Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`. |
|
67 // Excludes invalid directory name characters: `/:<>*?"|`. |
|
68 '[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?' |
|
69 ), |
|
70 array( |
|
71 array( |
|
72 'methods' => WP_REST_Server::READABLE, |
|
73 'callback' => array( $this, 'get_theme_item' ), |
|
74 'permission_callback' => array( $this, 'get_theme_item_permissions_check' ), |
|
75 'args' => array( |
|
76 'stylesheet' => array( |
|
77 'description' => __( 'The theme identifier' ), |
|
78 'type' => 'string', |
|
79 'sanitize_callback' => array( $this, '_sanitize_global_styles_callback' ), |
|
80 ), |
|
81 ), |
|
82 ), |
|
83 ) |
|
84 ); |
|
85 |
|
86 // Lists/updates a single global style variation based on the given id. |
|
87 register_rest_route( |
|
88 $this->namespace, |
|
89 '/' . $this->rest_base . '/(?P<id>[\/\w-]+)', |
|
90 array( |
|
91 array( |
|
92 'methods' => WP_REST_Server::READABLE, |
|
93 'callback' => array( $this, 'get_item' ), |
|
94 'permission_callback' => array( $this, 'get_item_permissions_check' ), |
|
95 'args' => array( |
|
96 'id' => array( |
|
97 'description' => __( 'The id of a template' ), |
|
98 'type' => 'string', |
|
99 'sanitize_callback' => array( $this, '_sanitize_global_styles_callback' ), |
|
100 ), |
|
101 ), |
|
102 ), |
|
103 array( |
|
104 'methods' => WP_REST_Server::EDITABLE, |
|
105 'callback' => array( $this, 'update_item' ), |
|
106 'permission_callback' => array( $this, 'update_item_permissions_check' ), |
|
107 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), |
|
108 ), |
|
109 'schema' => array( $this, 'get_public_item_schema' ), |
|
110 ) |
|
111 ); |
|
112 } |
|
113 |
|
114 /** |
|
115 * Sanitize the global styles ID or stylesheet to decode endpoint. |
|
116 * For example, `wp/v2/global-styles/twentytwentytwo%200.4.0` |
|
117 * would be decoded to `twentytwentytwo 0.4.0`. |
|
118 * |
|
119 * @since 5.9.0 |
|
120 * |
|
121 * @param string $id_or_stylesheet Global styles ID or stylesheet. |
|
122 * @return string Sanitized global styles ID or stylesheet. |
|
123 */ |
|
124 public function _sanitize_global_styles_callback( $id_or_stylesheet ) { |
|
125 return urldecode( $id_or_stylesheet ); |
|
126 } |
|
127 |
|
128 /** |
|
129 * Checks if a given request has access to read a single global style. |
|
130 * |
|
131 * @since 5.9.0 |
|
132 * |
|
133 * @param WP_REST_Request $request Full details about the request. |
|
134 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. |
|
135 */ |
|
136 public function get_item_permissions_check( $request ) { |
|
137 $post = $this->get_post( $request['id'] ); |
|
138 if ( is_wp_error( $post ) ) { |
|
139 return $post; |
|
140 } |
|
141 |
|
142 if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) { |
|
143 return new WP_Error( |
|
144 'rest_forbidden_context', |
|
145 __( 'Sorry, you are not allowed to edit this global style.' ), |
|
146 array( 'status' => rest_authorization_required_code() ) |
|
147 ); |
|
148 } |
|
149 |
|
150 if ( ! $this->check_read_permission( $post ) ) { |
|
151 return new WP_Error( |
|
152 'rest_cannot_view', |
|
153 __( 'Sorry, you are not allowed to view this global style.' ), |
|
154 array( 'status' => rest_authorization_required_code() ) |
|
155 ); |
|
156 } |
|
157 |
|
158 return true; |
|
159 } |
|
160 |
|
161 /** |
|
162 * Checks if a global style can be read. |
|
163 * |
|
164 * @since 5.9.0 |
|
165 * |
|
166 * @param WP_Post $post Post object. |
|
167 * @return bool Whether the post can be read. |
|
168 */ |
|
169 protected function check_read_permission( $post ) { |
|
170 return current_user_can( 'read_post', $post->ID ); |
|
171 } |
|
172 |
|
173 /** |
|
174 * Returns the given global styles config. |
|
175 * |
|
176 * @since 5.9.0 |
|
177 * |
|
178 * @param WP_REST_Request $request The request instance. |
|
179 * |
|
180 * @return WP_REST_Response|WP_Error |
|
181 */ |
|
182 public function get_item( $request ) { |
|
183 $post = $this->get_post( $request['id'] ); |
|
184 if ( is_wp_error( $post ) ) { |
|
185 return $post; |
|
186 } |
|
187 |
|
188 return $this->prepare_item_for_response( $post, $request ); |
|
189 } |
|
190 |
|
191 /** |
|
192 * Checks if a given request has access to write a single global styles config. |
|
193 * |
|
194 * @since 5.9.0 |
|
195 * |
|
196 * @param WP_REST_Request $request Full details about the request. |
|
197 * @return true|WP_Error True if the request has write access for the item, WP_Error object otherwise. |
|
198 */ |
|
199 public function update_item_permissions_check( $request ) { |
|
200 $post = $this->get_post( $request['id'] ); |
|
201 if ( is_wp_error( $post ) ) { |
|
202 return $post; |
|
203 } |
|
204 |
|
205 if ( $post && ! $this->check_update_permission( $post ) ) { |
|
206 return new WP_Error( |
|
207 'rest_cannot_edit', |
|
208 __( 'Sorry, you are not allowed to edit this global style.' ), |
|
209 array( 'status' => rest_authorization_required_code() ) |
|
210 ); |
|
211 } |
|
212 |
|
213 return true; |
|
214 } |
|
215 |
|
216 /** |
|
217 * Checks if a global style can be edited. |
|
218 * |
|
219 * @since 5.9.0 |
|
220 * |
|
221 * @param WP_Post $post Post object. |
|
222 * @return bool Whether the post can be edited. |
|
223 */ |
|
224 protected function check_update_permission( $post ) { |
|
225 return current_user_can( 'edit_post', $post->ID ); |
|
226 } |
|
227 |
|
228 /** |
|
229 * Updates a single global style config. |
|
230 * |
|
231 * @since 5.9.0 |
|
232 * |
|
233 * @param WP_REST_Request $request Full details about the request. |
|
234 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. |
|
235 */ |
|
236 public function update_item( $request ) { |
|
237 $post_before = $this->get_post( $request['id'] ); |
|
238 if ( is_wp_error( $post_before ) ) { |
|
239 return $post_before; |
|
240 } |
|
241 |
|
242 $changes = $this->prepare_item_for_database( $request ); |
|
243 $result = wp_update_post( wp_slash( (array) $changes ), true, false ); |
|
244 if ( is_wp_error( $result ) ) { |
|
245 return $result; |
|
246 } |
|
247 |
|
248 $post = get_post( $request['id'] ); |
|
249 $fields_update = $this->update_additional_fields_for_object( $post, $request ); |
|
250 if ( is_wp_error( $fields_update ) ) { |
|
251 return $fields_update; |
|
252 } |
|
253 |
|
254 wp_after_insert_post( $post, true, $post_before ); |
|
255 |
|
256 $response = $this->prepare_item_for_response( $post, $request ); |
|
257 |
|
258 return rest_ensure_response( $response ); |
|
259 } |
|
260 |
|
261 /** |
|
262 * Prepares a single global styles config for update. |
|
263 * |
|
264 * @since 5.9.0 |
|
265 * |
|
266 * @param WP_REST_Request $request Request object. |
|
267 * @return stdClass Changes to pass to wp_update_post. |
|
268 */ |
|
269 protected function prepare_item_for_database( $request ) { |
|
270 $changes = new stdClass(); |
|
271 $changes->ID = $request['id']; |
|
272 |
|
273 $post = get_post( $request['id'] ); |
|
274 $existing_config = array(); |
|
275 if ( $post ) { |
|
276 $existing_config = json_decode( $post->post_content, true ); |
|
277 $json_decoding_error = json_last_error(); |
|
278 if ( JSON_ERROR_NONE !== $json_decoding_error || ! isset( $existing_config['isGlobalStylesUserThemeJSON'] ) || |
|
279 ! $existing_config['isGlobalStylesUserThemeJSON'] ) { |
|
280 $existing_config = array(); |
|
281 } |
|
282 } |
|
283 |
|
284 if ( isset( $request['styles'] ) || isset( $request['settings'] ) ) { |
|
285 $config = array(); |
|
286 if ( isset( $request['styles'] ) ) { |
|
287 $config['styles'] = $request['styles']; |
|
288 } elseif ( isset( $existing_config['styles'] ) ) { |
|
289 $config['styles'] = $existing_config['styles']; |
|
290 } |
|
291 if ( isset( $request['settings'] ) ) { |
|
292 $config['settings'] = $request['settings']; |
|
293 } elseif ( isset( $existing_config['settings'] ) ) { |
|
294 $config['settings'] = $existing_config['settings']; |
|
295 } |
|
296 $config['isGlobalStylesUserThemeJSON'] = true; |
|
297 $config['version'] = WP_Theme_JSON::LATEST_SCHEMA; |
|
298 $changes->post_content = wp_json_encode( $config ); |
|
299 } |
|
300 |
|
301 // Post title. |
|
302 if ( isset( $request['title'] ) ) { |
|
303 if ( is_string( $request['title'] ) ) { |
|
304 $changes->post_title = $request['title']; |
|
305 } elseif ( ! empty( $request['title']['raw'] ) ) { |
|
306 $changes->post_title = $request['title']['raw']; |
|
307 } |
|
308 } |
|
309 |
|
310 return $changes; |
|
311 } |
|
312 |
|
313 /** |
|
314 * Prepare a global styles config output for response. |
|
315 * |
|
316 * @since 5.9.0 |
|
317 * |
|
318 * @param WP_Post $post Global Styles post object. |
|
319 * @param WP_REST_Request $request Request object. |
|
320 * @return WP_REST_Response Response object. |
|
321 */ |
|
322 public function prepare_item_for_response( $post, $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable |
|
323 $raw_config = json_decode( $post->post_content, true ); |
|
324 $is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON']; |
|
325 $config = array(); |
|
326 if ( $is_global_styles_user_theme_json ) { |
|
327 $config = ( new WP_Theme_JSON( $raw_config, 'custom' ) )->get_raw_data(); |
|
328 } |
|
329 |
|
330 // Base fields for every post. |
|
331 $data = array(); |
|
332 $fields = $this->get_fields_for_response( $request ); |
|
333 |
|
334 if ( rest_is_field_included( 'id', $fields ) ) { |
|
335 $data['id'] = $post->ID; |
|
336 } |
|
337 |
|
338 if ( rest_is_field_included( 'title', $fields ) ) { |
|
339 $data['title'] = array(); |
|
340 } |
|
341 if ( rest_is_field_included( 'title.raw', $fields ) ) { |
|
342 $data['title']['raw'] = $post->post_title; |
|
343 } |
|
344 if ( rest_is_field_included( 'title.rendered', $fields ) ) { |
|
345 add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); |
|
346 |
|
347 $data['title']['rendered'] = get_the_title( $post->ID ); |
|
348 |
|
349 remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) ); |
|
350 } |
|
351 |
|
352 if ( rest_is_field_included( 'settings', $fields ) ) { |
|
353 $data['settings'] = ! empty( $config['settings'] ) && $is_global_styles_user_theme_json ? $config['settings'] : new stdClass(); |
|
354 } |
|
355 |
|
356 if ( rest_is_field_included( 'styles', $fields ) ) { |
|
357 $data['styles'] = ! empty( $config['styles'] ) && $is_global_styles_user_theme_json ? $config['styles'] : new stdClass(); |
|
358 } |
|
359 |
|
360 $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; |
|
361 $data = $this->add_additional_fields_to_object( $data, $request ); |
|
362 $data = $this->filter_response_by_context( $data, $context ); |
|
363 |
|
364 // Wrap the data in a response object. |
|
365 $response = rest_ensure_response( $data ); |
|
366 |
|
367 $links = $this->prepare_links( $post->ID ); |
|
368 $response->add_links( $links ); |
|
369 if ( ! empty( $links['self']['href'] ) ) { |
|
370 $actions = $this->get_available_actions(); |
|
371 $self = $links['self']['href']; |
|
372 foreach ( $actions as $rel ) { |
|
373 $response->add_link( $rel, $self ); |
|
374 } |
|
375 } |
|
376 |
|
377 return $response; |
|
378 } |
|
379 |
|
380 /** |
|
381 * Get the post, if the ID is valid. |
|
382 * |
|
383 * @since 5.9.0 |
|
384 * |
|
385 * @param int $id Supplied ID. |
|
386 * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. |
|
387 */ |
|
388 protected function get_post( $id ) { |
|
389 $error = new WP_Error( |
|
390 'rest_global_styles_not_found', |
|
391 __( 'No global styles config exist with that id.' ), |
|
392 array( 'status' => 404 ) |
|
393 ); |
|
394 |
|
395 $id = (int) $id; |
|
396 if ( $id <= 0 ) { |
|
397 return $error; |
|
398 } |
|
399 |
|
400 $post = get_post( $id ); |
|
401 if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { |
|
402 return $error; |
|
403 } |
|
404 |
|
405 return $post; |
|
406 } |
|
407 |
|
408 |
|
409 /** |
|
410 * Prepares links for the request. |
|
411 * |
|
412 * @since 5.9.0 |
|
413 * |
|
414 * @param integer $id ID. |
|
415 * @return array Links for the given post. |
|
416 */ |
|
417 protected function prepare_links( $id ) { |
|
418 $base = sprintf( '%s/%s', $this->namespace, $this->rest_base ); |
|
419 |
|
420 $links = array( |
|
421 'self' => array( |
|
422 'href' => rest_url( trailingslashit( $base ) . $id ), |
|
423 ), |
|
424 ); |
|
425 |
|
426 return $links; |
|
427 } |
|
428 |
|
429 /** |
|
430 * Get the link relations available for the post and current user. |
|
431 * |
|
432 * @since 5.9.0 |
|
433 * |
|
434 * @return array List of link relations. |
|
435 */ |
|
436 protected function get_available_actions() { |
|
437 $rels = array(); |
|
438 |
|
439 $post_type = get_post_type_object( $this->post_type ); |
|
440 if ( current_user_can( $post_type->cap->publish_posts ) ) { |
|
441 $rels[] = 'https://api.w.org/action-publish'; |
|
442 } |
|
443 |
|
444 return $rels; |
|
445 } |
|
446 |
|
447 /** |
|
448 * Overwrites the default protected title format. |
|
449 * |
|
450 * By default, WordPress will show password protected posts with a title of |
|
451 * "Protected: %s", as the REST API communicates the protected status of a post |
|
452 * in a machine readable format, we remove the "Protected: " prefix. |
|
453 * |
|
454 * @since 5.9.0 |
|
455 * |
|
456 * @return string Protected title format. |
|
457 */ |
|
458 public function protected_title_format() { |
|
459 return '%s'; |
|
460 } |
|
461 |
|
462 /** |
|
463 * Retrieves the query params for the global styles collection. |
|
464 * |
|
465 * @since 5.9.0 |
|
466 * |
|
467 * @return array Collection parameters. |
|
468 */ |
|
469 public function get_collection_params() { |
|
470 return array(); |
|
471 } |
|
472 |
|
473 /** |
|
474 * Retrieves the global styles type' schema, conforming to JSON Schema. |
|
475 * |
|
476 * @since 5.9.0 |
|
477 * |
|
478 * @return array Item schema data. |
|
479 */ |
|
480 public function get_item_schema() { |
|
481 if ( $this->schema ) { |
|
482 return $this->add_additional_fields_schema( $this->schema ); |
|
483 } |
|
484 |
|
485 $schema = array( |
|
486 '$schema' => 'http://json-schema.org/draft-04/schema#', |
|
487 'title' => $this->post_type, |
|
488 'type' => 'object', |
|
489 'properties' => array( |
|
490 'id' => array( |
|
491 'description' => __( 'ID of global styles config.' ), |
|
492 'type' => 'string', |
|
493 'context' => array( 'embed', 'view', 'edit' ), |
|
494 'readonly' => true, |
|
495 ), |
|
496 'styles' => array( |
|
497 'description' => __( 'Global styles.' ), |
|
498 'type' => array( 'object' ), |
|
499 'context' => array( 'view', 'edit' ), |
|
500 ), |
|
501 'settings' => array( |
|
502 'description' => __( 'Global settings.' ), |
|
503 'type' => array( 'object' ), |
|
504 'context' => array( 'view', 'edit' ), |
|
505 ), |
|
506 'title' => array( |
|
507 'description' => __( 'Title of the global styles variation.' ), |
|
508 'type' => array( 'object', 'string' ), |
|
509 'default' => '', |
|
510 'context' => array( 'embed', 'view', 'edit' ), |
|
511 'properties' => array( |
|
512 'raw' => array( |
|
513 'description' => __( 'Title for the global styles variation, as it exists in the database.' ), |
|
514 'type' => 'string', |
|
515 'context' => array( 'view', 'edit', 'embed' ), |
|
516 ), |
|
517 'rendered' => array( |
|
518 'description' => __( 'HTML title for the post, transformed for display.' ), |
|
519 'type' => 'string', |
|
520 'context' => array( 'view', 'edit', 'embed' ), |
|
521 'readonly' => true, |
|
522 ), |
|
523 ), |
|
524 ), |
|
525 ), |
|
526 ); |
|
527 |
|
528 $this->schema = $schema; |
|
529 |
|
530 return $this->add_additional_fields_schema( $this->schema ); |
|
531 } |
|
532 |
|
533 /** |
|
534 * Checks if a given request has access to read a single theme global styles config. |
|
535 * |
|
536 * @since 5.9.0 |
|
537 * |
|
538 * @param WP_REST_Request $request Full details about the request. |
|
539 * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. |
|
540 */ |
|
541 public function get_theme_item_permissions_check( $request ) { |
|
542 // Verify if the current user has edit_theme_options capability. |
|
543 // This capability is required to edit/view/delete templates. |
|
544 if ( ! current_user_can( 'edit_theme_options' ) ) { |
|
545 return new WP_Error( |
|
546 'rest_cannot_manage_global_styles', |
|
547 __( 'Sorry, you are not allowed to access the global styles on this site.' ), |
|
548 array( |
|
549 'status' => rest_authorization_required_code(), |
|
550 ) |
|
551 ); |
|
552 } |
|
553 |
|
554 return true; |
|
555 } |
|
556 |
|
557 /** |
|
558 * Returns the given theme global styles config. |
|
559 * |
|
560 * @since 5.9.0 |
|
561 * |
|
562 * @param WP_REST_Request $request The request instance. |
|
563 * @return WP_REST_Response|WP_Error |
|
564 */ |
|
565 public function get_theme_item( $request ) { |
|
566 if ( wp_get_theme()->get_stylesheet() !== $request['stylesheet'] ) { |
|
567 // This endpoint only supports the active theme for now. |
|
568 return new WP_Error( |
|
569 'rest_theme_not_found', |
|
570 __( 'Theme not found.' ), |
|
571 array( 'status' => 404 ) |
|
572 ); |
|
573 } |
|
574 |
|
575 $theme = WP_Theme_JSON_Resolver::get_merged_data( 'theme' ); |
|
576 $data = array(); |
|
577 $fields = $this->get_fields_for_response( $request ); |
|
578 |
|
579 if ( rest_is_field_included( 'settings', $fields ) ) { |
|
580 $data['settings'] = $theme->get_settings(); |
|
581 } |
|
582 |
|
583 if ( rest_is_field_included( 'styles', $fields ) ) { |
|
584 $raw_data = $theme->get_raw_data(); |
|
585 $data['styles'] = isset( $raw_data['styles'] ) ? $raw_data['styles'] : array(); |
|
586 } |
|
587 |
|
588 $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; |
|
589 $data = $this->add_additional_fields_to_object( $data, $request ); |
|
590 $data = $this->filter_response_by_context( $data, $context ); |
|
591 |
|
592 $response = rest_ensure_response( $data ); |
|
593 |
|
594 $links = array( |
|
595 'self' => array( |
|
596 'href' => rest_url( sprintf( '%s/%s/themes/%s', $this->namespace, $this->rest_base, $request['stylesheet'] ) ), |
|
597 ), |
|
598 ); |
|
599 |
|
600 $response->add_links( $links ); |
|
601 |
|
602 return $response; |
|
603 } |
|
604 |
|
605 /** |
|
606 * Checks if a given request has access to read a single theme global styles config. |
|
607 * |
|
608 * @since 6.0.0 |
|
609 * |
|
610 * @param WP_REST_Request $request Full details about the request. |
|
611 * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. |
|
612 */ |
|
613 public function get_theme_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable |
|
614 // Verify if the current user has edit_theme_options capability. |
|
615 // This capability is required to edit/view/delete templates. |
|
616 if ( ! current_user_can( 'edit_theme_options' ) ) { |
|
617 return new WP_Error( |
|
618 'rest_cannot_manage_global_styles', |
|
619 __( 'Sorry, you are not allowed to access the global styles on this site.' ), |
|
620 array( |
|
621 'status' => rest_authorization_required_code(), |
|
622 ) |
|
623 ); |
|
624 } |
|
625 |
|
626 return true; |
|
627 } |
|
628 |
|
629 /** |
|
630 * Returns the given theme global styles variations. |
|
631 * |
|
632 * @since 6.0.0 |
|
633 * |
|
634 * @param WP_REST_Request $request The request instance. |
|
635 * |
|
636 * @return WP_REST_Response|WP_Error |
|
637 */ |
|
638 public function get_theme_items( $request ) { |
|
639 if ( wp_get_theme()->get_stylesheet() !== $request['stylesheet'] ) { |
|
640 // This endpoint only supports the active theme for now. |
|
641 return new WP_Error( |
|
642 'rest_theme_not_found', |
|
643 __( 'Theme not found.' ), |
|
644 array( 'status' => 404 ) |
|
645 ); |
|
646 } |
|
647 |
|
648 $variations = WP_Theme_JSON_Resolver::get_style_variations(); |
|
649 $response = rest_ensure_response( $variations ); |
|
650 |
|
651 return $response; |
|
652 } |
|
653 } |