Commit 055cb5d244 for woocommerce
commit 055cb5d244043744a190f7b2e9bd41c6c6883c68
Author: Albert Juhé Lluveras <contact@albertjuhe.com>
Date: Thu Sep 18 15:48:39 2025 +0200
Add to Cart + Options: skip adding default values to variations data object (#60966)
* Add to Cart + Options: skip adding default values to variations data object
* Add changelog file
* CodeRabbit suggestions
diff --git a/plugins/woocommerce/changelog/fix-add-to-cart-with-options-non-default-variation-data b/plugins/woocommerce/changelog/fix-add-to-cart-with-options-non-default-variation-data
new file mode 100644
index 0000000000..b4a3c8d583
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-add-to-cart-with-options-non-default-variation-data
@@ -0,0 +1,4 @@
+Significance: patch
+Type: update
+
+Add to Cart + Options: skip adding default values to variations data object
diff --git a/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts b/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
index f1ea3afad1..1db4c8cc10 100644
--- a/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/base/stores/woocommerce/cart.ts
@@ -47,6 +47,22 @@ export type ClientCartItem = Omit< OptimisticCartItem, 'variation' > & {
variation?: SelectedAttributes[];
};
+export type VariationData = {
+ attributes: Record< string, string >;
+ is_in_stock?: boolean;
+ price_html?: string;
+ image_id?: number;
+ availability?: string;
+ variation_description?: string;
+ sku?: string;
+ weight?: string;
+ dimensions?: string;
+ min?: number;
+ max?: number;
+ step?: number;
+ sold_individually?: boolean;
+};
+
export type ProductData = {
type: string;
price_html?: string;
@@ -58,23 +74,7 @@ export type ProductData = {
min?: number;
max?: number;
step?: number;
- variations?: {
- [ variationId: number ]: {
- attributes: Record< string, string >;
- is_in_stock: boolean;
- type: string;
- price_html?: string;
- image_id?: number;
- availability?: string;
- sku?: string;
- weight?: string;
- dimensions?: string;
- min?: number;
- max?: number;
- step?: number;
- sold_individually?: boolean;
- };
- };
+ variations?: Record< number, VariationData >;
};
type CartUpdateOptions = { showCartUpdatesNotices?: boolean };
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts
index b55f50741d..2579ba09ac 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts
@@ -6,6 +6,7 @@ import type {
Store as WooCommerce,
SelectedAttributes,
ProductData,
+ VariationData,
WooCommerceConfig,
} from '@woocommerce/stores/woocommerce/cart';
import '@woocommerce/stores/woocommerce/product-data';
@@ -55,10 +56,11 @@ export const getProductData = (
selectedAttributes: SelectedAttributes[]
) => {
let productId = id;
- let productData: ProductData | undefined;
+ let productData: ProductData | VariationData | undefined;
const { products } = getConfig( 'woocommerce' ) as WooCommerceConfig;
+ let type: ProductData[ 'type' ] | 'variation' | null = null;
if ( selectedAttributes && selectedAttributes.length > 0 ) {
if ( ! products || ! products[ id ] ) {
return null;
@@ -70,13 +72,14 @@ export const getProductData = (
);
if ( matchedVariation?.variation_id ) {
productId = matchedVariation.variation_id;
- productData =
- products?.[ id ]?.variations?.[
- matchedVariation?.variation_id
- ];
+ productData = products?.[ id ]?.variations?.[
+ matchedVariation?.variation_id
+ ] as VariationData;
+ type = 'variation';
}
} else {
- productData = products?.[ productId ];
+ productData = products?.[ productId ] as ProductData;
+ type = productData?.type;
}
if ( typeof productData !== 'object' || productData === null ) {
@@ -96,6 +99,7 @@ export const getProductData = (
min,
max,
step,
+ type,
};
};
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
index acb12f5192..94d8d3e6eb 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
@@ -258,7 +258,7 @@ class AddToCartWithOptions extends AbstractBlock {
);
if ( $product->is_type( ProductType::VARIABLE ) ) {
- $variation_data = array();
+ $variations_data = array();
$context['selectedAttributes'] = array();
$available_variations = $product->get_available_variations( 'objects' );
foreach ( $available_variations as $variation ) {
@@ -267,11 +267,14 @@ class AddToCartWithOptions extends AbstractBlock {
// input for all variations, so we want quantities to be in sync.
$context['quantity'][ $variation->get_id() ] = $default_quantity;
- $variation_data[ $variation->get_id() ] = array(
- 'is_in_stock' => $variation->is_in_stock(),
- 'attributes' => $variation->get_variation_attributes(),
- 'type' => $variation->get_type(),
+ $variation_data = array(
+ 'attributes' => $variation->get_variation_attributes(),
);
+ if ( $variation->is_in_stock() ) {
+ $variation_data['is_in_stock'] = true;
+ }
+
+ $variations_data[ $variation->get_id() ] = $variation_data;
}
wp_interactivity_config(
@@ -279,7 +282,7 @@ class AddToCartWithOptions extends AbstractBlock {
array(
'products' => array(
$product->get_id() => array(
- 'variations' => $variation_data,
+ 'variations' => $variations_data,
),
),
)
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/QuantitySelector.php b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/QuantitySelector.php
index d1d3745c6e..cbdf811561 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/QuantitySelector.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/QuantitySelector.php
@@ -129,13 +129,23 @@ class QuantitySelector extends AbstractBlock {
$variations_data = $product->get_available_variations( 'objects' );
$formatted_variations_data = array();
foreach ( $variations_data as $variation ) {
- $variation_quantity_constraints = AddToCartWithOptionsUtils::get_product_quantity_constraints( $variation );
- $formatted_variations_data[ $variation->get_id() ] = array(
- 'min' => $variation_quantity_constraints['min'],
- 'max' => $variation_quantity_constraints['max'],
- 'step' => $variation_quantity_constraints['step'],
- 'sold_individually' => (bool) $variation->is_sold_individually(),
- );
+ $variation_quantity_constraints = AddToCartWithOptionsUtils::get_product_quantity_constraints( $variation );
+ $variation_data = array();
+
+ // Only add variation data if it's different than the defaults.
+ if ( 1 !== $variation_quantity_constraints['min'] ) {
+ $variation_data['min'] = $variation_quantity_constraints['min'];
+ }
+ if ( null !== $variation_quantity_constraints['max'] ) {
+ $variation_data['max'] = $variation_quantity_constraints['max'];
+ }
+ if ( 1 !== $variation_quantity_constraints['step'] ) {
+ $variation_data['step'] = $variation_quantity_constraints['step'];
+ }
+ if ( $variation->is_sold_individually() ) {
+ $variation_data['sold_individually'] = true;
+ }
+ $formatted_variations_data[ $variation->get_id() ] = $variation_data;
}
wp_interactivity_config(
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/VariationDescription.php b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/VariationDescription.php
index 2d48f29251..e30ea5ea80 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/VariationDescription.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/VariationDescription.php
@@ -39,9 +39,12 @@ class VariationDescription extends AbstractBlock {
$variations = $product->get_available_variations( 'objects' );
$formatted_variations_data = array();
foreach ( $variations as $variation ) {
- $formatted_variations_data[ $variation->get_id() ] = array(
- 'variation_description' => wp_kses_post( wc_format_content( $variation->get_description() ) ),
- );
+ $variation_description = $variation->get_description();
+ if ( is_string( $variation_description ) && ! empty( $variation_description ) ) {
+ $formatted_variations_data[ $variation->get_id() ] = array(
+ 'variation_description' => wp_kses_post( wc_format_content( $variation_description ) ),
+ );
+ }
}
wp_interactivity_config(
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductGallery.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductGallery.php
index 2fd1c165f2..a6d74f2f4f 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductGallery.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductGallery.php
@@ -167,10 +167,15 @@ class ProductGallery extends AbstractBlock {
) {
continue;
}
- $has_variation_images = $has_variation_images || $variation['image_id'] !== $product->get_image_id();
- $formatted_variations_data[ $variation['variation_id'] ] = array(
- 'image_id' => (int) $variation['image_id'],
- );
+
+ $variation_image_id = (int) $variation['image_id'];
+ if ( $variation_image_id && $variation_image_id !== (int) $product->get_image_id() ) {
+ $has_variation_images = true;
+
+ $formatted_variations_data[ $variation['variation_id'] ] = array(
+ 'image_id' => $variation_image_id,
+ );
+ }
}
if ( $has_variation_images ) {
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductStockIndicator.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductStockIndicator.php
index ed20dc4f86..ff2ff9fcec 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductStockIndicator.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductStockIndicator.php
@@ -130,10 +130,12 @@ class ProductStockIndicator extends AbstractBlock {
$variations = $product_to_render->get_available_variations( 'objects' );
$formatted_variations_data = array();
foreach ( $variations as $variation ) {
- $variation_availability = $variation->get_availability();
- $formatted_variations_data[ $variation->get_id() ] = array(
- 'availability' => $variation_availability['availability'],
- );
+ $variation_availability = $variation->get_availability();
+ if ( is_string( $variation_availability['availability'] ) && ! empty( $variation_availability['availability'] ) ) {
+ $formatted_variations_data[ $variation->get_id() ] = array(
+ 'availability' => $variation_availability['availability'],
+ );
+ }
}
wp_interactivity_config(