I am using the code below to restrict two different category products to be added together into the cart, I have two categories “pickup” and “ship” product of these category can not be added together if a user tries to do so he gets an error message and cart get’s empty.
add_action( 'woocommerce_check_cart_items','prevent_multiple_category');
function prevent_multiple_category() {
$disallowed_categories = array( 'pickup', 'ship' );
$both_categories_in_cart = false;
$cart_items = WC()->cart->get_cart();
foreach ( $cart_items as $cart_item ) {
$product_id = $cart_item['product_id'];
$product_categories = get_the_terms( $product_id, 'product_cat' );
$product_categories_slugs = array_map( function( $term ) {
return $term->slug;
}, $product_categories );
$intersect = array_intersect( $product_categories_slugs, $disallowed_categories );
if ( ! empty( $intersect ) ) {
if ( $both_categories_in_cart ) {
//$woocommerce->cart->empty_cart();
wc_add_notice( __( 'You can not add Pickup Products and Shipping Products in the cart together.', 'text-domain' ), 'error' );
WC()->cart->empty_cart();
add_filter('woocommerce_cart_item_removed_notice_type', '__return_null');
break;
} else {
$both_categories_in_cart = true;
}
}
}
}
The issue I am getting is that if two different “pickup” category products are added together they get the same error as well same goes with the “ship” category products. Instead of restricting different category products to be added together I am not able to add different products from same cateogry together into the cart.
Any help please?
Thank you.
The code in its current form looks at the categories of the products in the cart, and if there are more than two products in the cart and any of the products are in the pickup
or ship
category, it adds the notice.
Try this (untested):
add_action( 'woocommerce_check_cart_items', static function () {
$cart_items = WC()->cart->get_cart();
$has_pickup = false;
$has_ship = false;
foreach ( $cart_items as $cart_item ) {
$has_pickup = $has_pickup || has_term( 'pickup', 'product_cat', $cart_item['product_id'] );
$has_ship = $has_ship || has_term( 'ship', 'product_cat', $cart_item['product_id'] );
if ( $has_pickup && $has_ship ) {
break;
}
}
$show_notice = $has_pickup && $has_ship;
if ( ! $show_notice ) {
return;
}
wc_add_notice( ... );
WC()->cart->empty_cart();
add_filter( 'woocommerce_cart_item_removed_notice_type', '__return_null' );
} );
There are of course other, possibly more elegant or performant, ways to solve this problem, but this should work, or at least point in the right direction (it is untested after all).
0