Using the hook 'woocommerce_order_status_completed'
I can get $order_id
then get the WC_Order object with $order = wc_get_order($order_id)
. But the following $logger->add("send-order-debug", json_encode($order->get_items())
returns empty item objects
{"257":{},"258":{},"259":{}}
I have no idea why this happening because I can see from the woocommerce orders page that there are actual items inside this order. Does anyone have any idea what is going on?
My end goal is to filter out products that are of category “Subscription” but this is impossible if I can’t do $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())); }
Advertisement
Answer
Update 1:
You can’t use
json_encode()
on$order->get_items()
as you will always get something like"257":{}
(where257
is the item ID) for each order item. Sojson_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
methodget_data()
and set it back in the order items array.
This can be done in a compact way using array_map()
with a custom function like:
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)); }
Now it works.
Original answer:
The WC_Order Object is already an included argument in woocommerce_order_status_completed
hook, so in your code it should be:
add_action( 'woocommerce_order_status_completed', 'send_order', 10, 2 ); function send_order( $order_id, $order ) { $order_items = $order->get_items(); }
That works… see this related answers threads…
So the problem is maybe related in the way you try to send the order items using:
$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.
Now to target subscription products you will use something like:
// 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 } }