[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

   1  <?php
   2  /**
   3   * REST API: WP_REST_Sidebars_Controller class
   4   *
   5   * Original code from {@link https://github.com/martin-pettersson/wp-rest-api-sidebars Martin Pettersson (martin_pettersson@outlook.com)}.
   6   *
   7   * @package WordPress
   8   * @subpackage REST_API
   9   * @since 5.8.0
  10   */
  11  
  12  /**
  13   * Core class used to manage a site's sidebars.
  14   *
  15   * @since 5.8.0
  16   *
  17   * @see WP_REST_Controller
  18   */
  19  class WP_REST_Sidebars_Controller extends WP_REST_Controller {
  20  
  21      /**
  22       * Sidebars controller constructor.
  23       *
  24       * @since 5.8.0
  25       */
  26  	public function __construct() {
  27          $this->namespace = 'wp/v2';
  28          $this->rest_base = 'sidebars';
  29      }
  30  
  31      /**
  32       * Registers the controllers routes.
  33       *
  34       * @since 5.8.0
  35       */
  36  	public function register_routes() {
  37          register_rest_route(
  38              $this->namespace,
  39              '/' . $this->rest_base,
  40              array(
  41                  array(
  42                      'methods'             => WP_REST_Server::READABLE,
  43                      'callback'            => array( $this, 'get_items' ),
  44                      'permission_callback' => array( $this, 'get_items_permissions_check' ),
  45                      'args'                => array(
  46                          'context' => $this->get_context_param( array( 'default' => 'view' ) ),
  47                      ),
  48                  ),
  49                  'schema' => array( $this, 'get_public_item_schema' ),
  50              )
  51          );
  52  
  53          register_rest_route(
  54              $this->namespace,
  55              '/' . $this->rest_base . '/(?P<id>[\w-]+)',
  56              array(
  57                  array(
  58                      'methods'             => WP_REST_Server::READABLE,
  59                      'callback'            => array( $this, 'get_item' ),
  60                      'permission_callback' => array( $this, 'get_item_permissions_check' ),
  61                      'args'                => array(
  62                          'id'      => array(
  63                              'description' => __( 'The id of a registered sidebar' ),
  64                              'type'        => 'string',
  65                          ),
  66                          'context' => $this->get_context_param( array( 'default' => 'view' ) ),
  67                      ),
  68                  ),
  69                  array(
  70                      'methods'             => WP_REST_Server::EDITABLE,
  71                      'callback'            => array( $this, 'update_item' ),
  72                      'permission_callback' => array( $this, 'update_item_permissions_check' ),
  73                      'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
  74                  ),
  75                  'schema' => array( $this, 'get_public_item_schema' ),
  76              )
  77          );
  78      }
  79  
  80      /**
  81       * Checks if a given request has access to get sidebars.
  82       *
  83       * @since 5.8.0
  84       *
  85       * @param WP_REST_Request $request Full details about the request.
  86       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
  87       */
  88  	public function get_items_permissions_check( $request ) {
  89          return $this->do_permissions_check();
  90      }
  91  
  92      /**
  93       * Retrieves the list of sidebars (active or inactive).
  94       *
  95       * @since 5.8.0
  96       *
  97       * @param WP_REST_Request $request Full details about the request.
  98       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
  99       */
 100  	public function get_items( $request ) {
 101          retrieve_widgets();
 102  
 103          $data = array();
 104          foreach ( wp_get_sidebars_widgets() as $id => $widgets ) {
 105              $sidebar = $this->get_sidebar( $id );
 106  
 107              if ( ! $sidebar ) {
 108                  continue;
 109              }
 110  
 111              $data[] = $this->prepare_response_for_collection(
 112                  $this->prepare_item_for_response( $sidebar, $request )
 113              );
 114          }
 115  
 116          return rest_ensure_response( $data );
 117      }
 118  
 119      /**
 120       * Checks if a given request has access to get a single sidebar.
 121       *
 122       * @since 5.8.0
 123       *
 124       * @param WP_REST_Request $request Full details about the request.
 125       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
 126       */
 127  	public function get_item_permissions_check( $request ) {
 128          return $this->do_permissions_check();
 129      }
 130  
 131      /**
 132       * Retrieves one sidebar from the collection.
 133       *
 134       * @since 5.8.0
 135       *
 136       * @param WP_REST_Request $request Full details about the request.
 137       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 138       */
 139  	public function get_item( $request ) {
 140          retrieve_widgets();
 141  
 142          $sidebar = $this->get_sidebar( $request['id'] );
 143  
 144          if ( ! $sidebar ) {
 145              return new WP_Error( 'rest_sidebar_not_found', __( 'No sidebar exists with that id.' ), array( 'status' => 404 ) );
 146          }
 147  
 148          return $this->prepare_item_for_response( $sidebar, $request );
 149      }
 150  
 151      /**
 152       * Checks if a given request has access to update sidebars.
 153       *
 154       * @since 5.8.0
 155       *
 156       * @param WP_REST_Request $request Full details about the request.
 157       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
 158       */
 159  	public function update_item_permissions_check( $request ) {
 160          return $this->do_permissions_check();
 161      }
 162  
 163      /**
 164       * Updates a sidebar.
 165       *
 166       * @since 5.8.0
 167       *
 168       * @param WP_REST_Request $request Full details about the request.
 169       * @return WP_REST_Response Response object on success, or WP_Error object on failure.
 170       */
 171  	public function update_item( $request ) {
 172          if ( isset( $request['widgets'] ) ) {
 173              $sidebars = wp_get_sidebars_widgets();
 174  
 175              foreach ( $sidebars as $sidebar_id => $widgets ) {
 176                  foreach ( $widgets as $i => $widget_id ) {
 177                      // This automatically removes the passed widget ids from any other sidebars in use.
 178                      if ( $sidebar_id !== $request['id'] && in_array( $widget_id, $request['widgets'], true ) ) {
 179                          unset( $sidebars[ $sidebar_id ][ $i ] );
 180                      }
 181  
 182                      // This automatically removes omitted widget ids to the inactive sidebar.
 183                      if ( $sidebar_id === $request['id'] && ! in_array( $widget_id, $request['widgets'], true ) ) {
 184                          $sidebars['wp_inactive_widgets'][] = $widget_id;
 185                      }
 186                  }
 187              }
 188  
 189              $sidebars[ $request['id'] ] = $request['widgets'];
 190  
 191              wp_set_sidebars_widgets( $sidebars );
 192          }
 193  
 194          $request['context'] = 'edit';
 195  
 196          $sidebar = $this->get_sidebar( $request['id'] );
 197  
 198          /**
 199           * Fires after a sidebar is updated via the REST API.
 200           *
 201           * @since 5.8.0
 202           *
 203           * @param array           $sidebar The updated sidebar.
 204           * @param WP_REST_Request $request Request object.
 205           */
 206          do_action( 'rest_save_sidebar', $sidebar, $request );
 207  
 208          return $this->prepare_item_for_response( $sidebar, $request );
 209      }
 210  
 211      /**
 212       * Checks if the user has permissions to make the request.
 213       *
 214       * @since 5.8.0
 215       *
 216       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
 217       */
 218  	protected function do_permissions_check() {
 219          // Verify if the current user has edit_theme_options capability.
 220          // This capability is required to access the widgets screen.
 221          if ( ! current_user_can( 'edit_theme_options' ) ) {
 222              return new WP_Error(
 223                  'rest_cannot_manage_widgets',
 224                  __( 'Sorry, you are not allowed to manage widgets on this site.' ),
 225                  array( 'status' => rest_authorization_required_code() )
 226              );
 227          }
 228  
 229          return true;
 230      }
 231  
 232      /**
 233       * Retrieves the registered sidebar with the given id.
 234       *
 235       * @since 5.8.0
 236       *
 237       * @global array $wp_registered_sidebars The registered sidebars.
 238       *
 239       * @param string|int $id ID of the sidebar.
 240       * @return array|null The discovered sidebar, or null if it is not registered.
 241       */
 242  	protected function get_sidebar( $id ) {
 243          global $wp_registered_sidebars;
 244  
 245          foreach ( (array) $wp_registered_sidebars as $sidebar ) {
 246              if ( $sidebar['id'] === $id ) {
 247                  return $sidebar;
 248              }
 249          }
 250  
 251          if ( 'wp_inactive_widgets' === $id ) {
 252              return array(
 253                  'id'   => 'wp_inactive_widgets',
 254                  'name' => __( 'Inactive widgets' ),
 255              );
 256          }
 257  
 258          return null;
 259      }
 260  
 261      /**
 262       * Prepares a single sidebar output for response.
 263       *
 264       * @since 5.8.0
 265       * @since 5.9.0 Renamed `$raw_sidebar` to `$item` to match parent class for PHP 8 named parameter support.
 266       *
 267       * @global array $wp_registered_sidebars The registered sidebars.
 268       * @global array $wp_registered_widgets  The registered widgets.
 269       *
 270       * @param array           $item    Sidebar instance.
 271       * @param WP_REST_Request $request Full details about the request.
 272       * @return WP_REST_Response Prepared response object.
 273       */
 274  	public function prepare_item_for_response( $item, $request ) {
 275          global $wp_registered_sidebars, $wp_registered_widgets;
 276  
 277          // Restores the more descriptive, specific name for use within this method.
 278          $raw_sidebar = $item;
 279          $id          = $raw_sidebar['id'];
 280          $sidebar     = array( 'id' => $id );
 281  
 282          if ( isset( $wp_registered_sidebars[ $id ] ) ) {
 283              $registered_sidebar = $wp_registered_sidebars[ $id ];
 284  
 285              $sidebar['status']        = 'active';
 286              $sidebar['name']          = isset( $registered_sidebar['name'] ) ? $registered_sidebar['name'] : '';
 287              $sidebar['description']   = isset( $registered_sidebar['description'] ) ? wp_sidebar_description( $id ) : '';
 288              $sidebar['class']         = isset( $registered_sidebar['class'] ) ? $registered_sidebar['class'] : '';
 289              $sidebar['before_widget'] = isset( $registered_sidebar['before_widget'] ) ? $registered_sidebar['before_widget'] : '';
 290              $sidebar['after_widget']  = isset( $registered_sidebar['after_widget'] ) ? $registered_sidebar['after_widget'] : '';
 291              $sidebar['before_title']  = isset( $registered_sidebar['before_title'] ) ? $registered_sidebar['before_title'] : '';
 292              $sidebar['after_title']   = isset( $registered_sidebar['after_title'] ) ? $registered_sidebar['after_title'] : '';
 293          } else {
 294              $sidebar['status']      = 'inactive';
 295              $sidebar['name']        = $raw_sidebar['name'];
 296              $sidebar['description'] = '';
 297              $sidebar['class']       = '';
 298          }
 299  
 300          $fields = $this->get_fields_for_response( $request );
 301          if ( rest_is_field_included( 'widgets', $fields ) ) {
 302              $sidebars = wp_get_sidebars_widgets();
 303              $widgets  = array_filter(
 304                  isset( $sidebars[ $sidebar['id'] ] ) ? $sidebars[ $sidebar['id'] ] : array(),
 305                  static function ( $widget_id ) use ( $wp_registered_widgets ) {
 306                      return isset( $wp_registered_widgets[ $widget_id ] );
 307                  }
 308              );
 309  
 310              $sidebar['widgets'] = array_values( $widgets );
 311          }
 312  
 313          $schema = $this->get_item_schema();
 314          $data   = array();
 315          foreach ( $schema['properties'] as $property_id => $property ) {
 316              if ( isset( $sidebar[ $property_id ] ) && true === rest_validate_value_from_schema( $sidebar[ $property_id ], $property ) ) {
 317                  $data[ $property_id ] = $sidebar[ $property_id ];
 318              } elseif ( isset( $property['default'] ) ) {
 319                  $data[ $property_id ] = $property['default'];
 320              }
 321          }
 322  
 323          $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
 324          $data    = $this->add_additional_fields_to_object( $data, $request );
 325          $data    = $this->filter_response_by_context( $data, $context );
 326  
 327          $response = rest_ensure_response( $data );
 328  
 329          $response->add_links( $this->prepare_links( $sidebar ) );
 330  
 331          /**
 332           * Filters the REST API response for a sidebar.
 333           *
 334           * @since 5.8.0
 335           *
 336           * @param WP_REST_Response $response    The response object.
 337           * @param array            $raw_sidebar The raw sidebar data.
 338           * @param WP_REST_Request  $request     The request object.
 339           */
 340          return apply_filters( 'rest_prepare_sidebar', $response, $raw_sidebar, $request );
 341      }
 342  
 343      /**
 344       * Prepares links for the sidebar.
 345       *
 346       * @since 5.8.0
 347       *
 348       * @param array $sidebar Sidebar.
 349       * @return array Links for the given widget.
 350       */
 351  	protected function prepare_links( $sidebar ) {
 352          return array(
 353              'collection'               => array(
 354                  'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
 355              ),
 356              'self'                     => array(
 357                  'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $sidebar['id'] ) ),
 358              ),
 359              'https://api.w.org/widget' => array(
 360                  'href'       => add_query_arg( 'sidebar', $sidebar['id'], rest_url( '/wp/v2/widgets' ) ),
 361                  'embeddable' => true,
 362              ),
 363          );
 364      }
 365  
 366      /**
 367       * Retrieves the block type' schema, conforming to JSON Schema.
 368       *
 369       * @since 5.8.0
 370       *
 371       * @return array Item schema data.
 372       */
 373  	public function get_item_schema() {
 374          if ( $this->schema ) {
 375              return $this->add_additional_fields_schema( $this->schema );
 376          }
 377  
 378          $schema = array(
 379              '$schema'    => 'http://json-schema.org/draft-04/schema#',
 380              'title'      => 'sidebar',
 381              'type'       => 'object',
 382              'properties' => array(
 383                  'id'            => array(
 384                      'description' => __( 'ID of sidebar.' ),
 385                      'type'        => 'string',
 386                      'context'     => array( 'embed', 'view', 'edit' ),
 387                      'readonly'    => true,
 388                  ),
 389                  'name'          => array(
 390                      'description' => __( 'Unique name identifying the sidebar.' ),
 391                      'type'        => 'string',
 392                      'context'     => array( 'embed', 'view', 'edit' ),
 393                      'readonly'    => true,
 394                  ),
 395                  'description'   => array(
 396                      'description' => __( 'Description of sidebar.' ),
 397                      'type'        => 'string',
 398                      'context'     => array( 'embed', 'view', 'edit' ),
 399                      'readonly'    => true,
 400                  ),
 401                  'class'         => array(
 402                      'description' => __( 'Extra CSS class to assign to the sidebar in the Widgets interface.' ),
 403                      'type'        => 'string',
 404                      'context'     => array( 'embed', 'view', 'edit' ),
 405                      'readonly'    => true,
 406                  ),
 407                  'before_widget' => array(
 408                      'description' => __( 'HTML content to prepend to each widget\'s HTML output when assigned to this sidebar. Default is an opening list item element.' ),
 409                      'type'        => 'string',
 410                      'default'     => '',
 411                      'context'     => array( 'embed', 'view', 'edit' ),
 412                      'readonly'    => true,
 413                  ),
 414                  'after_widget'  => array(
 415                      'description' => __( 'HTML content to append to each widget\'s HTML output when assigned to this sidebar. Default is a closing list item element.' ),
 416                      'type'        => 'string',
 417                      'default'     => '',
 418                      'context'     => array( 'embed', 'view', 'edit' ),
 419                      'readonly'    => true,
 420                  ),
 421                  'before_title'  => array(
 422                      'description' => __( 'HTML content to prepend to the sidebar title when displayed. Default is an opening h2 element.' ),
 423                      'type'        => 'string',
 424                      'default'     => '',
 425                      'context'     => array( 'embed', 'view', 'edit' ),
 426                      'readonly'    => true,
 427                  ),
 428                  'after_title'   => array(
 429                      'description' => __( 'HTML content to append to the sidebar title when displayed. Default is a closing h2 element.' ),
 430                      'type'        => 'string',
 431                      'default'     => '',
 432                      'context'     => array( 'embed', 'view', 'edit' ),
 433                      'readonly'    => true,
 434                  ),
 435                  'status'        => array(
 436                      'description' => __( 'Status of sidebar.' ),
 437                      'type'        => 'string',
 438                      'enum'        => array( 'active', 'inactive' ),
 439                      'context'     => array( 'embed', 'view', 'edit' ),
 440                      'readonly'    => true,
 441                  ),
 442                  'widgets'       => array(
 443                      'description' => __( 'Nested widgets.' ),
 444                      'type'        => 'array',
 445                      'items'       => array(
 446                          'type' => array( 'object', 'string' ),
 447                      ),
 448                      'default'     => array(),
 449                      'context'     => array( 'embed', 'view', 'edit' ),
 450                  ),
 451              ),
 452          );
 453  
 454          $this->schema = $schema;
 455  
 456          return $this->add_additional_fields_schema( $this->schema );
 457      }
 458  }


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