如何克隆现有WC_Order_Item_Product对象以创建WooCommerce新订单
问题原因
你直接复用已持久化的WC_Order_Item_Product实例的逻辑存在缺陷:每一个从数据库读取的订单项实例都绑定了唯一的订单项ID和所属原订单ID,调用WC_Order->add_item()方法时,WooCommerce会直接更新该实例关联的订单ID字段,导致原订单的订单项被转移到新订单。
正确实现方式
不需要手动处理受保护属性,你可以通过新建空白订单项实例、复制原有项的所有业务数据的方式实现克隆,完全不影响原有数据库条目,修改后的核心逻辑如下:
function update ($reminder_id = null) { global $woocommerce; global $wpdb; global $aboprodukt_table_name; // TODO if reminder id if ( ! $reminder_id) { $neworders = []; // get all reminders from db and loop through them $aboprodukt_reminders = $wpdb->get_results( 'SELECT * FROM ' . $aboprodukt_table_name . ' ORDER BY ' . $aboprodukt_table_name . '.targetdate ASC'); foreach ($aboprodukt_reminders as $item ) { // 读取原有订单项 $original_order_item = new \WC_Order_Item_Product($item->orderitem); // 新建空白订单项,不绑定任何订单和原有ID $new_order_item = new \WC_Order_Item_Product(); // 复制原有订单项的所有业务数据 $new_order_item->set_props( [ 'product_id' => $original_order_item->get_product_id(), 'variation_id' => $original_order_item->get_variation_id(), 'quantity' => $original_order_item->get_quantity(), 'subtotal' => $original_order_item->get_subtotal(), 'total' => $original_order_item->get_total(), 'taxes' => $original_order_item->get_taxes(), 'meta_data' => $original_order_item->get_meta_data(), 'name' => $original_order_item->get_name(), ] ); // 复制所有自定义元数据 $original_order_item->copy_meta_data_to( $new_order_item ); // get order object $order = $original_order_item->get_order(); // get customer id $customer = $order->get_customer_id(); // TODO abstract order items // assign user, adresses if not existing yet, copy from last order if ( ! isset($neworders[$customer]) ) { // check all reminders $customer_array = $order->get_data(); $args = array( 'customer_id' => $customer, 'created_via' => 'Aboprodukt', 'add_order_note' => __('Aboprodukt Custom Order', 'aboprodukt'), ); $neworders[$customer] = \wc_create_order($args); // 可以在这里同步复制原订单的地址、配送信息 $neworders[$customer]->set_billing( $order->get_billing() ); $neworders[$customer]->set_shipping( $order->get_shipping() ); } // 添加克隆后的新订单项 $neworders[$customer]->add_item( $new_order_item ); $neworders[$customer]->calculate_totals(); $neworders[$customer]->save(); } return print_r($neworders,true); } }
补充说明
- 上面的实现完全丢弃了原有订单项的ID和关联订单ID,新订单项在保存时会生成全新的自增ID,不会修改原订单的任何数据
- 你还可以在创建新订单的逻辑中补充复制原订单的配送方式、优惠信息等字段,匹配业务需求
内容的提问来源于stack exchange,提问作者Anselm
相关产品推荐
相关产品推荐

