Column sorting for the COT admin list table. (#33787)

* Column sorting for the COT admin list table.

* Add filter for easier extensibility.

* Changelog.

* Add support for orderby order’s total and creation/modification dates

* Remove unnecessary import

* Use ‘any’ instead of ‘all’ as status so that all valid statuses are used instead

* Use ‘order_total’ as orderby GET arg for backwards compat

* Rework sorting logic after support in `OrdersTableQuery`

* Update `@since` tag

* Make PHPCS happy

Co-authored-by: Jorge A. Torres <jorge.torres@automattic.com>
This commit is contained in:
Barry Hughes 2022-07-29 01:22:25 -07:00 committed by GitHub
parent be89ba6e06
commit 406853634a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 9 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: add
Add support for sorting columns in the COT admin list UI.

View File

@ -12,6 +12,13 @@ use WP_Screen;
* Admin list table for orders as managed by the OrdersTableDataStore.
*/
class ListTable extends WP_List_Table {
/**
* Contains the arguments to be used in the order query.
*
* @var array
*/
private $order_query_args = array();
/**
* Sets up the admin list table for orders (specifically, for orders managed by the OrdersTableDataStore).
*
@ -155,15 +162,26 @@ class ListTable extends WP_List_Table {
*/
public function prepare_items() {
$limit = $this->get_items_per_page( 'edit_orders_per_page' );
$args = array(
$this->order_query_args = array(
'limit' => $limit,
'page' => $this->get_pagenum(),
'paginate' => true,
'status' => sanitize_text_field( wp_unslash( $_REQUEST['status'] ?? 'all' ) ),
'status' => sanitize_text_field( wp_unslash( $_REQUEST['status'] ?? 'any' ) ),
'type' => 'shop_order',
);
$orders = wc_get_orders( $args );
$this->set_order_args();
/**
* Provides an opportunity to modify the query arguments used in the (Custom Order Table-powered) order list
* table.
*
* @since 6.9.0
*
* @param array $query_args Arguments to be passed to `wc_get_orders()`.
*/
$orders = wc_get_orders( (array) apply_filters( 'woocommerce_order_list_table_prepare_items_query_args', $this->order_query_args ) );
$this->items = $orders->orders;
$this->set_pagination_args(
@ -174,6 +192,22 @@ class ListTable extends WP_List_Table {
);
}
/**
* Updates the WC Order Query arguments as needed to support orderable columns.
*/
private function set_order_args() {
$sortable = $this->get_sortable_columns();
$field = sanitize_text_field( wp_unslash( $_GET['orderby'] ?? '' ) );
$direction = strtoupper( sanitize_text_field( wp_unslash( $_GET['order'] ?? '' ) ) );
if ( ! in_array( $field, $sortable, true ) ) {
return;
}
$this->order_query_args['orderby'] = $field;
$this->order_query_args['order'] = in_array( $direction, array( 'ASC', 'DESC' ), true ) ? $direction : 'ASC';
}
/**
* Get the list of views for this table (all orders, completed orders, etc, each with a count of the number of
* corresponding orders).
@ -204,6 +238,7 @@ class ListTable extends WP_List_Table {
return $view_links;
}
// phpcs:disable Generic.Commenting.Todo.CommentFound
/**
* Count orders by status.
*
@ -368,6 +403,19 @@ class ListTable extends WP_List_Table {
);
}
/**
* Defines the default sortable columns.
*
* @return string[]
*/
public function get_sortable_columns() {
return array(
'order_number' => 'ID',
'order_date' => 'date',
'order_total' => 'order_total',
);
}
/**
* Specify the columns we wish to hide by default.
*

View File

@ -261,12 +261,16 @@ class OrdersTableQuery {
// Translate $orderby to a valid field.
$mapping = array(
'ID' => "{$this->tables['orders']}.id",
'id' => "{$this->tables['orders']}.id",
'type' => "{$this->tables['orders']}.type",
'date' => "{$this->tables['orders']}.date_created_gmt",
'modified' => "{$this->tables['orders']}.date_updated_gmt",
'parent' => "{$this->tables['orders']}.parent_order_id",
'ID' => "{$this->tables['orders']}.id",
'id' => "{$this->tables['orders']}.id",
'type' => "{$this->tables['orders']}.type",
'date' => "{$this->tables['orders']}.date_created_gmt",
'date_created' => "{$this->tables['orders']}.date_created_gmt",
'modified' => "{$this->tables['orders']}.date_updated_gmt",
'date_modified' => "{$this->tables['orders']}.date_updated_gmt",
'parent' => "{$this->tables['orders']}.parent_order_id",
'total' => "{$this->tables['orders']}.total_amount",
'order_total' => "{$this->tables['orders']}.total_amount",
);
$order = $this->args['order'] ?? '';