PluginProbe
Gutenberg / 10.3.0
Gutenberg v10.3.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / class-wp-rest-widgets-controller.php

class-wp-rest-widgets-controller.php in Gutenberg 10.3.0, at lib/class-wp-rest-widgets-controller.php

733 lines 22.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST API: WP_REST_Widgets_Controller class
4 *
5 * @package WordPress
6 * @subpackage REST_API
7 * @since 5.6.0
8 */
9
10 /**
11 * Core class to access widgets via the REST API.
12 *
13 * @since 5.6.0
14 *
15 * @see WP_REST_Controller
16 */
17 class WP_REST_Widgets_Controller extends WP_REST_Controller {
18
19 /**
20 * Widgets controller constructor.
21 *
22 * @since 5.6.0
23 */
24 public function __construct() {
25 $this->namespace = 'wp/v2';
26 $this->rest_base = 'widgets';
27 }
28
29 /**
30 * Registers the widget routes for the controller.
31 *
32 * @since 5.6.0
33 */
34 public function register_routes() {
35 register_rest_route(
36 $this->namespace,
37 $this->rest_base,
38 array(
39 array(
40 'methods' => WP_REST_Server::READABLE,
41 'callback' => array( $this, 'get_items' ),
42 'permission_callback' => array( $this, 'get_items_permissions_check' ),
43 'args' => $this->get_collection_params(),
44 ),
45 array(
46 'methods' => WP_REST_Server::CREATABLE,
47 'callback' => array( $this, 'create_item' ),
48 'permission_callback' => array( $this, 'create_item_permissions_check' ),
49 'args' => $this->get_endpoint_args_for_item_schema(),
50 ),
51 'allow_batch' => array( 'v1' => true ),
52 'schema' => array( $this, 'get_public_item_schema' ),
53 )
54 );
55
56 register_rest_route(
57 $this->namespace,
58 $this->rest_base . '/(?P<id>[\w\-]+)',
59 array(
60 array(
61 'methods' => WP_REST_Server::READABLE,
62 'callback' => array( $this, 'get_item' ),
63 'permission_callback' => array( $this, 'get_item_permissions_check' ),
64 'args' => array(
65 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
66 ),
67 ),
68 array(
69 'methods' => WP_REST_Server::EDITABLE,
70 'callback' => array( $this, 'update_item' ),
71 'permission_callback' => array( $this, 'update_item_permissions_check' ),
72 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
73 ),
74 array(
75 'methods' => WP_REST_Server::DELETABLE,
76 'callback' => array( $this, 'delete_item' ),
77 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
78 'args' => array(
79 'force' => array(
80 'description' => __( 'Whether to force removal of the widget, or move it to the inactive sidebar.', 'gutenberg' ),
81 'type' => 'boolean',
82 ),
83 ),
84 ),
85 'allow_batch' => array( 'v1' => true ),
86 'schema' => array( $this, 'get_public_item_schema' ),
87 )
88 );
89 }
90
91 /**
92 * Checks if a given request has access to get widgets.
93 *
94 * @since 5.6.0
95 *
96 * @param WP_REST_Request $request Full details about the request.
97 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
98 */
99 public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
100 return $this->permissions_check();
101 }
102
103 /**
104 * Retrieves a collection of widgets.
105 *
106 * @since 5.6.0
107 *
108 * @param WP_REST_Request $request Full details about the request.
109 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
110 */
111 public function get_items( $request ) {
112 $prepared = array();
113
114 foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) {
115 if ( isset( $request['sidebar'] ) && $sidebar_id !== $request['sidebar'] ) {
116 continue;
117 }
118
119 foreach ( $widget_ids as $widget_id ) {
120 $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request );
121
122 if ( ! is_wp_error( $response ) ) {
123 $prepared[] = $this->prepare_response_for_collection( $response );
124 }
125 }
126 }
127
128 return new WP_REST_Response( $prepared );
129 }
130
131 /**
132 * Checks if a given request has access to get a widget.
133 *
134 * @since 5.6.0
135 *
136 * @param WP_REST_Request $request Full details about the request.
137 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
138 */
139 public function get_item_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
140 return $this->permissions_check();
141 }
142
143 /**
144 * Gets an individual widget.
145 *
146 * @since 5.6.0
147 *
148 * @param WP_REST_Request $request Full details about the request.
149 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
150 */
151 public function get_item( $request ) {
152 $widget_id = $request['id'];
153 $sidebar_id = $this->find_widgets_sidebar( $widget_id );
154
155 if ( is_wp_error( $sidebar_id ) ) {
156 return $sidebar_id;
157 }
158
159 return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request );
160 }
161
162 /**
163 * Checks if a given request has access to create widgets.
164 *
165 * @since 5.6.0
166 *
167 * @param WP_REST_Request $request Full details about the request.
168 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
169 */
170 public function create_item_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
171 return $this->permissions_check();
172 }
173
174 /**
175 * Creates a widget.
176 *
177 * @since 5.6.0
178 *
179 * @param WP_REST_Request $request Full details about the request.
180 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
181 */
182 public function create_item( $request ) {
183 $sidebar_id = $request['sidebar'];
184
185 $widget_id = $this->save_widget( $request );
186
187 if ( is_wp_error( $widget_id ) ) {
188 return $widget_id;
189 }
190
191 gutenberg_assign_widget_to_sidebar( $widget_id, $sidebar_id );
192
193 $request['context'] = 'edit';
194
195 $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request );
196
197 if ( is_wp_error( $response ) ) {
198 return $response;
199 }
200
201 $response->set_status( 201 );
202
203 return $response;
204 }
205
206 /**
207 * Checks if a given request has access to update widgets.
208 *
209 * @since 5.6.0
210 *
211 * @param WP_REST_Request $request Full details about the request.
212 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
213 */
214 public function update_item_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
215 return $this->permissions_check();
216 }
217
218 /**
219 * Updates an existing widget.
220 *
221 * @since 5.6.0
222 *
223 * @param WP_REST_Request $request Full details about the request.
224 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
225 */
226 public function update_item( $request ) {
227 $widget_id = $request['id'];
228 $sidebar_id = $this->find_widgets_sidebar( $widget_id );
229
230 // Allow sidebar to be unset or missing when widget is not a WP_Widget.
231 $parsed_id = gutenberg_parse_widget_id( $widget_id );
232 $widget_object = gutenberg_get_widget_object( $parsed_id['id_base'] );
233 if ( is_wp_error( $sidebar_id ) && $widget_object ) {
234 return $sidebar_id;
235 }
236
237 if (
238 $request->has_param( 'settings' ) || // Backwards compatibility. TODO: Remove.
239 $request->has_param( 'instance' ) ||
240 $request->has_param( 'form_data' )
241 ) {
242 $maybe_error = $this->save_widget( $request );
243 if ( is_wp_error( $maybe_error ) ) {
244 return $maybe_error;
245 }
246 }
247
248 if ( $request->has_param( 'sidebar' ) ) {
249 if ( $sidebar_id !== $request['sidebar'] ) {
250 $sidebar_id = $request['sidebar'];
251 gutenberg_assign_widget_to_sidebar( $widget_id, $sidebar_id );
252 }
253 }
254
255 $request['context'] = 'edit';
256
257 return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request );
258 }
259
260 /**
261 * Checks if a given request has access to delete widgets.
262 *
263 * @since 5.6.0
264 *
265 * @param WP_REST_Request $request Full details about the request.
266 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
267 */
268 public function delete_item_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
269 return $this->permissions_check();
270 }
271
272 /**
273 * Deletes a widget.
274 *
275 * @since 5.6.0
276 *
277 * @param WP_REST_Request $request Full details about the request.
278 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
279 */
280 public function delete_item( $request ) {
281 $widget_id = $request['id'];
282 $sidebar_id = $this->find_widgets_sidebar( $widget_id );
283
284 if ( is_wp_error( $sidebar_id ) ) {
285 return $sidebar_id;
286 }
287
288 $request['context'] = 'edit';
289
290 if ( $request['force'] ) {
291 $prepared = $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request );
292 gutenberg_assign_widget_to_sidebar( $widget_id, '' );
293 $prepared->set_data(
294 array(
295 'deleted' => true,
296 'previous' => $prepared->get_data(),
297 )
298 );
299 } else {
300 gutenberg_assign_widget_to_sidebar( $widget_id, 'wp_inactive_widgets' );
301 $prepared = $this->prepare_item_for_response(
302 array(
303 'sidebar_id' => 'wp_inactive_widgets',
304 'widget_id' => $widget_id,
305 ),
306 $request
307 );
308 }
309
310 return $prepared;
311 }
312
313 /**
314 * Performs a permissions check for managing widgets.
315 *
316 * @since 5.6.0
317 *
318 * @return true|WP_Error
319 */
320 protected function permissions_check() {
321 if ( ! current_user_can( 'edit_theme_options' ) ) {
322 return new WP_Error(
323 'rest_cannot_manage_widgets',
324 __( 'Sorry, you are not allowed to manage widgets on this site.', 'gutenberg' ),
325 array(
326 'status' => rest_authorization_required_code(),
327 )
328 );
329 }
330
331 return true;
332 }
333
334 /**
335 * Finds the sidebar a widget belongs to.
336 *
337 * @since 5.6.0
338 *
339 * @param string $widget_id The widget id to search for.
340 * @return string|WP_Error The found sidebar id, or a WP_Error instance if it does not exist.
341 */
342 protected function find_widgets_sidebar( $widget_id ) {
343 foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) {
344 foreach ( $widget_ids as $maybe_widget_id ) {
345 if ( $maybe_widget_id === $widget_id ) {
346 return (string) $sidebar_id;
347 }
348 }
349 }
350
351 return new WP_Error( 'rest_widget_not_found', __( 'No widget was found with that id.', 'gutenberg' ), array( 'status' => 404 ) );
352 }
353
354 /**
355 * Saves the widget in the request object.
356 *
357 * @since 5.6.0
358 *
359 * @param WP_REST_Request $request Full details about the request.
360 *
361 * @return string The saved widget ID.
362 */
363 protected function save_widget( $request ) {
364 global $wp_registered_widget_updates;
365
366 require_once ABSPATH . 'wp-admin/includes/widgets.php'; // For next_widget_id_number().
367
368 if ( isset( $request['id'] ) ) {
369 // Saving an existing widget.
370 $id = $request['id'];
371 $parsed_id = gutenberg_parse_widget_id( $id );
372 $id_base = $parsed_id['id_base'];
373 $number = isset( $parsed_id['number'] ) ? $parsed_id['number'] : null;
374 $widget_object = gutenberg_get_widget_object( $id_base );
375 } elseif ( $request['id_base'] ) {
376 // Saving a new widget.
377 $id_base = $request['id_base'];
378 $widget_object = gutenberg_get_widget_object( $id_base );
379 $number = $widget_object ? next_widget_id_number( $id_base ) : null;
380 $id = $widget_object ? $id_base . '-' . $number : $id_base;
381 } else {
382 return new WP_Error(
383 'rest_invalid_widget',
384 __( 'Widget type (id_base) is required.', 'gutenberg' ),
385 array( 'status' => 400 )
386 );
387 }
388
389 if ( ! isset( $wp_registered_widget_updates[ $id_base ] ) ) {
390 return new WP_Error(
391 'rest_invalid_widget',
392 __( 'The provided widget type (id_base) cannot be updated.', 'gutenberg' ),
393 array( 'status' => 400 )
394 );
395 }
396
397 if ( ! empty( $request['settings'] ) ) { // Backwards compatibility. TODO: Remove.
398 _deprecated_argument( 'settings', '10.2.0' );
399 if ( $widget_object ) {
400 $form_data = array(
401 "widget-$id_base" => array(
402 $number => $request['settings'],
403 ),
404 );
405 } else {
406 $form_data = $request['settings'];
407 }
408 } elseif ( isset( $request['instance'] ) ) {
409 if ( ! $widget_object ) {
410 return new WP_Error(
411 'rest_invalid_widget',
412 __( 'Cannot set instance on a widget that does not extend WP_Widget.', 'gutenberg' ),
413 array( 'status' => 400 )
414 );
415 }
416
417 if ( isset( $request['instance']['raw'] ) ) {
418 if ( empty( $widget_object->show_instance_in_rest ) ) {
419 return new WP_Error(
420 'rest_invalid_widget',
421 __( 'Widget type does not support raw instances.', 'gutenberg' ),
422 array( 'status' => 400 )
423 );
424 }
425 $instance = $request['instance']['raw'];
426 } elseif ( isset( $request['instance']['encoded'], $request['instance']['hash'] ) ) {
427 $serialized_instance = base64_decode( $request['instance']['encoded'] );
428 if ( ! hash_equals( wp_hash( $serialized_instance ), $request['instance']['hash'] ) ) {
429 return new WP_Error(
430 'rest_invalid_widget',
431 __( 'The provided instance is malformed.', 'gutenberg' ),
432 array( 'status' => 400 )
433 );
434 }
435 $instance = unserialize( $serialized_instance );
436 } else {
437 return new WP_Error(
438 'rest_invalid_widget',
439 __( 'The provided instance is invalid. Must contain raw OR encoded and hash.', 'gutenberg' ),
440 array( 'status' => 400 )
441 );
442 }
443
444 $form_data = array(
445 "widget-$id_base" => array(
446 $number => $instance,
447 ),
448 );
449 } elseif ( isset( $request['form_data'] ) ) {
450 $form_data = $request['form_data'];
451 } else {
452 $form_data = array();
453 }
454
455 $original_post = $_POST;
456 $original_request = $_REQUEST;
457
458 foreach ( $form_data as $key => $value ) {
459 $slashed_value = wp_slash( $value );
460 $_POST[ $key ] = $slashed_value;
461 $_REQUEST[ $key ] = $slashed_value;
462 }
463
464 $callback = $wp_registered_widget_updates[ $id_base ]['callback'];
465 $params = $wp_registered_widget_updates[ $id_base ]['params'];
466
467 if ( is_callable( $callback ) ) {
468 ob_start();
469 call_user_func_array( $callback, $params );
470 ob_end_clean();
471 }
472
473 $_POST = $original_post;
474 $_REQUEST = $original_request;
475
476 if ( $widget_object ) {
477 // Register any multi-widget that the update callback just created.
478 $widget_object->_set( $number );
479 $widget_object->_register_one( $number );
480
481 // WP_Widget sets updated = true after an update to prevent more
482 // than one widget from being saved per request. This isn't what we
483 // want in the REST API, though, as we support batch requests.
484 $widget_object->updated = false;
485 }
486
487 return $id;
488 }
489
490 /**
491 * Prepares the widget for the REST response.
492 *
493 * @since 5.6.0
494 *
495 * @global array $wp_registered_sidebars The registered sidebars.
496 * @global array $wp_registered_widgets The registered widgets.
497 * @global array $wp_registered_widget_controls The registered widget controls.
498 *
499 * @param array $item An array containing a widget_id and sidebar_id.
500 * @param WP_REST_Request $request Request object.
501 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
502 */
503 public function prepare_item_for_response( $item, $request ) {
504 global $wp_registered_widgets;
505
506 $widget_id = $item['widget_id'];
507 $sidebar_id = $item['sidebar_id'];
508
509 if ( ! isset( $wp_registered_widgets[ $widget_id ] ) ) {
510 return new WP_Error(
511 'rest_invalid_widget',
512 __( 'The requested widget is invalid.', 'gutenberg' ),
513 array( 'status' => 500 )
514 );
515 }
516
517 $widget = $wp_registered_widgets[ $widget_id ];
518 $parsed_id = gutenberg_parse_widget_id( $widget_id );
519 $fields = $this->get_fields_for_response( $request );
520
521 $prepared = array(
522 'id' => $widget_id,
523 'id_base' => $parsed_id['id_base'],
524 'sidebar' => $sidebar_id,
525 'rendered' => '',
526 'rendered_form' => null,
527 'instance' => null,
528 );
529
530 if (
531 rest_is_field_included( 'rendered', $fields ) &&
532 'wp_inactive_widgets' !== $sidebar_id
533 ) {
534 $prepared['rendered'] = trim( gutenberg_render_widget( $widget_id, $sidebar_id ) );
535 }
536
537 if ( rest_is_field_included( 'rendered_form', $fields ) ) {
538 $rendered_form = gutenberg_render_widget_control( $widget_id );
539 if ( ! is_null( $rendered_form ) ) {
540 $prepared['rendered_form'] = trim( $rendered_form );
541 }
542 }
543
544 if ( rest_is_field_included( 'instance', $fields ) ) {
545 $widget_object = gutenberg_get_widget_object( $parsed_id['id_base'] );
546 $instance = gutenberg_get_widget_instance( $widget_id );
547
548 if ( $instance ) {
549 $serialized_instance = serialize( $instance );
550 $prepared['instance']['encoded'] = base64_encode( $serialized_instance );
551 $prepared['instance']['hash'] = wp_hash( $serialized_instance );
552
553 if ( ! empty( $widget_object->show_instance_in_rest ) ) {
554 $prepared['instance']['raw'] = $instance;
555 }
556 }
557 }
558
559 // Backwards compatibility. TODO: Remove.
560 $widget_object = gutenberg_get_widget_object( $parsed_id['id_base'] );
561 $prepared['widget_class'] = $widget_object ? get_class( $widget_object ) : '';
562 $prepared['name'] = $widget['name'];
563 $prepared['description'] = ! empty( $widget['description'] ) ? $widget['description'] : '';
564 $prepared['number'] = $widget_object ? (int) $parsed_id['number'] : 0;
565 if ( rest_is_field_included( 'settings', $fields ) ) {
566 $instance = gutenberg_get_widget_instance( $widget_id );
567 $prepared['settings'] = $instance ? $instance : array();
568 }
569
570 $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
571 $prepared = $this->add_additional_fields_to_object( $prepared, $request );
572 $prepared = $this->filter_response_by_context( $prepared, $context );
573
574 $response = rest_ensure_response( $prepared );
575
576 $response->add_links( $this->prepare_links( $prepared ) );
577
578 /**
579 * Filters the REST API response for a widget.
580 *
581 * @since 5.6.0
582 *
583 * @param WP_REST_Response $response The response object.
584 * @param array $widget The registered widget data.
585 * @param WP_REST_Request $request Request used to generate the response.
586 */
587 return apply_filters( 'rest_prepare_widget', $response, $widget, $request );
588 }
589
590 /**
591 * Prepares links for the widget.
592 *
593 * @since 5.6.0
594 *
595 * @param array $prepared Widget.
596 * @return array Links for the given widget.
597 */
598 protected function prepare_links( $prepared ) {
599 $id_base = ! empty( $prepared['id_base'] ) ? $prepared['id_base'] : $prepared['id'];
600
601 return array(
602 'self' => array(
603 'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $prepared['id'] ) ),
604 ),
605 'collection' => array(
606 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
607 ),
608 'about' => array(
609 'href' => rest_url( sprintf( 'wp/v2/widget-types/%s', $id_base ) ),
610 'embeddable' => true,
611 ),
612 'https://api.w.org/sidebar' => array(
613 'href' => rest_url( sprintf( 'wp/v2/sidebars/%s/', $prepared['sidebar'] ) ),
614 ),
615 );
616 }
617
618 /**
619 * Gets the list of collection params.
620 *
621 * @since 5.6.0
622 *
623 * @return array[]
624 */
625 public function get_collection_params() {
626 return array(
627 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
628 'sidebar' => array(
629 'description' => __( 'The sidebar to return widgets for.', 'gutenberg' ),
630 'type' => 'string',
631 ),
632 );
633 }
634
635 /**
636 * Retrieves the widget's schema, conforming to JSON Schema.
637 *
638 * @since 5.6.0
639 *
640 * @return array Item schema data.
641 */
642 public function get_item_schema() {
643 if ( $this->schema ) {
644 return $this->add_additional_fields_schema( $this->schema );
645 }
646
647 $this->schema = array(
648 '$schema' => 'http://json-schema.org/draft-04/schema#',
649 'title' => 'widget',
650 'type' => 'object',
651 'properties' => array(
652 'id' => array(
653 'description' => __( 'Unique identifier for the widget.', 'gutenberg' ),
654 'type' => 'string',
655 'context' => array( 'view', 'edit', 'embed' ),
656 ),
657 'id_base' => array(
658 'description' => __( 'The type of the widget. Corresponds to ID in widget-types endpoint.', 'gutenberg' ),
659 'type' => 'string',
660 'context' => array( 'view', 'edit', 'embed' ),
661 ),
662 'sidebar' => array(
663 'description' => __( 'The sidebar the widget belongs to.', 'gutenberg' ),
664 'type' => 'string',
665 'default' => 'wp_inactive_widgets',
666 'required' => true,
667 'context' => array( 'view', 'edit', 'embed' ),
668 ),
669 'rendered' => array(
670 'description' => __( 'HTML representation of the widget.', 'gutenberg' ),
671 'type' => 'string',
672 'context' => array( 'view', 'edit', 'embed' ),
673 'readonly' => true,
674 ),
675 'rendered_form' => array(
676 'description' => __( 'HTML representation of the widget admin form.', 'gutenberg' ),
677 'type' => 'string',
678 'context' => array( 'edit' ),
679 'readonly' => true,
680 ),
681 'instance' => array(
682 'description' => __( 'Instance settings of the widget, if supported.', 'gutenberg' ),
683 'type' => 'object',
684 'context' => array( 'view', 'edit', 'embed' ),
685 'default' => null,
686 ),
687 'form_data' => array(
688 'description' => __( 'URL-encoded form data from the widget admin form. Used to update a widget that does not support instance. Write only.', 'gutenberg' ),
689 'type' => 'string',
690 'context' => array(),
691 'arg_options' => array(
692 'sanitize_callback' => function( $string ) {
693 $array = array();
694 wp_parse_str( $string, $array );
695 return $array;
696 },
697 ),
698 ),
699 // BEGIN backwards compatibility. TODO: Remove.
700 'widget_class' => array(
701 'description' => __( 'DEPRECATED. Class name of the widget implementation.', 'gutenberg' ),
702 'type' => 'string',
703 'context' => array( 'view', 'edit', 'embed' ),
704 ),
705 'name' => array(
706 'description' => __( 'DEPRECATED. Name of the widget.', 'gutenberg' ),
707 'type' => 'string',
708 'context' => array( 'view', 'edit', 'embed' ),
709 ),
710 'description' => array(
711 'description' => __( 'DEPRECATED. Description of the widget.', 'gutenberg' ),
712 'type' => 'string',
713 'context' => array( 'view', 'edit', 'embed' ),
714 ),
715 'number' => array(
716 'description' => __( 'DEPRECATED. Number of the widget.', 'gutenberg' ),
717 'type' => 'integer',
718 'context' => array( 'view', 'edit', 'embed' ),
719 ),
720 'settings' => array(
721 'description' => __( 'DEPRECATED. Settings of the widget.', 'gutenberg' ),
722 'type' => 'object',
723 'context' => array( 'view', 'edit', 'embed' ),
724 'default' => array(),
725 ),
726 // END backwards compatibility.
727 ),
728 );
729
730 return $this->add_additional_fields_schema( $this->schema );
731 }
732 }
733