Try to account for and re-create backup posts when syncing orders (#45332)
This commit is contained in:
parent
488bb62d82
commit
72cb02ac47
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: fix
|
||||
|
||||
Make sure backup posts are restored during sync when HPOS is enabled.
|
|
@ -442,7 +442,7 @@ class DataSynchronizer implements BatchProcessorInterface {
|
|||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_current_orders_pending_sync_count_cached() : int {
|
||||
public function get_current_orders_pending_sync_count_cached(): int {
|
||||
return $this->get_current_orders_pending_sync_count( true );
|
||||
}
|
||||
|
||||
|
@ -483,14 +483,14 @@ class DataSynchronizer implements BatchProcessorInterface {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare,WordPress.DB.PreparedSQL.NotPrepared --
|
||||
// -- $order_post_type_placeholder, $orders_table, self::PLACEHOLDER_ORDER_POST_TYPE are all safe to use in queries.
|
||||
if ( ! $this->get_table_exists() ) {
|
||||
$count = $wpdb->get_var(
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $order_post_type_placeholder is prepared.
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM $wpdb->posts where post_type in ( $order_post_type_placeholder )",
|
||||
$order_post_types
|
||||
)
|
||||
// phpcs:enable
|
||||
);
|
||||
return $count;
|
||||
}
|
||||
|
@ -499,30 +499,28 @@ class DataSynchronizer implements BatchProcessorInterface {
|
|||
$missing_orders_count_sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT COUNT(1) FROM $wpdb->posts posts
|
||||
INNER JOIN $orders_table orders ON posts.id=orders.id
|
||||
WHERE posts.post_type = '" . self::PLACEHOLDER_ORDER_POST_TYPE . "'
|
||||
AND orders.status not in ( 'auto-draft' )
|
||||
RIGHT JOIN $orders_table orders ON posts.ID=orders.id
|
||||
WHERE (posts.post_type IS NULL OR posts.post_type = '" . self::PLACEHOLDER_ORDER_POST_TYPE . "')
|
||||
AND orders.status NOT IN ( 'auto-draft' )
|
||||
AND orders.type IN ($order_post_type_placeholder)",
|
||||
$order_post_types
|
||||
);
|
||||
$operator = '>';
|
||||
} else {
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $order_post_type_placeholder is prepared.
|
||||
$missing_orders_count_sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT COUNT(1) FROM $wpdb->posts posts
|
||||
LEFT JOIN $orders_table orders ON posts.id=orders.id
|
||||
LEFT JOIN $orders_table orders ON posts.ID=orders.id
|
||||
WHERE
|
||||
posts.post_type in ($order_post_type_placeholder)
|
||||
AND posts.post_status != 'auto-draft'
|
||||
AND orders.id IS NULL",
|
||||
$order_post_types
|
||||
);
|
||||
// phpcs:enable
|
||||
|
||||
$operator = '<';
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $missing_orders_count_sql is prepared.
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT(
|
||||
|
@ -604,10 +602,9 @@ SELECT(
|
|||
$order_post_types = wc_get_order_types( 'cot-migration' );
|
||||
$order_post_type_placeholders = implode( ', ', array_fill( 0, count( $order_post_types ), '%s' ) );
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare,WordPress.DB.PreparedSQL.NotPrepared
|
||||
switch ( $type ) {
|
||||
case self::ID_TYPE_MISSING_IN_ORDERS_TABLE:
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $order_post_type_placeholders is prepared.
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT posts.ID FROM $wpdb->posts posts
|
||||
|
@ -619,23 +616,22 @@ WHERE
|
|||
ORDER BY posts.ID ASC",
|
||||
$order_post_types
|
||||
);
|
||||
// phpcs:enable WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
|
||||
break;
|
||||
case self::ID_TYPE_MISSING_IN_POSTS_TABLE:
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT posts.ID FROM $wpdb->posts posts
|
||||
INNER JOIN $orders_table orders ON posts.id=orders.id
|
||||
WHERE posts.post_type = '" . self::PLACEHOLDER_ORDER_POST_TYPE . "'
|
||||
AND orders.status not in ( 'auto-draft' )
|
||||
SELECT orders.id FROM $wpdb->posts posts
|
||||
RIGHT JOIN $orders_table orders ON posts.ID=orders.id
|
||||
WHERE (posts.post_type IS NULL OR posts.post_type = '" . self::PLACEHOLDER_ORDER_POST_TYPE . "')
|
||||
AND orders.status NOT IN ( 'auto-draft' )
|
||||
AND orders.type IN ($order_post_type_placeholders)
|
||||
ORDER BY posts.id ASC",
|
||||
ORDER BY posts.ID ASC",
|
||||
$order_post_types
|
||||
);
|
||||
break;
|
||||
case self::ID_TYPE_DIFFERENT_UPDATE_DATE:
|
||||
$operator = $this->custom_orders_table_is_authoritative() ? '>' : '<';
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $order_post_type_placeholders is prepared.
|
||||
|
||||
$sql = $wpdb->prepare(
|
||||
"
|
||||
SELECT orders.id FROM $orders_table orders
|
||||
|
@ -647,7 +643,6 @@ ORDER BY orders.id ASC
|
|||
",
|
||||
$order_post_types
|
||||
);
|
||||
// phpcs:enable
|
||||
break;
|
||||
case self::ID_TYPE_DELETED_FROM_ORDERS_TABLE:
|
||||
return $this->get_deleted_order_ids( true, $limit );
|
||||
|
@ -656,7 +651,7 @@ ORDER BY orders.id ASC
|
|||
default:
|
||||
throw new \Exception( 'Invalid $type, must be one of the ID_TYPE_... constants.' );
|
||||
}
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
// phpcs:enable
|
||||
|
||||
// phpcs:ignore WordPress.DB
|
||||
return array_map( 'intval', $wpdb->get_col( $sql . " LIMIT $limit" ) );
|
||||
|
@ -701,7 +696,7 @@ ORDER BY orders.id ASC
|
|||
*
|
||||
* @param array $batch Batch details.
|
||||
*/
|
||||
public function process_batch( array $batch ) : void {
|
||||
public function process_batch( array $batch ): void {
|
||||
if ( empty( $batch ) ) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -589,11 +589,24 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
|||
}
|
||||
|
||||
self::$backfilling_order_ids[] = $order->get_id();
|
||||
|
||||
// Attempt to create the backup post if missing.
|
||||
if ( $order->get_id() && is_null( get_post( $order->get_id() ) ) ) {
|
||||
if ( ! $this->maybe_create_backup_post( $order, 'backfill' ) ) {
|
||||
// translators: %d is an order ID.
|
||||
$this->error_logger->warning( sprintf( __( 'Unable to create backup post for order %d.', 'woocommerce' ), $order->get_id() ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$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 );
|
||||
|
||||
if ( $cpt_data_store->order_exists( $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() );
|
||||
|
@ -1822,20 +1835,10 @@ FROM $order_meta_table
|
|||
* @since 6.8.0
|
||||
*/
|
||||
protected function persist_order_to_db( &$order, bool $force_all_fields = false ) {
|
||||
$context = ( 0 === absint( $order->get_id() ) ) ? 'create' : 'update';
|
||||
$data_sync = wc_get_container()->get( DataSynchronizer::class );
|
||||
$context = ( 0 === absint( $order->get_id() ) ) ? 'create' : 'update';
|
||||
|
||||
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_id = $this->maybe_create_backup_post( $order, 'create' );
|
||||
if ( ! $post_id ) {
|
||||
throw new \Exception( esc_html__( 'Could not create order in posts table.', 'woocommerce' ) );
|
||||
}
|
||||
|
@ -1871,6 +1874,37 @@ FROM $order_meta_table
|
|||
$this->set_custom_taxonomies( $order, $default_taxonomies );
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes care of creating the backup post in the posts table (placeholder or actual order post, depending on sync settings).
|
||||
*
|
||||
* @since 8.8.0
|
||||
*
|
||||
* @param \WC_Abstract_Order $order The order.
|
||||
* @param string $context The context: either 'create' or 'backfill'.
|
||||
* @return int The new post ID.
|
||||
*/
|
||||
protected function maybe_create_backup_post( &$order, string $context ): int {
|
||||
$data_sync = wc_get_container()->get( DataSynchronizer::class );
|
||||
|
||||
$data = 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() ),
|
||||
);
|
||||
|
||||
if ( 'backfill' === $context ) {
|
||||
if ( ! $order->get_id() ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$data['import_id'] = $order->get_id();
|
||||
}
|
||||
|
||||
return wp_insert_post( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default taxonomies for the order.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue