X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/16e7b37c7914d753890c1a05a9335f3b43751eb8..aaf6ab9705b7f76e8b7d3a69f6fd52c173b6b3b8:/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php index 872a6607..7b27f60d 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php @@ -77,18 +77,28 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { '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[\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, @@ -345,6 +355,28 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { 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. * @@ -355,8 +387,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * @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() ) ); @@ -424,18 +458,16 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * @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; @@ -451,6 +483,9 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * @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 ); @@ -587,8 +622,11 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * @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 ) ) { @@ -620,11 +658,9 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * @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 ); @@ -710,8 +746,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * @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() ) ); @@ -730,15 +768,14 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * @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 ) { @@ -897,7 +934,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { // 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(); @@ -1919,10 +1961,16 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { 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; @@ -1975,18 +2023,18 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * @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( @@ -1994,7 +2042,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ), '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( @@ -2004,13 +2052,13 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ); } - $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( @@ -2019,7 +2067,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { 'default' => array(), ); - $params['include'] = array( + $query_params['include'] = array( 'description' => __( 'Limit result set to specific IDs.' ), 'type' => 'array', 'items' => array( @@ -2029,25 +2077,25 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ); 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', @@ -2062,13 +2110,13 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ); 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( @@ -2076,7 +2124,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ), '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( @@ -2086,7 +2134,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ); } - $params['slug'] = array( + $query_params['slug'] = array( 'description' => __( 'Limit result set to posts with one or more specific slugs.' ), 'type' => 'array', 'items' => array( @@ -2095,7 +2143,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { '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', @@ -2111,7 +2159,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { 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', @@ -2121,7 +2169,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { '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', @@ -2133,7 +2181,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { } if ( 'post' === $this->post_type ) { - $params['sticky'] = array( + $query_params['sticky'] = array( 'description' => __( 'Limit result set to items that are sticky.' ), 'type' => 'boolean', ); @@ -2151,10 +2199,10 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { * * @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 ); } /**