[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

   1  <?php
   2  /**
   3   * REST API: WP_REST_Block_Directory_Controller class
   4   *
   5   * @package WordPress
   6   * @subpackage REST_API
   7   * @since 5.5.0
   8   */
   9  
  10  /**
  11   * Controller which provides REST endpoint for the blocks.
  12   *
  13   * @since 5.5.0
  14   *
  15   * @see WP_REST_Controller
  16   */
  17  class WP_REST_Block_Directory_Controller extends WP_REST_Controller {
  18  
  19      /**
  20       * Constructs the controller.
  21       */
  22  	public function __construct() {
  23          $this->namespace = 'wp/v2';
  24          $this->rest_base = 'block-directory';
  25      }
  26  
  27      /**
  28       * Registers the necessary REST API routes.
  29       */
  30  	public function register_routes() {
  31          register_rest_route(
  32              $this->namespace,
  33              '/' . $this->rest_base . '/search',
  34              array(
  35                  array(
  36                      'methods'             => WP_REST_Server::READABLE,
  37                      'callback'            => array( $this, 'get_items' ),
  38                      'permission_callback' => array( $this, 'get_items_permissions_check' ),
  39                      'args'                => $this->get_collection_params(),
  40                  ),
  41                  'schema' => array( $this, 'get_public_item_schema' ),
  42              )
  43          );
  44      }
  45  
  46      /**
  47       * Checks whether a given request has permission to install and activate plugins.
  48       *
  49       * @since 5.5.0
  50       *
  51       * @param WP_REST_Request $request Full details about the request.
  52       * @return true|WP_Error True if the request has permission, WP_Error object otherwise.
  53       */
  54  	public function get_items_permissions_check( $request ) {
  55          if ( ! current_user_can( 'install_plugins' ) || ! current_user_can( 'activate_plugins' ) ) {
  56              return new WP_Error(
  57                  'rest_block_directory_cannot_view',
  58                  __( 'Sorry, you are not allowed to browse the block directory.' ),
  59                  array( 'status' => rest_authorization_required_code() )
  60              );
  61          }
  62  
  63          return true;
  64      }
  65  
  66      /**
  67       * Search and retrieve blocks metadata
  68       *
  69       * @since 5.5.0
  70       *
  71       * @param WP_REST_Request $request Full details about the request.
  72       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
  73       */
  74  	public function get_items( $request ) {
  75          require_once  ABSPATH . 'wp-admin/includes/plugin-install.php';
  76          require_once  ABSPATH . 'wp-admin/includes/plugin.php';
  77  
  78          $response = plugins_api(
  79              'query_plugins',
  80              array(
  81                  'block'    => $request['term'],
  82                  'per_page' => $request['per_page'],
  83                  'page'     => $request['page'],
  84              )
  85          );
  86  
  87          if ( is_wp_error( $response ) ) {
  88              $response->add_data( array( 'status' => 500 ) );
  89  
  90              return $response;
  91          }
  92  
  93          $result = array();
  94  
  95          foreach ( $response->plugins as $plugin ) {
  96              // If the API returned a plugin with empty data for 'blocks', skip it.
  97              if ( empty( $plugin['blocks'] ) ) {
  98                  continue;
  99              }
 100  
 101              $data     = $this->prepare_item_for_response( $plugin, $request );
 102              $result[] = $this->prepare_response_for_collection( $data );
 103          }
 104  
 105          return rest_ensure_response( $result );
 106      }
 107  
 108      /**
 109       * Parse block metadata for a block, and prepare it for an API response.
 110       *
 111       * @since 5.5.0
 112       * @since 5.9.0 Renamed `$plugin` to `$item` to match parent class for PHP 8 named parameter support.
 113       *
 114       * @param array           $item    The plugin metadata.
 115       * @param WP_REST_Request $request Request object.
 116       * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
 117       */
 118  	public function prepare_item_for_response( $item, $request ) {
 119          // Restores the more descriptive, specific name for use within this method.
 120          $plugin = $item;
 121  
 122          $fields = $this->get_fields_for_response( $request );
 123  
 124          // There might be multiple blocks in a plugin. Only the first block is mapped.
 125          $block_data = reset( $plugin['blocks'] );
 126  
 127          // A data array containing the properties we'll return.
 128          $block = array(
 129              'name'                => $block_data['name'],
 130              'title'               => ( $block_data['title'] ? $block_data['title'] : $plugin['name'] ),
 131              'description'         => wp_trim_words( $plugin['short_description'], 30, '...' ),
 132              'id'                  => $plugin['slug'],
 133              'rating'              => $plugin['rating'] / 20,
 134              'rating_count'        => (int) $plugin['num_ratings'],
 135              'active_installs'     => (int) $plugin['active_installs'],
 136              'author_block_rating' => $plugin['author_block_rating'] / 20,
 137              'author_block_count'  => (int) $plugin['author_block_count'],
 138              'author'              => wp_strip_all_tags( $plugin['author'] ),
 139              'icon'                => ( isset( $plugin['icons']['1x'] ) ? $plugin['icons']['1x'] : 'block-default' ),
 140              'last_updated'        => gmdate( 'Y-m-d\TH:i:s', strtotime( $plugin['last_updated'] ) ),
 141              'humanized_updated'   => sprintf(
 142                  /* translators: %s: Human-readable time difference. */
 143                  __( '%s ago' ),
 144                  human_time_diff( strtotime( $plugin['last_updated'] ) )
 145              ),
 146          );
 147  
 148          $this->add_additional_fields_to_object( $block, $request );
 149  
 150          $response = new WP_REST_Response( $block );
 151  
 152          if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
 153              $response->add_links( $this->prepare_links( $plugin ) );
 154          }
 155  
 156          return $response;
 157      }
 158  
 159      /**
 160       * Generates a list of links to include in the response for the plugin.
 161       *
 162       * @since 5.5.0
 163       *
 164       * @param array $plugin The plugin data from WordPress.org.
 165       * @return array
 166       */
 167  	protected function prepare_links( $plugin ) {
 168          $links = array(
 169              'https://api.w.org/install-plugin' => array(
 170                  'href' => add_query_arg( 'slug', urlencode( $plugin['slug'] ), rest_url( 'wp/v2/plugins' ) ),
 171              ),
 172          );
 173  
 174          $plugin_file = $this->find_plugin_for_slug( $plugin['slug'] );
 175  
 176          if ( $plugin_file ) {
 177              $links['https://api.w.org/plugin'] = array(
 178                  'href'       => rest_url( 'wp/v2/plugins/' . substr( $plugin_file, 0, - 4 ) ),
 179                  'embeddable' => true,
 180              );
 181          }
 182  
 183          return $links;
 184      }
 185  
 186      /**
 187       * Finds an installed plugin for the given slug.
 188       *
 189       * @since 5.5.0
 190       *
 191       * @param string $slug The WordPress.org directory slug for a plugin.
 192       * @return string The plugin file found matching it.
 193       */
 194  	protected function find_plugin_for_slug( $slug ) {
 195          require_once  ABSPATH . 'wp-admin/includes/plugin.php';
 196  
 197          $plugin_files = get_plugins( '/' . $slug );
 198  
 199          if ( ! $plugin_files ) {
 200              return '';
 201          }
 202  
 203          $plugin_files = array_keys( $plugin_files );
 204  
 205          return $slug . '/' . reset( $plugin_files );
 206      }
 207  
 208      /**
 209       * Retrieves the theme's schema, conforming to JSON Schema.
 210       *
 211       * @since 5.5.0
 212       *
 213       * @return array Item schema data.
 214       */
 215  	public function get_item_schema() {
 216          if ( $this->schema ) {
 217              return $this->add_additional_fields_schema( $this->schema );
 218          }
 219  
 220          $this->schema = array(
 221              '$schema'    => 'http://json-schema.org/draft-04/schema#',
 222              'title'      => 'block-directory-item',
 223              'type'       => 'object',
 224              'properties' => array(
 225                  'name'                => array(
 226                      'description' => __( 'The block name, in namespace/block-name format.' ),
 227                      'type'        => 'string',
 228                      'context'     => array( 'view' ),
 229                  ),
 230                  'title'               => array(
 231                      'description' => __( 'The block title, in human readable format.' ),
 232                      'type'        => 'string',
 233                      'context'     => array( 'view' ),
 234                  ),
 235                  'description'         => array(
 236                      'description' => __( 'A short description of the block, in human readable format.' ),
 237                      'type'        => 'string',
 238                      'context'     => array( 'view' ),
 239                  ),
 240                  'id'                  => array(
 241                      'description' => __( 'The block slug.' ),
 242                      'type'        => 'string',
 243                      'context'     => array( 'view' ),
 244                  ),
 245                  'rating'              => array(
 246                      'description' => __( 'The star rating of the block.' ),
 247                      'type'        => 'number',
 248                      'context'     => array( 'view' ),
 249                  ),
 250                  'rating_count'        => array(
 251                      'description' => __( 'The number of ratings.' ),
 252                      'type'        => 'integer',
 253                      'context'     => array( 'view' ),
 254                  ),
 255                  'active_installs'     => array(
 256                      'description' => __( 'The number sites that have activated this block.' ),
 257                      'type'        => 'integer',
 258                      'context'     => array( 'view' ),
 259                  ),
 260                  'author_block_rating' => array(
 261                      'description' => __( 'The average rating of blocks published by the same author.' ),
 262                      'type'        => 'number',
 263                      'context'     => array( 'view' ),
 264                  ),
 265                  'author_block_count'  => array(
 266                      'description' => __( 'The number of blocks published by the same author.' ),
 267                      'type'        => 'integer',
 268                      'context'     => array( 'view' ),
 269                  ),
 270                  'author'              => array(
 271                      'description' => __( 'The WordPress.org username of the block author.' ),
 272                      'type'        => 'string',
 273                      'context'     => array( 'view' ),
 274                  ),
 275                  'icon'                => array(
 276                      'description' => __( 'The block icon.' ),
 277                      'type'        => 'string',
 278                      'format'      => 'uri',
 279                      'context'     => array( 'view' ),
 280                  ),
 281                  'last_updated'        => array(
 282                      'description' => __( 'The date when the block was last updated.' ),
 283                      'type'        => 'string',
 284                      'format'      => 'date-time',
 285                      'context'     => array( 'view' ),
 286                  ),
 287                  'humanized_updated'   => array(
 288                      'description' => __( 'The date when the block was last updated, in fuzzy human readable format.' ),
 289                      'type'        => 'string',
 290                      'context'     => array( 'view' ),
 291                  ),
 292              ),
 293          );
 294  
 295          return $this->add_additional_fields_schema( $this->schema );
 296      }
 297  
 298      /**
 299       * Retrieves the search params for the blocks collection.
 300       *
 301       * @since 5.5.0
 302       *
 303       * @return array Collection parameters.
 304       */
 305  	public function get_collection_params() {
 306          $query_params = parent::get_collection_params();
 307  
 308          $query_params['context']['default'] = 'view';
 309  
 310          $query_params['term'] = array(
 311              'description' => __( 'Limit result set to blocks matching the search term.' ),
 312              'type'        => 'string',
 313              'required'    => true,
 314              'minLength'   => 1,
 315          );
 316  
 317          unset( $query_params['search'] );
 318  
 319          /**
 320           * Filters REST API collection parameters for the block directory controller.
 321           *
 322           * @since 5.5.0
 323           *
 324           * @param array $query_params JSON Schema-formatted collection parameters.
 325           */
 326          return apply_filters( 'rest_block_directory_collection_params', $query_params );
 327      }
 328  }


Generated : Fri Apr 19 08:20:01 2024 Cross-referenced by PHPXref