Make WordPress Core

Ticket #40510: 40510.2.diff

File 40510.2.diff, 13.8 KB (added by adamsilverstein, 7 years ago)
  • src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
    index 471c4c4b4f..d371006983 100644
    a b class WP_REST_Revisions_Controller extends WP_REST_Controller { 
    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            = (int) $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        /**
    class WP_REST_Revisions_Controller extends WP_REST_Controller { 
    326413                return $response;
    327414        }
    328415
     416        /**
     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
    329451        /**
    330452         * Prepares the revision for the REST response.
    331453         *
    class WP_REST_Revisions_Controller extends WP_REST_Controller { 
    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(),
     685                );
     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',
    552699                );
     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        /**
  • tests/qunit/fixtures/wp-api-generated.js

    diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js
    index 583843fbc1..73967d8fe4 100644
    a b mockedApiResponse.Schema = { 
    718718                            ],
    719719                            "description": "Scope under which the request is made; determines fields present in response.",
    720720                            "type": "string"
     721                        },
     722                        "page": {
     723                            "required": false,
     724                            "default": 1,
     725                            "description": "Current page of the collection.",
     726                            "type": "integer"
     727                        },
     728                        "per_page": {
     729                            "required": false,
     730                            "description": "Maximum number of items to be returned in result set.",
     731                            "type": "integer"
     732                        },
     733                        "search": {
     734                            "required": false,
     735                            "description": "Limit results to those matching a string.",
     736                            "type": "string"
     737                        },
     738                        "exclude": {
     739                            "required": false,
     740                            "default": [],
     741                            "description": "Ensure result set excludes specific IDs.",
     742                            "type": "array",
     743                            "items": {
     744                                "type": "integer"
     745                            }
     746                        },
     747                        "include": {
     748                            "required": false,
     749                            "default": [],
     750                            "description": "Limit result set to specific IDs.",
     751                            "type": "array",
     752                            "items": {
     753                                "type": "integer"
     754                            }
     755                        },
     756                        "offset": {
     757                            "required": false,
     758                            "description": "Offset the result set by a specific number of items.",
     759                            "type": "integer"
     760                        },
     761                        "order": {
     762                            "required": false,
     763                            "default": "desc",
     764                            "enum": [
     765                                "asc",
     766                                "desc"
     767                            ],
     768                            "description": "Order sort attribute ascending or descending.",
     769                            "type": "string"
     770                        },
     771                        "orderby": {
     772                            "required": false,
     773                            "default": "date",
     774                            "enum": [
     775                                "date",
     776                                "id",
     777                                "include",
     778                                "relevance",
     779                                "slug",
     780                                "include_slugs",
     781                                "title"
     782                            ],
     783                            "description": "Sort collection by object attribute.",
     784                            "type": "string"
    721785                        }
    722786                    }
    723787                }
    mockedApiResponse.Schema = { 
    12561320                            ],
    12571321                            "description": "Scope under which the request is made; determines fields present in response.",
    12581322                            "type": "string"
     1323                        },
     1324                        "page": {
     1325                            "required": false,
     1326                            "default": 1,
     1327                            "description": "Current page of the collection.",
     1328                            "type": "integer"
     1329                        },
     1330                        "per_page": {
     1331                            "required": false,
     1332                            "description": "Maximum number of items to be returned in result set.",
     1333                            "type": "integer"
     1334                        },
     1335                        "search": {
     1336                            "required": false,
     1337                            "description": "Limit results to those matching a string.",
     1338                            "type": "string"
     1339                        },
     1340                        "exclude": {
     1341                            "required": false,
     1342                            "default": [],
     1343                            "description": "Ensure result set excludes specific IDs.",
     1344                            "type": "array",
     1345                            "items": {
     1346                                "type": "integer"
     1347                            }
     1348                        },
     1349                        "include": {
     1350                            "required": false,
     1351                            "default": [],
     1352                            "description": "Limit result set to specific IDs.",
     1353                            "type": "array",
     1354                            "items": {
     1355                                "type": "integer"
     1356                            }
     1357                        },
     1358                        "offset": {
     1359                            "required": false,
     1360                            "description": "Offset the result set by a specific number of items.",
     1361                            "type": "integer"
     1362                        },
     1363                        "order": {
     1364                            "required": false,
     1365                            "default": "desc",
     1366                            "enum": [
     1367                                "asc",
     1368                                "desc"
     1369                            ],
     1370                            "description": "Order sort attribute ascending or descending.",
     1371                            "type": "string"
     1372                        },
     1373                        "orderby": {
     1374                            "required": false,
     1375                            "default": "date",
     1376                            "enum": [
     1377                                "date",
     1378                                "id",
     1379                                "include",
     1380                                "relevance",
     1381                                "slug",
     1382                                "include_slugs",
     1383                                "title"
     1384                            ],
     1385                            "description": "Sort collection by object attribute.",
     1386                            "type": "string"
    12591387                        }
    12601388                    }
    12611389                }