You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何克隆现有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 02:00:04