2
votes

I am trying to get the product categories for the woocommerce order item at woocommerce_checkout_create_order_line_item hook.

I am able to successfully get the product_id (thanks to help I got here) but now trying to get the product's categories the array comes back empty trying $product->get_categories() and alternatively trying wc_get_product_category_list($product->get_id().

I can't figure out what I am doing wrong.

add_action('woocommerce_checkout_create_order_line_item', 
'add_order_item_custom_meta', 10, 4 );
function add_order_item_custom_meta( $item, $cart_item_key, $cart_item, $order ) {

$product = $item->get_product(); // The WC_Product instance Object

$cat_names = $product->get_categories(); // one attempt  
$cat_names = wc_get_product_category_list($product->get_id()); // another attempt

$arrlength = count($cat_names);

for($x = 0; $x<$arrlength; $x++) {
$cat_name = $cat_names[$x];
}

$item->update_meta_data( '_raw_product_id', $product->get_id() ); 
$item->update_meta_data( '_raw_product_name', $cat_name ); 

}

So the add_action and the function work. The "$product=..." works and I can use it below in the 2nd to the last line of code as $product->get_id() and the correct value is stored as metadata as desired.

So since $product->get_id() works I thought it logical that $product->get_categories() would work. But it returns a null array.

I then read somewhere that it was deprecated and I should use wc_get_product_category_list. So I tried that and also no luck.

So I am now stuck and can't figure out what is wrong with my code. Thanks for any help.

1

1 Answers

2
votes

As you mentioned get_categories() method of WC_Product class is deprecated. Instead you can use get_category_ids() method. However this method returns product category IDs, and It seems that you need category names so we can get the names from WP_Term objects.

Final code would be something like this:

add_action('woocommerce_checkout_create_order_line_item', 'add_order_item_custom_meta', 10, 4 );
function add_order_item_custom_meta($item, $cart_item_key, $cart_item, $order)
{
    $product = $item->get_product(); // The WC_Product instance Object
    $cat_ids = $product->get_category_ids(); // returns an array of cat IDs
    $cat_names = [];    

    foreach ( (array) $cat_ids as $cat_id) {
        $cat_term = get_term_by('id', (int)$cat_id, 'product_cat');
        if($cat_term){
            $cat_names[] = $cat_term->name; // You may want to get slugs by $cat_term->slug
        }
    }

    $item->update_meta_data( '_raw_product_id', $product->get_id() );
    $item->update_meta_data( '_raw_product_name', $cat_names );
}

Note: foreach loop is the preferred way of doing this kind of stuff (instead of using a for loop).