在Woocommerce中为订单添加额外的元数据

34

我正在为我的网站创建一个自定义插件。

在这个插件的某些部分中,我需要为每个订单在wp_postmeta中存储额外的元数据。

我在我的插件类中添加了以下内容:

add_action ('woocommerce_before_checkout_process', array( &$this, 'add_item_meta', 10, 2) );

这是add_item_meta()函数:

function add_item_meta( $item_id, $values ) {
  wc_add_order_item_meta($item_id, '_has_event', 'yes' );
}

这个函数还没有完全开发好,但这些代码没有任何作用;我认为我需要使用另一个钩子,但我找不到合适的。

有人知道这方面的知识吗?

我还有一个关于$item_id的问题:这是woocommerce的全局变量,但我不能在我的插件中看到它!

我的意思是从我的插件中无法访问此变量或类似的内容!

4个回答

60

2018方法:

基于Guido W.P.的回答,您可以使用更轻便和有效的代码版本woocommerce_checkout_create_order动作挂钩,具体请参考(使用WC 3+ CRUD方法)

add_action('woocommerce_checkout_create_order', 'before_checkout_create_order', 20, 2);
function before_checkout_create_order( $order, $data ) {
    $order->update_meta_data( '_custom_meta_key', 'value' );
}

将代码放入您当前使用的子主题(或活动主题)的function.php文件中。

已在WooCommerce 3+中进行测试并工作(仅限此版本)


一些说明:

woocommerce_checkout_create_order 动作钩子仅在保存订单数据之前的一个步骤。请参见下面的 WC_Checkout create_order() 方法的摘录(包括两个钩子):

/**
 * Action hook to adjust order before save.
 * @since 3.0.0
 */
do_action( 'woocommerce_checkout_create_order', $order, $data );

// Save the order.
$order_id = $order->save();

do_action( 'woocommerce_checkout_update_order_meta', $order_id, $data );

return $order_id;

为什么要使用woocommerce_checkout_create_order:

  • 因为你不需要像以前一样使用$order = wc_get_order( $order_id );,因为在钩子函数中$order已经作为参数传递了。
  • 你也不需要使用$order->save();,因为这将在接下来的流程中执行(参见源代码)。
  • 自 WooCommerce 3 版本发布以来,就已经推出了这个钩子,并且它是为了同样的目的而设计的,允许使用所有可用的WC_Order方法。

所以只需在函数内加入一行代码即可。


这非常聪明,@LoicTheAztec! 我只有一个疑问:它是否像使用woocommerce_checkout_update_order_meta一样具有未来性? 看起来woocommerce_checkout_update_order_meta是由WooCommerce开发人员放置在那里的,目的是更新订单元数据。 我可能错了,但是为了特定目的使用另一个过滤器让我感到有点不舒服。 - coccoinomane
@GuidoWalterPettinari,您可以在同一个挂钩函数中使用代码来完成不同的目的,或者将两个不同的函数挂接在同一个挂钩上并设置不同的优先级...这并不是什么大问题:)...所以两种代码都可以正常工作...唯一的区别是,我的代码比您的代码轻一点,因为我没有回忆起WC_Order对象的实例,并且我不需要使用save()方法... - LoicTheAztec
嗨,Loic!你的解决方案确实比我的快,但我不会说这是唯一的区别。 根据过滤器名称,很可能WooCommerce团队希望我们使用过滤器woocommerce_checkout_update_order_meta更新订单元数据。 我的观点是,为了节省几毫秒的执行时间而忽略这个提示可能是不明智的,特别是因为WooCommerce的更新非常频繁,并且并不总是遵守向后兼容性。 我有点偏执,我知道。 - coccoinomane
1
@GuidoWalterPettinari 我不同意您的观点,因为 woocommerce_checkout_create_order 是用于CRUD设置器和获取器,并且与WC 3同时发布... 在CRUD设置器和获取器方法之前 *(也就是 WooCommerce 3 之前)*,唯一的方法是使用 update_post_meta() WP函数的 woocommerce_checkout_update_order_meta。所以没有问题,我在我的答案中只是提供了一个关于使用 CRUD 方法的良好替代方案。这就是全部。没什么大不了的... - LoicTheAztec
1
感谢您的澄清,@LoicTheAztec! 这很有道理,希望WooCommerce团队在某个时候能够澄清这个(小)问题。 祝您有一个愉快的一天, Guido - coccoinomane

32

1
如何将自定义元字段(分配给订购该项目的客户/用户)添加到订单元中? - Garconis
1
请注意,使用闭包作为钩子并不是一个好主意,因为您无法使用remove_action在以后删除它们。 - Reza Ramezanpour
1
请注意,现在应该使用 new WC_Order($order_id); 而不是 wc_get_order - Petschko

6
答案是: 我应该使用woocommerce_checkout_update_order_meta作为add_action,并且我应该简单地使用update_post_meta()添加额外的元数据到我的订单。
    function add_item_meta( $order_id ) {
            //global $woocommerce;
            update_post_meta( $order_id, '_has_event', 'yes' );
        } 

5

2016年的做法:

add_action('woocommerce_checkout_update_order_meta',function( $order_id, $posted ) {  
    update_post_meta( $order_id, 'my_custom_meta_key', 'my data' );  
} , 10, 2);
  • $order_id 是订单的id,存储为自定义文章类型。
  • $posted 包含来自 $_POST 的所有数据。

1
这段代码放在系统的哪里?在哪个文件中?这种方法会将自定义数据暴露给订单 API 调用,例如 https://shop.example.com/wc-api/v3/orders/1248 吗? - Rodrigo Murillo
您可以将此代码直接放入主题的functions.php文件中。WooCommerce会在订单创建并保存到数据库后立即运行该函数。 - gregdev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接