Use $cart_item['data']->get_category_ids()
to retrieve the category IDs:
$category_ids = $cart_item['data']->get_category_ids(); // array
The category_ids
you see is not a direct item in the $cart_item
array:
var_dump( $cart_item['category_ids'] ); // null and PHP throws a notice
It’s an item in a protected property of the product data ($cart_item['data']
) which is an object, or a class instance — e.g. the class is WC_Product_Simple
for Simple products.
UPDATE
If you want to collect all the product category IDs, you can do it like so:
$cat_ids = array();
foreach ( wc()->cart->get_cart() as $cart_item_key => $cart_item ) {
$cat_ids = array_merge(
$cat_ids, $cart_item['data']->get_category_ids()
);
}
var_dump( $cat_ids );
UPDATE #2
You can use this to check if a product in the cart is in certain categories:
$cat_ids = array( 39 );
foreach ( wc()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( has_term( $cat_ids, 'product_cat', $cart_item['data'] ) ) {
echo 'Has category 39<br>';
} else {
echo 'No category 39<br>';
}
}
UPDATE #3/#4/#5
This should work as expected:
// Collect the category IDs.
$cat_ids = array();
foreach ( wc()->cart->get_cart() as $cart_item_key => $cart_item ) {
$cat_ids = array_merge(
$cat_ids, $cart_item['data']->get_category_ids()
);
}
// And here we check the IDs.
$cat_id = 39;
$count = count( $cat_ids );
if ( 1 === $count && in_array( $cat_id, $cat_ids ) ) {
echo 'Only in category 39';
} elseif ( $count && in_array( $cat_id, $cat_ids ) ) {
echo 'In category 39 and other categories';
} else {
echo 'No category 39';
}
Here’s an alternate version of the if
block above:
if ( $count && in_array( $cat_id, $cat_ids ) ) {
// Only one category.
if ( $count < 2 ) {
echo 'Only in category 39';
// Multiple categories.
} else {
echo 'In category 39 and other categories';
}
} else {
echo 'No category 39';
}