Lordwhizy
Lordwhizy

Reputation: 143

Woocommerce - Prevent Adding items from two different categories to cart

I want to prevent users from adding products from different categories into cart at once. Say if the user navigates to another categories and tries to add product to cart, they get the cart cleared out first. Please anybody know how i might approach this? I am a newbie at things like this. Thanks

Upvotes: 7

Views: 6806

Answers (2)

David Manson
David Manson

Reputation: 216

Here is my solution for this (You can replace 'city' by 'product_cat' to make it work for product categories:

function validate_add_cart_item( $passed, $product_id, $quantity, $variation_id = '', $variations= '' ) {

    // Get the list of cities for the item to be added
    $product_cities = get_the_terms( $product_id, 'city' );
    $cities_array = array_map(function($city){
        return $city->slug;
    }, $product_cities);

    // Get the cart items
    $item_in_cart = WC()->cart->get_cart();

    // Check for each item if the city is different
    foreach ($item_in_cart as $item){
        $cities = get_the_terms( $item['product_id'], 'city' );
        foreach ($cities as $city){
            if(!in_array($city->slug, $cities_array)){
                $passed = false;
                wc_add_notice( __( 'You cannot mix products from two cities', 'domain' ), 'error' );
            }
        }
    }

    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'validate_add_cart_item', 10, 5 );

Upvotes: 0

Rebecca Dessonville
Rebecca Dessonville

Reputation: 640

I've solved this before. My write-up is here.

It differs slightly from your request in that instead of clearing the cart when they try to add a second category it keeps the original item in the cart and displays a warning.

For posterity:

<?php

// Enforce single parent category items in cart at a time based on first item in cart
function get_product_top_level_category ( $product_id ) {

    $product_terms            =  get_the_terms ( $product_id, 'product_cat' );
    $product_category_term    =  $product_terms[0];
    $product_category_parent  =  $product_terms[0]->parent;

    while ( $product_category_parent  !=  0 ) {
            $product_category_term    =  get_term($product_category_parent, 'product_cat' );
            $product_category_parent  =  $product_category_term->parent;
    }

    return $product_category_term;

}

add_filter ( 'woocommerce_before_cart', 'restrict_cart_to_single_category' );
function restrict_cart_to_single_category() {
        global $woocommerce;
        $cart_contents    =  $woocommerce->cart->get_cart( );
        $cart_item_keys   =  array_keys ( $cart_contents );
        $cart_item_count  =  count ( $cart_item_keys );

        // Do nothing if the cart is empty
        // Do nothing if the cart only has one item
        if ( ! $cart_contents || $cart_item_count == 1 ) {
                return null;
        }

        // Multiple Items in cart
        $first_item                    =  $cart_item_keys[0];
        $first_item_id                 =  $cart_contents[$first_item]['product_id'];
        $first_item_top_category       =  get_product_top_level_category ( $first_item_id );
        $first_item_top_category_term  =  get_term ( $first_item_top_category, 'product_cat' );
        $first_item_top_category_name  =  $first_item_top_category_term->name;

        // Now we check each subsequent items top-level parent category
        foreach ( $cart_item_keys as $key ) {
                if ( $key  ==  $first_item ) {
                        continue;
                }
                else {
                        $product_id            =  $cart_contents[$key]['product_id'];
                        $product_top_category  =  get_product_top_level_category( $product_id );

                        if ( $product_top_category  !=  $first_item_top_category ) {
                                $woocommerce->cart->set_quantity ( $key, 0, true );
                                $mismatched_categories  =  1;
                        }
                }
        }

        // we really only want to display this message once for anyone, including those that have carts already prefilled
        if ( isset ( $mismatched_categories ) ) {
                echo '<p class="woocommerce-error">Only one category allowed in cart at a time.<br />You are currently allowed only <strong>'.$first_item_top_category_name.'</strong> items in your cart.<br />To order a different category empty your cart first.</p>';
        }
}
?>

Upvotes: 8

Related Questions