首页 > 解决方案 > WC_Order->get_items() 返回空项目

问题描述

使用钩子'woocommerce_order_status_completed',我可以得到$order_idWC_Order 对象$order = wc_get_order($order_id)。但以下$logger->add("send-order-debug", json_encode($order->get_items())返回空项目对象

{"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()));
}

订单对象的内容:在此处输入图像描述

标签: phpwordpresswoocommerceorderswoocommerce-subscriptions

解决方案


更新1:

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

现在,对订单商品进行 JSON 编码的唯一方法是使用该方法取消对每个订单商品的保护,并将其设置回订单商品数组中。WC_Dataget_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();
}

这行得通……查看这个相关的答案线程……</p>

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

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

但由于您的代码不可测试,因此无法提供帮助:您的代码中未定义$loggerand变量。$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
    }
}

推荐阅读