在 WooCommerce 中下订单后删除产品

我正在使用最新版本的 WordPress 和 WooCommerce。


我知道这在上下文中可能看起来很奇怪,但我想在我的functions.php 中添加一个钩子,在下订单后按ID 从订单中删除某个产品。


到目前为止,这是我正在使用的内容:


add_action('woocommerce_new_order', 'custom_process_order', 10, 1);

function custom_process_order($order_id) {

    $order = new WC_Order( $order_id );

    $items = $order->get_items();

    foreach ($items as $item) {

        if ($item->get_id()==10766) {

          $order->remove_item( $item->get_id() );

        }

    }

    return $order_id;

}

如果该产品是订单的一部分,我正在尝试从订单中删除 ID 为 10766 的产品。我从这里的另一篇较旧的帖子中获取了这个,因此代码本身可能并不完美。它肯定是行不通的。


一些实验后更新:

在 Cameron Hurd 的帮助下,我尝试了以下代码:


add_action('woocommerce_new_order', 'custom_process_order', 10, 1);


function custom_process_order($order_id) {

    $order = new WC_Order( $order_id );

    $items = $order->get_items();

    foreach ($items as $item) {

        if ($item->get_id() === 10766) {

            $order->remove_item( $item->get_id() );

        }

    }


    $order->save_items();


    return $order_id;

}

这看起来很有希望,但是按下结帐按钮将提交一个空订单,同时还会抛出一个空的 WooCommerce 错误消息,让用户留在结帐页面上。


在此之后,我有 2 个想法:

1.)更改remove_item为wc_delete_order_item. 我真的不知道有什么区别,改变它似乎也没有什么不同。

2.) 更改钩子,使其在订单位于后端之后发生。我尝试将其从 更改woocommerce_new_order为woocommerce_thankyou. 然而,这打破了感谢页面,除了对订单没有做任何事情。


这就是我现在坐的:


add_action('woocommerce_checkout_create_order', 'custom_process_order', 10, 1);


function custom_process_order($order_id) {

    $order = new WC_Order( $order_id );

    $items = $order->get_items();

    foreach ($items as $item) {

        $current_item_id = $item->get_id();

        if ( $current_item_id === 10766) {

            $order->remove_item($current_item_id);

        }

    }


    $order->save_items();


    return $order_id;

}

仍在寻找有效的答案。


GCT1015
浏览 119回答 2
2回答

森栏

您可以使用woocommerce_checkout_order_processed操作挂钩,然后在其中指定产品 ID。所以你得到:function custom_process_order( $order_id ) {    if( ! $order_id ) return;    // get order object    $order = new WC_Order( $order_id );        // get order items = each product in the order    $items = $order->get_items();    foreach ( $items as $item ) {        $product = wc_get_product( $item['product_id'] );                if ( $product->get_id() == 10766 ) {            $order->remove_item( $item->get_id() );        }    }        // Calculate    $order->calculate_totals();        // Save    $order->save();}add_action( 'woocommerce_checkout_order_processed', 'custom_process_order', 10, 1 );

哔哔one

从中浏览代码abstracts/abstract-wc-order.php,remove_item方法所在的位置...我看到项目被添加到一个名为 的数组中items_to_delete。该变量再次出现在 中save_items,其中每个要删除的项目类都delete调用了它的方法。<?php// abstracts/abstract-wc-order.phpabstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Remove item from the order.&nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp;* @param int $item_id Item ID to delete.&nbsp; &nbsp; &nbsp;* @return false|void&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; public function remove_item( $item_id ) {&nbsp; &nbsp; &nbsp; &nbsp; $item&nbsp; &nbsp; &nbsp; = $this->get_item( $item_id, false );&nbsp; &nbsp; &nbsp; &nbsp; $items_key = $item ? $this->get_items_key( $item ) : false;&nbsp; &nbsp; &nbsp; &nbsp; if ( ! $items_key ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // Unset and remove later.&nbsp; &nbsp; &nbsp; &nbsp; $this->items_to_delete[] = $item;&nbsp; &nbsp; &nbsp; &nbsp; unset( $this->items[ $items_key ][ $item->get_id() ] );&nbsp; &nbsp; }&nbsp; &nbsp; // ...&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* Save all order items which are part of this order.&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; protected function save_items() {&nbsp; &nbsp; &nbsp; &nbsp; $items_changed = false;&nbsp; &nbsp; &nbsp; &nbsp; foreach ( $this->items_to_delete as $item ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $item->delete();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $items_changed = true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; $this->items_to_delete = array();&nbsp; &nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; }&nbsp; &nbsp; // ...}因此,您可以尝试$order->save_items()在自定义操作中的 foreach 循环之后调用:add_action('woocommerce_new_order', 'custom_process_order', 10, 1);function custom_process_order($order_id) {&nbsp; &nbsp; $order = new WC_Order( $order_id );&nbsp; &nbsp; $items = $order->get_items();&nbsp; &nbsp; foreach ($items as $item) {&nbsp; &nbsp; &nbsp; &nbsp; if ($item->get_id() === 10766) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $order->remove_item( $item->get_id() );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; $order->save_items();&nbsp; &nbsp; return $order_id;}
打开App,查看更多内容
随时随地看视频慕课网APP