Update post directly to update correct post_modified value (#34611)
Update post directly to update correct post_modified value. If we use wp's update_post function, then it will set the post-modified date to current time(). This is not desirable when backfilling order data where we want post data to be exactly the same as orders. * Add changelog. * Added protections and code standard fixes. * Use wp_update_post so that hooks fire as usual.
This commit is contained in:
parent
232d26846a
commit
657dceaba1
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: fix
|
||||
|
||||
Update post directly to update correct post_modified value.
|
|
@ -136,7 +136,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
|
|||
/**
|
||||
* In older versions, discounts may have been stored differently.
|
||||
* Update them now so if the object is saved, the correct values are
|
||||
* stored. @todo When meta is flattened, handle this during migration.
|
||||
* stored.
|
||||
*/
|
||||
if ( version_compare( $order->get_version( 'edit' ), '2.3.7', '<' ) && $order->get_prices_include_tax( 'edit' ) ) {
|
||||
$order->set_discount_total( (float) get_post_meta( $order->get_id(), '_cart_discount', true ) - (float) get_post_meta( $order->get_id(), '_cart_discount_tax', true ) );
|
||||
|
@ -471,21 +471,50 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
|
|||
* @return bool Whether the order was updated.
|
||||
*/
|
||||
public function update_order_from_object( $order ) {
|
||||
global $wpdb;
|
||||
if ( ! $order->get_id() ) {
|
||||
return false;
|
||||
}
|
||||
$this->update_order_meta_from_object( $order );
|
||||
return wp_update_post(
|
||||
// Add hook to update post_modified date so that it's the same as order. Without this hook, WP will set the modified date to current date, and we will think that posts and orders are out of sync again.
|
||||
add_filter( 'wp_insert_post_data', array( $this, 'update_post_modified_data' ), 10, 2 );
|
||||
$updated = wp_update_post(
|
||||
array(
|
||||
'ID' => $order->get_id(),
|
||||
'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_status' => $this->get_post_status( $order ),
|
||||
'post_parent' => $order->get_parent_id(),
|
||||
'post_excerpt' => method_exists( $order, 'get_customer_note' ) ? $order->get_customer_note() : '',
|
||||
'post_type' => $order->get_type(),
|
||||
'ID' => $order->get_id(),
|
||||
// phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date -- use of date is intentional.
|
||||
'post_date' => date( '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_status' => $this->get_post_status( $order ),
|
||||
'post_parent' => $order->get_parent_id(),
|
||||
'post_excerpt' => method_exists( $order, 'get_customer_note' ) ? $order->get_customer_note() : '',
|
||||
'post_type' => $order->get_type(),
|
||||
// phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date -- use of date is intentional.
|
||||
'order_modified' => ! is_null( $order->get_date_modified() ) ? date( 'Y-m-d H:i:s', $order->get_date_modified( 'edit' )->getTimestamp() ) : '',
|
||||
'order_modified_gmt' => ! is_null( $order->get_date_modified() ) ? gmdate( 'Y-m-d H:i:s', $order->get_date_modified( 'edit' )->getTimestamp() ) : '',
|
||||
)
|
||||
);
|
||||
remove_filter( 'wp_insert_post_data', array( $this, 'update_post_modified_data' ) );
|
||||
return $updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the modified date of the post to match the order's modified date if passed.
|
||||
*
|
||||
* @hooked wp_insert_post_data See function update_order_from_object.
|
||||
*
|
||||
* @param array $data An array of slashed, sanitized, and processed post data.
|
||||
* @param array $postarr An array of sanitized (and slashed) but otherwise unmodified post data.
|
||||
*
|
||||
* @return array Data with updated modified date.
|
||||
*/
|
||||
public function update_post_modified_data( $data, $postarr ) {
|
||||
if ( ! isset( $postarr['order_modified'] ) || ! isset( $postarr['order_modified_gmt'] ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$data['post_modified'] = $postarr['order_modified'];
|
||||
$data['post_modified_gmt'] = $postarr['order_modified_gmt'];
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,7 +46,7 @@ class DataSynchronizerTests extends WC_Unit_Test_Case {
|
|||
update_option( CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION, false );
|
||||
$post_data_store = WC_Data_Store::load( 'order' );
|
||||
|
||||
$cot_enabled = $authoritative_source === 'cot' ? 'yes' : 'no';
|
||||
$cot_enabled = 'cot' === $authoritative_source ? 'yes' : 'no';
|
||||
update_option( CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION, $cot_enabled );
|
||||
update_option( DataSynchronizer::ORDERS_DATA_SYNC_ENABLED_OPTION, 'no' );
|
||||
|
||||
|
@ -104,4 +104,23 @@ class DataSynchronizerTests extends WC_Unit_Test_Case {
|
|||
$this->assertEquals( 0, $this->sut->get_current_orders_pending_sync_count() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that orders that are backfilled later on don't need to be synced again.
|
||||
*/
|
||||
public function test_get_ids_orders_pending_async_backfill() {
|
||||
update_option( $this->sut::ORDERS_DATA_SYNC_ENABLED_OPTION, 'no' );
|
||||
update_option( CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION, 'yes' );
|
||||
$order = OrderHelper::create_complex_data_store_order();
|
||||
$this->assertEquals( 1, $this->sut->get_current_orders_pending_sync_count() );
|
||||
// Simulate that order was updated some time ago, and we are backfilling just now.
|
||||
$order->set_date_modified( time() - 1000 );
|
||||
$order->save();
|
||||
|
||||
$this->sut->process_batch( array( $order->get_id() ) );
|
||||
$this->assertEquals( 0, $this->sut->get_current_orders_pending_sync_count() );
|
||||
|
||||
// So far so good, now if we change the authoritative source to posts, we should still have 0 order pending sync.
|
||||
update_option( CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION, 'no' );
|
||||
$this->assertEquals( 0, $this->sut->get_current_orders_pending_sync_count() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,6 +140,19 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that modified date is backfilled correctly when syncing order.
|
||||
*/
|
||||
public function test_backfill_updated_date() {
|
||||
$order = $this->create_complex_cot_order();
|
||||
$hardcoded_modified_date = time() - 100;
|
||||
$order->set_date_modified( $hardcoded_modified_date );
|
||||
$order->save();
|
||||
|
||||
$this->sut->backfill_post_record( $order );
|
||||
$this->assertEquals( $hardcoded_modified_date, get_post_modified_time( 'U', true, $order->get_id() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests update() on the COT datastore.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue