[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/rest-api/endpoints/ -> class-wp-rest-widgets-controller.php (source)

   1  <?php
   2  /**
   3   * REST API: WP_REST_Widgets_Controller class
   4   *
   5   * @package WordPress
   6   * @subpackage REST_API
   7   * @since 5.8.0
   8   */
   9  
  10  /**
  11   * Core class to access widgets via the REST API.
  12   *
  13   * @since 5.8.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.8.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.8.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.' ),
  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.8.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 ) {
 100          return $this->permissions_check( $request );
 101      }
 102  
 103      /**
 104       * Retrieves a collection of widgets.
 105       *
 106       * @since 5.8.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          retrieve_widgets();
 113  
 114          $prepared = array();
 115  
 116          foreach ( wp_get_sidebars_widgets() as $sidebar_id => $widget_ids ) {
 117              if ( isset( $request['sidebar'] ) && $sidebar_id !== $request['sidebar'] ) {
 118                  continue;
 119              }
 120  
 121              foreach ( $widget_ids as $widget_id ) {
 122                  $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request );
 123  
 124                  if ( ! is_wp_error( $response ) ) {
 125                      $prepared[] = $this->prepare_response_for_collection( $response );
 126                  }
 127              }
 128          }
 129  
 130          return new WP_REST_Response( $prepared );
 131      }
 132  
 133      /**
 134       * Checks if a given request has access to get a widget.
 135       *
 136       * @since 5.8.0
 137       *
 138       * @param WP_REST_Request $request Full details about the request.
 139       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
 140       */
 141  	public function get_item_permissions_check( $request ) {
 142          return $this->permissions_check( $request );
 143      }
 144  
 145      /**
 146       * Gets an individual widget.
 147       *
 148       * @since 5.8.0
 149       *
 150       * @param WP_REST_Request $request Full details about the request.
 151       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 152       */
 153  	public function get_item( $request ) {
 154          retrieve_widgets();
 155  
 156          $widget_id  = $request['id'];
 157          $sidebar_id = wp_find_widgets_sidebar( $widget_id );
 158  
 159          if ( is_null( $sidebar_id ) ) {
 160              return new WP_Error(
 161                  'rest_widget_not_found',
 162                  __( 'No widget was found with that id.' ),
 163                  array( 'status' => 404 )
 164              );
 165          }
 166  
 167          return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request );
 168      }
 169  
 170      /**
 171       * Checks if a given request has access to create widgets.
 172       *
 173       * @since 5.8.0
 174       *
 175       * @param WP_REST_Request $request Full details about the request.
 176       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
 177       */
 178  	public function create_item_permissions_check( $request ) {
 179          return $this->permissions_check( $request );
 180      }
 181  
 182      /**
 183       * Creates a widget.
 184       *
 185       * @since 5.8.0
 186       *
 187       * @param WP_REST_Request $request Full details about the request.
 188       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 189       */
 190  	public function create_item( $request ) {
 191          $sidebar_id = $request['sidebar'];
 192  
 193          $widget_id = $this->save_widget( $request, $sidebar_id );
 194  
 195          if ( is_wp_error( $widget_id ) ) {
 196              return $widget_id;
 197          }
 198  
 199          wp_assign_widget_to_sidebar( $widget_id, $sidebar_id );
 200  
 201          $request['context'] = 'edit';
 202  
 203          $response = $this->prepare_item_for_response( compact( 'sidebar_id', 'widget_id' ), $request );
 204  
 205          if ( is_wp_error( $response ) ) {
 206              return $response;
 207          }
 208  
 209          $response->set_status( 201 );
 210  
 211          return $response;
 212      }
 213  
 214      /**
 215       * Checks if a given request has access to update widgets.
 216       *
 217       * @since 5.8.0
 218       *
 219       * @param WP_REST_Request $request Full details about the request.
 220       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
 221       */
 222  	public function update_item_permissions_check( $request ) {
 223          return $this->permissions_check( $request );
 224      }
 225  
 226      /**
 227       * Updates an existing widget.
 228       *
 229       * @since 5.8.0
 230       *
 231       * @global WP_Widget_Factory $wp_widget_factory
 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          global $wp_widget_factory;
 238  
 239          /*
 240           * retrieve_widgets() contains logic to move "hidden" or "lost" widgets to the
 241           * wp_inactive_widgets sidebar based on the contents of the $sidebars_widgets global.
 242           *
 243           * When batch requests are processed, this global is not properly updated by previous
 244           * calls, resulting in widgets incorrectly being moved to the wp_inactive_widgets
 245           * sidebar.
 246           *
 247           * See https://core.trac.wordpress.org/ticket/53657.
 248           */
 249          wp_get_sidebars_widgets();
 250  
 251          retrieve_widgets();
 252  
 253          $widget_id  = $request['id'];
 254          $sidebar_id = wp_find_widgets_sidebar( $widget_id );
 255  
 256          // Allow sidebar to be unset or missing when widget is not a WP_Widget.
 257          $parsed_id     = wp_parse_widget_id( $widget_id );
 258          $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] );
 259          if ( is_null( $sidebar_id ) && $widget_object ) {
 260              return new WP_Error(
 261                  'rest_widget_not_found',
 262                  __( 'No widget was found with that id.' ),
 263                  array( 'status' => 404 )
 264              );
 265          }
 266  
 267          if (
 268              $request->has_param( 'instance' ) ||
 269              $request->has_param( 'form_data' )
 270          ) {
 271              $maybe_error = $this->save_widget( $request, $sidebar_id );
 272              if ( is_wp_error( $maybe_error ) ) {
 273                  return $maybe_error;
 274              }
 275          }
 276  
 277          if ( $request->has_param( 'sidebar' ) ) {
 278              if ( $sidebar_id !== $request['sidebar'] ) {
 279                  $sidebar_id = $request['sidebar'];
 280                  wp_assign_widget_to_sidebar( $widget_id, $sidebar_id );
 281              }
 282          }
 283  
 284          $request['context'] = 'edit';
 285  
 286          return $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request );
 287      }
 288  
 289      /**
 290       * Checks if a given request has access to delete widgets.
 291       *
 292       * @since 5.8.0
 293       *
 294       * @param WP_REST_Request $request Full details about the request.
 295       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
 296       */
 297  	public function delete_item_permissions_check( $request ) {
 298          return $this->permissions_check( $request );
 299      }
 300  
 301      /**
 302       * Deletes a widget.
 303       *
 304       * @since 5.8.0
 305       *
 306       * @global WP_Widget_Factory $wp_widget_factory
 307       * @global array             $wp_registered_widget_updates The registered widget update functions.
 308       *
 309       * @param WP_REST_Request $request Full details about the request.
 310       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 311       */
 312  	public function delete_item( $request ) {
 313          global $wp_widget_factory, $wp_registered_widget_updates;
 314  
 315          /*
 316           * retrieve_widgets() contains logic to move "hidden" or "lost" widgets to the
 317           * wp_inactive_widgets sidebar based on the contents of the $sidebars_widgets global.
 318           *
 319           * When batch requests are processed, this global is not properly updated by previous
 320           * calls, resulting in widgets incorrectly being moved to the wp_inactive_widgets
 321           * sidebar.
 322           *
 323           * See https://core.trac.wordpress.org/ticket/53657.
 324           */
 325          wp_get_sidebars_widgets();
 326  
 327          retrieve_widgets();
 328  
 329          $widget_id  = $request['id'];
 330          $sidebar_id = wp_find_widgets_sidebar( $widget_id );
 331  
 332          if ( is_null( $sidebar_id ) ) {
 333              return new WP_Error(
 334                  'rest_widget_not_found',
 335                  __( 'No widget was found with that id.' ),
 336                  array( 'status' => 404 )
 337              );
 338          }
 339  
 340          $request['context'] = 'edit';
 341  
 342          if ( $request['force'] ) {
 343              $response = $this->prepare_item_for_response( compact( 'widget_id', 'sidebar_id' ), $request );
 344  
 345              $parsed_id = wp_parse_widget_id( $widget_id );
 346              $id_base   = $parsed_id['id_base'];
 347  
 348              $original_post    = $_POST;
 349              $original_request = $_REQUEST;
 350  
 351              $_POST    = array(
 352                  'sidebar'         => $sidebar_id,
 353                  "widget-$id_base" => array(),
 354                  'the-widget-id'   => $widget_id,
 355                  'delete_widget'   => '1',
 356              );
 357              $_REQUEST = $_POST;
 358  
 359              /** This action is documented in wp-admin/widgets-form.php */
 360              do_action( 'delete_widget', $widget_id, $sidebar_id, $id_base );
 361  
 362              $callback = $wp_registered_widget_updates[ $id_base ]['callback'];
 363              $params   = $wp_registered_widget_updates[ $id_base ]['params'];
 364  
 365              if ( is_callable( $callback ) ) {
 366                  ob_start();
 367                  call_user_func_array( $callback, $params );
 368                  ob_end_clean();
 369              }
 370  
 371              $_POST    = $original_post;
 372              $_REQUEST = $original_request;
 373  
 374              $widget_object = $wp_widget_factory->get_widget_object( $id_base );
 375  
 376              if ( $widget_object ) {
 377                  /*
 378                   * WP_Widget sets `updated = true` after an update to prevent more than one widget
 379                   * from being saved per request. This isn't what we want in the REST API, though,
 380                   * as we support batch requests.
 381                   */
 382                  $widget_object->updated = false;
 383              }
 384  
 385              wp_assign_widget_to_sidebar( $widget_id, '' );
 386  
 387              $response->set_data(
 388                  array(
 389                      'deleted'  => true,
 390                      'previous' => $response->get_data(),
 391                  )
 392              );
 393          } else {
 394              wp_assign_widget_to_sidebar( $widget_id, 'wp_inactive_widgets' );
 395  
 396              $response = $this->prepare_item_for_response(
 397                  array(
 398                      'sidebar_id' => 'wp_inactive_widgets',
 399                      'widget_id'  => $widget_id,
 400                  ),
 401                  $request
 402              );
 403          }
 404  
 405          /**
 406           * Fires after a widget is deleted via the REST API.
 407           *
 408           * @since 5.8.0
 409           *
 410           * @param string           $widget_id  ID of the widget marked for deletion.
 411           * @param string           $sidebar_id ID of the sidebar the widget was deleted from.
 412           * @param WP_REST_Response $response   The response data.
 413           * @param WP_REST_Request  $request    The request sent to the API.
 414           */
 415          do_action( 'rest_delete_widget', $widget_id, $sidebar_id, $response, $request );
 416  
 417          return $response;
 418      }
 419  
 420      /**
 421       * Performs a permissions check for managing widgets.
 422       *
 423       * @since 5.8.0
 424       *
 425       * @param WP_REST_Request $request Full details about the request.
 426       * @return true|WP_Error
 427       */
 428  	protected function permissions_check( $request ) {
 429          if ( ! current_user_can( 'edit_theme_options' ) ) {
 430              return new WP_Error(
 431                  'rest_cannot_manage_widgets',
 432                  __( 'Sorry, you are not allowed to manage widgets on this site.' ),
 433                  array(
 434                      'status' => rest_authorization_required_code(),
 435                  )
 436              );
 437          }
 438  
 439          return true;
 440      }
 441  
 442      /**
 443       * Saves the widget in the request object.
 444       *
 445       * @since 5.8.0
 446       *
 447       * @global WP_Widget_Factory $wp_widget_factory
 448       * @global array             $wp_registered_widget_updates The registered widget update functions.
 449       *
 450       * @param WP_REST_Request $request    Full details about the request.
 451       * @param string          $sidebar_id ID of the sidebar the widget belongs to.
 452       * @return string|WP_Error The saved widget ID.
 453       */
 454  	protected function save_widget( $request, $sidebar_id ) {
 455          global $wp_widget_factory, $wp_registered_widget_updates;
 456  
 457          require_once ABSPATH . 'wp-admin/includes/widgets.php'; // For next_widget_id_number().
 458  
 459          if ( isset( $request['id'] ) ) {
 460              // Saving an existing widget.
 461              $id            = $request['id'];
 462              $parsed_id     = wp_parse_widget_id( $id );
 463              $id_base       = $parsed_id['id_base'];
 464              $number        = isset( $parsed_id['number'] ) ? $parsed_id['number'] : null;
 465              $widget_object = $wp_widget_factory->get_widget_object( $id_base );
 466              $creating      = false;
 467          } elseif ( $request['id_base'] ) {
 468              // Saving a new widget.
 469              $id_base       = $request['id_base'];
 470              $widget_object = $wp_widget_factory->get_widget_object( $id_base );
 471              $number        = $widget_object ? next_widget_id_number( $id_base ) : null;
 472              $id            = $widget_object ? $id_base . '-' . $number : $id_base;
 473              $creating      = true;
 474          } else {
 475              return new WP_Error(
 476                  'rest_invalid_widget',
 477                  __( 'Widget type (id_base) is required.' ),
 478                  array( 'status' => 400 )
 479              );
 480          }
 481  
 482          if ( ! isset( $wp_registered_widget_updates[ $id_base ] ) ) {
 483              return new WP_Error(
 484                  'rest_invalid_widget',
 485                  __( 'The provided widget type (id_base) cannot be updated.' ),
 486                  array( 'status' => 400 )
 487              );
 488          }
 489  
 490          if ( isset( $request['instance'] ) ) {
 491              if ( ! $widget_object ) {
 492                  return new WP_Error(
 493                      'rest_invalid_widget',
 494                      __( 'Cannot set instance on a widget that does not extend WP_Widget.' ),
 495                      array( 'status' => 400 )
 496                  );
 497              }
 498  
 499              if ( isset( $request['instance']['raw'] ) ) {
 500                  if ( empty( $widget_object->widget_options['show_instance_in_rest'] ) ) {
 501                      return new WP_Error(
 502                          'rest_invalid_widget',
 503                          __( 'Widget type does not support raw instances.' ),
 504                          array( 'status' => 400 )
 505                      );
 506                  }
 507                  $instance = $request['instance']['raw'];
 508              } elseif ( isset( $request['instance']['encoded'], $request['instance']['hash'] ) ) {
 509                  $serialized_instance = base64_decode( $request['instance']['encoded'] );
 510                  if ( ! hash_equals( wp_hash( $serialized_instance ), $request['instance']['hash'] ) ) {
 511                      return new WP_Error(
 512                          'rest_invalid_widget',
 513                          __( 'The provided instance is malformed.' ),
 514                          array( 'status' => 400 )
 515                      );
 516                  }
 517                  $instance = unserialize( $serialized_instance );
 518              } else {
 519                  return new WP_Error(
 520                      'rest_invalid_widget',
 521                      __( 'The provided instance is invalid. Must contain raw OR encoded and hash.' ),
 522                      array( 'status' => 400 )
 523                  );
 524              }
 525  
 526              $form_data = array(
 527                  "widget-$id_base" => array(
 528                      $number => $instance,
 529                  ),
 530                  'sidebar'         => $sidebar_id,
 531              );
 532          } elseif ( isset( $request['form_data'] ) ) {
 533              $form_data = $request['form_data'];
 534          } else {
 535              $form_data = array();
 536          }
 537  
 538          $original_post    = $_POST;
 539          $original_request = $_REQUEST;
 540  
 541          foreach ( $form_data as $key => $value ) {
 542              $slashed_value    = wp_slash( $value );
 543              $_POST[ $key ]    = $slashed_value;
 544              $_REQUEST[ $key ] = $slashed_value;
 545          }
 546  
 547          $callback = $wp_registered_widget_updates[ $id_base ]['callback'];
 548          $params   = $wp_registered_widget_updates[ $id_base ]['params'];
 549  
 550          if ( is_callable( $callback ) ) {
 551              ob_start();
 552              call_user_func_array( $callback, $params );
 553              ob_end_clean();
 554          }
 555  
 556          $_POST    = $original_post;
 557          $_REQUEST = $original_request;
 558  
 559          if ( $widget_object ) {
 560              // Register any multi-widget that the update callback just created.
 561              $widget_object->_set( $number );
 562              $widget_object->_register_one( $number );
 563  
 564              /*
 565               * WP_Widget sets `updated = true` after an update to prevent more than one widget
 566               * from being saved per request. This isn't what we want in the REST API, though,
 567               * as we support batch requests.
 568               */
 569              $widget_object->updated = false;
 570          }
 571  
 572          /**
 573           * Fires after a widget is created or updated via the REST API.
 574           *
 575           * @since 5.8.0
 576           *
 577           * @param string          $id         ID of the widget being saved.
 578           * @param string          $sidebar_id ID of the sidebar containing the widget being saved.
 579           * @param WP_REST_Request $request    Request object.
 580           * @param bool            $creating   True when creating a widget, false when updating.
 581           */
 582          do_action( 'rest_after_save_widget', $id, $sidebar_id, $request, $creating );
 583  
 584          return $id;
 585      }
 586  
 587      /**
 588       * Prepares the widget for the REST response.
 589       *
 590       * @since 5.8.0
 591       *
 592       * @global WP_Widget_Factory $wp_widget_factory
 593       * @global array             $wp_registered_widgets The registered widgets.
 594       *
 595       * @param array           $item    An array containing a widget_id and sidebar_id.
 596       * @param WP_REST_Request $request Request object.
 597       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 598       */
 599  	public function prepare_item_for_response( $item, $request ) {
 600          global $wp_widget_factory, $wp_registered_widgets;
 601  
 602          $widget_id  = $item['widget_id'];
 603          $sidebar_id = $item['sidebar_id'];
 604  
 605          if ( ! isset( $wp_registered_widgets[ $widget_id ] ) ) {
 606              return new WP_Error(
 607                  'rest_invalid_widget',
 608                  __( 'The requested widget is invalid.' ),
 609                  array( 'status' => 500 )
 610              );
 611          }
 612  
 613          $widget    = $wp_registered_widgets[ $widget_id ];
 614          $parsed_id = wp_parse_widget_id( $widget_id );
 615          $fields    = $this->get_fields_for_response( $request );
 616  
 617          $prepared = array(
 618              'id'            => $widget_id,
 619              'id_base'       => $parsed_id['id_base'],
 620              'sidebar'       => $sidebar_id,
 621              'rendered'      => '',
 622              'rendered_form' => null,
 623              'instance'      => null,
 624          );
 625  
 626          if (
 627              rest_is_field_included( 'rendered', $fields ) &&
 628              'wp_inactive_widgets' !== $sidebar_id
 629          ) {
 630              $prepared['rendered'] = trim( wp_render_widget( $widget_id, $sidebar_id ) );
 631          }
 632  
 633          if ( rest_is_field_included( 'rendered_form', $fields ) ) {
 634              $rendered_form = wp_render_widget_control( $widget_id );
 635              if ( ! is_null( $rendered_form ) ) {
 636                  $prepared['rendered_form'] = trim( $rendered_form );
 637              }
 638          }
 639  
 640          if ( rest_is_field_included( 'instance', $fields ) ) {
 641              $widget_object = $wp_widget_factory->get_widget_object( $parsed_id['id_base'] );
 642              if ( $widget_object && isset( $parsed_id['number'] ) ) {
 643                  $all_instances                   = $widget_object->get_settings();
 644                  $instance                        = $all_instances[ $parsed_id['number'] ];
 645                  $serialized_instance             = serialize( $instance );
 646                  $prepared['instance']['encoded'] = base64_encode( $serialized_instance );
 647                  $prepared['instance']['hash']    = wp_hash( $serialized_instance );
 648  
 649                  if ( ! empty( $widget_object->widget_options['show_instance_in_rest'] ) ) {
 650                      // Use new stdClass so that JSON result is {} and not [].
 651                      $prepared['instance']['raw'] = empty( $instance ) ? new stdClass : $instance;
 652                  }
 653              }
 654          }
 655  
 656          $context  = ! empty( $request['context'] ) ? $request['context'] : 'view';
 657          $prepared = $this->add_additional_fields_to_object( $prepared, $request );
 658          $prepared = $this->filter_response_by_context( $prepared, $context );
 659  
 660          $response = rest_ensure_response( $prepared );
 661  
 662          $response->add_links( $this->prepare_links( $prepared ) );
 663  
 664          /**
 665           * Filters the REST API response for a widget.
 666           *
 667           * @since 5.8.0
 668           *
 669           * @param WP_REST_Response $response The response object.
 670           * @param array            $widget   The registered widget data.
 671           * @param WP_REST_Request  $request  Request used to generate the response.
 672           */
 673          return apply_filters( 'rest_prepare_widget', $response, $widget, $request );
 674      }
 675  
 676      /**
 677       * Prepares links for the widget.
 678       *
 679       * @since 5.8.0
 680       *
 681       * @param array $prepared Widget.
 682       * @return array Links for the given widget.
 683       */
 684  	protected function prepare_links( $prepared ) {
 685          $id_base = ! empty( $prepared['id_base'] ) ? $prepared['id_base'] : $prepared['id'];
 686  
 687          return array(
 688              'self'                      => array(
 689                  'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $prepared['id'] ) ),
 690              ),
 691              'collection'                => array(
 692                  'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
 693              ),
 694              'about'                     => array(
 695                  'href'       => rest_url( sprintf( 'wp/v2/widget-types/%s', $id_base ) ),
 696                  'embeddable' => true,
 697              ),
 698              'https://api.w.org/sidebar' => array(
 699                  'href' => rest_url( sprintf( 'wp/v2/sidebars/%s/', $prepared['sidebar'] ) ),
 700              ),
 701          );
 702      }
 703  
 704      /**
 705       * Gets the list of collection params.
 706       *
 707       * @since 5.8.0
 708       *
 709       * @return array[]
 710       */
 711  	public function get_collection_params() {
 712          return array(
 713              'context' => $this->get_context_param( array( 'default' => 'view' ) ),
 714              'sidebar' => array(
 715                  'description' => __( 'The sidebar to return widgets for.' ),
 716                  'type'        => 'string',
 717              ),
 718          );
 719      }
 720  
 721      /**
 722       * Retrieves the widget's schema, conforming to JSON Schema.
 723       *
 724       * @since 5.8.0
 725       *
 726       * @return array Item schema data.
 727       */
 728  	public function get_item_schema() {
 729          if ( $this->schema ) {
 730              return $this->add_additional_fields_schema( $this->schema );
 731          }
 732  
 733          $this->schema = array(
 734              '$schema'    => 'http://json-schema.org/draft-04/schema#',
 735              'title'      => 'widget',
 736              'type'       => 'object',
 737              'properties' => array(
 738                  'id'            => array(
 739                      'description' => __( 'Unique identifier for the widget.' ),
 740                      'type'        => 'string',
 741                      'context'     => array( 'view', 'edit', 'embed' ),
 742                  ),
 743                  'id_base'       => array(
 744                      'description' => __( 'The type of the widget. Corresponds to ID in widget-types endpoint.' ),
 745                      'type'        => 'string',
 746                      'context'     => array( 'view', 'edit', 'embed' ),
 747                  ),
 748                  'sidebar'       => array(
 749                      'description' => __( 'The sidebar the widget belongs to.' ),
 750                      'type'        => 'string',
 751                      'default'     => 'wp_inactive_widgets',
 752                      'required'    => true,
 753                      'context'     => array( 'view', 'edit', 'embed' ),
 754                  ),
 755                  'rendered'      => array(
 756                      'description' => __( 'HTML representation of the widget.' ),
 757                      'type'        => 'string',
 758                      'context'     => array( 'view', 'edit', 'embed' ),
 759                      'readonly'    => true,
 760                  ),
 761                  'rendered_form' => array(
 762                      'description' => __( 'HTML representation of the widget admin form.' ),
 763                      'type'        => 'string',
 764                      'context'     => array( 'edit' ),
 765                      'readonly'    => true,
 766                  ),
 767                  'instance'      => array(
 768                      'description' => __( 'Instance settings of the widget, if supported.' ),
 769                      'type'        => 'object',
 770                      'context'     => array( 'view', 'edit', 'embed' ),
 771                      'default'     => null,
 772                      'properties'  => array(
 773                          'encoded' => array(
 774                              'description' => __( 'Base64 encoded representation of the instance settings.' ),
 775                              'type'        => 'string',
 776                              'context'     => array( 'view', 'edit', 'embed' ),
 777                          ),
 778                          'hash'    => array(
 779                              'description' => __( 'Cryptographic hash of the instance settings.' ),
 780                              'type'        => 'string',
 781                              'context'     => array( 'view', 'edit', 'embed' ),
 782                          ),
 783                          'raw'     => array(
 784                              'description' => __( 'Unencoded instance settings, if supported.' ),
 785                              'type'        => 'object',
 786                              'context'     => array( 'view', 'edit', 'embed' ),
 787                          ),
 788                      ),
 789                  ),
 790                  'form_data'     => array(
 791                      'description' => __( 'URL-encoded form data from the widget admin form. Used to update a widget that does not support instance. Write only.' ),
 792                      'type'        => 'string',
 793                      'context'     => array(),
 794                      'arg_options' => array(
 795                          'sanitize_callback' => static function( $string ) {
 796                              $array = array();
 797                              wp_parse_str( $string, $array );
 798                              return $array;
 799                          },
 800                      ),
 801                  ),
 802              ),
 803          );
 804  
 805          return $this->add_additional_fields_schema( $this->schema );
 806      }
 807  }


Generated: Mon Sep 20 01:00:04 2021 Cross-referenced by PHPXref 0.7.1