Commit 5687cfd67d for woocommerce
commit 5687cfd67d912fa709fc43d1b75131268f69672e
Author: Albert Juhé Lluveras <contact@albertjuhe.com>
Date: Thu Jan 8 11:26:33 2026 +0100
Add to Cart + Options: Avoid loading unnecessary scripts when rendering 3rd-party product types (#62681)
* Add to Cart + Options: Avoid loading unnecessary scripts when rendering 3rd-party product types
* Add changelog file
* Update comments
* PHPStan fixes
* Fix PHPStan baseline file
* Strengthen context access
* Add missing 'file_exists()' to make both checks the same
* Strengthen context access (II)
diff --git a/plugins/woocommerce/changelog/fix-add-to-cart-with-options-3rd-party-product-type-script b/plugins/woocommerce/changelog/fix-add-to-cart-with-options-3rd-party-product-type-script
new file mode 100644
index 0000000000..0e040b2cfd
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-add-to-cart-with-options-3rd-party-product-type-script
@@ -0,0 +1,4 @@
+Significance: patch
+Type: performance
+
+Add to Cart + Options: Avoid loading unnecessary scripts when rendering 3rd-party product types
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/block.json b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/block.json
index d48c99347b..23a7b17da4 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/block.json
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/block.json
@@ -19,7 +19,6 @@
},
"apiVersion": 3,
"$schema": "https://schemas.wp.org/trunk/block.json",
- "viewScriptModule": "woocommerce/add-to-cart-with-options",
"style": "file:../woocommerce/add-to-cart-with-options-style.css",
"editorStyle": "file:../woocommerce/add-to-cart-with-options-editor.css"
}
diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index 061394480e..81813ff2f6 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -57903,12 +57903,6 @@ parameters:
count: 1
path: src/Blocks/BlockTypes/AddToCartForm.php
- -
- message: '#^Access to property \$context on an unknown class Automattic\\WooCommerce\\Blocks\\BlockTypes\\AddToCartWithOptions\\WP_Block\.$#'
- identifier: class.notFound
- count: 1
- path: src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
-
-
message: '#^Call to an undefined method WC_Product\:\:get_available_variations\(\)\.$#'
identifier: method.notFound
@@ -57939,18 +57933,6 @@ parameters:
count: 1
path: src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
- -
- message: '#^One or more @param tags has an invalid name or invalid syntax\.$#'
- identifier: phpDoc.parseError
- count: 1
- path: src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
-
- -
- message: '#^PHPDoc tag @param has invalid value \(mixed string\|boolean The template part path if it exists\)\: Unexpected token "string", expected variable at offset 121 on line 5$#'
- identifier: phpDoc.parseError
- count: 1
- path: src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
-
-
message: '#^Parameter \#1 \$amount of function wc_stock_amount expects float\|int, array\|string given\.$#'
identifier: argument.type
@@ -57975,12 +57957,6 @@ parameters:
count: 4
path: src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
- -
- message: '#^Parameter \$block of method Automattic\\WooCommerce\\Blocks\\BlockTypes\\AddToCartWithOptions\\AddToCartWithOptions\:\:render\(\) has invalid type Automattic\\WooCommerce\\Blocks\\BlockTypes\\AddToCartWithOptions\\WP_Block\.$#'
- identifier: class.notFound
- count: 1
- path: src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
-
-
message: '#^Cannot access property \$ID on WP_Post\|null\.$#'
identifier: property.nonObject
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartForm.php b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartForm.php
index 1172d454b1..ff5f78321e 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartForm.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartForm.php
@@ -37,7 +37,6 @@ class AddToCartForm extends AbstractBlock {
return wp_parse_args( $attributes, $defaults );
}
-
/**
* Enqueue assets specific to this block.
* We enqueue frontend scripts only if the quantitySelectorStyle is set to 'stepper'.
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
index 25cbbb3d38..abdbe1a2a1 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartWithOptions/AddToCartWithOptions.php
@@ -25,6 +25,58 @@ class AddToCartWithOptions extends AbstractBlock {
*/
protected $block_name = 'add-to-cart-with-options';
+ /**
+ * Get the template part path for a product type.
+ *
+ * @param string $product_type The product type.
+ * @return string|bool The template part path if it exists, false otherwise.
+ */
+ protected function get_template_part_path( $product_type ) {
+ if ( in_array( $product_type, array( ProductType::SIMPLE, ProductType::EXTERNAL, ProductType::VARIABLE, ProductType::GROUPED ), true ) ) {
+ return Package::get_path() . 'templates/' . BlockTemplateUtils::DIRECTORY_NAMES['TEMPLATE_PARTS'] . '/' . $product_type . '-product-add-to-cart-with-options.html';
+ }
+
+ /**
+ * Experimental filter for extensions to register a block template part
+ * for a product type.
+ *
+ * @since 9.9.0
+ * @param string|boolean $template_part_path The template part path if it exists
+ * @param string $product_type The product type
+ */
+ return apply_filters( '__experimental_woocommerce_' . $product_type . '_add_to_cart_with_options_block_template_part', false, $product_type );
+ }
+
+ /**
+ * Enqueue assets specific to this block.
+ * We enqueue frontend scripts only if the product type has a block template
+ * part (that's WC core product types and extensions that migrated to block
+ * templates).
+ *
+ * @param array $attributes Block attributes.
+ * @param string $content Block content.
+ * @param \WP_Block $block Block instance.
+ *
+ * @return void
+ */
+ protected function enqueue_assets( $attributes, $content, $block ) {
+ $product_id = ( is_object( $block ) && property_exists( $block, 'context' ) && is_array( $block->context ) && array_key_exists( 'postId', $block->context ) ) ? $block->context['postId'] : null;
+
+ if ( isset( $product_id ) ) {
+ $rendered_product = wc_get_product( $product_id );
+
+ if ( $rendered_product instanceof \WC_Product ) {
+ $template_part_path = $this->get_template_part_path( $rendered_product->get_type() );
+
+ if ( is_string( $template_part_path ) && '' !== $template_part_path && file_exists( $template_part_path ) ) {
+ wp_enqueue_script_module( 'woocommerce/add-to-cart-with-options' );
+ }
+ }
+ }
+
+ parent::enqueue_assets( $attributes, $content, $block );
+ }
+
/**
* Extra data passed through from server to client for block.
*
@@ -122,16 +174,16 @@ class AddToCartWithOptions extends AbstractBlock {
/**
* Render the block.
*
- * @param array $attributes Block attributes.
- * @param string $content Block content.
- * @param WP_Block $block Block instance.
+ * @param array $attributes Block attributes.
+ * @param string $content Block content.
+ * @param \WP_Block $block Block instance.
*
- * @return string | void Rendered block output.
+ * @return string|void Rendered block output.
*/
protected function render( $attributes, $content, $block ) {
global $product;
- $product_id = $block->context['postId'];
+ $product_id = ( is_object( $block ) && property_exists( $block, 'context' ) && is_array( $block->context ) && array_key_exists( 'postId', $block->context ) ) ? $block->context['postId'] : null;
if ( ! isset( $product_id ) ) {
return '';
@@ -148,21 +200,6 @@ class AddToCartWithOptions extends AbstractBlock {
// For variations, we display the simple product form.
$product_type = ProductType::VARIATION === $product->get_type() ? ProductType::SIMPLE : $product->get_type();
- $slug = $product_type . '-product-add-to-cart-with-options';
-
- if ( in_array( $product_type, array( ProductType::SIMPLE, ProductType::EXTERNAL, ProductType::VARIABLE, ProductType::GROUPED ), true ) ) {
- $template_part_path = Package::get_path() . 'templates/' . BlockTemplateUtils::DIRECTORY_NAMES['TEMPLATE_PARTS'] . '/' . $slug . '.html';
- } else {
- /**
- * Filter to declare product type's cart block template is supported.
- *
- * @since 9.9.0
- * @param mixed string|boolean The template part path if it exists
- * @param string $product_type The product type
- */
- $template_part_path = apply_filters( '__experimental_woocommerce_' . $product_type . '_add_to_cart_with_options_block_template_part', false, $product_type );
- }
-
$classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes, array(), array( 'extra_classes' ) );
$classes = implode(
' ',
@@ -174,8 +211,10 @@ class AddToCartWithOptions extends AbstractBlock {
)
);
- if ( is_string( $template_part_path ) && file_exists( $template_part_path ) ) {
+ $template_part_path = $this->get_template_part_path( $product_type );
+ if ( is_string( $template_part_path ) && '' !== $template_part_path && file_exists( $template_part_path ) ) {
+ $slug = $product_type . '-product-add-to-cart-with-options';
$template_part_contents = '';
// Determine if we need to load the template part from the DB, the theme or WooCommerce in that order.
$templates_from_db = BlockTemplateUtils::get_block_templates_from_db( array( $slug ), 'wp_template_part' );