rebase code on oct-10-2023
This commit is contained in:
@@ -194,41 +194,4 @@ abstract class CustomMetaDataStore {
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves metadata by meta key.
|
||||
*
|
||||
* @param \WC_Abstract_Order $object Object ID.
|
||||
* @param string $meta_key Meta key.
|
||||
*
|
||||
* @return \stdClass|bool Metadata object or FALSE if not found.
|
||||
*/
|
||||
public function get_metadata_by_key( &$object, string $meta_key ) {
|
||||
global $wpdb;
|
||||
|
||||
$db_info = $this->get_db_info();
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$meta = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT {$db_info['meta_id_field']}, meta_key, meta_value, {$db_info['object_id_field']} FROM {$db_info['table']} WHERE meta_key = %s AND {$db_info['object_id_field']} = %d",
|
||||
$meta_key,
|
||||
$object->get_id(),
|
||||
)
|
||||
);
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
|
||||
if ( empty( $meta ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $meta as $row ) {
|
||||
if ( isset( $row->meta_value ) ) {
|
||||
$row->meta_value = maybe_unserialize( $row->meta_value );
|
||||
}
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,19 +23,12 @@ defined( 'ABSPATH' ) || exit;
|
||||
class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements \WC_Object_Data_Store_Interface, \WC_Order_Data_Store_Interface {
|
||||
|
||||
/**
|
||||
* Order IDs for which we are checking sync on read in the current request. In WooCommerce, using wc_get_order is a very common pattern, to avoid performance issues, we only sync on read once per request per order. This works because we consider out of sync orders to be an anomaly, so we don't recommend running HPOS with incompatible plugins.
|
||||
* Order IDs for which we are checking read on sync in the current request.
|
||||
*
|
||||
* @var array.
|
||||
*/
|
||||
private static $reading_order_ids = array();
|
||||
|
||||
/**
|
||||
* Keep track of order IDs that are actively being backfilled. We use this to prevent further read on sync from add_|update_|delete_postmeta etc hooks. If we allow this, then we would end up syncing the same order multiple times as it is being backfilled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $backfilling_order_ids = array();
|
||||
|
||||
/**
|
||||
* Data stored in meta keys, but not considered "meta" for an order.
|
||||
*
|
||||
@@ -569,18 +562,7 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||
return;
|
||||
}
|
||||
|
||||
self::$backfilling_order_ids[] = $order->get_id();
|
||||
$this->update_order_meta_from_object( $order );
|
||||
$order_class = get_class( $order );
|
||||
$post_order = new $order_class();
|
||||
$post_order->set_id( $order->get_id() );
|
||||
$cpt_data_store->read( $post_order );
|
||||
|
||||
// This compares the order data to the post data and set changes array for props that are changed.
|
||||
$post_order->set_props( $order->get_data() );
|
||||
|
||||
$cpt_data_store->update_order_from_object( $post_order );
|
||||
|
||||
$cpt_data_store->update_order_from_object( $order );
|
||||
foreach ( $cpt_data_store->get_internal_data_store_key_getters() as $key => $getter_name ) {
|
||||
if (
|
||||
is_callable( array( $cpt_data_store, "set_$getter_name" ) ) &&
|
||||
@@ -598,7 +580,6 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||
);
|
||||
}
|
||||
}
|
||||
self::$backfilling_order_ids = array_diff( self::$backfilling_order_ids, array( $order->get_id() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -781,47 +762,6 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||
$this->set_stock_reduced( $order, $set );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get token ids for an order.
|
||||
*
|
||||
* @param WC_Order $order Order object.
|
||||
* @return array
|
||||
*/
|
||||
public function get_payment_token_ids( $order ) {
|
||||
/**
|
||||
* We don't store _payment_tokens in props to preserve backward compatibility. In CPT data store, `_payment_tokens` is always fetched directly from DB instead of from prop.
|
||||
*/
|
||||
$payment_tokens = $this->data_store_meta->get_metadata_by_key( $order, '_payment_tokens' );
|
||||
if ( $payment_tokens ) {
|
||||
$payment_tokens = $payment_tokens[0]->meta_value;
|
||||
}
|
||||
if ( ! $payment_tokens && version_compare( $order->get_version(), '8.0.0', '<' ) ) {
|
||||
// Before 8.0 we were incorrectly storing payment_tokens in the order meta. So we need to check there too.
|
||||
$payment_tokens = get_post_meta( $order->get_id(), '_payment_tokens', true );
|
||||
}
|
||||
return array_filter( (array) $payment_tokens );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update token ids for an order.
|
||||
*
|
||||
* @param WC_Order $order Order object.
|
||||
* @param array $token_ids Payment token ids.
|
||||
*/
|
||||
public function update_payment_token_ids( $order, $token_ids ) {
|
||||
$meta = new \WC_Meta_Data();
|
||||
$meta->key = '_payment_tokens';
|
||||
$meta->value = $token_ids;
|
||||
$existing_meta = $this->data_store_meta->get_metadata_by_key( $order, '_payment_tokens' );
|
||||
if ( $existing_meta ) {
|
||||
$existing_meta = $existing_meta[0];
|
||||
$meta->id = $existing_meta->id;
|
||||
$this->data_store_meta->update_meta( $order, $meta );
|
||||
} else {
|
||||
$this->data_store_meta->add_meta( $order, $meta );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get amount already refunded.
|
||||
*
|
||||
@@ -1111,7 +1051,7 @@ WHERE
|
||||
}
|
||||
|
||||
$data_sync_enabled = $data_synchronizer->data_sync_is_enabled();
|
||||
$load_posts_for = array_diff( $order_ids, array_merge( self::$reading_order_ids, self::$backfilling_order_ids ) );
|
||||
$load_posts_for = array_diff( $order_ids, self::$reading_order_ids );
|
||||
$post_orders = $data_sync_enabled ? $this->get_post_orders_for_ids( array_intersect_key( $orders, array_flip( $load_posts_for ) ) ) : array();
|
||||
|
||||
foreach ( $data as $order_data ) {
|
||||
@@ -1716,11 +1656,9 @@ FROM $order_meta_table
|
||||
if ( 'create' === $context ) {
|
||||
$post_id = wp_insert_post(
|
||||
array(
|
||||
'post_type' => $data_sync->data_sync_is_enabled() ? $order->get_type() : $data_sync::PLACEHOLDER_ORDER_POST_TYPE,
|
||||
'post_status' => 'draft',
|
||||
'post_parent' => $order->get_changes()['parent_id'] ?? $order->get_data()['parent_id'] ?? 0,
|
||||
'post_date' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getOffsetTimestamp() ),
|
||||
'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getTimestamp() ),
|
||||
'post_type' => $data_sync->data_sync_is_enabled() ? $order->get_type() : $data_sync::PLACEHOLDER_ORDER_POST_TYPE,
|
||||
'post_status' => 'draft',
|
||||
'post_parent' => $order->get_changes()['parent_id'] ?? $order->get_data()['parent_id'] ?? 0,
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1858,8 +1796,8 @@ FROM $order_meta_table
|
||||
if ( $row ) {
|
||||
$result[] = array(
|
||||
'table' => self::get_orders_table_name(),
|
||||
'data' => array_merge( $row['data'], array( 'id' => $order->get_id(), 'type' => $order->get_type() ) ),
|
||||
'format' => array_merge( $row['format'], array( 'id' => '%d', 'type' => '%s' ) ),
|
||||
'data' => array_merge( $row['data'], array( 'id' => $order->get_id() ) ),
|
||||
'format' => array_merge( $row['format'], array( 'id' => '%d' ) ),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1928,6 +1866,8 @@ FROM $order_meta_table
|
||||
protected function get_db_row_from_order( $order, $column_mapping, $only_changes = false ) {
|
||||
$changes = $only_changes ? $order->get_changes() : array_merge( $order->get_data(), $order->get_changes() );
|
||||
|
||||
$changes['type'] = $order->get_type();
|
||||
|
||||
// Make sure 'status' is correctly prefixed.
|
||||
if ( array_key_exists( 'status', $column_mapping ) && array_key_exists( 'status', $changes ) ) {
|
||||
$changes['status'] = $this->get_post_status( $order );
|
||||
@@ -2161,6 +2101,16 @@ FROM $order_meta_table
|
||||
'_wp_trash_meta_time' => time(),
|
||||
);
|
||||
|
||||
foreach ( $trash_metadata as $meta_key => $meta_value ) {
|
||||
$this->add_meta(
|
||||
$order,
|
||||
(object) array(
|
||||
'key' => $meta_key,
|
||||
'value' => $meta_value,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$wpdb->update(
|
||||
self::get_orders_table_name(),
|
||||
array(
|
||||
@@ -2174,16 +2124,6 @@ FROM $order_meta_table
|
||||
|
||||
$order->set_status( 'trash' );
|
||||
|
||||
foreach ( $trash_metadata as $meta_key => $meta_value ) {
|
||||
$this->add_meta(
|
||||
$order,
|
||||
(object) array(
|
||||
'key' => $meta_key,
|
||||
'value' => $meta_value,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$data_synchronizer = wc_get_container()->get( DataSynchronizer::class );
|
||||
if ( $data_synchronizer->data_sync_is_enabled() ) {
|
||||
wp_trash_post( $order->get_id() );
|
||||
@@ -2315,11 +2255,6 @@ FROM $order_meta_table
|
||||
|
||||
$this->persist_save( $order );
|
||||
|
||||
// Do not fire 'woocommerce_new_order' for draft statuses for backwards compatibility.
|
||||
if ( 'auto-draft' === $order->get_status( 'edit') ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when a new order is created.
|
||||
*
|
||||
@@ -2352,22 +2287,15 @@ FROM $order_meta_table
|
||||
$order->set_date_created( time() );
|
||||
}
|
||||
|
||||
if ( ! $order->get_date_modified( 'edit' ) ) {
|
||||
$order->set_date_modified( current_time( 'mysql' ) );
|
||||
}
|
||||
$this->update_order_meta( $order );
|
||||
|
||||
$this->persist_order_to_db( $order, $force_all_fields );
|
||||
|
||||
$this->update_order_meta( $order );
|
||||
|
||||
$order->save_meta_data();
|
||||
$order->apply_changes();
|
||||
|
||||
if ( $backfill ) {
|
||||
self::$backfilling_order_ids[] = $order->get_id();
|
||||
$r_order = wc_get_order( $order->get_id() ); // Refresh order to account for DB changes from post hooks.
|
||||
$this->maybe_backfill_post_record( $r_order );
|
||||
self::$backfilling_order_ids = array_diff( self::$backfilling_order_ids, array( $order->get_id() ) );
|
||||
$this->maybe_backfill_post_record( $order );
|
||||
}
|
||||
$this->clear_caches( $order );
|
||||
}
|
||||
@@ -2378,9 +2306,6 @@ FROM $order_meta_table
|
||||
* @param \WC_Order $order Order object.
|
||||
*/
|
||||
public function update( &$order ) {
|
||||
$previous_status = ArrayUtil::get_value_or_default( $order->get_data(), 'status' );
|
||||
$changes = $order->get_changes();
|
||||
|
||||
// Before updating, ensure date paid is set if missing.
|
||||
if (
|
||||
! $order->get_date_paid( 'edit' )
|
||||
@@ -2414,18 +2339,6 @@ FROM $order_meta_table
|
||||
$order->apply_changes();
|
||||
$this->clear_caches( $order );
|
||||
|
||||
// For backwards compatibility, moving an auto-draft order to a valid status triggers the 'woocommerce_new_order' hook.
|
||||
if ( ! empty( $changes['status'] ) && 'auto-draft' === $previous_status ) {
|
||||
do_action( 'woocommerce_new_order', $order->get_id(), $order ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment
|
||||
return;
|
||||
}
|
||||
|
||||
// For backwards compat with CPT, trashing/untrashing and changing previously datastore-level props does not trigger the update hook.
|
||||
if ( ( ! empty( $changes['status'] ) && in_array( 'trash', array( $changes['status'], $previous_status ), true ) )
|
||||
|| ! array_diff_key( $changes, array_flip( $this->get_post_data_store_for_backfill()->get_internal_data_store_key_getters() ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_update_order', $order->get_id(), $order ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment
|
||||
}
|
||||
|
||||
@@ -2457,33 +2370,19 @@ FROM $order_meta_table
|
||||
$changes = $order->get_changes();
|
||||
|
||||
if ( ! isset( $changes['date_modified'] ) ) {
|
||||
$order->set_date_modified( current_time( 'mysql' ) );
|
||||
$order->set_date_modified( time() );
|
||||
}
|
||||
|
||||
$this->persist_order_to_db( $order );
|
||||
$order->save_meta_data();
|
||||
|
||||
if ( $backfill ) {
|
||||
$this->clear_caches( $order );
|
||||
self::$backfilling_order_ids[] = $order->get_id();
|
||||
$r_order = wc_get_order( $order->get_id() ); // Refresh order to account for DB changes from post hooks.
|
||||
$this->maybe_backfill_post_record( $r_order );
|
||||
self::$backfilling_order_ids = array_diff( self::$backfilling_order_ids, array( $order->get_id() ) );
|
||||
$this->maybe_backfill_post_record( $order );
|
||||
}
|
||||
|
||||
return $changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check whether to backfill post record.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function should_backfill_post_record() {
|
||||
$data_sync = wc_get_container()->get( DataSynchronizer::class );
|
||||
return $data_sync->data_sync_is_enabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to decide whether to backfill post record.
|
||||
*
|
||||
@@ -2492,7 +2391,8 @@ FROM $order_meta_table
|
||||
* @return void
|
||||
*/
|
||||
private function maybe_backfill_post_record( $order ) {
|
||||
if ( $this->should_backfill_post_record() ) {
|
||||
$data_sync = wc_get_container()->get( DataSynchronizer::class );
|
||||
if ( $data_sync->data_sync_is_enabled() ) {
|
||||
$this->backfill_post_record( $order );
|
||||
}
|
||||
}
|
||||
@@ -2684,10 +2584,6 @@ FROM $order_meta_table
|
||||
$operational_data_table_name = $this->get_operational_data_table_name();
|
||||
$meta_table = $this->get_meta_table_name();
|
||||
|
||||
$max_index_length = $this->database_util->get_max_index_length();
|
||||
$composite_meta_value_index_length = max( $max_index_length - 8 - 100 - 1, 20 ); // 8 for order_id, 100 for meta_key, 10 minimum for meta_value.
|
||||
$composite_customer_id_email_length = max( $max_index_length - 20, 20 ); // 8 for customer_id, 20 minimum for email.
|
||||
|
||||
$sql = "
|
||||
CREATE TABLE $orders_table_name (
|
||||
id bigint(20) unsigned,
|
||||
@@ -2710,9 +2606,9 @@ CREATE TABLE $orders_table_name (
|
||||
PRIMARY KEY (id),
|
||||
KEY status (status),
|
||||
KEY date_created (date_created_gmt),
|
||||
KEY customer_id_billing_email (customer_id, billing_email({$composite_customer_id_email_length})),
|
||||
KEY billing_email (billing_email($max_index_length)),
|
||||
KEY type_status_date (type, status, date_created_gmt),
|
||||
KEY customer_id_billing_email (customer_id, billing_email),
|
||||
KEY billing_email (billing_email),
|
||||
KEY type_status (type, status),
|
||||
KEY parent_order_id (parent_order_id),
|
||||
KEY date_updated (date_updated_gmt)
|
||||
) $collate;
|
||||
@@ -2733,7 +2629,7 @@ CREATE TABLE $addresses_table_name (
|
||||
phone varchar(100) null,
|
||||
KEY order_id (order_id),
|
||||
UNIQUE KEY address_type_order_id (address_type, order_id),
|
||||
KEY email (email($max_index_length)),
|
||||
KEY email (email),
|
||||
KEY phone (phone)
|
||||
) $collate;
|
||||
CREATE TABLE $operational_data_table_name (
|
||||
@@ -2750,10 +2646,10 @@ CREATE TABLE $operational_data_table_name (
|
||||
order_stock_reduced tinyint(1) NULL,
|
||||
date_paid_gmt datetime NULL,
|
||||
date_completed_gmt datetime NULL,
|
||||
shipping_tax_amount decimal(26,8) NULL,
|
||||
shipping_total_amount decimal(26,8) NULL,
|
||||
discount_tax_amount decimal(26,8) NULL,
|
||||
discount_total_amount decimal(26,8) NULL,
|
||||
shipping_tax_amount decimal(26, 8) NULL,
|
||||
shipping_total_amount decimal(26, 8) NULL,
|
||||
discount_tax_amount decimal(26, 8) NULL,
|
||||
discount_total_amount decimal(26, 8) NULL,
|
||||
recorded_sales tinyint(1) NULL,
|
||||
UNIQUE KEY order_id (order_id),
|
||||
KEY order_key (order_key)
|
||||
@@ -2763,8 +2659,8 @@ CREATE TABLE $meta_table (
|
||||
order_id bigint(20) unsigned null,
|
||||
meta_key varchar(255),
|
||||
meta_value text null,
|
||||
KEY meta_key_value (meta_key(100), meta_value($composite_meta_value_index_length)),
|
||||
KEY order_id_meta_key_meta_value (order_id, meta_key(100), meta_value($composite_meta_value_index_length))
|
||||
KEY meta_key_value (meta_key, meta_value(100)),
|
||||
KEY order_id_meta_key_meta_value (order_id, meta_key, meta_value(100))
|
||||
) $collate;
|
||||
";
|
||||
|
||||
@@ -2785,28 +2681,16 @@ CREATE TABLE $meta_table (
|
||||
/**
|
||||
* Deletes meta based on meta ID.
|
||||
*
|
||||
* @param WC_Data $object WC_Data object.
|
||||
* @param \stdClass $meta (containing at least ->id).
|
||||
* @param WC_Data $object WC_Data object.
|
||||
* @param stdClass $meta (containing at least ->id).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete_meta( &$object, $meta ) {
|
||||
if ( $this->should_backfill_post_record() && isset( $meta->id ) ) {
|
||||
// Let's get the actual meta key before its deleted for backfilling. We cannot delete just by ID because meta IDs are different in HPOS and posts tables.
|
||||
$db_meta = $this->data_store_meta->get_metadata_by_id( $meta->id );
|
||||
if ( $db_meta ) {
|
||||
$meta->key = $db_meta->meta_key;
|
||||
$meta->value = $db_meta->meta_value;
|
||||
}
|
||||
}
|
||||
$delete_meta = $this->data_store_meta->delete_meta( $object, $meta );
|
||||
|
||||
$delete_meta = $this->data_store_meta->delete_meta( $object, $meta );
|
||||
$changes_applied = $this->after_meta_change( $object, $meta );
|
||||
|
||||
if ( ! $changes_applied && $object instanceof WC_Abstract_Order && $this->should_backfill_post_record() && isset( $meta->key ) ) {
|
||||
self::$backfilling_order_ids[] = $object->get_id();
|
||||
delete_post_meta( $object->get_id(), $meta->key, $meta->value );
|
||||
self::$backfilling_order_ids = array_diff( self::$backfilling_order_ids, array( $object->get_id() ) );
|
||||
if ( $object instanceof WC_Abstract_Order ) {
|
||||
$this->maybe_backfill_post_record( $object );
|
||||
}
|
||||
|
||||
return $delete_meta;
|
||||
@@ -2815,20 +2699,16 @@ CREATE TABLE $meta_table (
|
||||
/**
|
||||
* Add new piece of meta.
|
||||
*
|
||||
* @param WC_Data $object WC_Data object.
|
||||
* @param \stdClass $meta (containing ->key and ->value).
|
||||
* @param WC_Data $object WC_Data object.
|
||||
* @param stdClass $meta (containing ->key and ->value).
|
||||
*
|
||||
* @return int|bool meta ID or false on failure
|
||||
*/
|
||||
public function add_meta( &$object, $meta ) {
|
||||
$add_meta = $this->data_store_meta->add_meta( $object, $meta );
|
||||
$meta->id = $add_meta;
|
||||
$changes_applied = $this->after_meta_change( $object, $meta );
|
||||
$add_meta = $this->data_store_meta->add_meta( $object, $meta );
|
||||
|
||||
if ( ! $changes_applied && $object instanceof WC_Abstract_Order && $this->should_backfill_post_record() ) {
|
||||
self::$backfilling_order_ids[] = $object->get_id();
|
||||
add_post_meta( $object->get_id(), $meta->key, $meta->value );
|
||||
self::$backfilling_order_ids = array_diff( self::$backfilling_order_ids, array( $object->get_id() ) );
|
||||
if ( $object instanceof WC_Abstract_Order ) {
|
||||
$this->maybe_backfill_post_record( $object );
|
||||
}
|
||||
|
||||
return $add_meta;
|
||||
@@ -2837,58 +2717,18 @@ CREATE TABLE $meta_table (
|
||||
/**
|
||||
* Update meta.
|
||||
*
|
||||
* @param WC_Data $object WC_Data object.
|
||||
* @param \stdClass $meta (containing ->id, ->key and ->value).
|
||||
* @param WC_Data $object WC_Data object.
|
||||
* @param stdClass $meta (containing ->id, ->key and ->value).
|
||||
*
|
||||
* @return
|
||||
* @return bool
|
||||
*/
|
||||
public function update_meta( &$object, $meta ) {
|
||||
$update_meta = $this->data_store_meta->update_meta( $object, $meta );
|
||||
$changes_applied = $this->after_meta_change( $object, $meta );
|
||||
$update_meta = $this->data_store_meta->update_meta( $object, $meta );
|
||||
|
||||
if ( ! $changes_applied && $object instanceof WC_Abstract_Order && $this->should_backfill_post_record() ) {
|
||||
self::$backfilling_order_ids[] = $object->get_id();
|
||||
update_post_meta( $object->get_id(), $meta->key, $meta->value );
|
||||
self::$backfilling_order_ids = array_diff( self::$backfilling_order_ids, array( $object->get_id() ) );
|
||||
if ( $object instanceof WC_Abstract_Order ) {
|
||||
$this->maybe_backfill_post_record( $object );
|
||||
}
|
||||
|
||||
return $update_meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform after meta change operations, including updating the date_modified field, clearing caches and applying changes.
|
||||
*
|
||||
* @param WC_Abstract_Order $order Order object.
|
||||
* @param \WC_Meta_Data $meta Metadata object.
|
||||
*
|
||||
* @return bool True if changes were applied, false otherwise.
|
||||
*/
|
||||
protected function after_meta_change( &$order, $meta ) {
|
||||
method_exists( $meta, 'apply_changes' ) && $meta->apply_changes();
|
||||
$this->clear_caches( $order );
|
||||
|
||||
// Prevent this happening multiple time in same request.
|
||||
if ( $this->should_save_after_meta_change( $order ) ) {
|
||||
$order->set_date_modified( current_time( 'mysql' ) );
|
||||
$order->save();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to check whether the modified date needs to be updated after a meta save.
|
||||
*
|
||||
* This method prevents order->save() call multiple times in the same request after any meta update by checking if:
|
||||
* 1. Order modified date is already the current date, no updates needed in this case.
|
||||
* 2. If there are changes already queued for order object, then we don't need to update the modified date as it will be updated ina subsequent save() call.
|
||||
*
|
||||
* @param WC_Order $order Order object.
|
||||
*
|
||||
* @return bool Whether the modified date needs to be updated.
|
||||
*/
|
||||
private function should_save_after_meta_change( $order ) {
|
||||
$current_date_time = new \WC_DateTime( current_time( 'mysql', 1 ), new \DateTimeZone( 'GMT' ) );
|
||||
return $order->get_date_modified() < $current_date_time && empty( $order->get_changes() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Internal\DataStores\Orders;
|
||||
|
||||
use WC_Meta_Data;
|
||||
|
||||
/**
|
||||
* Class OrdersTableRefundDataStore.
|
||||
*/
|
||||
@@ -161,17 +159,8 @@ class OrdersTableRefundDataStore extends OrdersTableDataStore {
|
||||
|
||||
$props_to_update = $this->get_props_to_update( $refund, $meta_key_to_props );
|
||||
foreach ( $props_to_update as $meta_key => $prop ) {
|
||||
$meta_object = new WC_Meta_Data();
|
||||
$meta_object->key = $meta_key;
|
||||
$meta_object->value = $refund->{"get_$prop"}( 'edit' );
|
||||
$existing_meta = $this->data_store_meta->get_metadata_by_key( $refund, $meta_key );
|
||||
if ( $existing_meta ) {
|
||||
$existing_meta = $existing_meta[0];
|
||||
$meta_object->id = $existing_meta->id;
|
||||
$this->update_meta( $refund, $meta_object );
|
||||
} else {
|
||||
$this->add_meta( $refund, $meta_object );
|
||||
}
|
||||
$value = $refund->{"get_$prop"}( 'edit' );
|
||||
$refund->update_meta_data( $meta_key, $value );
|
||||
$updated_props[] = $prop;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user