diff -r c7c34916027a -r 177826044cd9 wp/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php --- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php Mon Oct 14 18:06:33 2019 +0200 +++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php Mon Oct 14 18:28:13 2019 +0200 @@ -42,7 +42,7 @@ public function __construct( $post_type ) { $this->post_type = $post_type; $this->namespace = 'wp/v2'; - $obj = get_post_type_object( $post_type ); + $obj = get_post_type_object( $post_type ); $this->rest_base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name; $this->meta = new WP_REST_Post_Meta_Fields( $this->post_type ); @@ -57,25 +57,29 @@ */ public function register_routes() { - register_rest_route( $this->namespace, '/' . $this->rest_base, array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), - 'args' => $this->get_collection_params(), - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base, array( - 'methods' => WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); - $schema = $this->get_item_schema(); + $schema = $this->get_item_schema(); $get_item_args = array( - 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ); if ( isset( $schema['properties']['password'] ) ) { $get_item_args['password'] = array( @@ -83,39 +87,43 @@ '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' => $get_item_args, - ), + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/(?P[\d]+)', array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'update_item_permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - array( - 'methods' => WP_REST_Server::DELETABLE, - 'callback' => array( $this, 'delete_item' ), - 'permission_callback' => array( $this, 'delete_item_permissions_check' ), - 'args' => array( - 'force' => array( - 'type' => 'boolean', - 'default' => false, - 'description' => __( 'Whether to bypass trash and force deletion.' ), + 'args' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the object.' ), + 'type' => 'integer', ), ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'args' => $get_item_args, + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'type' => 'boolean', + 'default' => false, + 'description' => __( 'Whether to bypass trash and force deletion.' ), + ), + ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) + ); } /** @@ -159,7 +167,7 @@ // Retrieve the list of registered collection query parameters. $registered = $this->get_collection_params(); - $args = array(); + $args = array(); /* * This array defines mappings between public API query parameters whose @@ -258,13 +266,13 @@ * @param array $args Key value array of query var to query value. * @param WP_REST_Request $request The request used. */ - $args = apply_filters( "rest_{$this->post_type}_query", $args, $request ); + $args = apply_filters( "rest_{$this->post_type}_query", $args, $request ); $query_args = $this->prepare_items_query( $args, $request ); $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { - $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; + $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $tax_exclude = $base . '_exclude'; if ( ! empty( $request[ $base ] ) ) { @@ -311,7 +319,7 @@ remove_filter( 'post_password_required', '__return_false' ); } - $page = (int) $query_args['paged']; + $page = (int) $query_args['paged']; $total_posts = $posts_query->found_posts; if ( $total_posts < 1 ) { @@ -329,13 +337,13 @@ return new WP_Error( 'rest_post_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); } - $response = rest_ensure_response( $posts ); + $response = rest_ensure_response( $posts ); $response->header( 'X-WP-Total', (int) $total_posts ); $response->header( 'X-WP-TotalPages', (int) $max_pages ); $request_params = $request->get_query_params(); - $base = add_query_arg( $request_params, rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); + $base = add_query_arg( urlencode_deep( $request_params ), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); if ( $page > 1 ) { $prev_page = $page - 1; @@ -466,7 +474,7 @@ $response = rest_ensure_response( $data ); if ( is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) { - $response->link_header( 'alternate', get_permalink( $post->ID ), array( 'type' => 'text/html' ) ); + $response->link_header( 'alternate', get_permalink( $post->ID ), array( 'type' => 'text/html' ) ); } return $response; @@ -591,7 +599,7 @@ } } - $post = get_post( $post_id ); + $post = get_post( $post_id ); $fields_update = $this->update_additional_fields_for_object( $post, $request ); if ( is_wp_error( $fields_update ) ) { @@ -600,6 +608,19 @@ $request->set_param( 'context', 'edit' ); + /** + * Fires after a single post is completely created or updated via the REST API. + * + * The dynamic portion of the hook name, `$this->post_type`, refers to the post type slug. + * + * @since 5.0.0 + * + * @param WP_Post $post Inserted or updated post object. + * @param WP_REST_Request $request Request object. + * @param bool $creating True when creating a post, false when updating. + */ + do_action( "rest_after_insert_{$this->post_type}", $post, $request, true ); + $response = $this->prepare_item_for_response( $post, $request ); $response = rest_ensure_response( $response ); @@ -717,7 +738,7 @@ } } - $post = get_post( $post_id ); + $post = get_post( $post_id ); $fields_update = $this->update_additional_fields_for_object( $post, $request ); if ( is_wp_error( $fields_update ) ) { @@ -726,6 +747,15 @@ $request->set_param( 'context', 'edit' ); + // Filter is fired in WP_REST_Attachments_Controller subclass. + if ( 'attachment' === $this->post_type ) { + $response = $this->prepare_item_for_response( $post, $request ); + return rest_ensure_response( $response ); + } + + /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ + do_action( "rest_after_insert_{$this->post_type}", $post, $request, false ); + $response = $this->prepare_item_for_response( $post, $request ); return rest_ensure_response( $response ); @@ -795,13 +825,17 @@ $request->set_param( 'context', 'edit' ); - // If we're forcing, then delete permanently. if ( $force ) { $previous = $this->prepare_item_for_response( $post, $request ); - $result = wp_delete_post( $id, true ); + $result = wp_delete_post( $id, true ); $response = new WP_REST_Response(); - $response->set_data( array( 'deleted' => true, 'previous' => $previous->get_data() ) ); + $response->set_data( + array( + 'deleted' => true, + 'previous' => $previous->get_data(), + ) + ); } else { // If we don't support trashing for this type, error out. if ( ! $supports_trash ) { @@ -816,8 +850,8 @@ // (Note that internally this falls through to `wp_delete_post` if // the trash is disabled.) - $result = wp_trash_post( $id ); - $post = get_post( $id ); + $result = wp_trash_post( $id ); + $post = get_post( $id ); $response = $this->prepare_item_for_response( $post, $request ); } @@ -864,7 +898,7 @@ * * @param string $value The query_var value. */ - $query_args[ $key ] = apply_filters( "rest_query_var-{$key}", $value ); + $query_args[ $key ] = apply_filters( "rest_query_var-{$key}", $value ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores } if ( 'post' !== $this->post_type || ! isset( $query_args['ignore_sticky_posts'] ) ) { @@ -991,14 +1025,14 @@ if ( ! empty( $date_data ) ) { list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data; - $prepared_post->edit_date = true; + $prepared_post->edit_date = true; } } elseif ( ! empty( $schema['properties']['date_gmt'] ) && ! empty( $request['date_gmt'] ) ) { $date_data = rest_get_date_with_gmt( $request['date_gmt'], true ); if ( ! empty( $date_data ) ) { list( $prepared_post->post_date, $prepared_post->post_date_gmt ) = $date_data; - $prepared_post->edit_date = true; + $prepared_post->edit_date = true; } } @@ -1193,7 +1227,7 @@ * Sets the template for a post. * * @since 4.7.0 - * @since 4.9.0 Introduced the $validate parameter. + * @since 4.9.0 Added the `$validate` parameter. * * @param string $template Page template filename. * @param integer $post_id Post ID. @@ -1493,16 +1527,17 @@ if ( in_array( 'content', $fields, true ) ) { $data['content'] = array( - 'raw' => $post->post_content, + 'raw' => $post->post_content, /** This filter is documented in wp-includes/post-template.php */ - 'rendered' => post_password_required( $post ) ? '' : apply_filters( 'the_content', $post->post_content ), - 'protected' => (bool) $post->post_password, + 'rendered' => post_password_required( $post ) ? '' : apply_filters( 'the_content', $post->post_content ), + 'protected' => (bool) $post->post_password, + 'block_version' => block_version( $post->post_content ), ); } if ( in_array( 'excerpt', $fields, true ) ) { /** This filter is documented in wp-includes/post-template.php */ - $excerpt = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ) ); + $excerpt = apply_filters( 'the_excerpt', apply_filters( 'get_the_excerpt', $post->post_excerpt, $post ) ); $data['excerpt'] = array( 'raw' => $post->post_excerpt, 'rendered' => post_password_required( $post ) ? '' : $excerpt, @@ -1570,11 +1605,28 @@ $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; if ( in_array( $base, $fields, true ) ) { - $terms = get_the_terms( $post, $taxonomy->name ); + $terms = get_the_terms( $post, $taxonomy->name ); $data[ $base ] = $terms ? array_values( wp_list_pluck( $terms, 'term_id' ) ) : array(); } } + $post_type_obj = get_post_type_object( $post->post_type ); + if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) { + + if ( ! function_exists( 'get_sample_permalink' ) ) { + require_once ABSPATH . 'wp-admin/includes/post.php'; + } + + $sample_permalink = get_sample_permalink( $post->ID, $post->post_title, '' ); + + if ( in_array( 'permalink_template', $fields, true ) ) { + $data['permalink_template'] = $sample_permalink[0]; + } + if ( in_array( 'generated_slug', $fields, true ) ) { + $data['generated_slug'] = $sample_permalink[1]; + } + } + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->add_additional_fields_to_object( $data, $request ); $data = $this->filter_response_by_context( $data, $context ); @@ -1637,14 +1689,14 @@ // Entity meta. $links = array( - 'self' => array( - 'href' => rest_url( trailingslashit( $base ) . $post->ID ), + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $post->ID ), ), 'collection' => array( - 'href' => rest_url( $base ), + 'href' => rest_url( $base ), ), 'about' => array( - 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), + 'href' => rest_url( 'wp/v2/types/' . $this->post_type ), ), ); @@ -1683,7 +1735,6 @@ 'id' => $last_revision, ); } - } $post_type_obj = get_post_type_object( $post->post_type ); @@ -1770,6 +1821,10 @@ $rels[] = 'https://api.w.org/action-publish'; } + if ( current_user_can( 'unfiltered_html' ) ) { + $rels[] = 'https://api.w.org/action-unfiltered-html'; + } + if ( 'post' === $post_type->name ) { if ( current_user_can( $post_type->cap->edit_others_posts ) && current_user_can( $post_type->cap->publish_posts ) ) { $rels[] = 'https://api.w.org/action-sticky'; @@ -1815,19 +1870,19 @@ 'type' => 'object', // Base properties for every Post. 'properties' => array( - 'date' => array( + 'date' => array( 'description' => __( "The date the object was published, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit', 'embed' ), ), - 'date_gmt' => array( + 'date_gmt' => array( 'description' => __( 'The date the object was published, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), ), - 'guid' => array( + 'guid' => array( 'description' => __( 'The globally unique identifier for the object.' ), 'type' => 'object', 'context' => array( 'view', 'edit' ), @@ -1847,34 +1902,34 @@ ), ), ), - 'id' => array( + 'id' => array( 'description' => __( 'Unique identifier for the object.' ), 'type' => 'integer', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), - 'link' => array( + 'link' => array( 'description' => __( 'URL to the object.' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), - 'modified' => array( + 'modified' => array( 'description' => __( "The date the object was last modified, in the site's timezone." ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'modified_gmt' => array( + 'modified_gmt' => array( 'description' => __( 'The date the object was last modified, as GMT.' ), 'type' => 'string', 'format' => 'date-time', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'slug' => array( + 'slug' => array( 'description' => __( 'An alphanumeric identifier for the object unique to its type.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), @@ -1882,19 +1937,19 @@ 'sanitize_callback' => array( $this, 'sanitize_slug' ), ), ), - 'status' => array( + 'status' => array( 'description' => __( 'A named status for the object.' ), 'type' => 'string', 'enum' => array_keys( get_post_stati( array( 'internal' => false ) ) ), 'context' => array( 'view', 'edit' ), ), - 'type' => array( + 'type' => array( 'description' => __( 'Type of Post for the object.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), - 'password' => array( + 'password' => array( 'description' => __( 'A password to protect access to the content and excerpt.' ), 'type' => 'string', 'context' => array( 'edit' ), @@ -1903,6 +1958,21 @@ ); $post_type_obj = get_post_type_object( $this->post_type ); + if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) { + $schema['properties']['permalink_template'] = array( + 'description' => __( 'Permalink template for the object.' ), + 'type' => 'string', + 'context' => array( 'edit' ), + 'readonly' => true, + ); + + $schema['properties']['generated_slug'] = array( + 'description' => __( 'Slug automatically generated from the object title.' ), + 'type' => 'string', + 'context' => array( 'edit' ), + 'readonly' => true, + ); + } if ( $post_type_obj->hierarchical ) { $schema['properties']['parent'] = array( @@ -1924,8 +1994,8 @@ 'post-formats', 'custom-fields', ); - $fixed_schemas = array( - 'post' => array( + $fixed_schemas = array( + 'post' => array( 'title', 'editor', 'author', @@ -1936,7 +2006,7 @@ 'post-formats', 'custom-fields', ), - 'page' => array( + 'page' => array( 'title', 'editor', 'author', @@ -1974,7 +2044,7 @@ 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() ), 'properties' => array( - 'raw' => array( + 'raw' => array( 'description' => __( 'Title for the object, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), @@ -1999,18 +2069,24 @@ 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() ), 'properties' => array( - 'raw' => array( + 'raw' => array( 'description' => __( 'Content for the object, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), - 'rendered' => array( + 'rendered' => array( 'description' => __( 'HTML content for the object, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'protected' => array( + 'block_version' => array( + 'description' => __( 'Version of the content block format used by the object.' ), + 'type' => 'integer', + 'context' => array( 'edit' ), + 'readonly' => true, + ), + 'protected' => array( 'description' => __( 'Whether the content is protected with a password.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit', 'embed' ), @@ -2038,18 +2114,18 @@ 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database() ), 'properties' => array( - 'raw' => array( + 'raw' => array( 'description' => __( 'Excerpt for the object, as it exists in the database.' ), 'type' => 'string', 'context' => array( 'edit' ), ), - 'rendered' => array( + 'rendered' => array( 'description' => __( 'HTML excerpt for the object, transformed for display.' ), 'type' => 'string', 'context' => array( 'view', 'edit', 'embed' ), 'readonly' => true, ), - 'protected' => array( + 'protected' => array( 'description' => __( 'Whether the excerpt is protected with a password.' ), 'type' => 'boolean', 'context' => array( 'view', 'edit', 'embed' ), @@ -2074,7 +2150,7 @@ 'enum' => array( 'open', 'closed' ), 'context' => array( 'view', 'edit' ), ); - $schema['properties']['ping_status'] = array( + $schema['properties']['ping_status'] = array( 'description' => __( 'Whether or not the object can be pinged.' ), 'type' => 'string', 'enum' => array( 'open', 'closed' ), @@ -2128,13 +2204,13 @@ $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); foreach ( $taxonomies as $taxonomy ) { - $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; + $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; $schema['properties'][ $base ] = array( /* translators: %s: taxonomy name */ 'description' => sprintf( __( 'The terms assigned to the object in the %s taxonomy.' ), $taxonomy->name ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + 'type' => 'integer', ), 'context' => array( 'view', 'edit' ), ); @@ -2179,6 +2255,22 @@ ); } + $links[] = array( + 'rel' => 'https://api.w.org/action-unfiltered-html', + 'title' => __( 'The current user can post unfiltered HTML markup and JavaScript.' ), + 'href' => $href, + 'targetSchema' => array( + 'type' => 'object', + 'properties' => array( + 'content' => array( + 'raw' => array( + 'type' => 'string', + ), + ), + ), + ), + ); + if ( 'post' === $this->post_type ) { $links[] = array( 'rel' => 'https://api.w.org/action-sticky', @@ -2272,78 +2364,78 @@ $query_params['context']['default'] = 'view'; $query_params['after'] = array( - 'description' => __( 'Limit response to posts published after a given ISO8601 compliant date.' ), - 'type' => 'string', - 'format' => 'date-time', + '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' ) ) { - $query_params['author'] = array( - 'description' => __( 'Limit result set to posts assigned to specific authors.' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', + $query_params['author'] = array( + 'description' => __( 'Limit result set to posts assigned to specific authors.' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', ), - 'default' => array(), + 'default' => array(), ); $query_params['author_exclude'] = array( - 'description' => __( 'Ensure result set excludes posts assigned to specific authors.' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', + 'description' => __( 'Ensure result set excludes posts assigned to specific authors.' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', ), - 'default' => array(), + 'default' => array(), ); } $query_params['before'] = array( - 'description' => __( 'Limit response to posts published before a given ISO8601 compliant date.' ), - 'type' => 'string', - 'format' => 'date-time', + 'description' => __( 'Limit response to posts published before a given ISO8601 compliant date.' ), + 'type' => 'string', + 'format' => 'date-time', ); $query_params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific IDs.' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', + 'description' => __( 'Ensure result set excludes specific IDs.' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', ), - 'default' => array(), + 'default' => array(), ); $query_params['include'] = array( - 'description' => __( 'Limit result set to specific IDs.' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', + 'description' => __( 'Limit result set to specific IDs.' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', ), - 'default' => array(), + 'default' => array(), ); if ( 'page' === $this->post_type || post_type_supports( $this->post_type, 'page-attributes' ) ) { $query_params['menu_order'] = array( - 'description' => __( 'Limit result set to posts with a specific menu_order value.' ), - 'type' => 'integer', + 'description' => __( 'Limit result set to posts with a specific menu_order value.' ), + 'type' => 'integer', ); } $query_params['offset'] = array( - 'description' => __( 'Offset the result set by a specific number of items.' ), - 'type' => 'integer', + 'description' => __( 'Offset the result set by a specific number of items.' ), + 'type' => 'integer', ); $query_params['order'] = array( - 'description' => __( 'Order sort attribute ascending or descending.' ), - 'type' => 'string', - 'default' => 'desc', - 'enum' => array( 'asc', 'desc' ), + 'description' => __( 'Order sort attribute ascending or descending.' ), + 'type' => 'string', + 'default' => 'desc', + 'enum' => array( 'asc', 'desc' ), ); $query_params['orderby'] = array( - 'description' => __( 'Sort collection by object attribute.' ), - 'type' => 'string', - 'default' => 'date', - 'enum' => array( + 'description' => __( 'Sort collection by object attribute.' ), + 'type' => 'string', + 'default' => 'date', + 'enum' => array( 'author', 'date', 'id', @@ -2364,21 +2456,21 @@ $post_type = get_post_type_object( $this->post_type ); if ( $post_type->hierarchical || 'attachment' === $this->post_type ) { - $query_params['parent'] = array( - 'description' => __( 'Limit result set to items with particular parent IDs.' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', + $query_params['parent'] = array( + 'description' => __( 'Limit result set to items with particular parent IDs.' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', ), - 'default' => array(), + 'default' => array(), ); $query_params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent ID.' ), - 'type' => 'array', - 'items' => array( - 'type' => 'integer', + 'description' => __( 'Limit result set to all items except those of a particular parent ID.' ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', ), - 'default' => array(), + 'default' => array(), ); } @@ -2386,7 +2478,7 @@ 'description' => __( 'Limit result set to posts with one or more specific slugs.' ), 'type' => 'array', 'items' => array( - 'type' => 'string', + 'type' => 'string', ), 'sanitize_callback' => 'wp_parse_slug_list', ); @@ -2396,8 +2488,8 @@ 'description' => __( 'Limit result set to posts assigned one or more statuses.' ), 'type' => 'array', 'items' => array( - 'enum' => array_merge( array_keys( get_post_stati() ), array( 'any' ) ), - 'type' => 'string', + 'enum' => array_merge( array_keys( get_post_stati() ), array( 'any' ) ), + 'type' => 'string', ), 'sanitize_callback' => array( $this, 'sanitize_post_statuses' ), ); @@ -2409,12 +2501,12 @@ $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', - 'items' => array( - 'type' => 'integer', + 'description' => sprintf( __( 'Limit result set to all items that have the specified term assigned in the %s taxonomy.' ), $base ), + 'type' => 'array', + 'items' => array( + 'type' => 'integer', ), - 'default' => array(), + 'default' => array(), ); $query_params[ $base . '_exclude' ] = array( @@ -2422,16 +2514,16 @@ 'description' => sprintf( __( 'Limit result set to all items except those that have the specified term assigned in the %s taxonomy.' ), $base ), 'type' => 'array', 'items' => array( - 'type' => 'integer', + 'type' => 'integer', ), - 'default' => array(), + 'default' => array(), ); } if ( 'post' === $this->post_type ) { $query_params['sticky'] = array( - 'description' => __( 'Limit result set to items that are sticky.' ), - 'type' => 'boolean', + 'description' => __( 'Limit result set to items that are sticky.' ), + 'type' => 'boolean', ); } @@ -2468,7 +2560,7 @@ $statuses = wp_parse_slug_list( $statuses ); // The default status is different in WP_REST_Attachments_Controller - $attributes = $request->get_attributes(); + $attributes = $request->get_attributes(); $default_status = $attributes['args']['status']['default']; foreach ( $statuses as $status ) { @@ -2478,7 +2570,7 @@ $post_type_obj = get_post_type_object( $this->post_type ); - if ( current_user_can( $post_type_obj->cap->edit_posts ) ) { + if ( current_user_can( $post_type_obj->cap->edit_posts ) || 'private' === $status && current_user_can( $post_type_obj->cap->read_private_posts ) ) { $result = rest_validate_request_arg( $status, $request, $parameter ); if ( is_wp_error( $result ) ) { return $result;