wp/wp-includes/rest-api/endpoints/class-wp-rest-block-patterns-controller.php
changeset 19 3d72ae0968f4
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
       
     1 <?php
       
     2 /**
       
     3  * REST API: WP_REST_Block_Patterns_Controller class
       
     4  *
       
     5  * @package    WordPress
       
     6  * @subpackage REST_API
       
     7  * @since      6.0.0
       
     8  */
       
     9 
       
    10 /**
       
    11  * Core class used to access block patterns via the REST API.
       
    12  *
       
    13  * @since 6.0.0
       
    14  *
       
    15  * @see WP_REST_Controller
       
    16  */
       
    17 class WP_REST_Block_Patterns_Controller extends WP_REST_Controller {
       
    18 
       
    19 	/**
       
    20 	 * Defines whether remote patterns should be loaded.
       
    21 	 *
       
    22 	 * @since 6.0.0
       
    23 	 * @var bool
       
    24 	 */
       
    25 	private $remote_patterns_loaded;
       
    26 
       
    27 	/**
       
    28 	 * Constructs the controller.
       
    29 	 *
       
    30 	 * @since 6.0.0
       
    31 	 */
       
    32 	public function __construct() {
       
    33 		$this->namespace = 'wp/v2';
       
    34 		$this->rest_base = 'block-patterns/patterns';
       
    35 	}
       
    36 
       
    37 	/**
       
    38 	 * Registers the routes for the objects of the controller.
       
    39 	 *
       
    40 	 * @since 6.0.0
       
    41 	 */
       
    42 	public function register_routes() {
       
    43 		register_rest_route(
       
    44 			$this->namespace,
       
    45 			'/' . $this->rest_base,
       
    46 			array(
       
    47 				array(
       
    48 					'methods'             => WP_REST_Server::READABLE,
       
    49 					'callback'            => array( $this, 'get_items' ),
       
    50 					'permission_callback' => array( $this, 'get_items_permissions_check' ),
       
    51 				),
       
    52 				'schema' => array( $this, 'get_public_item_schema' ),
       
    53 			)
       
    54 		);
       
    55 	}
       
    56 
       
    57 	/**
       
    58 	 * Checks whether a given request has permission to read block patterns.
       
    59 	 *
       
    60 	 * @since 6.0.0
       
    61 	 *
       
    62 	 * @param WP_REST_Request $request Full details about the request.
       
    63 	 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
       
    64 	 */
       
    65 	public function get_items_permissions_check( $request ) {
       
    66 		if ( current_user_can( 'edit_posts' ) ) {
       
    67 			return true;
       
    68 		}
       
    69 
       
    70 		foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
       
    71 			if ( current_user_can( $post_type->cap->edit_posts ) ) {
       
    72 				return true;
       
    73 			}
       
    74 		}
       
    75 
       
    76 		return new WP_Error(
       
    77 			'rest_cannot_view',
       
    78 			__( 'Sorry, you are not allowed to view the registered block patterns.' ),
       
    79 			array( 'status' => rest_authorization_required_code() )
       
    80 		);
       
    81 	}
       
    82 
       
    83 	/**
       
    84 	 * Retrieves all block patterns.
       
    85 	 *
       
    86 	 * @since 6.0.0
       
    87 	 *
       
    88 	 * @param WP_REST_Request $request Full details about the request.
       
    89 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
       
    90 	 */
       
    91 	public function get_items( $request ) {
       
    92 		if ( ! $this->remote_patterns_loaded ) {
       
    93 			// Load block patterns from w.org.
       
    94 			_load_remote_block_patterns(); // Patterns with the `core` keyword.
       
    95 			_load_remote_featured_patterns(); // Patterns in the `featured` category.
       
    96 			_register_remote_theme_patterns(); // Patterns requested by current theme.
       
    97 
       
    98 			$this->remote_patterns_loaded = true;
       
    99 		}
       
   100 
       
   101 		$response = array();
       
   102 		$patterns = WP_Block_Patterns_Registry::get_instance()->get_all_registered();
       
   103 		foreach ( $patterns as $pattern ) {
       
   104 			$prepared_pattern = $this->prepare_item_for_response( $pattern, $request );
       
   105 			$response[]       = $this->prepare_response_for_collection( $prepared_pattern );
       
   106 		}
       
   107 		return rest_ensure_response( $response );
       
   108 	}
       
   109 
       
   110 	/**
       
   111 	 * Prepare a raw block pattern before it gets output in a REST API response.
       
   112 	 *
       
   113 	 * @since 6.0.0
       
   114 	 *
       
   115 	 * @param array           $item    Raw pattern as registered, before any changes.
       
   116 	 * @param WP_REST_Request $request Request object.
       
   117 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
       
   118 	 */
       
   119 	public function prepare_item_for_response( $item, $request ) {
       
   120 		$fields = $this->get_fields_for_response( $request );
       
   121 		$keys   = array(
       
   122 			'name'          => 'name',
       
   123 			'title'         => 'title',
       
   124 			'description'   => 'description',
       
   125 			'viewportWidth' => 'viewport_width',
       
   126 			'blockTypes'    => 'block_types',
       
   127 			'categories'    => 'categories',
       
   128 			'keywords'      => 'keywords',
       
   129 			'content'       => 'content',
       
   130 			'inserter'      => 'inserter',
       
   131 		);
       
   132 		$data   = array();
       
   133 		foreach ( $keys as $item_key => $rest_key ) {
       
   134 			if ( isset( $item[ $item_key ] ) && rest_is_field_included( $rest_key, $fields ) ) {
       
   135 				$data[ $rest_key ] = $item[ $item_key ];
       
   136 			}
       
   137 		}
       
   138 
       
   139 		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
       
   140 		$data    = $this->add_additional_fields_to_object( $data, $request );
       
   141 		$data    = $this->filter_response_by_context( $data, $context );
       
   142 		return rest_ensure_response( $data );
       
   143 	}
       
   144 
       
   145 	/**
       
   146 	 * Retrieves the block pattern schema, conforming to JSON Schema.
       
   147 	 *
       
   148 	 * @since 6.0.0
       
   149 	 *
       
   150 	 * @return array Item schema data.
       
   151 	 */
       
   152 	public function get_item_schema() {
       
   153 		$schema = array(
       
   154 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
       
   155 			'title'      => 'block-pattern',
       
   156 			'type'       => 'object',
       
   157 			'properties' => array(
       
   158 				'name'           => array(
       
   159 					'description' => __( 'The pattern name.' ),
       
   160 					'type'        => 'string',
       
   161 					'readonly'    => true,
       
   162 					'context'     => array( 'view', 'edit', 'embed' ),
       
   163 				),
       
   164 				'title'          => array(
       
   165 					'description' => __( 'The pattern title, in human readable format.' ),
       
   166 					'type'        => 'string',
       
   167 					'readonly'    => true,
       
   168 					'context'     => array( 'view', 'edit', 'embed' ),
       
   169 				),
       
   170 				'description'    => array(
       
   171 					'description' => __( 'The pattern detailed description.' ),
       
   172 					'type'        => 'string',
       
   173 					'readonly'    => true,
       
   174 					'context'     => array( 'view', 'edit', 'embed' ),
       
   175 				),
       
   176 				'viewport_width' => array(
       
   177 					'description' => __( 'The pattern viewport width for inserter preview.' ),
       
   178 					'type'        => 'number',
       
   179 					'readonly'    => true,
       
   180 					'context'     => array( 'view', 'edit', 'embed' ),
       
   181 				),
       
   182 				'block_types'    => array(
       
   183 					'description' => __( 'Block types that the pattern is intended to be used with.' ),
       
   184 					'type'        => 'array',
       
   185 					'readonly'    => true,
       
   186 					'context'     => array( 'view', 'edit', 'embed' ),
       
   187 				),
       
   188 				'categories'     => array(
       
   189 					'description' => __( 'The pattern category slugs.' ),
       
   190 					'type'        => 'array',
       
   191 					'readonly'    => true,
       
   192 					'context'     => array( 'view', 'edit', 'embed' ),
       
   193 				),
       
   194 				'keywords'       => array(
       
   195 					'description' => __( 'The pattern keywords.' ),
       
   196 					'type'        => 'array',
       
   197 					'readonly'    => true,
       
   198 					'context'     => array( 'view', 'edit', 'embed' ),
       
   199 				),
       
   200 				'content'        => array(
       
   201 					'description' => __( 'The pattern content.' ),
       
   202 					'type'        => 'string',
       
   203 					'readonly'    => true,
       
   204 					'context'     => array( 'view', 'edit', 'embed' ),
       
   205 				),
       
   206 				'inserter'       => array(
       
   207 					'description' => __( 'Determines whether the pattern is visible in inserter.' ),
       
   208 					'type'        => 'boolean',
       
   209 					'readonly'    => true,
       
   210 					'context'     => array( 'view', 'edit', 'embed' ),
       
   211 				),
       
   212 			),
       
   213 		);
       
   214 
       
   215 		return $this->add_additional_fields_schema( $schema );
       
   216 	}
       
   217 }