Add hook to exclude certain properties from HPOS sync/verification (#43123)
Certain order properties (or metadata) are not relevant for HPOS verification. For example, `_edit_lock` which is an ephemeral key. So far we've been hardcoding these keys in various places. This provides a new API to access these keys. It also introduces hook `woocommerce_hpos_sync_ignored_order_props` which allows 3rd party code to add new keys to be ignored by sync/verification code. Fixes #41907
This commit is contained in:
parent
eabb27c72b
commit
9ce04dc807
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: tweak
|
||||||
|
|
||||||
|
Add hook 'woocommerce_hpos_sync_ignored_order_props' to allow keys to be ignored during HPOS sync/verification.
|
|
@ -583,11 +583,7 @@ class CLIRunner {
|
||||||
* @return array Failed IDs with meta details.
|
* @return array Failed IDs with meta details.
|
||||||
*/
|
*/
|
||||||
private function verify_meta_data( array $order_ids, array $failed_ids ) : array {
|
private function verify_meta_data( array $order_ids, array $failed_ids ) : array {
|
||||||
$meta_keys_to_ignore = array(
|
$meta_keys_to_ignore = $this->synchronizer->get_ignored_order_props();
|
||||||
'_paid_date', // This has been deprecated and replaced by '_date_paid' in the CPT datastore.
|
|
||||||
'_completed_date', // This has been deprecated and replaced by '_date_completed' in the CPT datastore.
|
|
||||||
'_edit_lock',
|
|
||||||
);
|
|
||||||
|
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
if ( ! count( $order_ids ) ) {
|
if ( ! count( $order_ids ) ) {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
namespace Automattic\WooCommerce\Internal\DataStores\Orders;
|
namespace Automattic\WooCommerce\Internal\DataStores\Orders;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Caches\OrderCache;
|
|
||||||
use Automattic\WooCommerce\Caches\OrderCacheController;
|
use Automattic\WooCommerce\Caches\OrderCacheController;
|
||||||
use Automattic\WooCommerce\Database\Migrations\CustomOrderTable\PostsToOrdersMigrationController;
|
use Automattic\WooCommerce\Database\Migrations\CustomOrderTable\PostsToOrdersMigrationController;
|
||||||
|
use Automattic\WooCommerce\Internal\Admin\Orders\EditLock;
|
||||||
use Automattic\WooCommerce\Internal\BatchProcessing\{ BatchProcessingController, BatchProcessorInterface };
|
use Automattic\WooCommerce\Internal\BatchProcessing\{ BatchProcessingController, BatchProcessorInterface };
|
||||||
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
||||||
use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods;
|
use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods;
|
||||||
|
@ -335,6 +335,33 @@ class DataSynchronizer implements BatchProcessorInterface {
|
||||||
return $interval;
|
return $interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keys that can be ignored during synchronization or verification.
|
||||||
|
*
|
||||||
|
* @since 8.6.0
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function get_ignored_order_props() {
|
||||||
|
/**
|
||||||
|
* Allows modifying the list of order properties that are ignored during HPOS synchronization or verification.
|
||||||
|
*
|
||||||
|
* @param string[] List of order properties or meta keys.
|
||||||
|
* @since 8.6.0
|
||||||
|
*/
|
||||||
|
$ignored_props = apply_filters( 'woocommerce_hpos_sync_ignored_order_props', array() );
|
||||||
|
$ignored_props = array_filter( array_map( 'trim', array_filter( $ignored_props, 'is_string' ) ) );
|
||||||
|
|
||||||
|
return array_merge(
|
||||||
|
$ignored_props,
|
||||||
|
array(
|
||||||
|
'_paid_date', // This has been deprecated and replaced by '_date_paid' in the CPT datastore.
|
||||||
|
'_completed_date', // This has been deprecated and replaced by '_date_completed' in the CPT datastore.
|
||||||
|
EditLock::META_KEY_NAME,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule an event to run background sync when the mode is set to interval.
|
* Schedule an event to run background sync when the mode is set to interval.
|
||||||
*
|
*
|
||||||
|
|
|
@ -97,6 +97,15 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
'_new_order_email_sent',
|
'_new_order_email_sent',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meta keys that are considered ephemereal and do not trigger a full save (updating modified date) when changed.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $ephemeral_meta_keys = array(
|
||||||
|
EditLock::META_KEY_NAME,
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles custom metadata in the wc_orders_meta table.
|
* Handles custom metadata in the wc_orders_meta table.
|
||||||
*
|
*
|
||||||
|
@ -2964,9 +2973,7 @@ CREATE TABLE $meta_table (
|
||||||
private function should_save_after_meta_change( $order, $meta = null ) {
|
private function should_save_after_meta_change( $order, $meta = null ) {
|
||||||
$current_time = $this->legacy_proxy->call_function( 'current_time', 'mysql', 1 );
|
$current_time = $this->legacy_proxy->call_function( 'current_time', 'mysql', 1 );
|
||||||
$current_date_time = new \WC_DateTime( $current_time, new \DateTimeZone( 'GMT' ) );
|
$current_date_time = new \WC_DateTime( $current_time, new \DateTimeZone( 'GMT' ) );
|
||||||
$skip_for = array(
|
|
||||||
EditLock::META_KEY_NAME,
|
return $order->get_date_modified() < $current_date_time && empty( $order->get_changes() ) && ( ! is_object( $meta ) || ! in_array( $meta->key, $this->ephemeral_meta_keys, true ) );
|
||||||
);
|
|
||||||
return $order->get_date_modified() < $current_date_time && empty( $order->get_changes() ) && ( ! is_object( $meta ) || ! in_array( $meta->key, $skip_for, true ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3239,4 +3239,25 @@ class OrdersTableDataStoreTests extends HposTestCase {
|
||||||
$this->assertContains( 'user@woo.test', $coupon->get_used_by( 'edit' ) );
|
$this->assertContains( 'user@woo.test', $coupon->get_used_by( 'edit' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that changes to certain keys don't trigger full order updates.
|
||||||
|
*/
|
||||||
|
public function test_ephemeral_meta_updates() {
|
||||||
|
$this->toggle_cot_authoritative( true );
|
||||||
|
|
||||||
|
// Set order in the past so that we can accurately compare dates.
|
||||||
|
$order = WC_Helper_Order::create_order();
|
||||||
|
$order->set_date_modified( time() - DAY_IN_SECONDS );
|
||||||
|
$order->save();
|
||||||
|
|
||||||
|
$date_modified = $order->get_date_modified();
|
||||||
|
$order->update_meta_data( '_edit_lock', 'whatever' );
|
||||||
|
$order->save_meta_data();
|
||||||
|
$this->assertEquals( $date_modified, $order->get_date_modified() );
|
||||||
|
|
||||||
|
$order->update_meta_data( 'other_meta', 'whatever' );
|
||||||
|
$order->save_meta_data();
|
||||||
|
$this->assertNotEquals( $date_modified, $order->get_date_modified() );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue