Commit 01c8de9e68f for woocommerce

commit 01c8de9e68f1d857449aefa8f2becba8310f2af8
Author: Ahmed Ismail <105542236+ahmedevsaad@users.noreply.github.com>
Date:   Tue Oct 13 11:44:14 2026 +0300

    Add a filter for the reports cache expiration (#69288)

    * Add an expiration argument to the reports Cache::set()

    * Use a filter for the reports cache expiration instead of a new parameter

    * Fall back to the default cache expiration for invalid filter results

    * Round positive fractional reports cache expirations up instead of to zero

    * Fall back to the default reports cache expiration for 0

    A filtered expiration of 0 made set_transient() store report cache entries as autoloaded options that never expire.

diff --git a/plugins/woocommerce/changelog/53344-add-cache-set-expiration b/plugins/woocommerce/changelog/53344-add-cache-set-expiration
new file mode 100644
index 00000000000..937fcb89d02
--- /dev/null
+++ b/plugins/woocommerce/changelog/53344-add-cache-set-expiration
@@ -0,0 +1,4 @@
+Significance: patch
+Type: dev
+
+Add the woocommerce_reports_cache_expiration filter to change how long Analytics report data is cached.
diff --git a/plugins/woocommerce/src/Admin/API/Reports/Cache.php b/plugins/woocommerce/src/Admin/API/Reports/Cache.php
index 7bea6059458..587b389b2b0 100644
--- a/plugins/woocommerce/src/Admin/API/Reports/Cache.php
+++ b/plugins/woocommerce/src/Admin/API/Reports/Cache.php
@@ -70,7 +70,18 @@ class Cache {
 			'value'   => $value,
 		);

-		$result = set_transient( $key, $transient_value, WEEK_IN_SECONDS );
+		/**
+		 * Filters how long a reports cache value is kept, in seconds.
+		 *
+		 * @since 11.3.0
+		 *
+		 * @param int    $expiration Time until expiration in seconds. Must be greater than 0; other values use the default of one week.
+		 * @param string $key        Cache key.
+		 */
+		$expiration = apply_filters( 'woocommerce_reports_cache_expiration', WEEK_IN_SECONDS, $key );
+		$expiration = is_numeric( $expiration ) && $expiration > 0 && is_finite( (float) $expiration ) ? (int) ceil( (float) $expiration ) : WEEK_IN_SECONDS;
+
+		$result = set_transient( $key, $transient_value, $expiration );

 		return $result;
 	}
diff --git a/plugins/woocommerce/tests/php/src/Admin/API/Reports/CacheTest.php b/plugins/woocommerce/tests/php/src/Admin/API/Reports/CacheTest.php
new file mode 100644
index 00000000000..66686883f9d
--- /dev/null
+++ b/plugins/woocommerce/tests/php/src/Admin/API/Reports/CacheTest.php
@@ -0,0 +1,43 @@
+<?php
+declare( strict_types = 1 );
+
+namespace Automattic\WooCommerce\Tests\Admin\API\Reports;
+
+use Automattic\WooCommerce\Admin\API\Reports\Cache;
+use WC_Unit_Test_Case;
+
+/**
+ * Tests for the reports Cache class.
+ */
+class CacheTest extends WC_Unit_Test_Case {
+
+	/**
+	 * @testdox set() stores the value for one week by default, or for the filtered expiration when it is valid.
+	 *
+	 * @testWith [null, 604800]
+	 *           [60, 60]
+	 *           [0.5, 1]
+	 *           [-60, 604800]
+	 *           [0, 604800]
+	 *           ["0", 604800]
+	 *           ["soon", 604800]
+	 *
+	 * @param mixed $expiration Filtered expiration, or null to leave the default.
+	 * @param int   $expected   Expected lifetime in seconds.
+	 */
+	public function test_set_uses_expiration( $expiration, int $expected ): void {
+		$filter = fn() => $expiration;
+		if ( null !== $expiration ) {
+			add_filter( 'woocommerce_reports_cache_expiration', $filter );
+		}
+		$before = time();
+
+		Cache::set( 'wc_cache_test', 'value' );
+
+		remove_filter( 'woocommerce_reports_cache_expiration', $filter );
+		$timeout = (int) get_option( '_transient_timeout_wc_cache_test' );
+		$this->assertGreaterThanOrEqual( $before + $expected, $timeout );
+		$this->assertLessThanOrEqual( time() + $expected, $timeout );
+		$this->assertSame( 'value', Cache::get( 'wc_cache_test' ) );
+	}
+}