WooCommerce allow only 1 product per category

  • Update On February 15th, 2020
  • in WooCommerce
woocommerce only one product per category in the cart 800x300 - WooCommerce allow only 1 product per category

This post was last updated on February 15th, 2020 at 01:45 pm

This quick snippet can prevent your visitors from adding more than one (or pre-defined no.) product from a specific category to their cart. This PHP code snippet should go in your theme’s functions.php file.

// Allow only one(or pre-defined) product per category in the cart
add_filter( 'woocommerce_add_to_cart_validation', 'allowed_quantity_per_category_in_the_cart', 10, 2 );
function allowed_quantity_per_category_in_the_cart( $passed, $product_id) {

    $max_num_products = 1;// change the maximum allowed in the cart
    $running_qty = 0;

    $restricted_product_cats = array();

    //Restrict particular category/categories by category slug
    $restricted_product_cats[] = 'cat-slug-one';
    $restricted_product_cats[] = 'cat-slug-two';

    // Getting the current product category slugs in an array
    $product_cats_object = get_the_terms( $product_id, 'product_cat' );
    foreach($product_cats_object as $obj_prod_cat) $current_product_cats[]=$obj_prod_cat->slug;


    // Iterating through each cart item
    foreach (WC()->cart->get_cart() as $cart_item_key=>$cart_item ){

    	// Restrict $max_num_products from each category
        if( has_term( $current_product_cats, 'product_cat', $cart_item['product_id'] )) {

        // Restrict $max_num_products from restricted product categories
        //if( array_intersect($restricted_product_cats, $current_product_cats) && has_term( $restricted_product_cats, 'product_cat', $cart_item['product_id'] )) {

        	// count(selected category) quantity
            $running_qty += (int) $cart_item['quantity'];

            // More than allowed products in the cart is not allowed
            if( $running_qty >= $max_num_products ) {
                wc_add_notice( sprintf( 'Only %s '.($max_num_products>1?'products from this category are':'product from this category is').' allowed in the cart.',  $max_num_products ), 'error' );
                $passed = false; // don't add the new product to the cart
                // We stop the loop
                break;
          	}

        }
    }
    return $passed;
}

 

This code is tested on WooCommerce version 3.0+. Let me know in the comments if you find this code snippet useful or have any questions!.

About This Author

My name is Parameshwar Roy (P. Roy), and I am a web developer. This is my personal blog to record my own thoughts. Though I am not a natural writer, I love to share my experiences. Hope my experiences will be useful to you...read more about me

15 Comments

You can post comments in this post.


  • Hi,

    Thanks for this post, i need for 2 categories not for 1 category.
    Kindly reply back.

    Thanks

    Muhammad Talib 8 years ago Reply


  • Only one error in php 7.01: on line 2 need 3 parameters.

    add_filter( ‘woocommerce_add_to_cart_validation’, ‘allowed_quantity_per_category_in_the_cart’, 10, 3 );

    After fix that and several customizations this code works for me.
    Thanks!!!

    Jorge 7 years ago Reply


  • Hi,
    This is awesome, I was wondering if you could help me with adding a functionality to this code. I would like to add a restriction to this : The client should only be able to order samples and nothing else if he adds a sample to the cart.

    Many thanks in advance,

    Rgds,
    Emmanuel

    Emmanuel 7 years ago Reply


  • It works great, but after I have added a product (i.e. belongs to a restricted category) into cart, it doesn’t allow me to add another product (i.e. belongs to a normal and not restricted category) into the cart. Why is that? Did I make a mistake?

    Thanks.

    Victor 7 years ago Reply


    • Parameshwar Roy Proy 150x150 - WooCommerce allow only 1 product per category

      The snippets mentioned above allowed only 1 product to be added to the cart from ANY CATEGORY.

      P. Roy 7 years ago Reply


    • Uncomment the If statement and delete the {. If you do not delete { you will wet an error

      That worked for me.

      Raúl 7 years ago Reply


  • Victor, this also happens to me. I did comment out the foreach on line 10, and uncomment the line 11 and change the “sample” to my category slug. But i can now only add 1 product from also all the other categories 🙁 I have temporary disabled this until i find a fix. I hope You can help 🙂

    Anders Jytzler 7 years ago Reply


    • Parameshwar Roy Proy 150x150 - WooCommerce allow only 1 product per category

      I have made some changes to the snippets. Give it a try.

      P. Roy 7 years ago Reply


  • Hi works fine. Returns passed == false. Ok. Although passed is equal to 0, it continues to add to the cart. Why? Any ideas?

    jose luis 7 years ago Reply


    • if you want remove last item you can use
      // Removing the cart item
      WC()->cart->remove_cart_item($cart_item_key);

      then i have a problem. When produt have variations dont’t call the function
      add_filter( ‘woocommerce_add_to_cart_validation’, ‘allowed_quantity_per_category_in_the_cart’, 10, 2 );

      any idea to call other types ?

      i saw this example but i don’t know how can i use

      $passed_validation = apply_filters( ‘woocommerce_add_to_cart_validation’, true, $product_id, $quantity, $variation_id, $variations );
      add_action( ‘woocommerce_add_to_cart_validation’, ‘allowed_quantity_per_category_in_the_cart’, 1, 5 );

      jose luis 7 years ago Reply


  • Works great for me! I just commented out the first if statement and am using the second one (which checks for my restricted categories). Thanks!

    Jon 7 years ago Reply


  • Works great on my side. I had to comment out the first if statement, which restricted all categories and uncommented the second if statement which checks the restricted categories only. Thanks for the code.

    Samuel Basash 6 years ago Reply


  • hello how are you not working with woocommerce 3.5.2
    This is injecting code into my header
    I’m using a child theme.

    Chrystelle 6 years ago Reply


  • This is a really useful function for my application, thanks.

    When I test the code everything works as expected. Because I am using a custom url “mydomain/?add-to-cart =123” when the limit is exceeded the “woocommerce_cart_redirect_after_error” doesn’t have anywhere to go and so dumps the user on the home page. Is there any way to handle this “error” case better? I mean change the redirect so that it either stays on the product page or redirects to the cart?

    Thanks in anticipation
    Russell

    russell 6 years ago Reply


  • I have tried this code it was working smoothly but after recent wordpress update it stop working.

    Here is my code.

    add_filter( ‘woocommerce_add_to_cart_validation’, ‘allowed_quantity_per_category_in_the_cart’, 10, 2 );
    function allowed_quantity_per_category_in_the_cart( $passed, $product_id) {
    $max_num_products = 1; // change the maximum allowed in the cart
    $running_qty = 0;
    $restricted_product_cats = array();
    //Restrict particular category/categories by category slug
    $restricted_product_cats[] = ‘games’;
    $restricted_product_cats[] = ‘console’;
    // Getting the current product category slugs in an array
    $product_cats_object = get_the_terms( $product_id, ‘product_cat’ );
    foreach($product_cats_object as $obj_prod_cat) $current_product_cats[]=$obj_prod_cat->slug;
    // Iterating through each cart item
    foreach (WC()->cart->get_cart() as $cart_item_key=>$cart_item ){
    if( array_intersect($restricted_product_cats, $current_product_cats) && has_term( $restricted_product_cats, ‘product_cat’, $cart_item[‘product_id’] )) {
    $running_qty += (int) $cart_item[‘quantity’];
    // More than 1 allowed products in the cart is not allowed redirect to checkout
    if( $running_qty >= $max_num_products ) {
    $passed = false; // don’t add the new product to the cart
    return get_permalink( 19 ); //Checkout page ID
    }
    }
    }
    return $passed;
    }

    Group of Oceninfo 6 years ago Reply


Leave A Reply