Commit e2163ad0ad3 for woocommerce
commit e2163ad0ad3450756b8d4decab2d1cddf35f1438
Author: Peter Petrov <peter.petrov89@gmail.com>
Date: Tue Sep 15 13:34:10 2026 +0300
Fix emailed Analytics report exports that never arrive (#68621)
Keep the report export status option out of autoloaded options
diff --git a/plugins/woocommerce/changelog/fix-analytics-export-email-never-arrives b/plugins/woocommerce/changelog/fix-analytics-export-email-never-arrives
new file mode 100644
index 00000000000..af8b12e1fd4
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-analytics-export-email-never-arrives
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix emailed Analytics report exports never arriving on stores with a persistent object cache.
diff --git a/plugins/woocommerce/src/Admin/ReportExporter.php b/plugins/woocommerce/src/Admin/ReportExporter.php
index ffd9b087cdb..f9d3d49a0f7 100644
--- a/plugins/woocommerce/src/Admin/ReportExporter.php
+++ b/plugins/woocommerce/src/Admin/ReportExporter.php
@@ -199,7 +199,9 @@ class ReportExporter {
$exports_status[ $status_key ] = $percentage;
- update_option( self::EXPORT_STATUS_OPTION, $exports_status );
+ // Not autoloaded: a persistent object cache can write back a stale copy of the autoloaded options from another
+ // request, which left the email action reading an old percentage and never sending the download link.
+ update_option( self::EXPORT_STATUS_OPTION, $exports_status, false );
}
/**
diff --git a/plugins/woocommerce/tests/php/src/Admin/ReportExporterTest.php b/plugins/woocommerce/tests/php/src/Admin/ReportExporterTest.php
index d5660b6524f..3c9b09f0745 100644
--- a/plugins/woocommerce/tests/php/src/Admin/ReportExporterTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/ReportExporterTest.php
@@ -538,4 +538,20 @@ class ReportExporterTest extends WC_Unit_Test_Case {
'The download handler should be registered.'
);
}
+
+ /**
+ * @testdox Export progress is saved outside the autoloaded options, and an autoloaded copy is moved out on the next save.
+ */
+ public function test_export_progress_is_not_autoloaded(): void {
+ global $wpdb;
+
+ update_option( ReportExporter::EXPORT_STATUS_OPTION, array( 'orders:earlier' => 100 ), true );
+
+ ReportExporter::update_export_percentage_complete( 'orders', 'current', 50 );
+
+ $this->assertArrayNotHasKey( ReportExporter::EXPORT_STATUS_OPTION, wp_load_alloptions(), 'A persistent object cache can write stale copies of the autoloaded options back, so export progress must not live there.' );
+ $this->assertSame( 'off', $wpdb->get_var( $wpdb->prepare( "SELECT autoload FROM {$wpdb->options} WHERE option_name = %s", ReportExporter::EXPORT_STATUS_OPTION ) ) );
+ $this->assertSame( 100, ReportExporter::get_export_percentage_complete( 'orders', 'earlier' ), 'Progress of earlier exports should survive the move.' );
+ $this->assertSame( 50, ReportExporter::get_export_percentage_complete( 'orders', 'current' ) );
+ }
}