【问题标题】:Can not get the product details from order_id on the new order hook function无法从新订单挂钩函数的 order_id 获取产品详细信息
【发布时间】:2017-01-12 04:41:23
【问题描述】:

使用 WooCommerce,在提交新订单后,我的 function.php 中有以下钩子:

add_action( 'woocommerce_new_order', 'create_job_openings');
function create_job_openings($order_id) {

    $order = new WC_Order($order_id);
    $items = $order->get_items();

    foreach ($order->get_items() as $key => $item) {
        $product_name = $item['name'];
        var_dump($product_name);
    }
}

上面的代码没有给我任何输出,即它没有进入 foreach 循环,这就是为什么 var_dump() 没有给我任何输出,但是如果我特别提到 order_id 就像 create_job_openings($order_id=517) 它可以工作,即使我在 @987654329 之前尝试了 echo $order_id @循环,它给了我order_id,那为什么它没有进入foreach循环呢?

注意:当我在 foreach 循环之前尝试 var_dump($items); 时,它给了我

array(0) {
} 

为什么下单后即使里面有商品也无法获取商品详情?

【问题讨论】:

  • 你检查$order_id真的来了吗??
  • 在函数中调用全局 woocommerce 做一件事
  • @LoicTheAztec wc_get_order 给了我正确的输出,太棒了!但它可以像 $items = $order->get_items() 一样使用吗?

标签: php wordpress woocommerce orders hook-woocommerce


【解决方案1】:

更新 2 — 可行的解决方案 (使用电子邮件通知挂钩)

问题在于,当使用电子邮件通知挂钩会触发一个操作2 次​​strong>,例如下一个新订单时(通知商店经理和通知客户)。

您想为处于“处理中”状态的订单使用此“新订单”事件。

为了避免使用新订单通知 WooCommerce 事件触发您的操作 2 次​​strong>,我们使用 'customer_processing_order' 而不是 'new_order'电子邮件 ID (通知事件)

这里我们不需要获取 $order 对象,因为我们在这个钩子函数中将它作为参数。

这是你的最终功能代码:

add_action( 'woocommerce_email_before_order_table', 'custom_action_on_completed_customer_email_notification', 10, 4 );
function custom_action_on_completed_customer_email_notification( $order, $sent_to_admin, $plain_text, $email ) {

    if( 'customer_processing_order' == $email->id ){ // for processing order status customer notification…
        foreach ($order->get_items() as $item_id => $item_values) {
            $product_name = $item_values['name'];
            echo $product_name;
            break; // (optional) stop loop to first item
        }
    }
}

这是对该问题的有效且有效的答案

相关工作答案:


更新 1 (挂钩替代)

尝试使用 woocommerce_thankyou 钩子,该钩子在订单处理后在审核订单上触发:

add_action( 'woocommerce_thankyou', 'create_job_openings', 10, 1 );
function create_job_openings( $order_id ) {
    if ( ! $order_id )
        return;
    
    $order = wc_get_order( $order_id );
    
    foreach ($order->get_items() as $item_id => $item_values) {
        $product_name = $item_values['name'];
        var_dump($product_name);
        break; // (optional) stop loop to first item
    }
}

(不适用于 OP)


你应该试试这个 wc_get_order() 这样的函数,你的代码将是:

add_action( 'woocommerce_new_order', 'create_job_openings', 10, 1);
function create_job_openings($order_id) {

    $order = wc_get_order( $order_id );
    $order_items = $order->get_items();

    foreach ($order_items as $item_id => $item_values) {
        $product_name = $item_values['name'];
        var_dump($product_name);
        break; // (optional) stops on first item
    }
}

你可以看看 How to get WooCommerce order details 里面解释了很多东西……

(不适用于 OP)

【讨论】:

    【解决方案2】:

    在 wordpress 中添加帖子时,您可以使用save_post 操作。更多访问:Link

    function wc_order_add_action($post_id, $post, $update)
    {
        $post_type = get_post_type($post_id);
    
        // If this isn't a 'shop_order' post, don't update it.
        if ("shop_order" != $post_type) return;
    
        $order = wc_get_order($post_id);
    
        foreach($order -> get_items() as $key => $item)
        {
            $product_name = $item['name'];
            var_dump($product_name);
        }
    }
    add_action('save_post', 'wc_order_add_action');
    

    【讨论】:

    • 为什么我需要 save_post?我只想让动作挂钩在新订单下达后执行某些操作
    • 订单添加为 wordpress 中的帖子。 @山姆
    • @sam woocommerce 插件商店订单作为数据库中的帖子类型“shop_order”。 :)
    • @sam 我已经更新了我的答案,请立即查看。希望它有效:)
    • 感谢您的回答,但我不想将每个订单另存为帖子!
    【解决方案3】:

    面临同样的问题。我通过将钩子更改为woocommerce_checkout_order_processed 来修复它。它适用于即时付款和货到付款,因为它在下订单后立即运行。请注意,这将在付款完成之前运行。因此,它与付款没有任何关系。

    用户单击继续结帐按钮,然后触发此挂钩。

    【讨论】:

      【解决方案4】:

      要从新订单中获取商品和产品详细信息,您只需为woocommerce_new_order 请求两个参数。第二个传递的参数将是新的订单对象。示例:

      add_action( 'woocommerce_new_order', 'so41605256_new_order', 10, 2 );
      function so41605256_new_order( $order_id, $order ) {
          // Directly access items from $order variable, do not use wc_get_order...
          foreach ($order->get_items() as $item_id => $item) {
              //...
          }
      }
      

      无论 WC 电子邮件配置如何,这都适用于以编程方式创建的订单和用户创建的订单。

      参考:WC_Order_Data_Store_CPT 核心类中的createupdate 方法。感谢this post 帮助我发现了这一点。

      【讨论】:

        猜你喜欢
        • 2016-05-14
        • 1970-01-01
        • 2012-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多