In Woocommerce, I'm trying to make a function that displays a message above the cart page when products with both categories are in the cart.
I'm trying to modify code that I found here but now it already shows the message when one of the categories is added instead of both:
add_action( 'woocommerce_before_cart', 'allclean_add_checkout_content', 12 );
function allclean_add_checkout_content() {
$special_cat2 = 'test-cat2';
$special_cat3 = 'test-cat3';
$bool = false;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$item = $cart_item['data'];
if ( has_term( $special_cat2 && $special_cat3, 'product_cat', $item->id ) )
$bool = true;
}
if ($bool)
echo '<div class="cartmessage">Warning! Beware of combining these materials!</div>';
}
There is some mistakes in your code like has_term()
does not support 2 terms separated with &&
and to get the product id from cart for custom taxonomy as product categories you need $cart_item['product_id']
instead that will also work with product variations……
To make that works when both product categories are in cart use this instead:
add_action( 'woocommerce_before_cart', 'allclean_add_checkout_content', 12 );
function allclean_add_checkout_content() {
$product_cats = array('test-cat2','test-cat3');
$found1 = $found2 = false;
foreach ( WC()->cart->get_cart() as $cart_item ) {
// The needed working product ID is $cart_item['product_id'] <====
if ( has_term( $product_cats[0], 'product_cat', $cart_item['product_id'] ) )
$found1 = true;
elseif ( has_term( $product_cats[1], 'product_cat', $cart_item['product_id'] ) )
$found2 = true;
}
if ( $found1 && $found2 )
echo '<div class="cartmessage">Warning! Beware of combining these materials!</div>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
The command $special_cat2 && $special_cat3
is an AND
calculation of two variables. Using the operator &&
will make PHP convert both variables to boolean. The result of this command is therefore also a boolean and true
in your case. So your call is equivalent to:
has_term(TRUE, 'product_cat', $item->id)
This is clearly not what you want.
What you want to do instead is to call has_term()
twice for each category:
if (has_term($special_cat2, 'product_cat', $item->id) && has_term($special_cat3, 'product_cat', $item->id)) {
... // Now both terms are present
}
The operaor &&
is different to a simple AND (&
), because it includes lazyness. This means, that if the first call of has_term()
returns false
already, the second call will not be done. This is perfect to reduce loading time.