Add support to HPOS CLI tool for handling deleted orders (#46970)

* Add support for removed orders to cleanup tool

* Add changelog
This commit is contained in:
Jorge A. Torres 2024-05-14 09:54:15 +01:00 committed by GitHub
parent 1e1e7dd65d
commit f241b4dd08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 23 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Allow HPOS CLI cleanup tool to remove metadata for deleted orders.

View File

@ -91,6 +91,8 @@ class LegacyDataHandler {
private function build_sql_query_for_cleanup( array $order_ids = array(), string $result = 'ids', int $limit = 0 ): string { private function build_sql_query_for_cleanup( array $order_ids = array(), string $result = 'ids', int $limit = 0 ): string {
global $wpdb; global $wpdb;
$hpos_orders_table = $this->data_store->get_orders_table_name();
$sql_where = ''; $sql_where = '';
if ( $order_ids ) { if ( $order_ids ) {
@ -123,7 +125,7 @@ class LegacyDataHandler {
$sql_where .= '('; $sql_where .= '(';
$sql_where .= "{$wpdb->posts}.post_type IN ('" . implode( "', '", esc_sql( wc_get_order_types( 'cot-migration' ) ) ) . "')"; $sql_where .= "{$wpdb->posts}.post_type IN ('" . implode( "', '", esc_sql( wc_get_order_types( 'cot-migration' ) ) ) . "')";
$sql_where .= $wpdb->prepare( $sql_where .= $wpdb->prepare(
" OR (post_type = %s AND EXISTS(SELECT 1 FROM {$wpdb->postmeta} WHERE post_id = {$wpdb->posts}.ID))", " OR (post_type = %s AND ( {$hpos_orders_table}.id IS NULL OR EXISTS(SELECT 1 FROM {$wpdb->postmeta} WHERE post_id = {$wpdb->posts}.ID)) )", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$this->data_synchronizer::PLACEHOLDER_ORDER_POST_TYPE $this->data_synchronizer::PLACEHOLDER_ORDER_POST_TYPE
); );
$sql_where .= ')'; $sql_where .= ')';
@ -135,11 +137,12 @@ class LegacyDataHandler {
$sql_fields = 'COUNT(*)'; $sql_fields = 'COUNT(*)';
$sql_limit = ''; $sql_limit = '';
} else { } else {
$sql_fields = 'ID'; $sql_fields = "{$wpdb->posts}.ID";
$sql_limit = $limit > 0 ? $wpdb->prepare( 'LIMIT %d', $limit ) : ''; $sql_limit = $limit > 0 ? $wpdb->prepare( 'LIMIT %d', $limit ) : '';
} }
return "SELECT {$sql_fields} FROM {$wpdb->posts} WHERE {$sql_where} {$sql_limit}"; $sql = "SELECT {$sql_fields} FROM {$wpdb->posts} LEFT JOIN {$hpos_orders_table} ON {$wpdb->posts}.ID = {$hpos_orders_table}.id WHERE {$sql_where} {$sql_limit}";
return $sql;
} }
/** /**
@ -153,10 +156,15 @@ class LegacyDataHandler {
public function cleanup_post_data( int $order_id, bool $skip_checks = false ): void { public function cleanup_post_data( int $order_id, bool $skip_checks = false ): void {
global $wpdb; global $wpdb;
$post_is_placeholder = get_post_type( $order_id ) === $this->data_synchronizer::PLACEHOLDER_ORDER_POST_TYPE; $post_type = get_post_type( $order_id );
if ( ! $post_is_placeholder ) { if ( ! in_array( $post_type, array_merge( wc_get_order_types( 'cot-migration' ), array( $this->data_synchronizer::PLACEHOLDER_ORDER_POST_TYPE ) ), true ) ) {
$order = wc_get_order( $order_id ); // translators: %d is an order ID.
throw new \Exception( esc_html( sprintf( __( '%d is not of a valid order type.', 'woocommerce' ), $order_id ) ) );
}
$order_exists = $this->data_store->order_exists( $order_id );
if ( $order_exists ) {
$order = wc_get_order( $order_id );
if ( ! $order ) { if ( ! $order ) {
// translators: %d is an order ID. // translators: %d is an order ID.
throw new \Exception( esc_html( sprintf( __( '%d is not a valid order ID.', 'woocommerce' ), $order_id ) ) ); throw new \Exception( esc_html( sprintf( __( '%d is not a valid order ID.', 'woocommerce' ), $order_id ) ) );
@ -168,24 +176,24 @@ class LegacyDataHandler {
} }
} }
// Delete all metadata. $wpdb->delete( $wpdb->postmeta, array( 'post_id' => $order_id ), array( '%d' ) ); // Delete all metadata.
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->postmeta} WHERE post_id = %d",
$order_id
)
);
// wp_update_post() changes the post modified date, so we do this manually. if ( $order_exists ) {
// Also, we suspect using wp_update_post() could lead to integrations mistakenly updating the entity. // wp_update_post() changes the post modified date, so we do this manually.
$wpdb->query( // Also, we suspect using wp_update_post() could lead to integrations mistakenly updating the entity.
$wpdb->prepare( $wpdb->update(
"UPDATE {$wpdb->posts} SET post_type = %s, post_status = %s WHERE ID = %d", $wpdb->posts,
$this->data_synchronizer::PLACEHOLDER_ORDER_POST_TYPE, array(
'draft', 'post_type' => $this->data_synchronizer::PLACEHOLDER_ORDER_POST_TYPE,
$order_id 'post_status' => 'draft',
) ),
); array( 'ID' => $order_id ),
array( '%s', '%s' ),
array( '%d' )
);
} else {
$wpdb->delete( $wpdb->posts, array( 'ID' => $order_id ), array( '%d' ) );
}
clean_post_cache( $order_id ); clean_post_cache( $order_id );
} }