'schema' => array( $this, 'get_public_item_schema' ),
) );
+ $schema = $this->get_item_schema();
+ $get_item_args = array(
+ 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
+ );
+ if ( isset( $schema['properties']['password'] ) ) {
+ $get_item_args['password'] = array(
+ 'description' => __( 'The password for the post if it is password protected.' ),
+ 'type' => 'string',
+ );
+ }
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
+ 'args' => array(
+ 'id' => array(
+ 'description' => __( 'Unique identifier for the object.' ),
+ 'type' => 'integer',
+ ),
+ ),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
- 'args' => array(
- 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
- 'password' => array(
- 'description' => __( 'The password for the post if it is password protected.' ),
- 'type' => 'string',
- ),
- ),
+ 'args' => $get_item_args,
),
array(
'methods' => WP_REST_Server::EDITABLE,
return $response;
}
+ /**
+ * Get the post, if the ID is valid.
+ *
+ * @since 4.7.2
+ *
+ * @param int $id Supplied ID.
+ * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
+ */
+ protected function get_post( $id ) {
+ $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ if ( (int) $id <= 0 ) {
+ return $error;
+ }
+
+ $post = get_post( (int) $id );
+ if ( empty( $post ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
+ return $error;
+ }
+
+ return $post;
+ }
+
/**
* Checks if a given request has access to read a post.
*
* @return bool|WP_Error True if the request has read access for the item, WP_Error object otherwise.
*/
public function get_item_permissions_check( $request ) {
-
- $post = get_post( (int) $request['id'] );
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
+ }
if ( 'edit' === $request['context'] && $post && ! $this->check_update_permission( $post ) ) {
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this post.' ), array( 'status' => rest_authorization_required_code() ) );
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_item( $request ) {
- $id = (int) $request['id'];
- $post = get_post( $id );
-
- if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
}
$data = $this->prepare_item_for_response( $post, $request );
$response = rest_ensure_response( $data );
if ( is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) {
- $response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) );
+ $response->link_header( 'alternate', get_permalink( $post->ID ), array( 'type' => 'text/html' ) );
}
return $response;
* @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
*/
public function create_item_permissions_check( $request ) {
+ if ( ! empty( $request['id'] ) ) {
+ return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) );
+ }
$post_type = get_post_type_object( $this->post_type );
* @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
*/
public function update_item_permissions_check( $request ) {
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
+ }
- $post = get_post( $request['id'] );
$post_type = get_post_type_object( $this->post_type );
if ( $post && ! $this->check_update_permission( $post ) ) {
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function update_item( $request ) {
- $id = (int) $request['id'];
- $post = get_post( $id );
-
- if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ $valid_check = $this->get_post( $request['id'] );
+ if ( is_wp_error( $valid_check ) ) {
+ return $valid_check;
}
$post = $this->prepare_item_for_database( $request );
* @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
*/
public function delete_item_permissions_check( $request ) {
-
- $post = get_post( $request['id'] );
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
+ }
if ( $post && ! $this->check_delete_permission( $post ) ) {
return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this post.' ), array( 'status' => rest_authorization_required_code() ) );
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function delete_item( $request ) {
- $id = (int) $request['id'];
- $force = (bool) $request['force'];
-
- $post = get_post( $id );
-
- if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
- return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
+ $post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $post ) ) {
+ return $post;
}
+ $id = $post->ID;
+ $force = (bool) $request['force'];
+
$supports_trash = ( EMPTY_TRASH_DAYS > 0 );
if ( 'attachment' === $post->post_type ) {
// Post ID.
if ( isset( $request['id'] ) ) {
- $prepared_post->ID = absint( $request['id'] );
+ $existing_post = $this->get_post( $request['id'] );
+ if ( is_wp_error( $existing_post ) ) {
+ return $existing_post;
+ }
+
+ $prepared_post->ID = $existing_post->ID;
}
$schema = $this->get_item_schema();
case 'post-formats':
$supports_formats = get_theme_support( 'post-formats' );
+
+ // Force to an array. Supports formats can return true even if empty in some cases.
+ $supports_formats = is_array( $supports_formats ) ? array_values( $supports_formats[0] ) : array();
+
+ $supported_formats = array_merge( array( 'standard' ), $supports_formats );
+
$schema['properties']['format'] = array(
'description' => __( 'The format for the object.' ),
'type' => 'string',
- 'enum' => array_merge( array( 'standard' ), $supports_formats ? array_values( $supports_formats[0] ) : array() ),
+ 'enum' => $supported_formats,
'context' => array( 'view', 'edit' ),
);
break;
* @return array Collection parameters.
*/
public function get_collection_params() {
- $params = parent::get_collection_params();
+ $query_params = parent::get_collection_params();
- $params['context']['default'] = 'view';
+ $query_params['context']['default'] = 'view';
- $params['after'] = array(
+ $query_params['after'] = array(
'description' => __( 'Limit response to posts published after a given ISO8601 compliant date.' ),
'type' => 'string',
'format' => 'date-time',
);
if ( post_type_supports( $this->post_type, 'author' ) ) {
- $params['author'] = array(
+ $query_params['author'] = array(
'description' => __( 'Limit result set to posts assigned to specific authors.' ),
'type' => 'array',
'items' => array(
),
'default' => array(),
);
- $params['author_exclude'] = array(
+ $query_params['author_exclude'] = array(
'description' => __( 'Ensure result set excludes posts assigned to specific authors.' ),
'type' => 'array',
'items' => array(
);
}
- $params['before'] = array(
+ $query_params['before'] = array(
'description' => __( 'Limit response to posts published before a given ISO8601 compliant date.' ),
'type' => 'string',
'format' => 'date-time',
);
- $params['exclude'] = array(
+ $query_params['exclude'] = array(
'description' => __( 'Ensure result set excludes specific IDs.' ),
'type' => 'array',
'items' => array(
'default' => array(),
);
- $params['include'] = array(
+ $query_params['include'] = array(
'description' => __( 'Limit result set to specific IDs.' ),
'type' => 'array',
'items' => array(
);
if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) {
- $params['menu_order'] = array(
+ $query_params['menu_order'] = array(
'description' => __( 'Limit result set to posts with a specific menu_order value.' ),
'type' => 'integer',
);
}
- $params['offset'] = array(
+ $query_params['offset'] = array(
'description' => __( 'Offset the result set by a specific number of items.' ),
'type' => 'integer',
);
- $params['order'] = array(
+ $query_params['order'] = array(
'description' => __( 'Order sort attribute ascending or descending.' ),
'type' => 'string',
'default' => 'desc',
'enum' => array( 'asc', 'desc' ),
);
- $params['orderby'] = array(
+ $query_params['orderby'] = array(
'description' => __( 'Sort collection by object attribute.' ),
'type' => 'string',
'default' => 'date',
);
if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) {
- $params['orderby']['enum'][] = 'menu_order';
+ $query_params['orderby']['enum'][] = 'menu_order';
}
- $post_type_obj = get_post_type_object( $this->post_type );
+ $post_type = get_post_type_object( $this->post_type );
- if ( $post_type_obj->hierarchical || 'attachment' === $this->post_type ) {
- $params['parent'] = array(
+ if ( $post_type->hierarchical || 'attachment' === $this->post_type ) {
+ $query_params['parent'] = array(
'description' => __( 'Limit result set to those of particular parent IDs.' ),
'type' => 'array',
'items' => array(
),
'default' => array(),
);
- $params['parent_exclude'] = array(
+ $query_params['parent_exclude'] = array(
'description' => __( 'Limit result set to all items except those of a particular parent ID.' ),
'type' => 'array',
'items' => array(
);
}
- $params['slug'] = array(
+ $query_params['slug'] = array(
'description' => __( 'Limit result set to posts with one or more specific slugs.' ),
'type' => 'array',
'items' => array(
'sanitize_callback' => 'wp_parse_slug_list',
);
- $params['status'] = array(
+ $query_params['status'] = array(
'default' => 'publish',
'description' => __( 'Limit result set to posts assigned one or more statuses.' ),
'type' => 'array',
foreach ( $taxonomies as $taxonomy ) {
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
- $params[ $base ] = array(
+ $query_params[ $base ] = array(
/* translators: %s: taxonomy name */
'description' => sprintf( __( 'Limit result set to all items that have the specified term assigned in the %s taxonomy.' ), $base ),
'type' => 'array',
'default' => array(),
);
- $params[ $base . '_exclude' ] = array(
+ $query_params[ $base . '_exclude' ] = array(
/* translators: %s: taxonomy name */
'description' => sprintf( __( 'Limit result set to all items except those that have the specified term assigned in the %s taxonomy.' ), $base ),
'type' => 'array',
}
if ( 'post' === $this->post_type ) {
- $params['sticky'] = array(
+ $query_params['sticky'] = array(
'description' => __( 'Limit result set to items that are sticky.' ),
'type' => 'boolean',
);
*
* @since 4.7.0
*
- * @param $params JSON Schema-formatted collection parameters.
- * @param WP_Post_Type $post_type_obj Post type object.
+ * @param array $query_params JSON Schema-formatted collection parameters.
+ * @param WP_Post_Type $post_type Post type object.
*/
- return apply_filters( "rest_{$this->post_type}_collection_params", $params, $post_type_obj );
+ return apply_filters( "rest_{$this->post_type}_collection_params", $query_params, $post_type );
}
/**