Add filters for customer email and order id for performance. (#43865)

* Add filters for customer email and order id for performance.

* Empty where should not cause invalid query.

* Add changelog.

* Add unit test for newly supported search params.

* Apply coding standards.

* Add a trailing wildcard to allow broader search.

* Remove extra line.

Co-authored-by: Corey McKrill <916023+coreymckrill@users.noreply.github.com>
This commit is contained in:
Vedanshu Jain 2024-01-25 05:38:07 +05:30 committed by GitHub
parent cd3feaa3dd
commit efd5ccebeb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 69 additions and 5 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: enhancement
HPOS: Add more select options when searching orders for Order ID and Customer email.

View File

@ -1623,9 +1623,11 @@ class ListTable extends WP_List_Table {
*/
private function search_filter() {
$options = array(
'customers' => __( 'Customers', 'woocommerce' ),
'products' => __( 'Products', 'woocommerce' ),
'all' => __( 'All', 'woocommerce' ),
'order_id' => __( 'Order ID', 'woocommerce' ),
'customer_email' => __( 'Customer Email', 'woocommerce' ),
'customers' => __( 'Customers', 'woocommerce' ),
'products' => __( 'Products', 'woocommerce' ),
'all' => __( 'All', 'woocommerce' ),
);
?>
<select name="search-filter" id="order-search-filter">

View File

@ -53,6 +53,8 @@ class OrdersTableSearchQuery {
*/
private function sanitize_search_filters( string $search_filter ) : array {
$available_filters = array(
'order_id',
'customer_email',
'customers', // customers also searches in meta.
'products',
);
@ -138,7 +140,10 @@ class OrdersTableSearchQuery {
}
foreach ( $this->search_filters as $search_filter ) {
$where[] = $this->generate_where_for_search_filter( $search_filter );
$search_where = $this->generate_where_for_search_filter( $search_filter );
if ( ! empty( $search_where ) ) {
$where[] = $search_where;
}
}
$where_statement = implode( ' OR ', $where );
@ -158,6 +163,20 @@ class OrdersTableSearchQuery {
$order_table = $this->query->get_table_name( 'orders' );
if ( 'customer_email' === $search_filter ) {
return $wpdb->prepare(
"`$order_table`.billing_email LIKE %s", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $order_table is hardcoded.
$wpdb->esc_like( $this->search_term ) . '%'
);
}
if ( 'order_id' === $search_filter && is_numeric( $this->search_term ) ) {
return $wpdb->prepare(
"`$order_table`.id = %d", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $order_table is hardcoded.
absint( $this->search_term )
);
}
if ( 'products' === $search_filter ) {
return $wpdb->prepare(
'search_query_items.order_item_name LIKE %s',
@ -169,6 +188,7 @@ class OrdersTableSearchQuery {
$meta_sub_query = $this->generate_where_for_meta_table();
return "`$order_table`.id IN ( $meta_sub_query ) ";
}
return '';
}

View File

@ -523,7 +523,7 @@ class OrdersTableQueryTests extends WC_Unit_Test_Case {
'return' => 'ids',
);
$query_args['search_filter'] = 'all';
// Default search filter is all, so we don't need to set it explicitly.
$query_args['s'] = 'Product';
$query = new OrdersTableQuery( $query_args );
@ -537,4 +537,42 @@ class OrdersTableQueryTests extends WC_Unit_Test_Case {
$query = new OrdersTableQuery( $query_args );
$this->assertEqualsCanonicalizing( $orders, $query->orders );
}
/**
* @testDox The 'search_filter' argument works with an 'order_id' param passed in.
*/
public function test_query_s_filters_order_id() {
$orders = $this->setup_dummy_orders_for_search_filter();
$query_args = array(
's' => $orders[0],
'return' => 'ids',
);
$query_args['search_filter'] = 'order_id';
$query = new OrdersTableQuery( $query_args );
$this->assertEqualsCanonicalizing( array( $orders[0] ), $query->orders );
$query_args['s'] = $orders[1];
$query = new OrdersTableQuery( $query_args );
$this->assertEqualsCanonicalizing( array( $orders[1] ), $query->orders );
}
/**
* @testDox The 'search_filter' argument works with an 'customer_email' param passed in.
*/
public function test_query_s_filters_customer_email() {
$orders = $this->setup_dummy_orders_for_search_filter();
$query_args = array(
's' => 'customer@woo.t',
'return' => 'ids',
);
$query_args['search_filter'] = 'customer_email';
$query = new OrdersTableQuery( $query_args );
$this->assertEqualsCanonicalizing( array( $orders[0] ), $query->orders );
}
}