Reputation: 613
How would I go about configuring the Woocommerce cart to only allow one product category type in it at a time?
Upvotes: 2
Views: 6367
Reputation: 1114
Thanks LoicTheAztec for providing the great answer!
However, the parent product categories version does not fit to my case.
LoicTheAztec's version returns false when the products's category does not have parent, even those products have the same category.
Here's the modification of it to handle the above case.
add_filter( 'woocommerce_add_to_cart_validation', 'only_one_product_category_allowed', 20, 3 );
function only_one_product_category_allowed( $passed, $product_id, $quantity) {
$parent_term_ids = $item_parent_term_ids = array(); // Initializing
// Loop through the current product category terms to get the parent main category term if any.
// Otherwise we get the current product's own category.
foreach( get_the_terms( $product_id, 'product_cat' ) as $term ){
if ( $term->parent > 0 ){
$parent_term_ids[] = $term->parent; // Set the parent product category
} else {
$parent_term_ids[] = $term->term_id; // Set the category itself of the current product for later comparison
}
}
// Loop through cart items
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item ){
// Loop through the cart item product category terms to get the parent main category term if any.
// Otherwise we get the cart item's own category.
foreach( get_the_terms( $cart_item['product_id'], 'product_cat' ) as $term ){
if ( $term->parent > 0 ){
$item_parent_term_ids[] = $term->parent; // Set the parent product category
} else {
$item_parent_term_ids[] = $term->term_id; // Set the category itself of the cart item for later comparison
}
}
// Check if parent product categories don't match
if( ! array_intersect( $parent_term_ids, $item_parent_term_ids ) ){
// Displaying a custom notice
wc_add_notice( __('Only items from one product category are allowed in cart'), 'error' );
// Avoid add to cart
return false; // exit
}
}
return $passed;
}
Upvotes: 0
Reputation: 253784
The following code will allow adding to cart only items from one product category avoiding add to cart and displaying a custom notice:
add_filter( 'woocommerce_add_to_cart_validation', 'only_one_product_category_allowed', 20, 3 );
function only_one_product_category_allowed( $passed, $product_id, $quantity) {
// Getting the product categories term slugs in an array for the current product
$term_slugs = wp_get_post_terms( $product_id, 'product_cat', array('fields' => 'slugs') );
// Loop through cart items
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item ){
// Check if the product category of the current product don't match with a cart item
if( ! has_term( $term_slugs, 'product_cat', $cart_item['product_id'] ) ){
// Displaying a custom notice
wc_add_notice( __('Only items from one product category are allowed in cart'), 'error' );
// Avoid add to cart
return false; // exit
}
}
return $passed;
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
Addition (updated) - The same but only for parent product categories:
add_filter( 'woocommerce_add_to_cart_validation', 'only_one_product_category_allowed', 20, 3 );
function only_one_product_category_allowed( $passed, $product_id, $quantity) {
$parent_term_ids = $item_parent_term_ids = array(); // Initializing
// Loop through the current product category terms to get only parent main category term
foreach( get_the_terms( $product_id, 'product_cat' ) as $term ){
if( $term->parent > 0 ){
$parent_term_ids[] = $term->parent; // Set the parent product category
}
}
// Loop through cart items
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item ){
// Loop through the cart item product category terms to get only parent main category term
foreach( get_the_terms( $cart_item['product_id'], 'product_cat' ) as $term ){
if( $term->parent > 0 ){
$item_parent_term_ids[] = $term->parent; // Set the parent product category
}
}
// Check if parent product categories don't match
if( ! array_intersect( $parent_term_ids, $item_parent_term_ids ) ){
// Displaying a custom notice
wc_add_notice( __('Only items from one product category are allowed in cart'), 'error' );
// Avoid add to cart
return false; // exit
}
}
return $passed;
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
Upvotes: 9