| 317 | | $page = (int) $query_args['paged']; |
| 318 | | $total_posts = $posts_query->found_posts; |
| 319 | | |
| 320 | | if ( $total_posts < 1 ) { |
| 321 | | // Out-of-bounds, run the query again without LIMIT for total count. |
| 322 | | unset( $query_args['paged'] ); |
| 323 | | |
| 324 | | $count_query = new WP_Query(); |
| 325 | | $count_query->query( $query_args ); |
| 326 | | $total_posts = $count_query->found_posts; |
| 327 | | } |
| 328 | | |
| 329 | | $max_pages = ceil( $total_posts / (int) $posts_query->query_vars['posts_per_page'] ); |
| 330 | | |
| 331 | | if ( $page > $max_pages && $total_posts > 0 ) { |
| 332 | | return new WP_Error( 'rest_post_invalid_page_number', __( 'The page number requested is larger than the number of pages available.' ), array( 'status' => 400 ) ); |
| 333 | | } |
| 334 | | |
| 335 | | $response = rest_ensure_response( $posts ); |
| 336 | | |
| 337 | | $response->header( 'X-WP-Total', (int) $total_posts ); |
| 338 | | $response->header( 'X-WP-TotalPages', (int) $max_pages ); |
| 339 | | |
| 340 | | $request_params = $request->get_query_params(); |
| 341 | | $base = add_query_arg( $request_params, rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); |
| 342 | | |
| 343 | | if ( $page > 1 ) { |
| 344 | | $prev_page = $page - 1; |
| 345 | | |
| 346 | | if ( $prev_page > $max_pages ) { |
| 347 | | $prev_page = $max_pages; |
| 348 | | } |
| 349 | | |
| 350 | | $prev_link = add_query_arg( 'page', $prev_page, $base ); |
| 351 | | $response->link_header( 'prev', $prev_link ); |
| 352 | | } |
| 353 | | if ( $max_pages > $page ) { |
| 354 | | $next_page = $page + 1; |
| 355 | | $next_link = add_query_arg( 'page', $next_page, $base ); |
| 356 | | |
| 357 | | $response->link_header( 'next', $next_link ); |
| 358 | | } |
| | 308 | $response = $this->prepare_paginate_response( $request, $query_args, $posts_query, $posts ); |
| | 2201 | |
| | 2202 | /** |
| | 2203 | * Create a collection of WordPress posts, formatted |
| | 2204 | * |
| | 2205 | * @since 4.7.3 |
| | 2206 | * |
| | 2207 | * @param WP_REST_Request $request Current request |
| | 2208 | * @param array $query_results An array of WP_Post objects, as returned by WP_Query::query() |
| | 2209 | * |
| | 2210 | * @return array |
| | 2211 | */ |
| | 2212 | protected function prepare_posts_for_response( $request, $query_results ) { |
| | 2213 | $posts = array(); |
| | 2214 | |
| | 2215 | foreach ( $query_results as $post ) { |
| | 2216 | if ( ! $this->check_read_permission( $post ) ) { |
| | 2217 | continue; |
| | 2218 | } |
| | 2219 | |
| | 2220 | $data = $this->prepare_item_for_response( $post, $request ); |
| | 2221 | $posts[] = $this->prepare_response_for_collection( $data ); |
| | 2222 | } |
| | 2223 | |
| | 2224 | return $posts; |
| | 2225 | |
| | 2226 | } |
| | 2227 | |
| | 2228 | /** |
| | 2229 | * Create a WP_REST_Response for a collection of posts, with the right pagination headers |
| | 2230 | * |
| | 2231 | * @since 4.7.3 |
| | 2232 | * |
| | 2233 | * @param WP_REST_Request $request Current request object. |
| | 2234 | * @param array $query_args The request's prepared WP_Query arguments, used to do the count query. |
| | 2235 | * @param WP_Query $posts_query The WP_Query object used to prepare the posts for the response. |
| | 2236 | * @param array $prepared_posts The prepared posts to return in response body. |
| | 2237 | * |
| | 2238 | * @return WP_REST_Response |
| | 2239 | */ |
| | 2240 | protected function prepare_paginate_response( $request, $query_args, $posts_query, $prepared_posts ) { |
| | 2241 | $page = (int) $query_args[ 'paged' ]; |
| | 2242 | $total_posts = $posts_query->found_posts; |
| | 2243 | |
| | 2244 | if ( $total_posts < 1 ) { |
| | 2245 | // Out-of-bounds, run the query again without LIMIT for total count. |
| | 2246 | unset( $query_args[ 'paged' ] ); |
| | 2247 | |
| | 2248 | $count_query = new WP_Query(); |
| | 2249 | $count_query->query( $query_args ); |
| | 2250 | $total_posts = $count_query->found_posts; |
| | 2251 | } |
| | 2252 | |
| | 2253 | $max_pages = ceil( $total_posts / (int) $posts_query->query_vars[ 'posts_per_page' ] ); |
| | 2254 | $response = rest_ensure_response( $prepared_posts ); |
| | 2255 | |
| | 2256 | $response->header( 'X-WP-Total', (int) $total_posts ); |
| | 2257 | $response->header( 'X-WP-TotalPages', (int) $max_pages ); |
| | 2258 | |
| | 2259 | $request_params = $request->get_query_params(); |
| | 2260 | $base = add_query_arg( $request_params, rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) ); |
| | 2261 | |
| | 2262 | if ( $page > 1 ) { |
| | 2263 | $prev_page = $page - 1; |
| | 2264 | |
| | 2265 | if ( $prev_page > $max_pages ) { |
| | 2266 | $prev_page = $max_pages; |
| | 2267 | } |
| | 2268 | |
| | 2269 | $prev_link = add_query_arg( 'page', $prev_page, $base ); |
| | 2270 | $response->link_header( 'prev', $prev_link ); |
| | 2271 | } |
| | 2272 | |
| | 2273 | if ( $max_pages > $page ) { |
| | 2274 | $next_page = $page + 1; |
| | 2275 | $next_link = add_query_arg( 'page', $next_page, $base ); |
| | 2276 | |
| | 2277 | $response->link_header( 'next', $next_link ); |
| | 2278 | |
| | 2279 | return $response; |
| | 2280 | |
| | 2281 | } |
| | 2282 | |
| | 2283 | return $response; |
| | 2284 | } |
| | 2285 | |