Improve pagination header generation
This commit is contained in:
parent
3a6de36db7
commit
767719c329
|
@ -40,7 +40,8 @@ class WC_REST_Product_Attribute_Terms_V1_Controller extends WC_REST_Terms_Contro
|
||||||
* Register the routes for terms.
|
* Register the routes for terms.
|
||||||
*/
|
*/
|
||||||
public function register_routes() {
|
public function register_routes() {
|
||||||
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
|
register_rest_route( $this->namespace, '/' . $this->rest_base,
|
||||||
|
array(
|
||||||
'args' => array(
|
'args' => array(
|
||||||
'attribute_id' => array(
|
'attribute_id' => array(
|
||||||
'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ),
|
'description' => __( 'Unique identifier for the attribute of the terms.', 'woocommerce' ),
|
||||||
|
|
|
@ -9,7 +9,8 @@ namespace WooCommerce\RestApi\Controllers\Version4;
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions;
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions;
|
||||||
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRUD Object Controller.
|
* CRUD Object Controller.
|
||||||
|
@ -296,42 +297,11 @@ abstract class AbstractObjectsController extends AbstractController {
|
||||||
$objects[] = $this->prepare_response_for_collection( $data );
|
$objects[] = $this->prepare_response_for_collection( $data );
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = (int) $query_args['paged'];
|
$total = $query_results['total'];
|
||||||
$max_pages = $query_results['pages'];
|
$max_pages = $query_results['pages'];
|
||||||
|
|
||||||
$response = rest_ensure_response( $objects );
|
$response = rest_ensure_response( $objects );
|
||||||
$response->header( 'X-WP-Total', $query_results['total'] );
|
$response = Pagination::add_pagination_headers( $response, $request, $total, $max_pages );
|
||||||
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
|
||||||
|
|
||||||
$base = $this->rest_base;
|
|
||||||
$attrib_prefix = '(?P<';
|
|
||||||
if ( strpos( $base, $attrib_prefix ) !== false ) {
|
|
||||||
$attrib_names = array();
|
|
||||||
preg_match( '/\(\?P<[^>]+>.*\)/', $base, $attrib_names, PREG_OFFSET_CAPTURE );
|
|
||||||
foreach ( $attrib_names as $attrib_name_match ) {
|
|
||||||
$beginning_offset = strlen( $attrib_prefix );
|
|
||||||
$attrib_name_end = strpos( $attrib_name_match[0], '>', $attrib_name_match[1] );
|
|
||||||
$attrib_name = substr( $attrib_name_match[0], $beginning_offset, $attrib_name_end - $beginning_offset );
|
|
||||||
if ( isset( $request[ $attrib_name ] ) ) {
|
|
||||||
$base = str_replace( "(?P<$attrib_name>[\d]+)", $request[ $attrib_name ], $base );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ) );
|
|
||||||
|
|
||||||
if ( $page > 1 ) {
|
|
||||||
$prev_page = $page - 1;
|
|
||||||
if ( $prev_page > $max_pages ) {
|
|
||||||
$prev_page = $max_pages;
|
|
||||||
}
|
|
||||||
$prev_link = add_query_arg( 'page', $prev_page, $base );
|
|
||||||
$response->link_header( 'prev', $prev_link );
|
|
||||||
}
|
|
||||||
if ( $max_pages > $page ) {
|
|
||||||
$next_page = $page + 1;
|
|
||||||
$next_link = add_query_arg( 'page', $next_page, $base );
|
|
||||||
$response->link_header( 'next', $next_link );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,8 @@ namespace WooCommerce\RestApi\Controllers\Version4;
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
use \WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions;
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions;
|
||||||
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terms controller class.
|
* Terms controller class.
|
||||||
|
@ -203,31 +204,12 @@ abstract class AbstractTermsContoller extends AbstractController {
|
||||||
$response[] = $this->prepare_response_for_collection( $data );
|
$response[] = $this->prepare_response_for_collection( $data );
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = rest_ensure_response( $response );
|
|
||||||
|
|
||||||
// Store pagination values for headers then unset for count query.
|
// Store pagination values for headers then unset for count query.
|
||||||
$per_page = (int) $prepared_args['number'];
|
$per_page = (int) $prepared_args['number'];
|
||||||
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
|
|
||||||
|
|
||||||
$response->header( 'X-WP-Total', (int) $total_terms );
|
|
||||||
$max_pages = ceil( $total_terms / $per_page );
|
$max_pages = ceil( $total_terms / $per_page );
|
||||||
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
|
||||||
|
|
||||||
$base = str_replace( '(?P<attribute_id>[\d]+)', $request['attribute_id'], $this->rest_base );
|
$response = rest_ensure_response( $response );
|
||||||
$base = add_query_arg( $request->get_query_params(), rest_url( '/' . $this->namespace . '/' . $base ) );
|
$response = Pagination::add_pagination_headers( $response, $request, $total_terms, $max_pages );
|
||||||
if ( $page > 1 ) {
|
|
||||||
$prev_page = $page - 1;
|
|
||||||
if ( $prev_page > $max_pages ) {
|
|
||||||
$prev_page = $max_pages;
|
|
||||||
}
|
|
||||||
$prev_link = add_query_arg( 'page', $prev_page, $base );
|
|
||||||
$response->link_header( 'prev', $prev_link );
|
|
||||||
}
|
|
||||||
if ( $max_pages > $page ) {
|
|
||||||
$next_page = $page + 1;
|
|
||||||
$next_link = add_query_arg( 'page', $next_page, $base );
|
|
||||||
$response->link_header( 'next', $next_link );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ defined( 'ABSPATH' ) || exit;
|
||||||
use \WP_REST_Server;
|
use \WP_REST_Server;
|
||||||
use WooCommerce\RestApi\Controllers\Version4\Requests\CustomerRequest;
|
use WooCommerce\RestApi\Controllers\Version4\Requests\CustomerRequest;
|
||||||
use WooCommerce\RestApi\Controllers\Version4\Responses\CustomerResponse;
|
use WooCommerce\RestApi\Controllers\Version4\Responses\CustomerResponse;
|
||||||
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REST API Customers controller class.
|
* REST API Customers controller class.
|
||||||
|
@ -190,8 +191,6 @@ class Customers extends AbstractController {
|
||||||
$users[] = $this->prepare_response_for_collection( $data );
|
$users[] = $this->prepare_response_for_collection( $data );
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = rest_ensure_response( $users );
|
|
||||||
|
|
||||||
// Store pagination values for headers then unset for count query.
|
// Store pagination values for headers then unset for count query.
|
||||||
$per_page = (int) $prepared_args['number'];
|
$per_page = (int) $prepared_args['number'];
|
||||||
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
|
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
|
||||||
|
@ -199,6 +198,7 @@ class Customers extends AbstractController {
|
||||||
$prepared_args['fields'] = 'ID';
|
$prepared_args['fields'] = 'ID';
|
||||||
|
|
||||||
$total_users = $query->get_total();
|
$total_users = $query->get_total();
|
||||||
|
|
||||||
if ( $total_users < 1 ) {
|
if ( $total_users < 1 ) {
|
||||||
// Out-of-bounds, run the query again without LIMIT for total count.
|
// Out-of-bounds, run the query again without LIMIT for total count.
|
||||||
unset( $prepared_args['number'] );
|
unset( $prepared_args['number'] );
|
||||||
|
@ -206,24 +206,9 @@ class Customers extends AbstractController {
|
||||||
$count_query = new \ WP_User_Query( $prepared_args );
|
$count_query = new \ WP_User_Query( $prepared_args );
|
||||||
$total_users = $count_query->get_total();
|
$total_users = $count_query->get_total();
|
||||||
}
|
}
|
||||||
$response->header( 'X-WP-Total', (int) $total_users );
|
|
||||||
$max_pages = ceil( $total_users / $per_page );
|
|
||||||
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
|
||||||
|
|
||||||
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
|
$response = rest_ensure_response( $users );
|
||||||
if ( $page > 1 ) {
|
$response = Pagination::add_pagination_headers( $response, $request, $total_users, ceil( $total_users / $per_page ) );
|
||||||
$prev_page = $page - 1;
|
|
||||||
if ( $prev_page > $max_pages ) {
|
|
||||||
$prev_page = $max_pages;
|
|
||||||
}
|
|
||||||
$prev_link = add_query_arg( 'page', $prev_page, $base );
|
|
||||||
$response->link_header( 'prev', $prev_link );
|
|
||||||
}
|
|
||||||
if ( $max_pages > $page ) {
|
|
||||||
$next_page = $page + 1;
|
|
||||||
$next_link = add_query_arg( 'page', $next_page, $base );
|
|
||||||
$response->link_header( 'next', $next_link );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
use WooCommerce\RestApi\Controllers\Version4\Responses\ProductReviewResponse;
|
use WooCommerce\RestApi\Controllers\Version4\Responses\ProductReviewResponse;
|
||||||
use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions;
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Permissions;
|
||||||
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REST API Product Reviews controller class.
|
* REST API Product Reviews controller class.
|
||||||
|
@ -242,28 +243,7 @@ class ProductReviews extends AbstractController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = rest_ensure_response( $reviews );
|
$response = rest_ensure_response( $reviews );
|
||||||
$response->header( 'X-WP-Total', $total_reviews );
|
$response = Pagination::add_pagination_headers( $response, $request, $total_reviews, $max_pages );
|
||||||
$response->header( 'X-WP-TotalPages', $max_pages );
|
|
||||||
|
|
||||||
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ) );
|
|
||||||
|
|
||||||
if ( $request['page'] > 1 ) {
|
|
||||||
$prev_page = $request['page'] - 1;
|
|
||||||
|
|
||||||
if ( $prev_page > $max_pages ) {
|
|
||||||
$prev_page = $max_pages;
|
|
||||||
}
|
|
||||||
|
|
||||||
$prev_link = add_query_arg( 'page', $prev_page, $base );
|
|
||||||
$response->link_header( 'prev', $prev_link );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $max_pages > $request['page'] ) {
|
|
||||||
$next_page = $request['page'] + 1;
|
|
||||||
$next_link = add_query_arg( 'page', $next_page, $base );
|
|
||||||
|
|
||||||
$response->link_header( 'next', $next_link );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4;
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REST API Taxes controller class.
|
* REST API Taxes controller class.
|
||||||
*/
|
*/
|
||||||
|
@ -175,8 +177,6 @@ class Taxes extends AbstractController {
|
||||||
$taxes[] = $this->prepare_response_for_collection( $data );
|
$taxes[] = $this->prepare_response_for_collection( $data );
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = rest_ensure_response( $taxes );
|
|
||||||
|
|
||||||
// Store pagination values for headers then unset for count query.
|
// Store pagination values for headers then unset for count query.
|
||||||
$per_page = (int) $prepared_args['number'];
|
$per_page = (int) $prepared_args['number'];
|
||||||
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
|
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
|
||||||
|
@ -186,24 +186,10 @@ class Taxes extends AbstractController {
|
||||||
|
|
||||||
// Calculate totals.
|
// Calculate totals.
|
||||||
$total_taxes = (int) $wpdb->num_rows;
|
$total_taxes = (int) $wpdb->num_rows;
|
||||||
$response->header( 'X-WP-Total', (int) $total_taxes );
|
$max_pages = ceil( $total_taxes / $per_page );
|
||||||
$max_pages = ceil( $total_taxes / $per_page );
|
|
||||||
$response->header( 'X-WP-TotalPages', (int) $max_pages );
|
|
||||||
|
|
||||||
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
|
$response = rest_ensure_response( $taxes );
|
||||||
if ( $page > 1 ) {
|
$response = Pagination::add_pagination_headers( $response, $request, $total_taxes, $max_pages );
|
||||||
$prev_page = $page - 1;
|
|
||||||
if ( $prev_page > $max_pages ) {
|
|
||||||
$prev_page = $max_pages;
|
|
||||||
}
|
|
||||||
$prev_link = add_query_arg( 'page', $prev_page, $base );
|
|
||||||
$response->link_header( 'prev', $prev_link );
|
|
||||||
}
|
|
||||||
if ( $max_pages > $page ) {
|
|
||||||
$next_page = $page + 1;
|
|
||||||
$next_link = add_query_arg( 'page', $next_page, $base );
|
|
||||||
$response->link_header( 'next', $next_link );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pagination helper.
|
||||||
|
*
|
||||||
|
* Handles permission checks for endpoints.
|
||||||
|
*
|
||||||
|
* @package WooCommerce/RestApi
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace WooCommerce\RestApi\Controllers\Version4\Utilities;
|
||||||
|
|
||||||
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permissions class.
|
||||||
|
*/
|
||||||
|
class Pagination {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add pagination headers to a response object.
|
||||||
|
*
|
||||||
|
* @param \WP_REST_Response $response Reference to the response object.
|
||||||
|
* @param \WP_REST_Request $request The request object.
|
||||||
|
* @param int $total_items Total items found.
|
||||||
|
* @param int $total_pages Total pages found.
|
||||||
|
* @return \WP_REST_Response
|
||||||
|
*/
|
||||||
|
public static function add_pagination_headers( $response, $request, $total_items, $total_pages ) {
|
||||||
|
$response->header( 'X-WP-Total', $total_items );
|
||||||
|
$response->header( 'X-WP-TotalPages', $total_pages );
|
||||||
|
|
||||||
|
$current_page = self::get_current_page( $request );
|
||||||
|
$link_base = self::get_link_base( $request );
|
||||||
|
|
||||||
|
if ( $current_page > 1 ) {
|
||||||
|
$previous_page = $current_page - 1;
|
||||||
|
if ( $previous_page > $total_pages ) {
|
||||||
|
$previous_page = $total_pages;
|
||||||
|
}
|
||||||
|
self::add_page_link( $response, 'prev', $previous_page, $link_base );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $total_pages > $current_page ) {
|
||||||
|
self::add_page_link( $response, 'next', ( $current_page + 1 ), $link_base );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current page.
|
||||||
|
*
|
||||||
|
* @param \WP_REST_Request $request The request object.
|
||||||
|
* @return int Get the page from the request object.
|
||||||
|
*/
|
||||||
|
protected static function get_current_page( $request ) {
|
||||||
|
return (int) $request->get_param( 'page' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get base for links from the request object.
|
||||||
|
*
|
||||||
|
* @param \WP_REST_Request $request The request object.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function get_link_base( $request ) {
|
||||||
|
return add_query_arg( $request->get_query_params(), rest_url( $request->get_route() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a page link.
|
||||||
|
*
|
||||||
|
* @param \WP_REST_Response $response Reference to the response object.
|
||||||
|
* @param string $name Page link name. e.g. prev.
|
||||||
|
* @param int $page Page number.
|
||||||
|
* @param string $link_base Base URL.
|
||||||
|
*/
|
||||||
|
protected static function add_page_link( &$response, $name, $page, $link_base ) {
|
||||||
|
$response->link_header( $name, add_query_arg( 'page', $page, $link_base ) );
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ namespace WooCommerce\RestApi\Controllers\Version4;
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
use WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* REST API Webhooks controller class.
|
* REST API Webhooks controller class.
|
||||||
*/
|
*/
|
||||||
|
@ -179,29 +181,11 @@ class Webhooks extends AbstractController {
|
||||||
$webhooks[] = $this->prepare_response_for_collection( $data );
|
$webhooks[] = $this->prepare_response_for_collection( $data );
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = rest_ensure_response( $webhooks );
|
|
||||||
$per_page = (int) $prepared_args['limit'];
|
|
||||||
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
|
|
||||||
$total_webhooks = $results->total;
|
$total_webhooks = $results->total;
|
||||||
$max_pages = $results->max_num_pages;
|
$max_pages = $results->max_num_pages;
|
||||||
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
|
$response = rest_ensure_response( $webhooks );
|
||||||
|
$response = Pagination::add_pagination_headers( $response, $request, $total_webhooks, $max_pages );
|
||||||
$response->header( 'X-WP-Total', $total_webhooks );
|
|
||||||
$response->header( 'X-WP-TotalPages', $max_pages );
|
|
||||||
|
|
||||||
if ( $page > 1 ) {
|
|
||||||
$prev_page = $page - 1;
|
|
||||||
if ( $prev_page > $max_pages ) {
|
|
||||||
$prev_page = $max_pages;
|
|
||||||
}
|
|
||||||
$prev_link = add_query_arg( 'page', $prev_page, $base );
|
|
||||||
$response->link_header( 'prev', $prev_link );
|
|
||||||
}
|
|
||||||
if ( $max_pages > $page ) {
|
|
||||||
$next_page = $page + 1;
|
|
||||||
$next_link = add_query_arg( 'page', $next_page, $base );
|
|
||||||
$response->link_header( 'next', $next_link );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue