Commit 11e23793326 for woocommerce

commit 11e23793326f76c13dc5c30450de6564b0dedb98
Author: David Arenas <david.arenas@automattic.com>
Date:   Mon May 4 15:28:41 2026 +0200

    Fix Add to Cart + Options grouped child quantity inputs on WordPress 6.8 (#64508)

    * Fix Add to Cart + Options grouped product child quantity inputs using parent constraints on WordPress 6.8

    * Fix double-escaping of data-wp-context value in grouped product quantity inputs

    * Add context to div with class `quantity`

    * Fix PHP lint errors

    * Fix changelog

    * Check if div exists before setting context directive

    * Fix PHP lint error

diff --git a/plugins/woocommerce/changelog/wooplug-6628-add-to-cart-options-grouped-product-child-quantity-inputs b/plugins/woocommerce/changelog/wooplug-6628-add-to-cart-options-grouped-product-child-quantity-inputs
new file mode 100644
index 00000000000..60be629be28
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooplug-6628-add-to-cart-options-grouped-product-child-quantity-inputs
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix Add to Cart + Options grouped product child quantity inputs to respect each child product's own constraints on WordPress 6.8
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/Utils.php b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/Utils.php
index 90182b67b47..472b7dab08b 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/Utils.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/Utils.php
@@ -117,6 +117,34 @@ class Utils {
 		$processor = new \WP_HTML_Tag_Processor( $quantity_html );
 		global $product;

+		if ( $set_product_context && $product instanceof \WC_Product ) {
+			$product_context = array(
+				'productId'   => $product->get_id(),
+				'variationId' => null,
+			);
+
+			$products_context = 'woocommerce/products::' . wp_json_encode( $product_context, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP );
+
+			// This moves the `woocommerce/products` context to a nested `div`,
+			// as multiple context directives are not supported in the same
+			// element in WordPress 6.8. Once WooCommerce drops support for
+			// WordPress 6.8, this code can be refactored.
+			if (
+				$processor->next_tag(
+					array(
+						'tag_name'   => 'div',
+						'class_name' => 'quantity',
+					)
+				)
+			) {
+				$processor->set_attribute( 'data-wp-context', $products_context );
+			} else {
+				// If filtered markup omits the `div.quantity`, reinitialize the
+				// processor so the input bindings below still execute.
+				$processor = new \WP_HTML_Tag_Processor( $quantity_html );
+			}
+		}
+
 		if (
 			$processor->next_tag( 'input' ) &&
 			$processor->get_attribute( 'type' ) === 'number' &&
@@ -151,22 +179,10 @@ class Utils {

 		$context_attribute = wp_interactivity_data_wp_context( $context );

-		$product_context_directive = '';
-		if ( $set_product_context && $product instanceof \WC_Product ) {
-			$product_context = array(
-				'productId'   => $product->get_id(),
-				'variationId' => null,
-			);
-
-			// This should use `wp_interactivity_data_wp_context` as well, but it currently doesn't support unique IDs.
-			$product_context_directive = 'data-wp-context---products="woocommerce/products::' . esc_attr( (string) wp_json_encode( $product_context, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) ) . '"';
-		}
-
 		return sprintf(
-			'<div %1$s %2$s %3$s>%4$s</div>',
+			'<div %1$s %2$s>%3$s</div>',
 			get_block_wrapper_attributes( $wrapper_attributes ),
 			$context_attribute,
-			$product_context_directive,
 			$quantity_html
 		);
 	}