Commit 8ce23619390 for woocommerce
commit 8ce23619390fd20109c0b42a9a5b3bba41a6f2ab
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date: Wed Jun 3 07:30:49 2026 +0200
[Performance] Addressed cache invalidation gaps for product instance caching refresh (#65431)
Adds missing post cache invalidation identified by gap analysis for #64418 combined with #62041.
diff --git a/plugins/woocommerce/changelog/performance-products-instance-caching-groundwork b/plugins/woocommerce/changelog/performance-products-instance-caching-groundwork
new file mode 100644
index 00000000000..a8e07499955
--- /dev/null
+++ b/plugins/woocommerce/changelog/performance-products-instance-caching-groundwork
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Addressed cache invalidation gaps for product instance caching refresh.
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php
index 9aac5fae00d..5de82de01b6 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-product-data-store-cpt.php
@@ -1621,18 +1621,20 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
public function sort_all_product_variations( $parent_id ) {
global $wpdb;
- // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
+ $index = 1;
$ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product_variation' AND post_parent = %d AND post_status in ( 'publish', 'private' ) ORDER BY menu_order ASC, ID ASC",
$parent_id
)
);
- $index = 1;
foreach ( $ids as $id ) {
- // phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
- $wpdb->update( $wpdb->posts, array( 'menu_order' => ( $index++ ) ), array( 'ID' => absint( $id ) ) );
+ $product_id = absint( $id );
+ $updated = (bool) $wpdb->update( $wpdb->posts, array( 'menu_order' => ( $index++ ) ), array( 'ID' => $product_id ) );
+ if ( $updated ) {
+ clean_post_cache( $product_id );
+ }
}
}
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
index 10082c363aa..bd271a223b4 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
@@ -778,6 +778,7 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
if ( $new_name !== $previous_name ) {
global $wpdb;
+ $product_id = $product->get_id();
$wpdb->query(
$wpdb->prepare(
"UPDATE {$wpdb->posts}
@@ -786,16 +787,16 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
AND post_parent = %d",
$previous_name ? $previous_name : 'AUTO-DRAFT',
$new_name,
- $product->get_id()
+ $product_id
)
);
$invalidator = wc_get_container()->get( ProductVersionStringInvalidator::class );
- $children = $product->get_children();
- foreach ( $children as $child_id ) {
+ foreach ( $product->get_children() as $child_id ) {
+ clean_post_cache( $child_id );
$invalidator->invalidate( $child_id );
}
- $invalidator->invalidate( $product->get_id() );
+ $invalidator->invalidate( $product_id );
}
}
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-product-variation-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-product-variation-data-store-cpt.php
index 18195ace922..731f2d0a242 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-product-variation-data-store-cpt.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-product-variation-data-store-cpt.php
@@ -645,15 +645,20 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
protected function update_guid( $product ) {
global $wpdb;
- $guid = home_url(
+ $product_id = $product->get_id();
+ $guid = home_url(
add_query_arg(
array(
'post_type' => 'product_variation',
- 'p' => $product->get_id(),
+ 'p' => $product_id,
),
''
)
);
- $wpdb->update( $wpdb->posts, array( 'guid' => $guid ), array( 'ID' => $product->get_id() ) );
+
+ $updated = (bool) $wpdb->update( $wpdb->posts, array( 'guid' => $guid ), array( 'ID' => $product_id ) );
+ if ( $updated ) {
+ clean_post_cache( $product_id );
+ }
}
}
diff --git a/plugins/woocommerce/src/Internal/Caches/ProductCacheController.php b/plugins/woocommerce/src/Internal/Caches/ProductCacheController.php
index d526eafcc6d..28846c1c5e4 100644
--- a/plugins/woocommerce/src/Internal/Caches/ProductCacheController.php
+++ b/plugins/woocommerce/src/Internal/Caches/ProductCacheController.php
@@ -90,10 +90,10 @@ class ProductCacheController {
add_action( 'added_post_meta', array( $this, 'invalidate_product_cache_by_meta' ), 10, 2 );
add_action( 'deleted_post_meta', array( $this, 'invalidate_product_cache_by_meta' ), 10, 2 );
- // Handle direct stock/sales updates (which uses direct SQL and cache manipulation, bypassing standard meta hooks)
- // In the future, update WC_Product_Data_Store_CPT::update_product_stock() and
- // update_product_sales() to trigger standard WordPress updated_post_meta hooks instead
- // of requiring specific hooks here.
+ // Handle direct stock/sales updates (which use direct SQL and cache manipulation, bypassing standard meta hooks)
+ // In the future, update WC_Product_Data_Store_CPT::update_product_stock() and update_product_sales() to trigger
+ // standard WordPress updated_post_meta hooks instead of requiring specific hooks here.
+ // We also skip 'woocommerce_updated_product_price' due to metas update in the corresponding methods.
add_action( 'woocommerce_updated_product_stock', array( $this, 'invalidate_product_cache' ), 10, 1 );
add_action( 'woocommerce_updated_product_sales', array( $this, 'invalidate_product_cache' ), 10, 1 );
}