无法从 order_id 的新订单挂钩函数中获取产品详细信息

Can not get the product details from order_id on the new order hook function

使用 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) 它有效,即使我在 foreach 循环之前尝试了 echo $order_id ,它给了我 order_id,那为什么不进入foreach循环呢?

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

array(0) {
} 

为什么新下单后里面有商品却无法获取商品详情?

Update 2 — The working solution (using an email notification hook)

问题是当使用电子邮件通知挂钩时可以触发一个动作 2 次,例如在下新订单时(商店经理的通知和客户的通知) .

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

To avoid your action to be fired 2 times using New order notification WooCommerce event, we use 'customer_processing_order' instead of 'new_order' email ID (notification event).

这里我们不需要获取 $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
        }
    }
}

这是对这个问题的有效答案

相关工作答案:


Update 1 (hook alternative)

尝试使用 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
    }
}

你可以看看 解释了很多东西……

(不适用于 OP)

在 wordpress 中添加 post 时,您可以使用 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');

遇到了同样的问题。我通过将挂钩更改为 woocommerce_checkout_order_processed 来修复它。它非常适合即时付款和货到付款,因为它会在下订单后立即 运行。请注意,这将在付款完成前 运行。所以,它与付款没有任何关系。

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

要从新订单中获取项目和产品详细信息,您只需为 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 电子邮件配置如何,这都适用于以编程方式创建的订单和用户创建的订单。

参考:createupdate 方法在 WC_Order_Data_Store_CPT 核心 class 中。感谢 帮助我发现了这一点。