wp-graphql-woocommerce icon indicating copy to clipboard operation
wp-graphql-woocommerce copied to clipboard

Featured product "tax_query" argument overwritten

Open lstellway opened this issue 3 years ago • 2 comments

Describe the bug When querying "featured" products in a category product connection, the tax_query argument is overwritten.

To Reproduce Steps to reproduce the behavior:

  1. Setup WooCommerce store with products and WPGraphQL extensions
  2. Mark a single item as featured
  3. Query the category products, with a featured filter
query GetProducts {
  productCategory(idType:SLUG, id:"uncategorized") {
    products(where: {
      featured:true
    }) {
      nodes {
        name
      }
    }
  }
}

Expected behavior Only the featured item should appear.

Desktop (please complete the following information):

  • OS: OSX
  • Browser: Postman

Additional context The issue occurs somewhere between class-products.php::$resolve_product_from_taxonomy() and class-product-connection-resolver.php::set_query_arg().

I'm curious if the logic in class-product-connection-resolver.php::set_query_arg() is correct. Should the $overwrite variable in the if statement have a ! (bang) in front of it? I would think so, so the tax_query is appended to instead of overwritten.

lstellway avatar Nov 16 '20 01:11 lstellway

It sounds like this logic is going to be refactored (reference). Here's a patch in case anyone is running into the same issue and wants a temporary fix:

diff --git a/includes/data/connection/class-product-connection-resolver.php b/includes/data/connection/class-product-connection-resolver.php
index 97fcda2..bec3ad5 100644
--- a/includes/data/connection/class-product-connection-resolver.php
+++ b/includes/data/connection/class-product-connection-resolver.php
@@ -584,9 +584,9 @@ class Product_Connection_Resolver extends AbstractConnectionResolver {
 	 */
 	public function set_query_arg( $key, $value, $overwrite = false ) {
 		if ( ! empty( $this->query_args[ $key ] )
-			&& is_array( $this->query_args[ $key ] ) && $overwrite
+			&& is_array( $this->query_args[ $key ] ) && ! $overwrite
 		) {
-			$this->query_args[ $key ] = array_intersect( $value, $this->query_args[ $key ] );
+			$this->query_args[ $key ][] = $value;
 		} else {
 			$this->query_args[ $key ] = $value;
 		}

(if you're using composer, you can include it with cweagans/composer-patches)

lstellway avatar Nov 18 '20 00:11 lstellway

I am experiencing this again - (my patch became obsolete after updating).

The tax_query argument is set when products are resolved. When stepping through the code with xdebug, the referenced statement was used to filter the category.

Because of this statement, I cannot filter "featured" products, which relies on the tax_query parameter.

Removing the old WPGraphQL\WooCommerce\Data\Connection\Product_Connection_Resolver::set_query_arg() method causes the entire tax_query argument to be overwritten.

To fix for myself, I have created another patch, placing the old function back:

diff --git a/includes/data/connection/class-product-connection-resolver.php b/includes/data/connection/class-product-connection-resolver.php
index 3322830..4f4ecf1 100644
--- a/includes/data/connection/class-product-connection-resolver.php
+++ b/includes/data/connection/class-product-connection-resolver.php
@@ -569,4 +569,23 @@ class Product_Connection_Resolver extends AbstractConnectionResolver {
 	public function is_valid_offset( $offset ) {
 		return $this->is_valid_post_offset( $offset );
 	}
+
+	/**
+	 * Given a key and value, this sets a query_arg which will modify the query_args used by
+	 * the connection resolvers get_query();
+	 *
+	 * @param string $key   The key of the query arg to set
+	 * @param mixed  $value The value of the query arg to set
+	 *
+	 * @return AbstractConnectionResolver
+	 */
+	public function set_query_arg( $key, $value, $overwrite = false ) {
+		if ( is_array( $this->query_args ) && ! empty( $this->query_args[ $key ] ) && ! $overwrite ) {
+			$this->query_args[ $key ][] = $value;
+		} else {
+			$this->query_args[ $key ] = $value;
+		}
+
+		return $this;
+	}
 }

lstellway avatar Jan 20 '21 04:01 lstellway