diff --git a/plugins/woocommerce/changelog/fix-delete-meta-by-id b/plugins/woocommerce/changelog/fix-delete-meta-by-id new file mode 100644 index 00000000000..7321786bf3a --- /dev/null +++ b/plugins/woocommerce/changelog/fix-delete-meta-by-id @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +[HPOS] Support deleting metadata just by meta id. diff --git a/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php b/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php index 9646752ebab..bbe90ccce78 100644 --- a/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php +++ b/plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php @@ -2803,10 +2803,19 @@ CREATE TABLE $meta_table ( * @return bool */ public function delete_meta( &$object, $meta ) { + if ( $this->should_backfill_post_record() && isset( $meta->id ) && ! isset( $meta->key ) ) { + // 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 ); $this->after_meta_change( $object, $meta ); - if ( $object instanceof WC_Abstract_Order && $this->should_backfill_post_record() ) { + if ( $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() ) ); diff --git a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php index da66db16c09..f7dd3721bf4 100644 --- a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php +++ b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php @@ -2804,4 +2804,26 @@ class OrdersTableDataStoreTests extends HposTestCase { $reset_state->call( $sut ); wp_cache_flush(); } + + /** + * @testDox Test that we can delete metadata just by sending the meta ID. + */ + public function test_allow_deleting_meta_with_id_only() { + $this->toggle_cot_authoritative( true ); + $this->enable_cot_sync(); + + $order = OrderHelper::create_order(); + $order->add_meta_data( 'test_key', 'test_value' ); + $order->save(); + + $meta_data = $this->sut->read_meta( $order ); + + foreach ( $meta_data as $meta ) { + $this->sut->delete_meta( $order, (object) array( 'id' => $meta->meta_id ) ); + } + + $r_order = wc_get_order( $order->get_id() ); + $this->assertEmpty( $r_order->get_meta_data() ); + $this->assertEquals( '', get_post_meta( $order->get_id(), 'test_key', true ) ); + } }