【问题标题】:WC_Order->get_items() returns empty itemsWC_Order->get_items() 返回空项目
【发布时间】:2020-10-06 11:51:35
【问题描述】:

使用钩子'woocommerce_order_status_completed'我可以得到$order_id然后用$order = wc_get_order($order_id)得到WC_Order对象。但是下面的$logger->add("send-order-debug", json_encode($order->get_items())返回的是空的item对象

{"257":{},"258":{},"259":{}}

我不知道为什么会发生这种情况,因为我可以从 woocommerce 订单页面看到该订单中有实际商品。有人知道发生了什么吗?

我的最终目标是过滤掉属于“订阅”类别的产品,但如果我做不到$item->get_product_id,这是不可能的

function send_order($order_id) {
    $order = wc_get_order($order_id);
    $logger = wc_get_logger();
    $logger->add("send-order-debug", json_encode($order->get_items()));
}

订单对象内容:

【问题讨论】:

    标签: php wordpress woocommerce orders woocommerce-subscriptions


    【解决方案1】:

    更新 1:

    您不能在$order->get_items() 上使用json_encode(),因为对于每个订单商品,您总会得到类似"257":{} (其中257 是商品ID)。因此,json_encode() 无法对位于商品数组中的每个订单商品数据进行编码,因为订单商品受到保护。

    现在对订单商品进行 JSON 编码的唯一方法是取消保护每个订单商品,使用 WC_Data 方法 get_data() 并将其设置回订单商品数组中。

    这可以使用array_map() 和自定义函数以紧凑的方式完成,例如:

    add_action( 'woocommerce_order_status_completed', 'send_order', 10, 2 );
    function send_order( $order_id, $order ) {
        // Unprotect each order item in the array of order items
        $order_items_data = array_map( function($item){ return $item->get_data(); }, $order->get_items() );
    
        $logger = wc_get_logger();
        $logger->add("send-order-debug", json_encode($order_items_data));
    }
    

    现在可以了。


    原答案

    WC_Order 对象已经是 woocommerce_order_status_completed 挂钩中包含的参数,因此在您的代码中应该是:

    add_action( 'woocommerce_order_status_completed', 'send_order', 10, 2 );
    function send_order( $order_id, $order ) {
        $order_items = $order->get_items();
    }
    

    这行得通……见this related answers threads……

    所以问题可能与您尝试使用以下方式发送订单商品的方式有关:

    $logger->add($TAG, json_encode($order->get_items()));
    

    但由于您的代码不可测试,因此无法提供帮助:$logger$TAG 变量未在您的代码中定义。

    现在要定位订阅产品,您将使用以下内容:

    // Loop through order items
    foreach( $order->get_items() as $item ) {
        $product = $item->get_product(); // get the WC_Product Object
        
        // Targeting subscription products only
        if ( in_array( $product->get_type(), ['subscription', 'subscription_variation'] ) ) {
            // Do something
        }
    }
    

    【讨论】:

    • 我非常感谢详细的回复,但它似乎仍然无法正常工作。我尝试使用包含的 WC_Order,但问题仍然存在。 $logger 仅用于调试目的。我将更新我的问题以包括以下内容:$logger = wc_get_logger()$TAG = "send-order-debug"。似乎在创建 WC_Order 时问题正在发生。当我打印 WC_Order 内容时,line_items 看起来一团糟:"line_items":{"257":{}, "258":{}, "259":{}}
    • @DallinDavis 我已经对此进行了测试,我发现了问题和解决方案。请参阅我的更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 2017-07-22
    • 2019-02-22
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多