Filtering for the COT admin list table. (#33789)

* Column sorting for the COT admin list table.

* Add filter for easier extensibility.

* Implement date based filtering within the admin order list table.

* Implement customer-based filtering within admin order list table.

* Allow filtering down to no results, better management of http_referer state.

* Changelog.

* Bring up-to-date, fix some conflict resolution mis-steps.

* Address coding standards.

* Remove unused import.
This commit is contained in:
Barry Hughes 2022-08-11 09:00:47 -07:00 committed by GitHub
parent a498cc8280
commit bc31065b8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 13 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: add
Add support for filtering the Custom Order Table admin list UI.

View File

@ -19,6 +19,13 @@ class ListTable extends WP_List_Table {
*/
private $order_query_args = array();
/**
* Tracks if a filter (ie, date or customer filter) has been applied.
*
* @var bool
*/
private $has_filter = false;
/**
* Sets up the admin list table for orders (specifically, for orders managed by the OrdersTableDataStore).
*
@ -41,7 +48,6 @@ class ListTable extends WP_List_Table {
*/
public function setup(): void {
add_action( 'admin_notices', array( $this, 'bulk_action_notices' ) );
add_filter( 'manage_woocommerce_page_wc-orders_columns', array( $this, 'get_columns' ) );
add_filter( 'set_screen_option_edit_orders_per_page', array( $this, 'set_items_per_page' ), 10, 3 );
add_filter( 'default_hidden_columns', array( $this, 'default_hidden_columns' ), 10, 2 );
@ -73,7 +79,7 @@ class ListTable extends WP_List_Table {
* @return mixed
*/
public function set_items_per_page( $default, string $option, int $value ) {
return 'edit_orders_per_page' === $option ? absint( $value ) : $default;
return $option === 'edit_orders_per_page' ? absint( $value ) : $default;
}
/**
@ -93,7 +99,7 @@ class ListTable extends WP_List_Table {
<hr class='wp-header-end'>
";
if ( $this->has_items() ) {
if ( $this->has_items() || $this->has_filter ) {
$this->views();
echo '<form id="wc-orders-filter" method="get" action="' . esc_url( get_admin_url( null, 'admin.php' ) ) . '">';
@ -172,6 +178,8 @@ class ListTable extends WP_List_Table {
);
$this->set_order_args();
$this->set_date_args();
$this->set_customer_args();
/**
* Provides an opportunity to modify the query arguments used in the (Custom Order Table-powered) order list
@ -208,6 +216,43 @@ class ListTable extends WP_List_Table {
$this->order_query_args['order'] = in_array( $direction, array( 'ASC', 'DESC' ), true ) ? $direction : 'ASC';
}
/**
* Implements date (month-based) filtering.
*/
private function set_date_args() {
$year_month = sanitize_text_field( wp_unslash( $_GET['m'] ?? '' ) );
if ( empty( $year_month ) || ! preg_match( '/^[0-9]{6}$/', $year_month ) ) {
return;
}
$year = (int) substr( $year_month, 0, 4 );
$month = (int) substr( $year_month, 4, 2 );
if ( $month < 0 || $month > 12 ) {
return;
}
$last_day_of_month = date_create( "$year-$month" )->format( 'Y-m-t' );
$this->order_query_args['date_created'] = "$year-$month-01..." . $last_day_of_month;
$this->has_filter = true;
}
/**
* Implements filtering of orders by customer.
*/
private function set_customer_args() {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$customer = (int) wp_unslash( $_GET['_customer_user'] ?? '' );
if ( $customer < 1 ) {
return;
}
$this->order_query_args['customer'] = $customer;
$this->has_filter = true;
}
/**
* Get the list of views for this table (all orders, completed orders, etc, each with a count of the number of
* corresponding orders).
@ -229,7 +274,7 @@ class ListTable extends WP_List_Table {
}
$all_count = array_sum( $view_counts );
$view_links['all'] = $this->get_view_link( 'all', __( 'All', 'woocommerce' ), $all_count, 'all' === $current );
$view_links['all'] = $this->get_view_link( 'all', __( 'All', 'woocommerce' ), $all_count, $current === 'all' );
foreach ( $view_counts as $slug => $count ) {
$view_links[ $slug ] = $this->get_view_link( $slug, $statuses[ $slug ], $count, $slug === $current );
@ -238,7 +283,6 @@ class ListTable extends WP_List_Table {
return $view_links;
}
// phpcs:disable Generic.Commenting.Todo.CommentFound
/**
* Count orders by status.
*
@ -287,7 +331,7 @@ class ListTable extends WP_List_Table {
protected function extra_tablenav( $which ) {
echo '<div class="alignleft actions">';
if ( 'top' === $which ) {
if ( $which === 'top' ) {
$this->months_filter();
$this->customers_filter();
@ -557,7 +601,7 @@ class ListTable extends WP_List_Table {
$latest_note = current( $latest_notes );
if ( isset( $latest_note->content ) && 1 === $approved_comments_count ) {
if ( isset( $latest_note->content ) && $approved_comments_count === 1 ) {
$tooltip = wc_sanitize_tooltip( $latest_note->content );
} elseif ( isset( $latest_note->content ) ) {
/* translators: %d: notes count */
@ -704,8 +748,6 @@ class ListTable extends WP_List_Table {
echo '<input type="hidden" name="page" value="wc-orders" >';
$state_params = array(
'_customer_user',
'm',
'paged',
'status',
);
@ -715,7 +757,7 @@ class ListTable extends WP_List_Table {
continue;
}
echo '<input type="hidden" name="status" value="' . esc_attr( sanitize_text_field( wp_unslash( $_GET[ $param ] ) ) ) . '" >';
echo '<input type="hidden" name="' . esc_attr( $param ) . '" value="' . esc_attr( sanitize_text_field( wp_unslash( $_GET[ $param ] ) ) ) . '" >';
}
}

View File

@ -63,8 +63,6 @@ class PageController {
}
/**
=======
>>>>>>> trunk
* Sets up the page controller, including registering the menu item.
*
* @return void
@ -168,6 +166,23 @@ class PageController {
if ( $this->orders_table->current_action() ) {
$this->orders_table->handle_bulk_actions();
}
$this->strip_http_referer();
}
/**
* Perform a redirect to remove the `_wp_http_referer` and `_wpnonce` strings if present in the URL (see also
* wp-admin/edit.php where a similar process takes place), otherwise the size of this field builds to an
* unmanageable length over time.
*/
private function strip_http_referer(): void {
$current_url = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ?? '' ) );
$stripped_url = remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), $current_url );
if ( $stripped_url !== $current_url ) {
wp_safe_redirect( $stripped_url );
exit;
}
}
/**
@ -196,5 +211,4 @@ class PageController {
$this->order->save();
$theorder = $this->order;
}
}