From 7a15ad61b74e6303dbfb351339e43d6ac1ddcdfa Mon Sep 17 00:00:00 2001 From: Vedanshu Jain Date: Wed, 28 Dec 2022 15:22:17 +0530 Subject: [PATCH 1/6] Skip custom search for HPOS API queries as it's handled already. For HPOS, we don't need a seperate step of passing the args through wc_order_search since we take care of search params in the final query itself. This duplication was actually causing for some results to not be displayed since we were ending up not honouring pagination arguments and would search only in first 10 matches. --- .../class-wc-rest-orders-v2-controller.php | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php index 88601765bc7..39cf28d7a59 100644 --- a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -8,8 +8,11 @@ * @since 2.6.0 */ +use Automattic\WooCommerce\Utilities\OrderUtil; + defined( 'ABSPATH' ) || exit; +// phpcs:disable Squiz.Classes.ClassFileName.NoMatch, Squiz.Classes.ValidClassName.NotCamelCaps -- Legacy class name, can't change without breaking backward compat. /** * REST API Orders controller class. * @@ -18,6 +21,7 @@ defined( 'ABSPATH' ) || exit; */ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { + // phpcs:enable /** * Endpoint namespace. * @@ -314,7 +318,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { if ( array_key_exists( $meta_item->id, $formatted_meta_data ) ) { $formatted_meta_item = $formatted_meta_data[ $meta_item->id ]; - $result['display_key'] = wc_clean( $formatted_meta_item->display_key ); + $result['display_key'] = wc_clean( $formatted_meta_item->display_key ); $result['display_value'] = wc_clean( $formatted_meta_item->display_value ); } @@ -346,14 +350,14 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { // Only fetch fields that we need. $fields = $this->get_fields_for_response( $this->request ); foreach ( $dependent_fields as $field_key => $dependency ) { - if ( in_array( $field_key, $fields ) && ! in_array( $dependency, $fields ) ) { + if ( in_array( $field_key, $fields, true ) && ! in_array( $dependency, $fields, true ) ) { $fields[] = $dependency; } } - $extra_fields = array_intersect( $extra_fields, $fields ); - $format_decimal = array_intersect( $format_decimal, $fields ); - $format_date = array_intersect( $format_date, $fields ); + $extra_fields = array_intersect( $extra_fields, $fields ); + $format_decimal = array_intersect( $format_decimal, $fields ); + $format_date = array_intersect( $format_date, $fields ); $format_line_items = array_intersect( $format_line_items, $fields ); @@ -506,6 +510,8 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { * @param WP_REST_Response $response The response object. * @param WC_Data $object Object data. * @param WP_REST_Request $request Request object. + * + * @since 4.5.0 */ return apply_filters( "woocommerce_rest_prepare_{$this->post_type}_object", $response, $object, $request ); } @@ -594,7 +600,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { } // Search. - if ( ! empty( $args['s'] ) ) { + if ( ! OrderUtil::custom_orders_table_usage_is_enabled() && ! empty( $args['s'] ) ) { $order_ids = wc_order_search( $args['s'] ); if ( ! empty( $order_ids ) ) { @@ -610,6 +616,8 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { * * @param array $args Key value array of query var to query value. * @param WP_REST_Request $request The request used. + * + * @since 4.5.0. */ $args = apply_filters( 'woocommerce_rest_orders_prepare_object_query', $args, $request ); @@ -693,6 +701,8 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { * @param WC_Data $order Object object. * @param WP_REST_Request $request Request object. * @param bool $creating If is creating a new object. + * + * @since 4.5.0. */ return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $order, $request, $creating ); } @@ -979,6 +989,14 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { // Prepare item data. $item = $this->$method( $posted, $action, $item ); + /** + * Allow extensions be notified before the item before is saved. + * + * @param WC_Order_Item $item The item object. + * @param array $posted The item data. + * + * @since 4.5.0. + */ do_action( 'woocommerce_rest_set_order_item', $item, $posted ); // If creating the order, add the item to it. From 2712b4724f60396902c24365dce986bf5ea959e1 Mon Sep 17 00:00:00 2001 From: Vedanshu Jain Date: Wed, 28 Dec 2022 15:27:15 +0530 Subject: [PATCH 2/6] Add changelog. --- plugins/woocommerce/changelog/fix-36212 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 plugins/woocommerce/changelog/fix-36212 diff --git a/plugins/woocommerce/changelog/fix-36212 b/plugins/woocommerce/changelog/fix-36212 new file mode 100644 index 00000000000..9540f4d7035 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-36212 @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Skip custom search for HPOS API queries as it's handled already. From d00f60684944027f16df5bb075e1845f97e96b61 Mon Sep 17 00:00:00 2001 From: Vedanshu Jain Date: Wed, 28 Dec 2022 15:44:56 +0530 Subject: [PATCH 3/6] Add support for sorting by includes param. --- .../DataStores/Orders/OrdersTableQuery.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableQuery.php b/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableQuery.php index 8b71df2aed5..76c3c167bd9 100644 --- a/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableQuery.php +++ b/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableQuery.php @@ -509,8 +509,17 @@ class OrdersTableQuery { return; } + // No need to sanitize, will be processed in calling function. + if ( 'include' === $orderby || 'post__in' === $orderby ) { + return; + } + if ( is_string( $orderby ) ) { - $orderby = array( $orderby => $order ); + $orderby_fields = array_map( 'trim', explode( ' ', $orderby ) ); + $orderby = array(); + foreach ( $orderby_fields as $field ) { + $orderby[ $field ] = $order; + } } $this->args['orderby'] = array(); @@ -977,6 +986,13 @@ class OrdersTableQuery { return; } + if ( 'include' === $orderby || 'post__in' === $orderby ) { + $ids = $this->args['id']; + $ids = array_map( 'absint', $ids ); + $this->orderby = array( "FIELD( {$this->tables['orders']}.id, " . implode( ',', $ids ) . ' )' ); + return; + } + $orderby_array = array(); foreach ( $this->args['orderby'] as $_orderby => $order ) { $orderby_array[] = "{$_orderby} {$order}"; From e163e1a265cad741b9016049a800e8fce6437fa9 Mon Sep 17 00:00:00 2001 From: Vedanshu Jain Date: Wed, 28 Dec 2022 15:45:41 +0530 Subject: [PATCH 4/6] Add changelog. --- plugins/woocommerce/changelog/fix-36214 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 plugins/woocommerce/changelog/fix-36214 diff --git a/plugins/woocommerce/changelog/fix-36214 b/plugins/woocommerce/changelog/fix-36214 new file mode 100644 index 00000000000..29a3e542e5d --- /dev/null +++ b/plugins/woocommerce/changelog/fix-36214 @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Add support for sorting by includes param. From be97c1353b57a03d862390241d05567a7404a7cd Mon Sep 17 00:00:00 2001 From: Vedanshu Jain Date: Mon, 2 Jan 2023 16:20:25 +0530 Subject: [PATCH 5/6] Add test for sorting by include param. --- .../DataStores/Orders/OrdersTableQuery.php | 5 ++- .../Orders/OrdersTableDataStoreTests.php | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableQuery.php b/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableQuery.php index 76c3c167bd9..53a2606641f 100644 --- a/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableQuery.php +++ b/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableQuery.php @@ -987,7 +987,10 @@ class OrdersTableQuery { } if ( 'include' === $orderby || 'post__in' === $orderby ) { - $ids = $this->args['id']; + $ids = $this->args['id'] ?? $this->args['includes']; + if ( empty( $ids ) ) { + return; + } $ids = array_map( 'absint', $ids ); $this->orderby = array( "FIELD( {$this->tables['orders']}.id, " . implode( ',', $ids ) . ' )' ); return; diff --git a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php index 765095fe095..581a7f52755 100644 --- a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php +++ b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php @@ -1349,6 +1349,39 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case { ); } + /** + * @testDox Ensure sorting by `includes` param works as expected. + */ + public function test_cot_query_sort_includes() { + $this->disable_cot_sync(); + $order_1 = new WC_Order(); + $this->switch_data_store( $order_1, $this->sut ); + $order_1->save(); + + $order_2 = new WC_Order(); + $this->switch_data_store( $order_2, $this->sut ); + $this->disable_cot_sync(); + $order_2->save(); + + $query = new OrdersTableQuery( + array( + 'orderby' => 'include', + 'includes' => array( $order_1->get_id(), $order_2->get_id() ), + ) + ); + $orders_array = $query->orders; + $this->assertEquals( array( $order_1->get_id(), $order_2->get_id() ), array( $orders_array[0], $orders_array[1] ) ); + + $query = new OrdersTableQuery( + array( + 'orderby' => 'include', + 'includes' => array( $order_2->get_id(), $order_1->get_id() ), + ) + ); + $orders_array = $query->orders; + $this->assertEquals( array( $order_2->get_id(), $order_1->get_id() ), array( $orders_array[0], $orders_array[1] ) ); + } + /** * @testDox Ensure search works as expected on updated orders. */ From cb8c6f8b2461799c3b71ceec41230feeb58f0955 Mon Sep 17 00:00:00 2001 From: Vedanshu Jain Date: Thu, 5 Jan 2023 14:57:33 +0530 Subject: [PATCH 6/6] Remove duplicated statement. Co-authored-by: Barry Hughes <3594411+barryhughes@users.noreply.github.com> --- .../src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php index 581a7f52755..ec3e4075f78 100644 --- a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php +++ b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php @@ -1360,7 +1360,6 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case { $order_2 = new WC_Order(); $this->switch_data_store( $order_2, $this->sut ); - $this->disable_cot_sync(); $order_2->save(); $query = new OrdersTableQuery(