Commit 71c0f62586 for woocommerce

commit 71c0f625863227f025fe8f9f6b253bca9caca99e
Author: Tung Du <dinhtungdu@gmail.com>
Date:   Tue Jan 6 10:29:36 2026 +0700

    Follow up: performance issue with filter data transient (#62591)

    * fix: delete filter data cache when in transient clean up tool

    * fix: only register cache cleanup hooks when neccessary

    * chore: changelog

    * chore: better method name

    * fix: simplify the check

    * chore: phpstan

    * chore: update phpstan baseline

diff --git a/plugins/woocommerce/changelog/wooplug-6049-follow-up b/plugins/woocommerce/changelog/wooplug-6049-follow-up
new file mode 100644
index 0000000000..4357480be8
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooplug-6049-follow-up
@@ -0,0 +1,4 @@
+Significance: patch
+Type: performance
+
+Performance: clean up filter data transients cache along with the product/shop transients cache.
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php
index edac8bb4b1..6c21fb4eea 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-system-status-tools-v2-controller.php
@@ -9,7 +9,7 @@
  */

 use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
-use Automattic\WooCommerce\Internal\Utilities\DatabaseUtil;
+use Automattic\WooCommerce\Internal\ProductFilters\CacheController;

 defined( 'ABSPATH' ) || exit;

@@ -475,6 +475,9 @@ class WC_REST_System_Status_Tools_V2_Controller extends WC_REST_Controller {
 				}

 				WC_Cache_Helper::get_transient_version( 'shipping', true );
+
+				wc_get_container()->get( CacheController::class )->delete_filter_data_transients();
+
 				$message = __( 'Product transients cleared', 'woocommerce' );
 				break;

diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index a01212f6db..5e21e3591e 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -74388,12 +74388,6 @@ parameters:
 			count: 1
 			path: src/Internal/ProductDownloads/ApprovedDirectories/Synchronize.php

-		-
-			message: '#^Method Automattic\\WooCommerce\\Internal\\ProductFilters\\CacheController\:\:clear_filter_data_cache\(\) has no return type specified\.$#'
-			identifier: missingType.return
-			count: 1
-			path: src/Internal/ProductFilters/CacheController.php
-
 		-
 			message: '#^Method Automattic\\WooCommerce\\Internal\\ProductFilters\\CacheController\:\:clear_taxonomy_hierarchy_cache\(\) has no return type specified\.$#'
 			identifier: missingType.return
diff --git a/plugins/woocommerce/src/Internal/ProductFilters/CacheController.php b/plugins/woocommerce/src/Internal/ProductFilters/CacheController.php
index b524916c31..2321822fff 100644
--- a/plugins/woocommerce/src/Internal/ProductFilters/CacheController.php
+++ b/plugins/woocommerce/src/Internal/ProductFilters/CacheController.php
@@ -39,8 +39,12 @@ class CacheController implements RegisterHooksInterface {
 	 * Hook into actions and filters.
 	 */
 	public function register() {
-		add_action( 'woocommerce_after_product_object_save', array( $this, 'clear_filter_data_cache' ) );
-		add_action( 'woocommerce_delete_product_transients', array( $this, 'clear_filter_data_cache' ) );
+		if ( ! $this->need_cleanup() ) {
+			return;
+		}
+
+		add_action( 'woocommerce_after_product_object_save', array( $this, 'invalidate_filter_data_cache' ) );
+		add_action( 'woocommerce_delete_product_transients', array( $this, 'invalidate_filter_data_cache' ) );

 		// Clear taxonomy hierarchy cache when terms change.
 		add_action( 'created_term', array( $this, 'clear_taxonomy_hierarchy_cache' ), 10, 3 );
@@ -51,7 +55,7 @@ class CacheController implements RegisterHooksInterface {
 	/**
 	 * Invalidate all cache under filter data group.
 	 */
-	public function clear_filter_data_cache() {
+	public function invalidate_filter_data_cache(): void {
 		WC_Cache_Helper::get_transient_version( self::CACHE_GROUP, true );
 		WC_Cache_Helper::invalidate_cache_group( self::CACHE_GROUP );
 	}
@@ -69,4 +73,33 @@ class CacheController implements RegisterHooksInterface {
 			$this->taxonomy_hierarchy_data->clear_cache( $taxonomy );
 		}
 	}
+
+	/**
+	 * Delete all filter data transients.
+	 */
+	public function delete_filter_data_transients(): void {
+		if ( ! $this->need_cleanup() ) {
+			return;
+		}
+
+		global $wpdb;
+		$wpdb->query(
+			$wpdb->prepare(
+				"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
+				$wpdb->esc_like( '_transient_wc_filter_data_' ) . '%',
+				$wpdb->esc_like( '_transient_timeout_wc_filter_data_' ) . '%'
+			)
+		);
+	}
+
+	/**
+	 * Check if the filter data cache should be cleaned up.
+	 * If the cache group is not set, it means that the store is not using
+	 * the product filters and we don't need to register the hooks.
+	 *
+	 * @return bool
+	 */
+	public function need_cleanup() {
+		return ! empty( get_transient( self::CACHE_GROUP . '-transient-version' ) );
+	}
 }