Commit 7cc97cbe19e for woocommerce
commit 7cc97cbe19ee08af58261775268393848e8e3761
Author: Michael Pretty <prettyboymp@users.noreply.github.com>
Date: Thu Jun 11 06:23:27 2026 -0400
Add OrderUtil::custom_orders_table_data_sync_is_enabled() accessor (#65649)
* Add OrderUtil::custom_orders_table_data_sync_is_enabled() accessor
Expose a cheap public check for whether HPOS real-time data sync is enabled,
delegating to DataSynchronizer::data_sync_is_enabled() via COTMigrationUtil.
Extensions currently call OrderUtil::is_custom_order_tables_in_sync() just to
learn whether sync is turned on, which additionally runs an expensive
posts<->orders pending-sync query on every call. This accessor answers the
"is sync enabled" question with a single option read.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix return type colon spacing for PSR12 (lint)
Remove the space before the colon in the new accessor's return type
declaration to satisfy PSR12.Functions.ReturnTypeDeclaration.SpaceBeforeColon.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
diff --git a/plugins/woocommerce/changelog/wooplug-6190-order-util-data-sync-enabled-accessor b/plugins/woocommerce/changelog/wooplug-6190-order-util-data-sync-enabled-accessor
new file mode 100644
index 00000000000..78d4acc08ca
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooplug-6190-order-util-data-sync-enabled-accessor
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add OrderUtil::custom_orders_table_data_sync_is_enabled() so extensions can cheaply check whether HPOS data sync is enabled without running the expensive is_custom_order_tables_in_sync() query.
diff --git a/plugins/woocommerce/src/Internal/Utilities/COTMigrationUtil.php b/plugins/woocommerce/src/Internal/Utilities/COTMigrationUtil.php
index c6695e98286..b24cf82fc80 100644
--- a/plugins/woocommerce/src/Internal/Utilities/COTMigrationUtil.php
+++ b/plugins/woocommerce/src/Internal/Utilities/COTMigrationUtil.php
@@ -81,6 +81,21 @@ class COTMigrationUtil {
return ! $this->data_synchronizer->has_orders_pending_sync();
}
+ /**
+ * Checks whether the real-time data sync between the posts and orders tables is enabled.
+ *
+ * Unlike is_custom_order_tables_in_sync(), this only reflects whether the sync setting is enabled and does
+ * not run a query to determine whether the tables are currently fully synchronized, so it is much cheaper
+ * to call. Use this when you only need to know if sync is turned on, not whether every order is in sync.
+ *
+ * @since 11.0.0
+ *
+ * @return bool True if data sync is enabled, false otherwise.
+ */
+ public function custom_orders_table_data_sync_is_enabled(): bool {
+ return $this->data_synchronizer->data_sync_is_enabled();
+ }
+
/**
* Gets value of a meta key from WC_Data object if passed, otherwise from the post object.
* This helper function support backward compatibility for meta box functions, when moving from posts based store to custom tables.
diff --git a/plugins/woocommerce/src/Utilities/OrderUtil.php b/plugins/woocommerce/src/Utilities/OrderUtil.php
index 4e6fefd8cdd..e2d5a6811ea 100644
--- a/plugins/woocommerce/src/Utilities/OrderUtil.php
+++ b/plugins/woocommerce/src/Utilities/OrderUtil.php
@@ -67,6 +67,21 @@ final class OrderUtil {
return wc_get_container()->get( COTMigrationUtil::class )->is_custom_order_tables_in_sync();
}
+ /**
+ * Checks whether the real-time data sync between the posts and orders tables is enabled.
+ *
+ * Unlike is_custom_order_tables_in_sync(), this only reflects whether the sync setting is enabled (a cheap
+ * option read) and does not run a query to check whether the tables are currently fully synchronized. Use
+ * this when you only need to know if sync is turned on, not whether every order is currently in sync.
+ *
+ * @since 11.0.0
+ *
+ * @return bool True if data sync is enabled, false otherwise.
+ */
+ public static function custom_orders_table_data_sync_is_enabled(): bool {
+ return wc_get_container()->get( COTMigrationUtil::class )->custom_orders_table_data_sync_is_enabled();
+ }
+
/**
* Gets value of a meta key from WC_Data object if passed, otherwise from the post object.
* This helper function support backward compatibility for meta box functions, when moving from posts based store to custom tables.
diff --git a/plugins/woocommerce/tests/php/src/Internal/Utilities/COTMigrationUtilTest.php b/plugins/woocommerce/tests/php/src/Internal/Utilities/COTMigrationUtilTest.php
index 08aca344c70..0493ff5867b 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Utilities/COTMigrationUtilTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Utilities/COTMigrationUtilTest.php
@@ -137,6 +137,67 @@ class COTMigrationUtilTest extends \WC_Unit_Test_Case {
$this->assertFalse( $this->sut->is_custom_order_tables_in_sync() );
}
+ /**
+ * @testdox `custom_orders_table_data_sync_is_enabled` should return true when data sync is enabled.
+ */
+ public function test_custom_orders_table_data_sync_is_enabled_is_true() {
+ $data_sync_mock = $this->getMockBuilder( DataSynchronizer::class )
+ ->setMethods( array( 'data_sync_is_enabled' ) )
+ ->getMock();
+
+ $data_sync_mock->method( 'data_sync_is_enabled' )->willReturn( true );
+
+ // This is needed to prevent "Call to private method Mock_DataSynchronizer_xxxx::process_added_option" errors.
+ remove_filter( 'updated_option', array( $data_sync_mock, 'process_updated_option' ), 999, 3 );
+ remove_filter( 'added_option', array( $data_sync_mock, 'process_added_option' ), 999, 2 );
+
+ $cot_controller = wc_get_container()->get( CustomOrdersTableController::class );
+ $this->sut = new COTMigrationUtil();
+ $this->sut->init( $cot_controller, $data_sync_mock );
+ $this->assertTrue( $this->sut->custom_orders_table_data_sync_is_enabled() );
+ }
+
+ /**
+ * @testdox `custom_orders_table_data_sync_is_enabled` should return false when data sync is disabled.
+ */
+ public function test_custom_orders_table_data_sync_is_enabled_is_false() {
+ $data_sync_mock = $this->getMockBuilder( DataSynchronizer::class )
+ ->setMethods( array( 'data_sync_is_enabled' ) )
+ ->getMock();
+
+ $data_sync_mock->method( 'data_sync_is_enabled' )->willReturn( false );
+
+ // This is needed to prevent "Call to private method Mock_DataSynchronizer_xxxx::process_added_option" errors.
+ remove_filter( 'updated_option', array( $data_sync_mock, 'process_updated_option' ), 999, 3 );
+ remove_filter( 'added_option', array( $data_sync_mock, 'process_added_option' ), 999, 2 );
+
+ $cot_controller = wc_get_container()->get( CustomOrdersTableController::class );
+ $this->sut = new COTMigrationUtil();
+ $this->sut->init( $cot_controller, $data_sync_mock );
+ $this->assertFalse( $this->sut->custom_orders_table_data_sync_is_enabled() );
+ }
+
+ /**
+ * @testdox `custom_orders_table_data_sync_is_enabled` should not run the expensive pending-sync query.
+ */
+ public function test_custom_orders_table_data_sync_is_enabled_does_not_query_pending_sync() {
+ $data_sync_mock = $this->getMockBuilder( DataSynchronizer::class )
+ ->setMethods( array( 'has_orders_pending_sync', 'data_sync_is_enabled' ) )
+ ->getMock();
+
+ $data_sync_mock->method( 'data_sync_is_enabled' )->willReturn( true );
+ $data_sync_mock->expects( $this->never() )->method( 'has_orders_pending_sync' );
+
+ // This is needed to prevent "Call to private method Mock_DataSynchronizer_xxxx::process_added_option" errors.
+ remove_filter( 'updated_option', array( $data_sync_mock, 'process_updated_option' ), 999, 3 );
+ remove_filter( 'added_option', array( $data_sync_mock, 'process_added_option' ), 999, 2 );
+
+ $cot_controller = wc_get_container()->get( CustomOrdersTableController::class );
+ $this->sut = new COTMigrationUtil();
+ $this->sut->init( $cot_controller, $data_sync_mock );
+ $this->sut->custom_orders_table_data_sync_is_enabled();
+ }
+
/**
* @testdox `get_table_for_orders` should return the name of the posts table when HPOS is not in use.
*/