While many plugins treat all products as if they’re the same, your client may not want to for your store’s needs. For example, shop owners may want to show Checkout Field Editor fields only for certain product types, show a mailing list opt in for membership products only, or add a banner at checkout if a customer is purchasing an item from a specific category.

As such, it can be useful to have some quick template code handy for making customizations that check if a product in the cart is within a particular category.

This tutorial is for developers with basic – intermediate PHP / WooCommerce familiarity

There are usually a couple uses for this — you may want to check if any product in the cart is from a category, or you may want to check if all products in the cart are from a category.

Check if any WooCommerce cart product is from a category

If you want to see whether the WooCommerce cart contains a particular category, regardless of whether all products are in the category (or how many), then you can use a simple flag and a has_term() check for your desired product category. We’ll:

  1. Set our flag to false
  2. Loop through all products in the cart, checking for our category
  3. If we find a product that is in this category, set our flag to true and break out of the loop (as we don’t need to check every product once we’ve found one within our desired category)
// set our flag to be false until we find a product in that category
$cat_check = false;
        
// check each cart item for our category
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
            
    $product = $cart_item['data'];
    
    // replace 'membership' with your category's slug
    if ( has_term( 'membership', 'product_cat', $product->id ) ) {
        $cat_check = true;
        // break because we only need one "true" to matter here
        break;
    }
}
        
// if a product in the cart is in our category, do something
if ( $cat_check ) {
    // we have the category, do what we want
}

In the last part, once you have if ( $cat_check ) evaluating to true, you know that you have your desired category in the cart at least once. You can add your code to do whatever it is you’d like to do (such as display a notice), then hook this into the cart template, checkout template, or wherever needed.

Check if all products in the WooCommerce cart are from a category

What if you have a customization that should only apply if all products in the cart are from a given category? For example, if all products are in a category for “gifts”, perhaps you want to display a note that a packing slip with prices will not be included in the shipped parcel. Or, you could check if all products are in a “Freight” category (or have a “Freight” shipping class, a shipping classes are taxonomies too), and display a notice that handling takes a couple extra days.

For that, we can use an array of checks, and then add a true / false value for every product. This way, we can see if we have all “true” values, indicating that all products are within a particular category.

// holds checks for all products in cart to see if they're in our category
$category_checks = array();
        
// check each cart item for our category
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
            
    $product = $cart_item['data'];
    $product_in_cat = false;
    
    // replace 'membership' with your category's slug
    if ( has_term( 'membership', 'product_cat', $product->id ) ) {
        $product_in_cat = true;
    }
            
    array_push( $category_checks, $product_in_cat );
}
        
// if all items are in this category, do something
if ( ! in_array( false, $category_checks, true ) ) {
    // do what we came here to do
}

Following that? You can also make it a bit simpler now that you see what it’s doing. You could replace:

foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
            
    $product = $cart_item['data'];
    $product_in_cat = false;
    
    // replace 'membership' with your category's slug
    if ( has_term( 'membership', 'product_cat', $product->id ) ) {
        $product_in_cat = true;
    }
            
    array_push( $category_checks, $product_in_cat );
}

with a simpler check:

foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
            
    $product = $cart_item['data'];
    $product_in_cat = has_term( 'membership', 'product_cat', $product->id );
    
    array_push( $category_checks, $product_in_cat );
}

Since we want the value of $product_in_cat to be equal to the has_term() check, we can just set it equal to this check itself instead of saying “If the product is in this category, add a true into the array, otherwise keep it false.”

Checking the WooCommerce Cart for Product Categories

In either situation, as you always have access to the WC()->cart object on the frontend of the site, you can perform these checks and execute your code as needed, whether you’re at checkout, in the shop archives, or perhaps on a blog post, allowing you to perform customizations easily based on the categories within the cart.

Published by Beka Rice

Beka leads product direction for SkyVerge and technical documentation. She spends a lot of time on research and interviews, but likes to write so she has an excuse to spend more time jamming out to anything from The Clash to Lady Gaga.

17 Comments

  1. This saved me many hours of work (‘search’ in fact)! Many thanks!

  2. Hi Beka,

    I would like to use this code to be able to stop anyone from advancing to the checkout unless they had a specific category in their basket. Any ideas how I can achieve this? So, I have a category of standard and another called sibling. Standard must be in the cart in order to advance to checkout.

  3. Hi Beka,
    nice to write to you again after a few time. 🙂 Hope you’re good!
    Listen… thanks for sharing those tips above, very good post!
    I tried to use your snippet in order to automatically add a gift in the cart IF ONLY this one already has a specific brand product (I use Woocommerce Brands).
    My snippet adds the gift but as many times as it wants, randomly. How can I fix this?
    `add_action( ‘init’, ‘robertocavalli’ );
    // set our flag to be false until we find a product in that category
    function robertocavalli(){
    if ( ! is_admin() ) {
    global $woocommerce;
    $cat_check = false;
    $product_id = 20185;

    // check each cart item for our category
    foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $cart_item ) {

    $product = $cart_item['data'];

    // replace 'membership' with your category's slug
    if ( has_term( 'roberto-cavalli-home', 'product_brand', $product->id ) ) {
    $cat_check = true;
    // break because we only need one "true" to matter here
    break;
    }
    }

    }

    // if a product in the cart is in our category, do something
    if ( $cat_check ) {
    // we have the category, do what we want
    $woocommerce->cart->add_to_cart( $product_id );
    }
    }`

    • Alessandro ,

      Here’s my suggestion:

      Use the below to count the number of gift items
      $total_gifts= 0;

      //loop through all cart products
      foreach ( $woocommerce->cart->cart_contents as $product ) {
      // See if any product is from the gifts and then total those

      if ( has_term( 'giftcategory', 'product_cat', $product['product_id'] ) ) {
      $total_gifts += $product['quantity'];
      }

      (You can also modify your cat check loop so you can avoid having two for loops)

      Edit your code to include another if statement

      // if a product in the cart is in our category, do something
      if (( $cat_check ) && ($total_gifts < 1)){
      $woocommerce->cart->add_to_cart( $product_id );
      }

      And I would use if( is_cart() || is_checkout() ) instead of if ( ! is_admin() )

      Hope this helps

      • Hi Pradeep, i have the same problem as Alessandro.
        I’ve used Alessandro`s snippet but please could you explain how i have to use your snippet?

        For me your snippet doesn´t work, but i think i´m doing something wrong. :-/

        Thanks in advance, Hasi

        • Thanks Pradeep M. for your reply! Didn’t realize that someone replied to me! 3 months has passed and in the meantime I had to get rid of my snippet because it wasn’t working at all…
          I will try and let you know. 🙂

        • Hello Hasi,

          It’s great to hear that someone at least trying my snippets 😀 Do you want to share your code and exact issues you are experiencing so I can look into it in detail?

          Regards,

  4. Such a great post.

    Thanks a lot!

    • Hello Pradeep, first of all thanks for your answer!

      This is the snippet i currently use:

      function add_product_to_cart(){
      $product_id = 100;
      $cat_check = false;

      // check each cart item for our category
      foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {

      $product = $cart_item['data'];

      if ( has_term( 'sample-productcategory', 'product_cat', $product->id ) ) {
      $cat_check = true;
      // break because we only need one "true" to matter here
      break;
      }

      }

      // if a product in the cart is in our category, do something
      if ( $cat_check ) {
      WC()->cart->add_to_cart( $product_id );
      }

      }
      ‘add_action(‘woocommerce_add_to_cart’, ‘add_product_to_cart’);

      The problem is, that i get this errror message if product is added to cart: “You cannot add another “Here the product name” to your cart.”
      I’ve started with Alessandro’s snippet and tried to add your code, but without success.
      It would be great if you could point me to the right direction.

      Regards, Hasi

      • Hello Hasi,

        Since posting that code snippet, I’ve changed my code so it can handle duplicates and few other things that we needed for a particular site. Using that, I wrote the below for you. Give it a try and let me know if it works or not for you.

        add_action( ‘woocommerce_check_cart_items’, ‘check_total’ );
        function check_total() {
        // Only run on Cart or Checkout pages
        if( is_cart() || is_checkout() ) {
        global $woocommerce, $product;
        $total_quantity = 0; //sample-productcategory
        $total_gquantity = 0; //gift
        $i = 0;

        $product_id = 148; //replace it with your gift product ID

        //loop through all cart products
        foreach ( $woocommerce->cart->cart_contents as $product ) {
        if ( has_term( 'sample-productcategory', 'product_cat', $product['product_id'] ) ) {
        $total_quantity += $product['quantity'];
        }

        if ( has_term( 'gift-category', 'product_cat', $product['product_id'] )) {
        $total_gquantity += $product['quantity'];
        }
        }

        if ($total_quantity == 0 ) && ($total_gquantity > 0 )) {
        // Get the gift item's unique ID within the Cart
        $prod_unique_id = WC()->cart->generate_cart_id( $product_id );
        // Remove it from the cart by un-setting it
        unset( WC()->cart->cart_contents[$prod_unique_id] );
        }
        else
        if (($total_quantity > 0 ) && ($total_gquantity == 0 )){
        WC()->cart->add_to_cart( $product_id );
        }
        }
        }

  5. Thanks, this was very helpful!

  6. Maybe off-topic, but…I found a snippet to show the product’s Category in the Cart, and have been using it in a copy of Cart.php in the child theme. Is it possible to use the snippet my functions.php instead, and “hook” it into the cart template, so I don’t have to edit the Cart.php after major updates?

    Here’s that snippet:
    $terms = get_the_terms( $product_id, ‘product_cat’ );
    foreach ($terms as $term) { $product_cat = $term->name; }
    echo ‘

    Category:‘.$product_cat.’

    ‘;

  7. Hi Bekka,

    I’ve been a silent follower for years. Thanks for all you do?

    using your first snippet, I get the following error:
    Fatal error: Call to a member function get_cart() on a non-object in home/fuu/public_html/etc/etc/functions.php

    I’m using WP version 4.8 and WC version 3.1.0 and a vanilla twentyseventeen theme (for development). Any chance the major updates in WC 3.0 affect the performance of this function?

    Thank you again!

  8. Gracias a tu ayuda Pude configurar un Sistema de Pago Específico dependendiendo de las categorías de producto en el carrito, almacenándolas en un array. luego haciendo comparaciones…

    Gracias Beka from Spain.

  9. Hi Beka, thank you for the snippet!

    I was curious what if our category has two words (supplies package)?

    Thank you!
    Luke

Hmm, looks like this article is quite old! Its content may be outdated, so comments are now closed.