在 Woocommerce 3 中添加自定义结帐字段作为订单自定义元数据

Add custom checkout field as Order custom-meta data in Woocommerce 3

WooCommerce 3.0 出来之前,我的代码非常有效,可以在结账时将购物车中的自定义值保存到订单中。但从那以后,我无法为订单创建自定义元数据。

环境: Wordpress 4.9.4 & WooCommerce 3.3.3

挂钩

  1. add_action('woocommerce_checkout_update_order_meta', 'custom_meta_to_order', 20, 1);
  2. add_action('woocommerce_checkout_create_order', 'custom_meta_to_order', 20, 1);

第 1 个 Hook 是我尝试最多的那个,第 2 个只是一些文字的实验 changes mentioned in this topic

函数

以下函数-代码与钩号1相关:

if (!function_exists('custom_meta_to_order')) {
    function custom_meta_to_order($order_id, $values) {
        $order = wc_get_order( $order_id );

        $order->update_meta_data('_TESTKEYstart', 'Hello');

        if (isset($values['myValue'])) {
            $myValue = $values['myValue'];
            if (!empty($myValue)) $order->update_meta_data('_myKey', $myValue);
        }

        $order->update_meta_data('_TESTKEYend', 'Bye');

        $order->save();
    }
}

我还在 mySQL table table wp_woocommerce_order_itemmeta 中检查过是否至少有两个 _TESTKEY*-元条目已创建(因为它们没有条件)。

所以我的问题是:"What am I doing wrong?"

更新:您的代码中存在一些错误……

  • 两个钩子只有 1 个参数(不是 2 个,所以 $values 不存在)
  • 要获取您的自定义字段,您应该使用 $_POST['myValue']
  • 和其他东西,比如每个钩子都有不同的参数:
    • $order_id 对于 woocommerce_checkout_update_order_meta
    • $order 对于 woocommerce_checkout_create_order

下面我将 $_POST['myValue'] 替换为 $_POST['billing_country'],因为您没有提供此自定义结帐字段的代码…

所以这里有两种方法:

1) 对我来说最好的方法,正如所解释的 here:

if ( ! function_exists('custom_meta_to_order') ) {
    add_action( 'woocommerce_checkout_create_order', 'custom_meta_to_order', 20, 1 );
    function custom_meta_to_order( $order ) {

        $order->update_meta_data('_TESTKEYstart', 'Hello');

        if (isset($_POST['billing_country'])) {
            $myValue = $_POST['billing_country'];
            if (!empty($myValue)) $order->update_meta_data('_my_key', $myValue);
        }

        $order->update_meta_data('_TESTKEYend', 'Bye');
    }
}

代码进入您的活动子主题(或主题)的 function.php 文件。已测试并有效。


2) 另一种方式:

if ( ! function_exists('custom_meta_to_order') ) {
    add_action('woocommerce_checkout_update_order_meta', 'custom_meta_to_order', 20, 1);
    function custom_meta_to_order( $order_id ) {
        // get an instance of the WC_Order object
        $order = wc_get_order( $order_id );

        $order->update_meta_data('_TESTKEYstart', 'Hello');

        if (isset($_POST['billing_country'])) {
            $myValue = $_POST['billing_country'];
            if (!empty($myValue)) $order->update_meta_data('_my_key', $myValue);
        }

        $order->update_meta_data('_TESTKEYend', 'Bye');

        // Save the order data and meta data
        $order->save();
    }
}

代码进入您的活动子主题(或主题)的 function.php 文件。已测试并有效。

证明:

(在数据库wp_postmeta table中为这个订单ID):

Tested in WooCommerce version 3.3+


你也可以使用旧方法(有效):

if ( ! function_exists('custom_meta_to_order') ) {
    add_action('woocommerce_checkout_update_order_meta', 'custom_meta_to_order', 20, 1);
    function custom_meta_to_order( $order_id ) {

        update_post_meta( $order_id, '_TESTKEYstart', 'Hello' );

        if ( isset( $_POST['billing_country'] ) ) {
            $myValue = $_POST['billing_country'];
            if (!empty($myValue)) 
                update_post_meta( $order_id, '_my_key', $myValue);
        }

        update_post_meta( $order_id, '_TESTKEYend', 'Bye');
    }
}

代码进入您的活动子主题(或主题)的 function.php 文件。已测试并有效。


相关:Add extra meta for orders in Woocommerce

因为评论真的很难读(因为格式限制太多),这个答案只是对 .

的回应

我写了一个较长的答案,但它似乎已经消失了,所以我现在为更短的答案感到抱歉!

先是我们的误会

您了解我想使用产品的自定义值,但在我的情况下有点不同。我编写了一个外部应用程序,其中包含 wp-load.php 和 posted,然后将数据返回 product-page 放入购物车。

所以这里出现的问题是试图在结账时将购物车中的数据写入订单。

推荐的方法一开始没有用

您建议的推荐方式均无效。我也将它们剥离得如此之少,以至于它们应该可以工作并且只需在元数据中写入一些东西。我不知道这次是哪个 plugin/theme-function 恶作剧了我。

但是我能够解决问题

还有更多!只是因为我发现the blog-post where I found out in the past, how to do this and as addition to my personal luck the author wrote already the changes for WP3.0,与这个过程有关

还是你的post帮助了我

从那时起,您向我展示的错误一直困扰着我,因为很难用 Sublime 和 CodeIntel(以及我从 Symfony 本身开始)跟踪和检查所有内容,所以我决定购买 PHPStorm,它显示并允许我修复所有问题我弃用的 (legacy-using) 通过正确更新它们来运行。

(终于没有了 global-variables: 耶。)

我的意思是,显示内联参数和 deprecation-strokes 已经做得很好了。但是 bug-free 工作 code-intel/reference 不会在大项目中死掉真是太棒了。

这就是为什么我现在将您的答案标记为解决方案,谢谢。否则我可能会解决这个问题(感谢作者 blog-post),但仍然会坐在一个定时炸弹上。