[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

   1  <?php
   2  
   3  /**
   4   * REST API: WP_REST_Icons_Controller class
   5   *
   6   * @package    WordPress
   7   * @subpackage REST_API
   8   * @since      7.0.0
   9   */
  10  
  11  /**
  12   * Controller which provides a REST endpoint for the editor to read registered
  13   * icons. Icons are grouped into collections (the default one being `core`).
  14   *
  15   * @since 7.0.0
  16   *
  17   * @see WP_REST_Controller
  18   */
  19  class WP_REST_Icons_Controller extends WP_REST_Controller {
  20  
  21      /**
  22       * Constructs the controller.
  23       *
  24       * @since 7.0.0
  25       */
  26  	public function __construct() {
  27          $this->namespace = 'wp/v2';
  28          $this->rest_base = 'icons';
  29      }
  30  
  31      /**
  32       * Registers the routes for the objects of the controller.
  33       *
  34       * @since 7.0.0
  35       * @since 7.1.0 Added the `/icons/<collection>` collection-scoped route.
  36       */
  37  	public function register_routes() {
  38          register_rest_route(
  39              $this->namespace,
  40              '/' . $this->rest_base,
  41              array(
  42                  array(
  43                      'methods'             => WP_REST_Server::READABLE,
  44                      'callback'            => array( $this, 'get_items' ),
  45                      'permission_callback' => array( $this, 'get_items_permissions_check' ),
  46                      'args'                => $this->get_collection_params(),
  47                  ),
  48                  'schema' => array( $this, 'get_public_item_schema' ),
  49              )
  50          );
  51  
  52          register_rest_route(
  53              $this->namespace,
  54              '/' . $this->rest_base . '/(?P<collection>[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)',
  55              array(
  56                  'args'   => array(
  57                      'collection' => array(
  58                          'description' => __( 'Icon collection slug.' ),
  59                          'type'        => 'string',
  60                      ),
  61                  ),
  62                  array(
  63                      'methods'             => WP_REST_Server::READABLE,
  64                      'callback'            => array( $this, 'get_items' ),
  65                      'permission_callback' => array( $this, 'get_items_permissions_check' ),
  66                      'args'                => $this->get_collection_params(),
  67                  ),
  68                  'schema' => array( $this, 'get_public_item_schema' ),
  69              )
  70          );
  71  
  72          register_rest_route(
  73              $this->namespace,
  74              '/' . $this->rest_base . '/(?P<name>[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?/[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)',
  75              array(
  76                  'args'   => array(
  77                      'name' => array(
  78                          'description' => __( 'Icon name.' ),
  79                          'type'        => 'string',
  80                      ),
  81                  ),
  82                  array(
  83                      'methods'             => WP_REST_Server::READABLE,
  84                      'callback'            => array( $this, 'get_item' ),
  85                      'permission_callback' => array( $this, 'get_item_permissions_check' ),
  86                      'args'                => array(
  87                          'context' => $this->get_context_param( array( 'default' => 'view' ) ),
  88                      ),
  89                  ),
  90                  'schema' => array( $this, 'get_public_item_schema' ),
  91              )
  92          );
  93      }
  94  
  95      /**
  96       * Checks whether a given request has permission to read icons.
  97       *
  98       * @since 7.0.0
  99       *
 100       * @param WP_REST_Request $request Full details about the request.
 101       * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
 102       */
 103  	public function get_items_permissions_check(
 104          // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
 105          $request
 106      ) {
 107          if ( current_user_can( 'edit_posts' ) ) {
 108              return true;
 109          }
 110  
 111          foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
 112              if ( current_user_can( $post_type->cap->edit_posts ) ) {
 113                  return true;
 114              }
 115          }
 116  
 117          return new WP_Error(
 118              'rest_cannot_view',
 119              __( 'Sorry, you are not allowed to view the registered icons.' ),
 120              array( 'status' => rest_authorization_required_code() )
 121          );
 122      }
 123  
 124      /**
 125       * Checks if a given request has access to read a specific icon.
 126       *
 127       * @since 7.0.0
 128       *
 129       * @param WP_REST_Request $request Full details about the request.
 130       * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise.
 131       */
 132  	public function get_item_permissions_check( $request ) {
 133          $check = $this->get_items_permissions_check( $request );
 134          if ( is_wp_error( $check ) ) {
 135              return $check;
 136          }
 137  
 138          return true;
 139      }
 140  
 141      /**
 142       * Retrieves all icons, optionally scoped to a collection.
 143       *
 144       * @since 7.0.0
 145       * @since 7.1.0 Supports filtering by collection.
 146       * @since 7.2.0 Icons belonging to non-public collections are omitted.
 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_items( $request ) {
 152          $collection            = $request->get_param( 'collection' );
 153          $collections_registry  = WP_Icon_Collections_Registry::get_instance();
 154          $registered_collection = null !== $collection ? $collections_registry->get_registered( $collection ) : null;
 155  
 156          if ( null !== $collection && ( null === $registered_collection || ! $registered_collection['public'] ) ) {
 157              return new WP_Error(
 158                  'rest_icon_collection_not_found',
 159                  sprintf(
 160                      /* translators: %s: Icon collection slug. */
 161                      __( 'Icon collection not found: "%s".' ),
 162                      $collection
 163                  ),
 164                  array( 'status' => 404 )
 165              );
 166          }
 167  
 168          $response = array();
 169          $search   = $request->get_param( 'search' );
 170          $icons    = WP_Icons_Registry::get_instance()->get_registered_icons( $search );
 171  
 172          foreach ( $icons as $icon ) {
 173              if ( null !== $collection && ( ! isset( $icon['collection'] ) || $icon['collection'] !== $collection ) ) {
 174                  continue;
 175              }
 176              $icon_collection = isset( $icon['collection'] ) ? $collections_registry->get_registered( $icon['collection'] ) : null;
 177              if ( null === $icon_collection || ! $icon_collection['public'] ) {
 178                  continue;
 179              }
 180              $prepared_icon = $this->prepare_item_for_response( $icon, $request );
 181              $response[]    = $this->prepare_response_for_collection( $prepared_icon );
 182          }
 183          return rest_ensure_response( $response );
 184      }
 185  
 186      /**
 187       * Retrieves a specific icon.
 188       *
 189       * @since 7.0.0
 190       *
 191       * @param WP_REST_Request $request Full details about the request.
 192       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 193       */
 194  	public function get_item( $request ) {
 195          $icon = $this->get_icon( $request['name'] );
 196          if ( is_wp_error( $icon ) ) {
 197              return $icon;
 198          }
 199  
 200          $data = $this->prepare_item_for_response( $icon, $request );
 201          return rest_ensure_response( $data );
 202      }
 203  
 204      /**
 205       * Retrieves a specific icon from the registry.
 206       *
 207       * @since 7.0.0
 208       * @since 7.2.0 Icons belonging to non-public collections are reported as not found.
 209       *
 210       * @param string $name Icon name.
 211       * @return array|WP_Error Icon data on success, or WP_Error object on failure.
 212       */
 213  	public function get_icon( $name ) {
 214          $registry = WP_Icons_Registry::get_instance();
 215          $icon     = $registry->get_registered_icon( $name );
 216  
 217          $collection = null !== $icon && isset( $icon['collection'] )
 218              ? WP_Icon_Collections_Registry::get_instance()->get_registered( $icon['collection'] )
 219              : null;
 220  
 221          if ( null === $icon || null === $collection || ! $collection['public'] ) {
 222              return new WP_Error(
 223                  'rest_icon_not_found',
 224                  sprintf(
 225                      // translators: %s is the name of any user-provided name
 226                      __( 'Icon not found: "%s".' ),
 227                      $name
 228                  ),
 229                  array( 'status' => 404 )
 230              );
 231          }
 232  
 233          return $icon;
 234      }
 235  
 236      /**
 237       * Prepare a raw icon before it gets output in a REST API response.
 238       *
 239       * Adds `collection` and `keywords` fields to the base response while keeping
 240       * the namespaced icon name (e.g. `core/arrow-left`) as the `name` field.
 241       *
 242       * @since 7.0.0
 243       * @since 7.1.0 Added the `collection` field.
 244       * @since 7.2.0 Added the `keywords` field.
 245       *
 246       * @param array           $item    Raw icon as registered, before any changes.
 247       * @param WP_REST_Request $request Request object.
 248       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 249       */
 250  	public function prepare_item_for_response( $item, $request ) {
 251          $fields = $this->get_fields_for_response( $request );
 252          $keys   = array(
 253              'name'       => 'name',
 254              'label'      => 'label',
 255              'content'    => 'content',
 256              'collection' => 'collection',
 257          );
 258          $data   = array();
 259          foreach ( $keys as $item_key => $rest_key ) {
 260              if ( isset( $item[ $item_key ] ) && rest_is_field_included( $rest_key, $fields ) ) {
 261                  $data[ $rest_key ] = $item[ $item_key ];
 262              }
 263          }
 264  
 265          /*
 266           * Keywords are optional at registration time, but the field is always
 267           * present in the response so consumers do not have to handle its absence.
 268           */
 269          if ( rest_is_field_included( 'keywords', $fields ) ) {
 270              $data['keywords'] = isset( $item['keywords'] ) ? array_values( $item['keywords'] ) : array();
 271          }
 272  
 273          $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
 274          $data    = $this->add_additional_fields_to_object( $data, $request );
 275          $data    = $this->filter_response_by_context( $data, $context );
 276          return rest_ensure_response( $data );
 277      }
 278  
 279      /**
 280       * Retrieves the icon schema, conforming to JSON Schema.
 281       *
 282       * @since 7.0.0
 283       * @since 7.1.0 Added the `collection` property.
 284       * @since 7.2.0 Added the `keywords` property.
 285       *
 286       * @return array Item schema data.
 287       */
 288  	public function get_item_schema() {
 289          if ( $this->schema ) {
 290              return $this->add_additional_fields_schema( $this->schema );
 291          }
 292  
 293          $schema = array(
 294              '$schema'    => 'http://json-schema.org/draft-04/schema#',
 295              'title'      => 'icon',
 296              'type'       => 'object',
 297              'properties' => array(
 298                  'name'       => array(
 299                      'description' => __( 'The icon name.' ),
 300                      'type'        => 'string',
 301                      'readonly'    => true,
 302                      'context'     => array( 'view', 'edit', 'embed' ),
 303                  ),
 304                  'label'      => array(
 305                      'description' => __( 'The icon label.' ),
 306                      'type'        => 'string',
 307                      'readonly'    => true,
 308                      'context'     => array( 'view', 'edit', 'embed' ),
 309                  ),
 310                  'content'    => array(
 311                      'description' => __( 'The icon content (SVG markup).' ),
 312                      'type'        => 'string',
 313                      'readonly'    => true,
 314                      'context'     => array( 'view', 'edit', 'embed' ),
 315                  ),
 316                  'collection' => array(
 317                      'description' => __( 'The slug of the collection this icon belongs to.' ),
 318                      'type'        => 'string',
 319                      'readonly'    => true,
 320                      'context'     => array( 'view', 'edit', 'embed' ),
 321                  ),
 322                  'keywords'   => array(
 323                      'description' => __( 'Additional search terms for the icon.' ),
 324                      'type'        => 'array',
 325                      'items'       => array(
 326                          'type' => 'string',
 327                      ),
 328                      'readonly'    => true,
 329                      'context'     => array( 'view', 'edit', 'embed' ),
 330                  ),
 331              ),
 332          );
 333  
 334          $this->schema = $schema;
 335  
 336          return $this->add_additional_fields_schema( $this->schema );
 337      }
 338  
 339      /**
 340       * Retrieves the query params for the icons collection.
 341       *
 342       * @since 7.0.0
 343       * @since 7.1.0 Added the `collection` parameter.
 344       *
 345       * @return array Collection parameters.
 346       */
 347  	public function get_collection_params() {
 348          $query_params                       = parent::get_collection_params();
 349          $query_params['context']['default'] = 'view';
 350          $query_params['collection']         = array(
 351              'description' => __( 'Limit results to icons belonging to the given collection slug.' ),
 352              'type'        => 'string',
 353              'pattern'     => '^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$',
 354          );
 355          return $query_params;
 356      }
 357  }


Generated : Tue Oct 13 08:20:33 2026 Cross-referenced by PHPXref