Update pagination args/headers

Part of #4055
This commit is contained in:
Max Rice 2013-11-18 21:06:45 -05:00
parent 87ff36db12
commit 490dc758a9
6 changed files with 120 additions and 46 deletions

View File

@ -63,9 +63,12 @@ class WC_API_Coupons extends WC_API_Resource {
* @since 2.1
* @param string $fields
* @param array $filter
* @param int $page
* @return array
*/
public function get_coupons( $fields = null, $filter = array() ) {
public function get_coupons( $fields = null, $filter = array(), $page = 1 ) {
$filter['page'] = $page;
$query = $this->query_coupons( $filter );
@ -79,7 +82,7 @@ class WC_API_Coupons extends WC_API_Resource {
$coupons[] = $this->get_coupon( $coupon_id, $fields );
}
$this->server->query_navigation_headers( $query );
$this->server->add_pagination_headers( $query );
return array( 'coupons' => $coupons );
}

View File

@ -87,15 +87,18 @@ class WC_API_Customers extends WC_API_Resource {
* @since 2.1
* @param array $fields
* @param array $filter
* @param int $page
* @return array
*/
public function get_customers( $fields = null, $filter = array() ) {
public function get_customers( $fields = null, $filter = array(), $page = 1 ) {
$filter['page'] = $page;
$query = $this->query_customers( $filter );
$customers = array();
foreach( $query->results as $user_id ) {
foreach( $query->get_results() as $user_id ) {
if ( ! $this->is_readable( $user_id ) )
continue;
@ -103,7 +106,7 @@ class WC_API_Customers extends WC_API_Resource {
$customers[] = $this->get_customer( $user_id, $fields );
}
// TODO: add navigation/total count headers for pagination
$this->server->add_pagination_headers( $query );
return array( 'customers' => $customers );
}
@ -191,7 +194,7 @@ class WC_API_Customers extends WC_API_Resource {
if ( ! current_user_can( 'list_users' ) )
return new WP_Error( 'woocommerce_api_user_cannot_read_customer', __( 'You do not have permission to read customers', 'woocommerce' ), array( 'status' => 401 ) );
return array( 'count' => $query->get_total() );
return array( 'count' => count( $query->get_results() ) );
}
@ -289,37 +292,65 @@ class WC_API_Customers extends WC_API_Resource {
/**
* Helper method to get customer user objects
*
* Note that WP_User_Query does not have built-in pagination so limit & offset are used to provide limited
* pagination support
*
* @since 2.1
* @param array $args request arguments for filtering query
* @return array
*/
private function query_customers( $args = array() ) {
// default users per page
$users_per_page = get_option( 'posts_per_page' );
// set base query arguments
$query_args = array(
'fields' => 'ID',
'role' => 'customer',
'orderby' => 'registered',
'number' => $users_per_page,
);
if ( ! empty( $args['q'] ) )
// search
if ( ! empty( $args['q'] ) ) {
$query_args['search'] = $args['q'];
}
if ( ! empty( $args['limit'] ) )
$query_args['number'] = $args['limit'];
// limit number of users returned
if ( ! empty( $args['limit'] ) ) {
if ( ! empty( $args['offset'] ) )
$query_args['offset'] = $args['offset'];
$query_args['number'] = absint( $args['limit'] );
if ( ! empty( $args['created_at_min'] ) )
$users_per_page = absint( $args['limit'] );
}
// page
$page = absint( $args['page'] );
// offset
if ( ! empty( $args['offset'] ) ) {
$query_args['offset'] = absint( $args['offset'] );
} else {
$query_args['offset'] = $users_per_page * ( $page - 1 );
}
// created date
if ( ! empty( $args['created_at_min'] ) ) {
$this->created_at_min = $this->server->parse_datetime( $args['created_at_min'] );
}
if ( ! empty( $args['created_at_max'] ) )
if ( ! empty( $args['created_at_max'] ) ) {
$this->created_at_max = $this->server->parse_datetime( $args['created_at_max'] );
}
// TODO: support page argument - requires custom implementation as WP_User_Query has no built-in pagination like WP_Query
$query = new WP_User_Query( $query_args );
return new WP_User_Query( $query_args );
// helper members for pagination headers
$query->total_pages = ceil( $query->get_total() / $users_per_page );
$query->page = $page;
return $query;
}
/**

View File

@ -63,13 +63,16 @@ class WC_API_Orders extends WC_API_Resource {
* @param string $fields
* @param array $filter
* @param string $status
* @param int $page
* @return array
*/
public function get_orders( $fields = null, $filter = array(), $status = null ) {
public function get_orders( $fields = null, $filter = array(), $status = null, $page = 1 ) {
if ( ! empty( $status ) )
$filter['status'] = $status;
$filter['page'] = $page;
$query = $this->query_orders( $filter );
$orders = array();
@ -82,7 +85,7 @@ class WC_API_Orders extends WC_API_Resource {
$orders[] = $this->get_order( $order_id, $fields );
}
$this->server->query_navigation_headers( $query );
$this->server->add_pagination_headers( $query );
return array( 'orders' => $orders );
}

View File

@ -63,13 +63,16 @@ class WC_API_Products extends WC_API_Resource {
* @param string $fields
* @param string $type
* @param array $filter
* @param int $page
* @return array
*/
public function get_products( $fields = null, $type = null, $filter = array() ) {
public function get_products( $fields = null, $type = null, $filter = array(), $page = 1 ) {
if ( ! empty( $type ) )
$filter['type'] = $type;
$filter['page'] = $page;
$query = $this->query_products( $filter );
$products = array();
@ -82,7 +85,7 @@ class WC_API_Products extends WC_API_Resource {
$products[] = $this->get_product( $product_id, $fields );
}
$this->server->query_navigation_headers( $query );
$this->server->add_pagination_headers( $query );
return array( 'products' => $products );
}

View File

@ -152,10 +152,7 @@ class WC_API_Resource {
$args['offset'] = $request_args['offset'];
// resource page
if ( empty( $request_args['page'] ) )
$args['paged'] = 1;
else
$args['paged'] = absint( $request_args['page'] );
$args['paged'] = absint( $request_args['page'] );
return array_merge( $base_args, $args );
}

View File

@ -517,40 +517,77 @@ class WC_API_Server {
}
/**
* Send navigation-related headers for post collections
* Send pagination headers for resources
*
* @since 2.1
* @param WP_Query $query
* @param WP_Query|WP_User_Query $query
*/
public function query_navigation_headers( $query ) {
$max_page = $query->max_num_pages;
$paged = $query->get('paged');
public function add_pagination_headers( $query ) {
if ( !$paged )
$paged = 1;
// WP_User_Query
if ( is_a( $query, 'WP_User_Query' ) ) {
$nextpage = intval($paged) + 1;
// TODO: change from `page` query arg to filter[page] arg
if ( ! $query->is_single() ) {
if ( $paged > 1 ) {
$request = remove_query_arg( 'page' );
$request = add_query_arg( 'page', $paged - 1, $request );
$this->link_header( 'prev', $request );
}
$page = $query->page;
$single = count( $query->get_results() ) > 1;
$total = $query->get_total();
$total_pages = $query->total_pages;
if ( $nextpage <= $max_page ) {
$request = remove_query_arg( 'page' );
$request = add_query_arg( 'page', $nextpage, $request );
$this->link_header( 'next', $request );
}
// WP_Query
} else {
$page = $query->get( 'paged' );
$single = $query->is_single();
$total = $query->found_posts * $query->max_num_pages;
$total_pages = $query->max_num_pages;
}
$this->header( 'X-WP-Total', $query->found_posts );
$this->header( 'X-WP-TotalPages', $max_page );
if ( ! $page )
$page = 1;
do_action('woocommerce_api_query_navigation_headers', $this, $query);
$next_page = absint( $page ) + 1;
if ( ! $single ) {
// first/prev
if ( $page > 1 ) {
$this->link_header( 'first', $this->get_paginated_url( 1 ) );
$this->link_header( 'prev', $this->get_paginated_url( $page -1 ) );
}
// next
if ( $next_page <= $total_pages ) {
$this->link_header( 'next', $this->get_paginated_url( $next_page ) );
}
// last
if ( $page != $total_pages )
$this->link_header( 'last', $this->get_paginated_url( $total_pages ) );
}
$this->header( 'X-WC-Total', $total );
$this->header( 'X-WC-TotalPages', $total_pages );
do_action( 'woocommerce_api_pagination_headers', $this, $query );
}
/**
* Returns the request URL with the page query parmeter set to the specified page
*
* @since 2.1
* @param int $page
* @return string
*/
private function get_paginated_url( $page ) {
// remove existing page query param
$request = remove_query_arg( 'page' );
// add provided page query param
$request = urldecode( add_query_arg( 'page', $page, $request ) );
// return full URL
return get_woocommerce_api_url( str_replace( '/wc-api/v1/', '', $request ) );
}
/**
* Retrieve the raw request entity (body)