WC_Abstract_Order::remove_order_items │ public │ WC 1.0
Remove all line items (products, coupons, shipping, taxes) from the order.
The items are cleared from the in-memory order immediately, but core data stores defer database deletion until the next call to save(). Custom stores overriding delete_items() without also overriding delete_items_by_ids() retain the historical synchronous behavior.
public function remove_order_items( $type = null ) {
// Guard against extension code passing non-string values. Anything not
// a string or null is ignored so it never reaches the deferred queue or
// the data store. Surface the misuse so it's traceable rather than silent.
if ( null !== $type && ! is_string( $type ) ) {
wc_doing_it_wrong(
__METHOD__,
/* translators: %s: PHP type that was passed instead of a string. */
sprintf( esc_html__( 'remove_order_items() expects a string item type or null; received %s.', 'woocommerce' ), esc_html( gettype( $type ) ) ),
'11.0.0'
);
return;
}
/**
* Trigger action before removing all order line items. Allows you to track order items.
*
* @param WC_Order $this The current order object.
* @param string|null $type Order item type. Default null.
*
* @since 7.8.0
*/
do_action( 'woocommerce_remove_order_items', $this, $type );
// Unsaved orders (id 0) have no persisted items — there's nothing to defer for deletion.
$has_persisted_items = $this->get_id() > 0;
$delete_synchronously = ! $this->data_store_supports_deferred_item_deletion();
if ( $delete_synchronously && $has_persisted_items ) {
// @phpstan-ignore-next-line -- Required order data store method forwarded by WC_Data_Store::__call().
$this->data_store->delete_items( $this, $type );
}
if ( ! empty( $type ) ) {
if ( $has_persisted_items && ! $delete_synchronously ) {
$item_ids = $this->get_persisted_item_ids( $type );
if ( $this->bulk_delete_all_items_pending ) {
$this->item_ids_to_bulk_delete = array_values(
array_unique(
array_merge( $this->item_ids_to_bulk_delete, $item_ids )
)
);
} else {
$this->item_types_to_bulk_delete[] = $type;
$this->item_ids_to_bulk_delete_by_type[ $type ] = array_values(
array_unique(
array_merge(
$this->item_ids_to_bulk_delete_by_type[ $type ] ?? array(),
$item_ids
)
)
);
}
}
$group = $this->type_to_group( $type );
if ( $group ) {
// Set to an empty array (rather than unset) so that subsequent get_items() calls
// return the in-memory "removed" state without re-reading the still-present rows
// from the data store.
$this->items[ $group ] = array();
}
} else {
if ( $has_persisted_items && ! $delete_synchronously ) {
$item_ids = $this->get_persisted_item_ids();
foreach ( $this->item_ids_to_bulk_delete_by_type as $typed_item_ids ) {
$item_ids = array_merge( $item_ids, $typed_item_ids );
}
$this->bulk_delete_all_items_pending = true;
$this->item_ids_to_bulk_delete = array_values(
array_unique(
array_merge( $this->item_ids_to_bulk_delete, $item_ids )
)
);
$this->item_types_to_bulk_delete = array();
$this->item_ids_to_bulk_delete_by_type = array();
}
$type_to_group = $this->get_item_types_to_group();
// Union with currently populated keys so any group already loaded into
// $this->items (including by direct manipulation) is reset too. This
// matches the historical "wipe everything" semantics that the original
// $this->items = array() provided.
$groups = array_unique(
array_merge( array_values( $type_to_group ), array_keys( $this->items ) )
);
foreach ( $groups as $group ) {
$this->items[ $group ] = array();
}
}
if ( $delete_synchronously ) {
/**
* This action is documented in save_items().
*
* @since 7.8.0
*/
do_action( 'woocommerce_removed_order_items', $this, $type );
}
}