WC_Order->get_items() returns 空项目

WC_Order->get_items() returns empty items

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

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

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

我的最终目标是过滤掉 "Subscription" 类别的产品,但如果我做不到 $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()));
}

订单对象内容:

更新 1:

You can't use json_encode() on $order->get_items() as you will always get something like "257":{} (where 257 is the item ID) for each order item. So json_encode() fails encoding each order item data located in the array of items, as order items are protected.

Now the only way to JSON encode order items is to unprotect each order item using the WC_Data method get_data() and set it back in the order items array.

这可以使用 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()));

But it's not possible to help as your code is not testable: the $logger and $TAG variables are not defined in your code.

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

// 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
    }
}