WordPress.org

Make WordPress Core

Ticket #40510: 40510.diff

File 40510.diff, 6.9 KB (added by flixos90, 3 years ago)
  • src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php

     
    201201                        return $parent;
    202202                }
    203203
    204                 $revisions = wp_get_post_revisions( $request['parent'] );
     204                // Ensure a search string is set in case the orderby is set to 'relevance'.
     205                if ( ! empty( $request['orderby'] ) && 'relevance' === $request['orderby'] && empty( $request['search'] ) ) {
     206                        return new WP_Error( 'rest_no_search_term_defined', __( 'You need to define a search term to order by relevance.' ), array( 'status' => 400 ) );
     207                }
     208
     209                // Ensure an include parameter is set in case the orderby is set to 'include'.
     210                if ( ! empty( $request['orderby'] ) && 'include' === $request['orderby'] && empty( $request['include'] ) ) {
     211                        return new WP_Error( 'rest_orderby_include_missing_include', __( 'You need to define an include parameter to order by include.' ), array( 'status' => 400 ) );
     212                }
     213
     214                if ( wp_revisions_enabled( $parent ) ) {
     215                        $registered = $this->get_collection_params();
     216                        $args       = array(
     217                                'post_parent'      => $parent->ID,
     218                                'post_type'        => 'revision',
     219                                'post_status'      => 'inherit',
     220                                'posts_per_page'   => -1,
     221                                'suppress_filters' => true,
     222                        );
     223
     224                        $parameter_mappings = array(
     225                                'exclude'  => 'post__not_in',
     226                                'include'  => 'post__in',
     227                                'offset'   => 'offset',
     228                                'order'    => 'order',
     229                                'orderby'  => 'orderby',
     230                                'page'     => 'paged',
     231                                'per_page' => 'posts_per_page',
     232                                'search'   => 's',
     233                        );
     234
     235                        foreach ( $parameter_mappings as $api_param => $wp_param ) {
     236                                if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) {
     237                                        $args[ $wp_param ] = $request[ $api_param ];
     238                                }
     239                        }
     240
     241                        /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */
     242                        $args       = apply_filters( "rest_revision_query", $args, $request );
     243                        $query_args = $this->prepare_items_query( $args, $request );
     244
     245                        $revisions_query = new WP_Query();
     246                        $revisions       = $revisions_query->query( $query_args );
     247
     248                        if ( $revisions_query->query_vars['posts_per_page'] > 0 ) {
     249                                $total_revisions = (int) $revisions_query->found_posts;
     250                                $max_pages       = ceil( $total_revisions / (int) $revisions_query->query_vars['posts_per_page'] );
     251                        } else {
     252                                $total_revisions = count( $revisions );
     253                                $max_pages       = $total_revisions > 0 ? 1 : 0;
     254                        }
     255
     256                        $page = (int) $query_args['paged'];
     257                        if ( $page > $max_pages && $total_revisions > 0 ) {
     258                                return new WP_Error( 'rest_revision_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) );
     259                        }
     260                } else {
     261                        $revisions       = array();
     262                        $total_revisions = 0;
     263                        $max_pages       = 0;
     264                        $page            = $request['page'];
     265                }
    205266
    206267                $response = array();
    207268                foreach ( $revisions as $revision ) {
    208269                        $data       = $this->prepare_item_for_response( $revision, $request );
    209270                        $response[] = $this->prepare_response_for_collection( $data );
    210271                }
    211                 return rest_ensure_response( $response );
     272
     273                $response = rest_ensure_response( $response );
     274
     275                $response->header( 'X-WP-Total', (int) $total_revisions );
     276                $response->header( 'X-WP-TotalPages', (int) $max_pages );
     277
     278                $request_params = $request->get_query_params();
     279                $base           = add_query_arg( $request_params, rest_url( sprintf( '%s/%s/%d/%s', $this->namespace, $this->parent_base, $request['parent'], $this->rest_base ) ) );
     280
     281                if ( $page > 1 ) {
     282                        $prev_page = $page - 1;
     283
     284                        if ( $prev_page > $max_pages ) {
     285                                $prev_page = $max_pages;
     286                        }
     287
     288                        $prev_link = add_query_arg( 'page', $prev_page, $base );
     289                        $response->link_header( 'prev', $prev_link );
     290                }
     291                if ( $max_pages > $page ) {
     292                        $next_page = $page + 1;
     293                        $next_link = add_query_arg( 'page', $next_page, $base );
     294
     295                        $response->link_header( 'next', $next_link );
     296                }
     297
     298                return $response;
    212299        }
    213300
    214301        /**
     
    327414        }
    328415
    329416        /**
     417         * Determines the allowed query_vars for a get_items() response and prepares
     418         * them for WP_Query.
     419         *
     420         * @since 5.0.0
     421         *
     422         * @param array           $prepared_args Optional. Prepared WP_Query arguments. Default empty array.
     423         * @param WP_REST_Request $request       Optional. Full details about the request.
     424         * @return array Items query arguments.
     425         */
     426        protected function prepare_items_query( $prepared_args = array(), $request = null ) {
     427                $query_args = array();
     428
     429                foreach ( $prepared_args as $key => $value ) {
     430                        /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */
     431                        $query_args[ $key ] = apply_filters( "rest_query_var-{$key}", $value );
     432                }
     433
     434                // Map to proper WP_Query orderby param.
     435                if ( isset( $query_args['orderby'] ) && isset( $request['orderby'] ) ) {
     436                        $orderby_mappings = array(
     437                                'id'            => 'ID',
     438                                'include'       => 'post__in',
     439                                'slug'          => 'post_name',
     440                                'include_slugs' => 'post_name__in',
     441                        );
     442
     443                        if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) {
     444                                $query_args['orderby'] = $orderby_mappings[ $request['orderby'] ];
     445                        }
     446                }
     447
     448                return $query_args;
     449        }
     450
     451        /**
    330452         * Prepares the revision for the REST response.
    331453         *
    332454         * @since 4.7.0
     
    547669         * @return array Collection parameters.
    548670         */
    549671        public function get_collection_params() {
    550                 return array(
    551                         'context' => $this->get_context_param( array( 'default' => 'view' ) ),
     672                $query_params = parent::get_collection_params();
     673
     674                $query_params['context']['default'] = 'view';
     675
     676                unset( $query_params['per_page']['default'] );
     677
     678                $query_params['exclude'] = array(
     679                        'description' => __( 'Ensure result set excludes specific IDs.' ),
     680                        'type'        => 'array',
     681                        'items'       => array(
     682                                'type' => 'integer',
     683                        ),
     684                        'default'     => array(),
    552685                );
     686
     687                $query_params['include'] = array(
     688                        'description' => __( 'Limit result set to specific IDs.' ),
     689                        'type'        => 'array',
     690                        'items'       => array(
     691                                'type' => 'integer',
     692                        ),
     693                        'default'     => array(),
     694                );
     695
     696                $query_params['offset'] = array(
     697                        'description' => __( 'Offset the result set by a specific number of items.' ),
     698                        'type'        => 'integer',
     699                );
     700
     701                $query_params['order'] = array(
     702                        'description' => __( 'Order sort attribute ascending or descending.' ),
     703                        'type'        => 'string',
     704                        'default'     => 'desc',
     705                        'enum'        => array( 'asc', 'desc' ),
     706                );
     707
     708                $query_params['orderby'] = array(
     709                        'description' => __( 'Sort collection by object attribute.' ),
     710                        'type'        => 'string',
     711                        'default'     => 'date',
     712                        'enum'        => array(
     713                                'date',
     714                                'id',
     715                                'include',
     716                                'relevance',
     717                                'slug',
     718                                'include_slugs',
     719                                'title',
     720                        ),
     721                );
     722
     723                return $query_params;
    553724        }
    554725
    555726        /**