[ 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' => WP_Http::NOT_FOUND )
 174              );
 175          }
 176  
 177          $parent_post_id = isset( $template->wp_id ) ? (int) $template->wp_id : 0;
 178  
 179          if ( $parent_post_id <= 0 ) {
 180              return new WP_Error(
 181                  'rest_invalid_template',
 182                  __( 'Templates based on theme files can\'t have revisions.' ),
 183                  array( 'status' => WP_Http::BAD_REQUEST )
 184              );
 185          }
 186  
 187          return get_post( $template->wp_id );
 188      }
 189  
 190      /**
 191       * Prepares the item for the REST response.
 192       *
 193       * @since 6.4.0
 194       *
 195       * @param WP_Post         $item    Post revision object.
 196       * @param WP_REST_Request $request Request object.
 197       * @return WP_REST_Response Response object.
 198       */
 199  	public function prepare_item_for_response( $item, $request ) {
 200          $template = _build_block_template_result_from_post( $item );
 201          $response = $this->parent_controller->prepare_item_for_response( $template, $request );
 202  
 203          $fields = $this->get_fields_for_response( $request );
 204          $data   = $response->get_data();
 205  
 206          if ( in_array( 'parent', $fields, true ) ) {
 207              $data['parent'] = (int) $item->post_parent;
 208          }
 209  
 210          $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
 211          $data    = $this->filter_response_by_context( $data, $context );
 212  
 213          // Wrap the data in a response object.
 214          $response = new WP_REST_Response( $data );
 215  
 216          if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
 217              $links = $this->prepare_links( $template );
 218              $response->add_links( $links );
 219          }
 220  
 221          return $response;
 222      }
 223  
 224      /**
 225       * Checks if a given request has access to delete a revision.
 226       *
 227       * @since 6.4.0
 228       *
 229       * @param WP_REST_Request $request Full details about the request.
 230       * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
 231       */
 232  	public function delete_item_permissions_check( $request ) {
 233          $parent = $this->get_parent( $request['parent'] );
 234          if ( is_wp_error( $parent ) ) {
 235              return $parent;
 236          }
 237  
 238          if ( ! current_user_can( 'delete_post', $parent->ID ) ) {
 239              return new WP_Error(
 240                  'rest_cannot_delete',
 241                  __( 'Sorry, you are not allowed to delete revisions of this post.' ),
 242                  array( 'status' => rest_authorization_required_code() )
 243              );
 244          }
 245  
 246          $revision = $this->get_revision( $request['id'] );
 247          if ( is_wp_error( $revision ) ) {
 248              return $revision;
 249          }
 250  
 251          if ( ! current_user_can( 'edit_theme_options' ) ) {
 252              return new WP_Error(
 253                  'rest_cannot_delete',
 254                  __( 'Sorry, you are not allowed to delete this revision.' ),
 255                  array( 'status' => rest_authorization_required_code() )
 256              );
 257          }
 258  
 259          return true;
 260      }
 261  
 262      /**
 263       * Prepares links for the request.
 264       *
 265       * @since 6.4.0
 266       *
 267       * @param WP_Block_Template $template Template.
 268       * @return array Links for the given post.
 269       */
 270  	protected function prepare_links( $template ) {
 271          $links = array(
 272              'self'   => array(
 273                  'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ),
 274              ),
 275              'parent' => array(
 276                  'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ),
 277              ),
 278          );
 279  
 280          return $links;
 281      }
 282  
 283      /**
 284       * Retrieves the item's schema, conforming to JSON Schema.
 285       *
 286       * @since 6.4.0
 287       *
 288       * @return array Item schema data.
 289       */
 290  	public function get_item_schema() {
 291          if ( $this->schema ) {
 292              return $this->add_additional_fields_schema( $this->schema );
 293          }
 294  
 295          $schema = $this->parent_controller->get_item_schema();
 296  
 297          $schema['properties']['parent'] = array(
 298              'description' => __( 'The ID for the parent of the revision.' ),
 299              'type'        => 'integer',
 300              'context'     => array( 'view', 'edit', 'embed' ),
 301          );
 302  
 303          $this->schema = $schema;
 304  
 305          return $this->add_additional_fields_schema( $this->schema );
 306      }
 307  }


Generated : Thu Jan 30 08:20:01 2025 Cross-referenced by PHPXref