From ac8267533b74df6ea81eeade9278d32498627612 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Thu, 2 Mar 2023 21:38:55 +0100 Subject: [PATCH 1/3] Merge tax_query of attributes and visibility taxonomies when building Products query --- src/BlockTypes/ProductQuery.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/BlockTypes/ProductQuery.php b/src/BlockTypes/ProductQuery.php index 2eae4a8cdf5..65c6cd39847 100644 --- a/src/BlockTypes/ProductQuery.php +++ b/src/BlockTypes/ProductQuery.php @@ -113,6 +113,22 @@ public function update_query( $pre_render, $parsed_block ) { } } + /** + * Merge tax_queries from various queries. + * + * @param array[] ...$queries Query arrays to be merged. + * @return array + */ + private function merge_tax_queries( ...$queries ) { + $tax_query = array(); + foreach ( $queries as $query ) { + if ( ! empty( $query['tax_query'] ) ) { + $tax_query = array_merge( $tax_query, $query['tax_query'] ); + } + } + return array( 'tax_query' => $tax_query ); + } + /** * Update the query for the product query block in Editor. * @@ -128,8 +144,9 @@ public function update_rest_query( $args, $request ) { $attributes_query = is_array( $woo_attributes ) ? $this->get_product_attributes_query( $woo_attributes ) : array(); $stock_query = is_array( $woo_stock_status ) ? $this->get_stock_status_query( $woo_stock_status ) : array(); $visibility_query = $this->get_product_visibility_query( $stock_query ); + $tax_query = $this->merge_tax_queries( $attributes_query, $visibility_query ); - return array_merge( $args, $on_sale_query, $orderby_query, $attributes_query, $stock_query, $visibility_query ); + return array_merge( $args, $on_sale_query, $orderby_query, $stock_query, $tax_query ); } /** From d05d7133123bd74247ff4efd8585c8e784b67e75 Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Fri, 3 Mar 2023 13:45:51 +0100 Subject: [PATCH 2/3] Add tests confirming the tax_query is merged correctly --- tests/php/BlockTypes/ProductQuery.php | 96 ++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/tests/php/BlockTypes/ProductQuery.php b/tests/php/BlockTypes/ProductQuery.php index f4806646dc4..af375f53db4 100644 --- a/tests/php/BlockTypes/ProductQuery.php +++ b/tests/php/BlockTypes/ProductQuery.php @@ -8,7 +8,7 @@ */ class ProductQuery extends \WP_UnitTestCase { /** - * This variable holds our cart object. + * This variable holds our Product Query object. * * @var ProductQueryMock */ @@ -73,6 +73,23 @@ private function initialize_merged_query( $parsed_block = array() ) { return $this->block_instance->build_query( $query ); } + /** + * Build a simplified request for testing. + * + * @param bool $woocommerce_on_sale WooCommerce on sale. + * @param array $woocommerce_attributes WooCommerce attributes. + * @param array $woocommerce_stock_status WooCommerce stock status. + * @return array + */ + private function build_request( $woocommerce_on_sale = 'false', $woocommerce_attributes = array(), $woocommerce_stock_status = array() ) { + $request = new \WP_REST_Request( 'GET', '/wp/v2/product' ); + $request->set_param( '__woocommerceOnSale', $woocommerce_on_sale ); + $request->set_param( '__woocommerceAttributes', $woocommerce_attributes ); + $request->set_param( '__woocommerceStockStatus', $woocommerce_stock_status ); + + return $request; + } + /** * Test merging on sale queries. */ @@ -513,5 +530,80 @@ public function test_merging_multiple_filter_queries() { set_query_var( 'min_price', '' ); set_query_var( 'filter_stock_status', '' ); } -} + /** + * Test merging multiple filter queries. + */ + public function test_updating_rest_query_without_attributes() { + $args = array(); + $request = $this->build_request(); + + $updated_query = $this->block_instance->update_rest_query( $args, $request ); + + $this->assertContainsEquals( + array( + 'key' => '_stock_status', + 'value' => array(), + 'compare' => 'IN', + ), + $updated_query['meta_query'], + ); + + $this->assertEquals( + array( + array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( 0 ), + 'operator' => 'NOT IN', + ), + ), + $updated_query['tax_query'], + ); + } + + /** + * Test merging multiple filter queries. + */ + public function test_updating_rest_query_with_attributes() { + $args = array(); + $on_sale = 'true'; + $attributes = array( + array( + 'taxonomy' => 'pa_test', + 'termId' => 1, + ), + ); + $stock_status = array( 'instock', 'outofstock' ); + $request = $this->build_request( $on_sale, $attributes, $stock_status ); + + $updated_query = $this->block_instance->update_rest_query( $args, $request ); + + $this->assertContainsEquals( + array( + 'key' => '_stock_status', + 'value' => array( 'instock', 'outofstock' ), + 'compare' => 'IN', + ), + $updated_query['meta_query'], + ); + + $this->assertEquals( + array( + array( + 'taxonomy' => 'pa_test', + 'field' => 'term_id', + 'terms' => array( 1 ), + 'operator' => 'IN', + ), + array( + 'taxonomy' => 'product_visibility', + 'field' => 'term_taxonomy_id', + 'terms' => array( 0 ), + 'operator' => 'NOT IN', + ), + ), + $updated_query['tax_query'], + ); + } +} From 8ce39a005c1eeec902a3ffe3e489fa63689b4f2a Mon Sep 17 00:00:00 2001 From: Karol Manijak Date: Fri, 3 Mar 2023 19:52:58 +0100 Subject: [PATCH 3/3] Improve syntax after code review --- src/BlockTypes/ProductQuery.php | 6 +++--- tests/php/BlockTypes/ProductQuery.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/BlockTypes/ProductQuery.php b/src/BlockTypes/ProductQuery.php index 65c6cd39847..7013de7b61e 100644 --- a/src/BlockTypes/ProductQuery.php +++ b/src/BlockTypes/ProductQuery.php @@ -116,17 +116,17 @@ public function update_query( $pre_render, $parsed_block ) { /** * Merge tax_queries from various queries. * - * @param array[] ...$queries Query arrays to be merged. + * @param array ...$queries Query arrays to be merged. * @return array */ private function merge_tax_queries( ...$queries ) { - $tax_query = array(); + $tax_query = []; foreach ( $queries as $query ) { if ( ! empty( $query['tax_query'] ) ) { $tax_query = array_merge( $tax_query, $query['tax_query'] ); } } - return array( 'tax_query' => $tax_query ); + return [ 'tax_query' => $tax_query ]; } /** diff --git a/tests/php/BlockTypes/ProductQuery.php b/tests/php/BlockTypes/ProductQuery.php index af375f53db4..6c365da46dc 100644 --- a/tests/php/BlockTypes/ProductQuery.php +++ b/tests/php/BlockTypes/ProductQuery.php @@ -79,7 +79,7 @@ private function initialize_merged_query( $parsed_block = array() ) { * @param bool $woocommerce_on_sale WooCommerce on sale. * @param array $woocommerce_attributes WooCommerce attributes. * @param array $woocommerce_stock_status WooCommerce stock status. - * @return array + * @return WP_REST_Request */ private function build_request( $woocommerce_on_sale = 'false', $woocommerce_attributes = array(), $woocommerce_stock_status = array() ) { $request = new \WP_REST_Request( 'GET', '/wp/v2/product' );