在 WooCommerce 中下订单后删除产品
Remove product after an order has been placed in 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 的产品(如果该产品是订单的一部分)。
这是我从一个不同的、较旧的 post 此处获取的,因此代码本身可能并不完美。肯定不行。
经过一些实验更新:
在 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 错误消息,使用户留在结帐页面上。
在此之后我有两个想法:
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;
}
仍在寻找有效的答案。
浏览 abstracts/abstract-wc-order.php
中的代码,remove_item
方法所在的位置...我看到项目已添加到名为 items_to_delete
的数组中。该变量再次出现在 save_items
中,其中要删除的每个项目 class 都会调用其 delete
方法。
<?php
// abstracts/abstract-wc-order.php
abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
/**
* Remove item from the order.
*
* @param int $item_id Item ID to delete.
* @return false|void
*/
public function remove_item( $item_id ) {
$item = $this->get_item( $item_id, false );
$items_key = $item ? $this->get_items_key( $item ) : false;
if ( ! $items_key ) {
return false;
}
// Unset and remove later.
$this->items_to_delete[] = $item;
unset( $this->items[ $items_key ][ $item->get_id() ] );
}
// ...
/**
* Save all order items which are part of this order.
*/
protected function save_items() {
$items_changed = false;
foreach ( $this->items_to_delete as $item ) {
$item->delete();
$items_changed = true;
}
$this->items_to_delete = array();
// ...
}
// ...
}
因此,您可以尝试在自定义操作的 foreach 循环之后调用 $order->save_items()
:
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_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 );
我使用的是最新版本的 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 的产品(如果该产品是订单的一部分)。 这是我从一个不同的、较旧的 post 此处获取的,因此代码本身可能并不完美。肯定不行。
经过一些实验更新:
在 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 错误消息,使用户留在结帐页面上。
在此之后我有两个想法:
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;
}
仍在寻找有效的答案。
浏览 abstracts/abstract-wc-order.php
中的代码,remove_item
方法所在的位置...我看到项目已添加到名为 items_to_delete
的数组中。该变量再次出现在 save_items
中,其中要删除的每个项目 class 都会调用其 delete
方法。
<?php
// abstracts/abstract-wc-order.php
abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
/**
* Remove item from the order.
*
* @param int $item_id Item ID to delete.
* @return false|void
*/
public function remove_item( $item_id ) {
$item = $this->get_item( $item_id, false );
$items_key = $item ? $this->get_items_key( $item ) : false;
if ( ! $items_key ) {
return false;
}
// Unset and remove later.
$this->items_to_delete[] = $item;
unset( $this->items[ $items_key ][ $item->get_id() ] );
}
// ...
/**
* Save all order items which are part of this order.
*/
protected function save_items() {
$items_changed = false;
foreach ( $this->items_to_delete as $item ) {
$item->delete();
$items_changed = true;
}
$this->items_to_delete = array();
// ...
}
// ...
}
因此,您可以尝试在自定义操作的 foreach 循环之后调用 $order->save_items()
:
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_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 );