Commit d2118dd2ab7 for woocommerce
commit d2118dd2ab79c77176d534660107f2323cd7b496
Author: Darren Ethier <darren@roughsmootheng.in>
Date: Sun Aug 23 09:46:39 2026 -0400
Prepare the order-item deletion query explicitly (#67932)
diff --git a/plugins/woocommerce/changelog/prepare-order-item-deletion-query b/plugins/woocommerce/changelog/prepare-order-item-deletion-query
new file mode 100644
index 00000000000..e74f7d0e90a
--- /dev/null
+++ b/plugins/woocommerce/changelog/prepare-order-item-deletion-query
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Prepare order-item deletion queries with an integer placeholder.
diff --git a/plugins/woocommerce/includes/class-wc-post-data.php b/plugins/woocommerce/includes/class-wc-post-data.php
index 1aa4c691cb8..9d5e0cc0a66 100644
--- a/plugins/woocommerce/includes/class-wc-post-data.php
+++ b/plugins/woocommerce/includes/class-wc-post-data.php
@@ -608,13 +608,16 @@ class WC_Post_Data {
do_action( 'woocommerce_delete_order_items', $postid );
$wpdb->query(
- "
+ $wpdb->prepare(
+ "
DELETE {$wpdb->prefix}woocommerce_order_items, {$wpdb->prefix}woocommerce_order_itemmeta
FROM {$wpdb->prefix}woocommerce_order_items
JOIN {$wpdb->prefix}woocommerce_order_itemmeta ON {$wpdb->prefix}woocommerce_order_items.order_item_id = {$wpdb->prefix}woocommerce_order_itemmeta.order_item_id
- WHERE {$wpdb->prefix}woocommerce_order_items.order_id = '{$postid}';
- "
- ); // WPCS: unprepared SQL ok.
+ WHERE {$wpdb->prefix}woocommerce_order_items.order_id = %d;
+ ",
+ $postid
+ )
+ );
do_action( 'woocommerce_deleted_order_items', $postid );
}
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-post-data-test.php b/plugins/woocommerce/tests/php/includes/class-wc-post-data-test.php
index 1c9ba3227b7..24e522b1f56 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-post-data-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-post-data-test.php
@@ -5,11 +5,34 @@
* @package WooCommerce\Tests\Post_Data.
*/
+use Automattic\WooCommerce\RestApi\UnitTests\HPOSToggleTrait;
+use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper;
+use Automattic\WooCommerce\Utilities\OrderUtil;
+
/**
* Class WC_Post_Data_Test
*/
class WC_Post_Data_Test extends \WC_Unit_Test_Case {
+ use HPOSToggleTrait;
+
+ /**
+ * Ensure the HPOS tables exist before per-test transactions start.
+ */
+ public static function wpSetUpBeforeClass(): void {
+ $previous_hpos_state = OrderUtil::custom_orders_table_usage_is_enabled();
+ add_filter( 'wc_allow_changing_orders_storage_while_sync_is_pending', '__return_true' );
+
+ try {
+ self::setup_cot_tables();
+ if ( OrderUtil::custom_orders_table_usage_is_enabled() !== $previous_hpos_state ) {
+ OrderHelper::toggle_cot_feature_and_usage( $previous_hpos_state );
+ }
+ } finally {
+ remove_filter( 'wc_allow_changing_orders_storage_while_sync_is_pending', '__return_true' );
+ }
+ }
+
/**
* @testdox coupon code should be always sanitized.
*/
@@ -34,16 +57,36 @@ class WC_Post_Data_Test extends \WC_Unit_Test_Case {
}
/**
- * Order items should be deleted before deleting order.
+ * @testdox Should remove order items when permanently deleting an order.
+ * @testWith [false]
+ * [true]
+ *
+ * @param bool $hpos_enabled Whether HPOS is enabled.
*/
- public function test_before_delete_order() {
- $order = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_order();
- $items = $order->get_items();
- $this->assertNotEmpty( $items );
-
- WC_Post_Data::before_delete_order( $order->get_id() );
- $order = wc_get_order( $order->get_id() );
- $this->assertEmpty( $order->get_items() );
+ public function test_deleting_order_removes_items( bool $hpos_enabled ): void {
+ $previous_hpos_state = OrderUtil::custom_orders_table_usage_is_enabled();
+ add_filter( 'wc_allow_changing_orders_storage_while_sync_is_pending', '__return_true' );
+ remove_filter( 'query', array( $this, '_create_temporary_tables' ) );
+ remove_filter( 'query', array( $this, '_drop_temporary_tables' ) );
+
+ try {
+ $this->toggle_cot_authoritative( $hpos_enabled );
+
+ $order = OrderHelper::create_order();
+ $item_ids = array_keys( $order->get_items() );
+ $this->assertNotEmpty( $item_ids, 'The order should contain an item' );
+
+ $order->delete( true );
+
+ $this->assertFalse( WC_Order_Factory::get_order_item( reset( $item_ids ) ), 'The deleted order item should no longer be available' );
+ } finally {
+ if ( OrderUtil::custom_orders_table_usage_is_enabled() !== $previous_hpos_state ) {
+ $this->toggle_cot_authoritative( $previous_hpos_state );
+ }
+ add_filter( 'query', array( $this, '_create_temporary_tables' ) );
+ add_filter( 'query', array( $this, '_drop_temporary_tables' ) );
+ remove_filter( 'wc_allow_changing_orders_storage_while_sync_is_pending', '__return_true' );
+ }
}
/**