wp/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php
changeset 21 48c4eec2b7e6
child 22 8c2e4d02f4ef
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
       
     1 <?php
       
     2 /**
       
     3  * REST API: WP_REST_Template_Autosaves_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 autosaves via the REST API.
       
    12  *
       
    13  * @since 6.4.0
       
    14  *
       
    15  * @see WP_REST_Autosaves_Controller
       
    16  */
       
    17 class WP_REST_Template_Autosaves_Controller extends WP_REST_Autosaves_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 post controller.
       
    28 	 *
       
    29 	 * @since 6.4.0
       
    30 	 * @var WP_REST_Controller
       
    31 	 */
       
    32 	private $parent_controller;
       
    33 
       
    34 	/**
       
    35 	 * Revision controller.
       
    36 	 *
       
    37 	 * @since 6.4.0
       
    38 	 * @var WP_REST_Revisions_Controller
       
    39 	 */
       
    40 	private $revisions_controller;
       
    41 
       
    42 	/**
       
    43 	 * The base of the parent controller's route.
       
    44 	 *
       
    45 	 * @since 6.4.0
       
    46 	 * @var string
       
    47 	 */
       
    48 	private $parent_base;
       
    49 
       
    50 	/**
       
    51 	 * Constructor.
       
    52 	 *
       
    53 	 * @since 6.4.0
       
    54 	 *
       
    55 	 * @param string $parent_post_type Post type of the parent.
       
    56 	 */
       
    57 	public function __construct( $parent_post_type ) {
       
    58 		parent::__construct( $parent_post_type );
       
    59 		$this->parent_post_type = $parent_post_type;
       
    60 		$post_type_object       = get_post_type_object( $parent_post_type );
       
    61 		$parent_controller      = $post_type_object->get_rest_controller();
       
    62 
       
    63 		if ( ! $parent_controller ) {
       
    64 			$parent_controller = new WP_REST_Templates_Controller( $parent_post_type );
       
    65 		}
       
    66 
       
    67 		$this->parent_controller = $parent_controller;
       
    68 
       
    69 		$revisions_controller = $post_type_object->get_revisions_rest_controller();
       
    70 		if ( ! $revisions_controller ) {
       
    71 			$revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type );
       
    72 		}
       
    73 		$this->revisions_controller = $revisions_controller;
       
    74 		$this->rest_base            = 'autosaves';
       
    75 		$this->parent_base          = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
       
    76 		$this->namespace            = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2';
       
    77 	}
       
    78 
       
    79 	/**
       
    80 	 * Registers the routes for autosaves.
       
    81 	 *
       
    82 	 * @since 6.4.0
       
    83 	 *
       
    84 	 * @see register_rest_route()
       
    85 	 */
       
    86 	public function register_routes() {
       
    87 		register_rest_route(
       
    88 			$this->namespace,
       
    89 			sprintf(
       
    90 				'/%s/(?P<id>%s%s)/%s',
       
    91 				$this->parent_base,
       
    92 				/*
       
    93 				 * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
       
    94 				 * Excludes invalid directory name characters: `/:<>*?"|`.
       
    95 				 */
       
    96 				'([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
       
    97 				// Matches the template name.
       
    98 				'[\/\w%-]+',
       
    99 				$this->rest_base
       
   100 			),
       
   101 			array(
       
   102 				'args'   => array(
       
   103 					'id' => array(
       
   104 						'description'       => __( 'The id of a template' ),
       
   105 						'type'              => 'string',
       
   106 						'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ),
       
   107 					),
       
   108 				),
       
   109 				array(
       
   110 					'methods'             => WP_REST_Server::READABLE,
       
   111 					'callback'            => array( $this, 'get_items' ),
       
   112 					'permission_callback' => array( $this, 'get_items_permissions_check' ),
       
   113 					'args'                => $this->get_collection_params(),
       
   114 				),
       
   115 				array(
       
   116 					'methods'             => WP_REST_Server::CREATABLE,
       
   117 					'callback'            => array( $this, 'create_item' ),
       
   118 					'permission_callback' => array( $this, 'create_item_permissions_check' ),
       
   119 					'args'                => $this->parent_controller->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
       
   120 				),
       
   121 				'schema' => array( $this, 'get_public_item_schema' ),
       
   122 			)
       
   123 		);
       
   124 
       
   125 		register_rest_route(
       
   126 			$this->namespace,
       
   127 			sprintf(
       
   128 				'/%s/(?P<parent>%s%s)/%s/%s',
       
   129 				$this->parent_base,
       
   130 				/*
       
   131 				 * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
       
   132 				 * Excludes invalid directory name characters: `/:<>*?"|`.
       
   133 				 */
       
   134 				'([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
       
   135 				// Matches the template name.
       
   136 				'[\/\w%-]+',
       
   137 				$this->rest_base,
       
   138 				'(?P<id>[\d]+)'
       
   139 			),
       
   140 			array(
       
   141 				'args'   => array(
       
   142 					'parent' => array(
       
   143 						'description'       => __( 'The id of a template' ),
       
   144 						'type'              => 'string',
       
   145 						'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ),
       
   146 					),
       
   147 					'id'     => array(
       
   148 						'description' => __( 'The ID for the autosave.' ),
       
   149 						'type'        => 'integer',
       
   150 					),
       
   151 				),
       
   152 				array(
       
   153 					'methods'             => WP_REST_Server::READABLE,
       
   154 					'callback'            => array( $this, 'get_item' ),
       
   155 					'permission_callback' => array( $this->revisions_controller, 'get_item_permissions_check' ),
       
   156 					'args'                => array(
       
   157 						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
       
   158 					),
       
   159 				),
       
   160 				'schema' => array( $this, 'get_public_item_schema' ),
       
   161 			)
       
   162 		);
       
   163 	}
       
   164 
       
   165 	/**
       
   166 	 * Prepares the item for the REST response.
       
   167 	 *
       
   168 	 * @since 6.4.0
       
   169 	 *
       
   170 	 * @param WP_Post         $item    Post revision object.
       
   171 	 * @param WP_REST_Request $request Request object.
       
   172 	 * @return WP_REST_Response Response object.
       
   173 	 */
       
   174 	public function prepare_item_for_response( $item, $request ) {
       
   175 		$template = _build_block_template_result_from_post( $item );
       
   176 		$response = $this->parent_controller->prepare_item_for_response( $template, $request );
       
   177 
       
   178 		$fields = $this->get_fields_for_response( $request );
       
   179 		$data   = $response->get_data();
       
   180 
       
   181 		if ( in_array( 'parent', $fields, true ) ) {
       
   182 			$data['parent'] = (int) $item->post_parent;
       
   183 		}
       
   184 
       
   185 		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
       
   186 		$data    = $this->filter_response_by_context( $data, $context );
       
   187 
       
   188 		// Wrap the data in a response object.
       
   189 		$response = new WP_REST_Response( $data );
       
   190 
       
   191 		if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
       
   192 			$links = $this->prepare_links( $template );
       
   193 			$response->add_links( $links );
       
   194 		}
       
   195 
       
   196 		return $response;
       
   197 	}
       
   198 
       
   199 	/**
       
   200 	 * Gets the autosave, if the ID is valid.
       
   201 	 *
       
   202 	 * @since 6.4.0
       
   203 	 *
       
   204 	 * @param WP_REST_Request $request Full details about the request.
       
   205 	 * @return WP_Post|WP_Error Autosave post object if ID is valid, WP_Error otherwise.
       
   206 	 */
       
   207 	public function get_item( $request ) {
       
   208 		$parent = $this->get_parent( $request['parent'] );
       
   209 		if ( is_wp_error( $parent ) ) {
       
   210 			return $parent;
       
   211 		}
       
   212 
       
   213 		$autosave = wp_get_post_autosave( $parent->ID );
       
   214 
       
   215 		if ( ! $autosave ) {
       
   216 			return new WP_Error(
       
   217 				'rest_post_no_autosave',
       
   218 				__( 'There is no autosave revision for this template.' ),
       
   219 				array( 'status' => 404 )
       
   220 			);
       
   221 		}
       
   222 
       
   223 		$response = $this->prepare_item_for_response( $autosave, $request );
       
   224 		return $response;
       
   225 	}
       
   226 
       
   227 	/**
       
   228 	 * Get the parent post.
       
   229 	 *
       
   230 	 * @since 6.4.0
       
   231 	 *
       
   232 	 * @param int $parent_id Supplied ID.
       
   233 	 * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
       
   234 	 */
       
   235 	protected function get_parent( $parent_id ) {
       
   236 		return $this->revisions_controller->get_parent( $parent_id );
       
   237 	}
       
   238 
       
   239 	/**
       
   240 	 * Prepares links for the request.
       
   241 	 *
       
   242 	 * @since 6.4.0
       
   243 	 *
       
   244 	 * @param WP_Block_Template $template Template.
       
   245 	 * @return array Links for the given post.
       
   246 	 */
       
   247 	protected function prepare_links( $template ) {
       
   248 		$links = array(
       
   249 			'self'   => array(
       
   250 				'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ),
       
   251 			),
       
   252 			'parent' => array(
       
   253 				'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ),
       
   254 			),
       
   255 		);
       
   256 
       
   257 		return $links;
       
   258 	}
       
   259 
       
   260 	/**
       
   261 	 * Retrieves the autosave's schema, conforming to JSON Schema.
       
   262 	 *
       
   263 	 * @since 6.4.0
       
   264 	 *
       
   265 	 * @return array Item schema data.
       
   266 	 */
       
   267 	public function get_item_schema() {
       
   268 		if ( $this->schema ) {
       
   269 			return $this->add_additional_fields_schema( $this->schema );
       
   270 		}
       
   271 
       
   272 		$this->schema = $this->revisions_controller->get_item_schema();
       
   273 
       
   274 		return $this->add_additional_fields_schema( $this->schema );
       
   275 	}
       
   276 }