[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

   1  <?php
   2  /**
   3   * REST API: WP_REST_Template_Revisions_Controller class
   4   *
   5   * @package WordPress
   6   * @subpackage REST_API
   7   * @since 6.4.0
   8   */
   9  
  10  /**
  11   * Core class used to access template revisions via the REST API.
  12   *
  13   * @since 6.4.0
  14   *
  15   * @see WP_REST_Controller
  16   */
  17  class WP_REST_Template_Revisions_Controller extends WP_REST_Revisions_Controller {
  18      /**
  19       * Parent post type.
  20       *
  21       * @since 6.4.0
  22       * @var string
  23       */
  24      private $parent_post_type;
  25  
  26      /**
  27       * Parent controller.
  28       *
  29       * @since 6.4.0
  30       * @var WP_REST_Controller
  31       */
  32      private $parent_controller;
  33  
  34      /**
  35       * The base of the parent controller's route.
  36       *
  37       * @since 6.4.0
  38       * @var string
  39       */
  40      private $parent_base;
  41  
  42      /**
  43       * Constructor.
  44       *
  45       * @since 6.4.0
  46       *
  47       * @param string $parent_post_type Post type of the parent.
  48       */
  49  	public function __construct( $parent_post_type ) {
  50          parent::__construct( $parent_post_type );
  51          $this->parent_post_type = $parent_post_type;
  52          $post_type_object       = get_post_type_object( $parent_post_type );
  53          $parent_controller      = $post_type_object->get_rest_controller();
  54  
  55          if ( ! $parent_controller ) {
  56              $parent_controller = new WP_REST_Templates_Controller( $parent_post_type );
  57          }
  58  
  59          $this->parent_controller = $parent_controller;
  60          $this->rest_base         = 'revisions';
  61          $this->parent_base       = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
  62          $this->namespace         = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2';
  63      }
  64  
  65      /**
  66       * Registers the routes for revisions based on post types supporting revisions.
  67       *
  68       * @since 6.4.0
  69       *
  70       * @see register_rest_route()
  71       */
  72  	public function register_routes() {
  73  
  74          register_rest_route(
  75              $this->namespace,
  76              sprintf(
  77                  '/%s/(?P<parent>%s%s)/%s',
  78                  $this->parent_base,
  79                  /*
  80                   * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
  81                   * Excludes invalid directory name characters: `/:<>*?"|`.
  82                   */
  83                  '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
  84                  // Matches the template name.
  85                  '[\/\w%-]+',
  86                  $this->rest_base
  87              ),
  88              array(
  89                  'args'   => array(
  90                      'parent' => array(
  91                          'description'       => __( 'The id of a template' ),
  92                          'type'              => 'string',
  93                          'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ),
  94                      ),
  95                  ),
  96                  array(
  97                      'methods'             => WP_REST_Server::READABLE,
  98                      'callback'            => array( $this, 'get_items' ),
  99                      'permission_callback' => array( $this, 'get_items_permissions_check' ),
 100                      'args'                => $this->get_collection_params(),
 101                  ),
 102                  'schema' => array( $this, 'get_public_item_schema' ),
 103              )
 104          );
 105  
 106          register_rest_route(
 107              $this->namespace,
 108              sprintf(
 109                  '/%s/(?P<parent>%s%s)/%s/%s',
 110                  $this->parent_base,
 111                  /*
 112                   * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
 113                   * Excludes invalid directory name characters: `/:<>*?"|`.
 114                   */
 115                  '([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
 116                  // Matches the template name.
 117                  '[\/\w%-]+',
 118                  $this->rest_base,
 119                  '(?P<id>[\d]+)'
 120              ),
 121              array(
 122                  'args'   => array(
 123                      'parent' => array(
 124                          'description'       => __( 'The id of a template' ),
 125                          'type'              => 'string',
 126                          'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ),
 127                      ),
 128                      'id'     => array(
 129                          'description' => __( 'Unique identifier for the revision.' ),
 130                          'type'        => 'integer',
 131                      ),
 132                  ),
 133                  array(
 134                      'methods'             => WP_REST_Server::READABLE,
 135                      'callback'            => array( $this, 'get_item' ),
 136                      'permission_callback' => array( $this, 'get_item_permissions_check' ),
 137                      'args'                => array(
 138                          'context' => $this->get_context_param( array( 'default' => 'view' ) ),
 139                      ),
 140                  ),
 141                  array(
 142                      'methods'             => WP_REST_Server::DELETABLE,
 143                      'callback'            => array( $this, 'delete_item' ),
 144                      'permission_callback' => array( $this, 'delete_item_permissions_check' ),
 145                      'args'                => array(
 146                          'force' => array(
 147                              'type'        => 'boolean',
 148                              'default'     => false,
 149                              'description' => __( 'Required to be true, as revisions do not support trashing.' ),
 150                          ),
 151                      ),
 152                  ),
 153                  'schema' => array( $this, 'get_public_item_schema' ),
 154              )
 155          );
 156      }
 157  
 158      /**
 159       * Gets the parent post, if the template ID is valid.
 160       *
 161       * @since 6.4.0
 162       *
 163       * @param string $parent_template_id Supplied ID.
 164       * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
 165       */
 166  	protected function get_parent( $parent_template_id ) {
 167          $template = get_block_template( $parent_template_id, $this->parent_post_type );
 168  
 169          if ( ! $template ) {
 170              return new WP_Error(
 171                  'rest_post_invalid_parent',
 172                  __( 'Invalid template parent ID.' ),
 173                  array( 'status' => 404 )
 174              );
 175          }
 176  
 177          return get_post( $template->wp_id );
 178      }
 179  
 180      /**
 181       * Prepares the item for the REST response.
 182       *
 183       * @since 6.4.0
 184       *
 185       * @param WP_Post         $item    Post revision object.
 186       * @param WP_REST_Request $request Request object.
 187       * @return WP_REST_Response Response object.
 188       */
 189  	public function prepare_item_for_response( $item, $request ) {
 190          $template = _build_block_template_result_from_post( $item );
 191          $response = $this->parent_controller->prepare_item_for_response( $template, $request );
 192  
 193          $fields = $this->get_fields_for_response( $request );
 194          $data   = $response->get_data();
 195  
 196          if ( in_array( 'parent', $fields, true ) ) {
 197              $data['parent'] = (int) $item->post_parent;
 198          }
 199  
 200          $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
 201          $data    = $this->filter_response_by_context( $data, $context );
 202  
 203          // Wrap the data in a response object.
 204          $response = new WP_REST_Response( $data );
 205  
 206          if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
 207              $links = $this->prepare_links( $template );
 208              $response->add_links( $links );
 209          }
 210  
 211          return $response;
 212      }
 213  
 214      /**
 215       * Checks if a given request has access to delete a revision.
 216       *
 217       * @since 6.4.0
 218       *
 219       * @param WP_REST_Request $request Full details about the request.
 220       * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
 221       */
 222  	public function delete_item_permissions_check( $request ) {
 223          $parent = $this->get_parent( $request['parent'] );
 224          if ( is_wp_error( $parent ) ) {
 225              return $parent;
 226          }
 227  
 228          if ( ! current_user_can( 'delete_post', $parent->ID ) ) {
 229              return new WP_Error(
 230                  'rest_cannot_delete',
 231                  __( 'Sorry, you are not allowed to delete revisions of this post.' ),
 232                  array( 'status' => rest_authorization_required_code() )
 233              );
 234          }
 235  
 236          $revision = $this->get_revision( $request['id'] );
 237          if ( is_wp_error( $revision ) ) {
 238              return $revision;
 239          }
 240  
 241          if ( ! current_user_can( 'edit_theme_options' ) ) {
 242              return new WP_Error(
 243                  'rest_cannot_delete',
 244                  __( 'Sorry, you are not allowed to delete this revision.' ),
 245                  array( 'status' => rest_authorization_required_code() )
 246              );
 247          }
 248  
 249          return true;
 250      }
 251  
 252      /**
 253       * Prepares links for the request.
 254       *
 255       * @since 6.4.0
 256       *
 257       * @param WP_Block_Template $template Template.
 258       * @return array Links for the given post.
 259       */
 260  	protected function prepare_links( $template ) {
 261          $links = array(
 262              'self'   => array(
 263                  'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ),
 264              ),
 265              'parent' => array(
 266                  'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ),
 267              ),
 268          );
 269  
 270          return $links;
 271      }
 272  
 273      /**
 274       * Retrieves the item's schema, conforming to JSON Schema.
 275       *
 276       * @since 6.4.0
 277       *
 278       * @return array Item schema data.
 279       */
 280  	public function get_item_schema() {
 281          if ( $this->schema ) {
 282              return $this->add_additional_fields_schema( $this->schema );
 283          }
 284  
 285          $schema = $this->parent_controller->get_item_schema();
 286  
 287          $schema['properties']['parent'] = array(
 288              'description' => __( 'The ID for the parent of the revision.' ),
 289              'type'        => 'integer',
 290              'context'     => array( 'view', 'edit', 'embed' ),
 291          );
 292  
 293          $this->schema = $schema;
 294  
 295          return $this->add_additional_fields_schema( $this->schema );
 296      }
 297  }


Generated : Tue Dec 24 08:20:01 2024 Cross-referenced by PHPXref