balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-wp-rest-post-statuses-controller.php (10081B)


      1 <?php
      2 /**
      3  * REST API: WP_REST_Post_Statuses_Controller class
      4  *
      5  * @package WordPress
      6  * @subpackage REST_API
      7  * @since 4.7.0
      8  */
      9 
     10 /**
     11  * Core class used to access post statuses via the REST API.
     12  *
     13  * @since 4.7.0
     14  *
     15  * @see WP_REST_Controller
     16  */
     17 class WP_REST_Post_Statuses_Controller extends WP_REST_Controller {
     18 
     19 	/**
     20 	 * Constructor.
     21 	 *
     22 	 * @since 4.7.0
     23 	 */
     24 	public function __construct() {
     25 		$this->namespace = 'wp/v2';
     26 		$this->rest_base = 'statuses';
     27 	}
     28 
     29 	/**
     30 	 * Registers the routes for post statuses.
     31 	 *
     32 	 * @since 4.7.0
     33 	 *
     34 	 * @see register_rest_route()
     35 	 */
     36 	public function register_routes() {
     37 
     38 		register_rest_route(
     39 			$this->namespace,
     40 			'/' . $this->rest_base,
     41 			array(
     42 				array(
     43 					'methods'             => WP_REST_Server::READABLE,
     44 					'callback'            => array( $this, 'get_items' ),
     45 					'permission_callback' => array( $this, 'get_items_permissions_check' ),
     46 					'args'                => $this->get_collection_params(),
     47 				),
     48 				'schema' => array( $this, 'get_public_item_schema' ),
     49 			)
     50 		);
     51 
     52 		register_rest_route(
     53 			$this->namespace,
     54 			'/' . $this->rest_base . '/(?P<status>[\w-]+)',
     55 			array(
     56 				'args'   => array(
     57 					'status' => array(
     58 						'description' => __( 'An alphanumeric identifier for the status.' ),
     59 						'type'        => 'string',
     60 					),
     61 				),
     62 				array(
     63 					'methods'             => WP_REST_Server::READABLE,
     64 					'callback'            => array( $this, 'get_item' ),
     65 					'permission_callback' => array( $this, 'get_item_permissions_check' ),
     66 					'args'                => array(
     67 						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
     68 					),
     69 				),
     70 				'schema' => array( $this, 'get_public_item_schema' ),
     71 			)
     72 		);
     73 	}
     74 
     75 	/**
     76 	 * Checks whether a given request has permission to read post statuses.
     77 	 *
     78 	 * @since 4.7.0
     79 	 *
     80 	 * @param WP_REST_Request $request Full details about the request.
     81 	 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
     82 	 */
     83 	public function get_items_permissions_check( $request ) {
     84 		if ( 'edit' === $request['context'] ) {
     85 			$types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
     86 
     87 			foreach ( $types as $type ) {
     88 				if ( current_user_can( $type->cap->edit_posts ) ) {
     89 					return true;
     90 				}
     91 			}
     92 
     93 			return new WP_Error(
     94 				'rest_cannot_view',
     95 				__( 'Sorry, you are not allowed to manage post statuses.' ),
     96 				array( 'status' => rest_authorization_required_code() )
     97 			);
     98 		}
     99 
    100 		return true;
    101 	}
    102 
    103 	/**
    104 	 * Retrieves all post statuses, depending on user context.
    105 	 *
    106 	 * @since 4.7.0
    107 	 *
    108 	 * @param WP_REST_Request $request Full details about the request.
    109 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
    110 	 */
    111 	public function get_items( $request ) {
    112 		$data              = array();
    113 		$statuses          = get_post_stati( array( 'internal' => false ), 'object' );
    114 		$statuses['trash'] = get_post_status_object( 'trash' );
    115 
    116 		foreach ( $statuses as $slug => $obj ) {
    117 			$ret = $this->check_read_permission( $obj );
    118 
    119 			if ( ! $ret ) {
    120 				continue;
    121 			}
    122 
    123 			$status             = $this->prepare_item_for_response( $obj, $request );
    124 			$data[ $obj->name ] = $this->prepare_response_for_collection( $status );
    125 		}
    126 
    127 		return rest_ensure_response( $data );
    128 	}
    129 
    130 	/**
    131 	 * Checks if a given request has access to read a post status.
    132 	 *
    133 	 * @since 4.7.0
    134 	 *
    135 	 * @param WP_REST_Request $request Full details about the request.
    136 	 * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise.
    137 	 */
    138 	public function get_item_permissions_check( $request ) {
    139 		$status = get_post_status_object( $request['status'] );
    140 
    141 		if ( empty( $status ) ) {
    142 			return new WP_Error(
    143 				'rest_status_invalid',
    144 				__( 'Invalid status.' ),
    145 				array( 'status' => 404 )
    146 			);
    147 		}
    148 
    149 		$check = $this->check_read_permission( $status );
    150 
    151 		if ( ! $check ) {
    152 			return new WP_Error(
    153 				'rest_cannot_read_status',
    154 				__( 'Cannot view status.' ),
    155 				array( 'status' => rest_authorization_required_code() )
    156 			);
    157 		}
    158 
    159 		return true;
    160 	}
    161 
    162 	/**
    163 	 * Checks whether a given post status should be visible.
    164 	 *
    165 	 * @since 4.7.0
    166 	 *
    167 	 * @param object $status Post status.
    168 	 * @return bool True if the post status is visible, otherwise false.
    169 	 */
    170 	protected function check_read_permission( $status ) {
    171 		if ( true === $status->public ) {
    172 			return true;
    173 		}
    174 
    175 		if ( false === $status->internal || 'trash' === $status->name ) {
    176 			$types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
    177 
    178 			foreach ( $types as $type ) {
    179 				if ( current_user_can( $type->cap->edit_posts ) ) {
    180 					return true;
    181 				}
    182 			}
    183 		}
    184 
    185 		return false;
    186 	}
    187 
    188 	/**
    189 	 * Retrieves a specific post status.
    190 	 *
    191 	 * @since 4.7.0
    192 	 *
    193 	 * @param WP_REST_Request $request Full details about the request.
    194 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
    195 	 */
    196 	public function get_item( $request ) {
    197 		$obj = get_post_status_object( $request['status'] );
    198 
    199 		if ( empty( $obj ) ) {
    200 			return new WP_Error(
    201 				'rest_status_invalid',
    202 				__( 'Invalid status.' ),
    203 				array( 'status' => 404 )
    204 			);
    205 		}
    206 
    207 		$data = $this->prepare_item_for_response( $obj, $request );
    208 
    209 		return rest_ensure_response( $data );
    210 	}
    211 
    212 	/**
    213 	 * Prepares a post status object for serialization.
    214 	 *
    215 	 * @since 4.7.0
    216 	 *
    217 	 * @param stdClass        $status  Post status data.
    218 	 * @param WP_REST_Request $request Full details about the request.
    219 	 * @return WP_REST_Response Post status data.
    220 	 */
    221 	public function prepare_item_for_response( $status, $request ) {
    222 
    223 		$fields = $this->get_fields_for_response( $request );
    224 		$data   = array();
    225 
    226 		if ( in_array( 'name', $fields, true ) ) {
    227 			$data['name'] = $status->label;
    228 		}
    229 
    230 		if ( in_array( 'private', $fields, true ) ) {
    231 			$data['private'] = (bool) $status->private;
    232 		}
    233 
    234 		if ( in_array( 'protected', $fields, true ) ) {
    235 			$data['protected'] = (bool) $status->protected;
    236 		}
    237 
    238 		if ( in_array( 'public', $fields, true ) ) {
    239 			$data['public'] = (bool) $status->public;
    240 		}
    241 
    242 		if ( in_array( 'queryable', $fields, true ) ) {
    243 			$data['queryable'] = (bool) $status->publicly_queryable;
    244 		}
    245 
    246 		if ( in_array( 'show_in_list', $fields, true ) ) {
    247 			$data['show_in_list'] = (bool) $status->show_in_admin_all_list;
    248 		}
    249 
    250 		if ( in_array( 'slug', $fields, true ) ) {
    251 			$data['slug'] = $status->name;
    252 		}
    253 
    254 		if ( in_array( 'date_floating', $fields, true ) ) {
    255 			$data['date_floating'] = $status->date_floating;
    256 		}
    257 
    258 		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
    259 		$data    = $this->add_additional_fields_to_object( $data, $request );
    260 		$data    = $this->filter_response_by_context( $data, $context );
    261 
    262 		$response = rest_ensure_response( $data );
    263 
    264 		if ( 'publish' === $status->name ) {
    265 			$response->add_link( 'archives', rest_url( 'wp/v2/posts' ) );
    266 		} else {
    267 			$response->add_link( 'archives', add_query_arg( 'status', $status->name, rest_url( 'wp/v2/posts' ) ) );
    268 		}
    269 
    270 		/**
    271 		 * Filters a post status returned from the REST API.
    272 		 *
    273 		 * Allows modification of the status data right before it is returned.
    274 		 *
    275 		 * @since 4.7.0
    276 		 *
    277 		 * @param WP_REST_Response $response The response object.
    278 		 * @param object           $status   The original post status object.
    279 		 * @param WP_REST_Request  $request  Request used to generate the response.
    280 		 */
    281 		return apply_filters( 'rest_prepare_status', $response, $status, $request );
    282 	}
    283 
    284 	/**
    285 	 * Retrieves the post status' schema, conforming to JSON Schema.
    286 	 *
    287 	 * @since 4.7.0
    288 	 *
    289 	 * @return array Item schema data.
    290 	 */
    291 	public function get_item_schema() {
    292 		if ( $this->schema ) {
    293 			return $this->add_additional_fields_schema( $this->schema );
    294 		}
    295 
    296 		$schema = array(
    297 			'$schema'    => 'http://json-schema.org/draft-04/schema#',
    298 			'title'      => 'status',
    299 			'type'       => 'object',
    300 			'properties' => array(
    301 				'name'          => array(
    302 					'description' => __( 'The title for the status.' ),
    303 					'type'        => 'string',
    304 					'context'     => array( 'embed', 'view', 'edit' ),
    305 					'readonly'    => true,
    306 				),
    307 				'private'       => array(
    308 					'description' => __( 'Whether posts with this status should be private.' ),
    309 					'type'        => 'boolean',
    310 					'context'     => array( 'edit' ),
    311 					'readonly'    => true,
    312 				),
    313 				'protected'     => array(
    314 					'description' => __( 'Whether posts with this status should be protected.' ),
    315 					'type'        => 'boolean',
    316 					'context'     => array( 'edit' ),
    317 					'readonly'    => true,
    318 				),
    319 				'public'        => array(
    320 					'description' => __( 'Whether posts of this status should be shown in the front end of the site.' ),
    321 					'type'        => 'boolean',
    322 					'context'     => array( 'view', 'edit' ),
    323 					'readonly'    => true,
    324 				),
    325 				'queryable'     => array(
    326 					'description' => __( 'Whether posts with this status should be publicly-queryable.' ),
    327 					'type'        => 'boolean',
    328 					'context'     => array( 'view', 'edit' ),
    329 					'readonly'    => true,
    330 				),
    331 				'show_in_list'  => array(
    332 					'description' => __( 'Whether to include posts in the edit listing for their post type.' ),
    333 					'type'        => 'boolean',
    334 					'context'     => array( 'edit' ),
    335 					'readonly'    => true,
    336 				),
    337 				'slug'          => array(
    338 					'description' => __( 'An alphanumeric identifier for the status.' ),
    339 					'type'        => 'string',
    340 					'context'     => array( 'embed', 'view', 'edit' ),
    341 					'readonly'    => true,
    342 				),
    343 				'date_floating' => array(
    344 					'description' => __( 'Whether posts of this status may have floating published dates.' ),
    345 					'type'        => 'boolean',
    346 					'context'     => array( 'view', 'edit' ),
    347 					'readonly'    => true,
    348 				),
    349 			),
    350 		);
    351 
    352 		$this->schema = $schema;
    353 
    354 		return $this->add_additional_fields_schema( $this->schema );
    355 	}
    356 
    357 	/**
    358 	 * Retrieves the query params for collections.
    359 	 *
    360 	 * @since 4.7.0
    361 	 *
    362 	 * @return array Collection parameters.
    363 	 */
    364 	public function get_collection_params() {
    365 		return array(
    366 			'context' => $this->get_context_param( array( 'default' => 'view' ) ),
    367 		);
    368 	}
    369 
    370 }