Fix/34271 unlimited results (#34289)
Support for unlimited ('-1') results in COT queries.
This commit is contained in:
parent
4693e251f7
commit
1a4060d689
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Ensure COT order queries respect unlimited ('-1') as a pagination limit.
|
|
@ -12,6 +12,12 @@ defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides a `WP_Query`-like interface to custom order tables.
|
* This class provides a `WP_Query`-like interface to custom order tables.
|
||||||
|
*
|
||||||
|
* @property-read int $found_orders Number of found orders.
|
||||||
|
* @property-read int $found_posts Alias of the `$found_orders` property.
|
||||||
|
* @property-read int $max_num_pages Max number of pages matching the current query.
|
||||||
|
* @property-read array $orders Order objects, or order IDs.
|
||||||
|
* @property-read array $posts Alias of the $orders property.
|
||||||
*/
|
*/
|
||||||
class OrdersTableQuery {
|
class OrdersTableQuery {
|
||||||
|
|
||||||
|
@ -25,6 +31,13 @@ class OrdersTableQuery {
|
||||||
*/
|
*/
|
||||||
public const REGEX_SHORTHAND_DATES = '/([^.<>]*)(>=|<=|>|<|\.\.\.)([^.<>]+)/';
|
public const REGEX_SHORTHAND_DATES = '/([^.<>]*)(>=|<=|>|<|\.\.\.)([^.<>]+)/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highest possible unsigned bigint value (unsigned bigints being the type of the `id` column).
|
||||||
|
*
|
||||||
|
* This is deliberately held as a string, rather than a numeric type, for inclusion within queries.
|
||||||
|
*/
|
||||||
|
private const MYSQL_MAX_UNSIGNED_BIGINT = '18446744073709551615';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Names of all COT tables (orders, addresses, operational_data, meta) in the form 'table_id' => 'table name'.
|
* Names of all COT tables (orders, addresses, operational_data, meta) in the form 'table_id' => 'table name'.
|
||||||
*
|
*
|
||||||
|
@ -562,7 +575,13 @@ class OrdersTableQuery {
|
||||||
$orderby = $this->orderby ? ( 'ORDER BY ' . implode( ', ', $this->orderby ) ) : '';
|
$orderby = $this->orderby ? ( 'ORDER BY ' . implode( ', ', $this->orderby ) ) : '';
|
||||||
|
|
||||||
// LIMITS.
|
// LIMITS.
|
||||||
$limits = $this->limits ? 'LIMIT ' . implode( ',', $this->limits ) : '';
|
$limits = '';
|
||||||
|
|
||||||
|
if ( ! empty( $this->limits ) && count( $this->limits ) === 2 ) {
|
||||||
|
list( $offset, $row_count ) = $this->limits;
|
||||||
|
$row_count = $row_count === -1 ? self::MYSQL_MAX_UNSIGNED_BIGINT : (int) $row_count;
|
||||||
|
$limits = 'LIMIT ' . (int) $offset . ', ' . $row_count;
|
||||||
|
}
|
||||||
|
|
||||||
// GROUP BY.
|
// GROUP BY.
|
||||||
$groupby = $this->groupby ? 'GROUP BY ' . implode( ', ', (array) $this->groupby ) : '';
|
$groupby = $this->groupby ? 'GROUP BY ' . implode( ', ', (array) $this->groupby ) : '';
|
||||||
|
@ -876,15 +895,20 @@ class OrdersTableQuery {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function process_limit(): void {
|
private function process_limit(): void {
|
||||||
$limit = ( $this->arg_isset( 'limit' ) ? absint( $this->args['limit'] ) : false );
|
$row_count = ( $this->arg_isset( 'limit' ) ? (int) $this->args['limit'] : false );
|
||||||
$page = ( $this->arg_isset( 'page' ) ? absint( $this->args['page'] ) : 1 );
|
$page = ( $this->arg_isset( 'page' ) ? absint( $this->args['page'] ) : 1 );
|
||||||
$offset = ( $this->arg_isset( 'offset' ) ? absint( $this->args['offset'] ) : false );
|
$offset = ( $this->arg_isset( 'offset' ) ? absint( $this->args['offset'] ) : false );
|
||||||
|
|
||||||
if ( ! $limit ) {
|
// Bool false indicates no limit was specified; less than -1 means an invalid value was passed (such as -3).
|
||||||
|
if ( $row_count === false || $row_count < -1 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->limits = array( $offset ? $offset : absint( ( $page - 1 ) * $limit ), $limit );
|
if ( $offset === false && $row_count > -1 ) {
|
||||||
|
$offset = (int) ( ( $page - 1 ) * $row_count );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->limits = array( $offset, $row_count );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -790,6 +790,54 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
$this->assertCount( 6, $query->orders );
|
$this->assertCount( 6, $query->orders );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @testdox Test pagination works for COT queries.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function test_cot_query_pagination(): void {
|
||||||
|
$test_orders = array();
|
||||||
|
$this->assertEquals( 0, ( new OrdersTableQuery() )->found_orders, 'We initially have zero orders within our custom order tables.' );
|
||||||
|
|
||||||
|
for ( $i = 0; $i < 30; $i++ ) {
|
||||||
|
$order = new WC_Order();
|
||||||
|
$this->switch_data_store( $order, $this->sut );
|
||||||
|
$order->save();
|
||||||
|
$test_orders[] = $order->get_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = new OrdersTableQuery();
|
||||||
|
$this->assertCount( 30, $query->orders, 'If no limits are specified, we fetch all available orders.' );
|
||||||
|
|
||||||
|
$query = new OrdersTableQuery( array( 'limit' => -1 ) );
|
||||||
|
$this->assertCount( 30, $query->orders, 'A limit of -1 is equivalent to requesting all available orders.' );
|
||||||
|
|
||||||
|
$query = new OrdersTableQuery( array( 'limit' => -10 ) );
|
||||||
|
$this->assertCount( 30, $query->orders, 'An invalid limit is treated as a request for all available orders.' );
|
||||||
|
|
||||||
|
$query = new OrdersTableQuery(
|
||||||
|
array(
|
||||||
|
'limit' => -1,
|
||||||
|
'offset' => 18,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertCount( 12, $query->orders, 'A limit of -1 can successfully be combined with an offset.' );
|
||||||
|
$this->assertEquals( array_slice( $test_orders, 18 ), $query->orders, 'The expected dataset is supplied when an offset is combined with a limit of -1.' );
|
||||||
|
|
||||||
|
$query = new OrdersTableQuery( array( 'limit' => 5 ) );
|
||||||
|
$this->assertCount( 5, $query->orders, 'Limits are respected when applied.' );
|
||||||
|
|
||||||
|
$query = new OrdersTableQuery(
|
||||||
|
array(
|
||||||
|
'limit' => 5,
|
||||||
|
'paged' => 2,
|
||||||
|
'return' => 'ids',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assertCount( 5, $query->orders, 'Pagination works with specified limit.' );
|
||||||
|
$this->assertEquals( array_slice( $test_orders, 5, 5 ), $query->orders, 'The expected dataset is supplied when paginating through orders.' );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to delete all meta for post.
|
* Helper function to delete all meta for post.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue