• I am wanting a way to restrict a customer to only be able to buy from a single parent category from my site in a purchase.

    I run a website which delivers food from restaurants and I have multiple restaurants all within parent categories, these then break down into sub menus.

    I want a way so when the user puts in a product from Restaurant A they can only now add other items from Restaurant A.

    I’ve searched all over for a plugin which I can’t find. please help me

Viewing 3 replies - 1 through 3 (of 3 total)
  • Thread Starter dave031284

    (@dave031284)

    I have this the following but doesn’t seem to work quite right

    function is_product_the_same_cat($valid, $product_id, $quantity) {
    global $woocommerce;
    // start of the loop that fetches the cart items
    foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
    $_product = $values[‘data’];
    $terms = get_the_terms( $_product->id, ‘product_cat’ );
    $target_terms = get_the_terms( $product_id, ‘product_cat’ ); //get the current items
    foreach ($terms as $term) {
    $cat_ids[] = $term->term_id; //get all the item categories in the cart
    }
    foreach ($target_terms as $term) {
    $target_cat_ids[] = $term->term_id; //get all the categories of the product
    }
    }
    $same_cat = array_intersect($cat_ids, $target_cat_ids); //check if they have the same category
    if(count($same_cat) > 0) return $valid;
    else {
    wc_add_notice( ‘This product is in another category!’, ‘error’ );
    return false;
    }
    }
    add_filter( ‘woocommerce_add_to_cart_validation’, ‘is_product_the_same_cat’,10,3);

    ############## and also ###################

    // 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 = $product_terms[0]->parent;
    $product_category_term = get_term ( $product_category, ‘product_cat’ );
    $product_category_parent = $product_category_term->parent;
    $product_top_category = $product_category_term->term_id;

    while ( $product_category_parent != 0 ) {
    $product_category_term = get_term ( $product_category_parent, ‘product_cat’ );
    $product_category_parent = $product_category_term->parent;
    $product_top_category = $product_category_term->term_id;
    }

    return $product_top_category;
    }

    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 ‘.$first_item_top_category_name.’ items in your cart.<br />To order a different category empty your cart first.</p>’;
    }
    }

    This method works, tested and tried. Add to your functions.php. file at the end.

     // 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         =  $product_terms[0]->parent;
                $product_category_term    =  get_term ( $product_category, 'product_cat' );
                $product_category_parent  =  $product_category_term->parent;
                $product_top_category     =  $product_category_term->term_id;
        
                while ( $product_category_parent  !=  0 ) {
                        $product_category_term    =  get_term ( $product_category_parent, 'product_cat' );
                        $product_category_parent  =  $product_category_term->parent;
                        $product_top_category     =  $product_category_term->term_id;
                }
        
                return $product_top_category;
        }
        
        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>';
                }
        }
    

    Awesome @mikon82, this works really well and just what I was looking for.
    All the best

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Restrict Woocommerce to only allowing purchases from a sinlge parent category’ is closed to new replies.