Search code examples
phpwordpresswoocommercecarthook-woocommerce

Exclude certain categories when automatically adding products to the cart WooCommerce


In WooCommerce, I use a code that auto adds packaging when adding any dish to the cart.

function add_delivery_charge_to_cart( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    $lunchbox_id  = 5737; // "LunchBox" to be added to cart
    $pakket_id = 5738; // "Pakket" to be added to cart

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // Check if "LunchBox" product is already in cart
        if( $cart_item['data']->get_id() == $lunchbox_id ) {
            $lunchbox_key = $cart_item_key;
            $lunchbox_qty = $cart_item['quantity'];
        }

        // Check if "Pakket" product is already in cart
        if( $cart_item['data']->get_id() == $pakket_id ) {
            $pakket_key = $cart_item_key;
            $pakket_qty = $cart_item['quantity'];
        }       
    }

    // Get total items in cart, counts number of products and quantity per product
    $total_items_in_cart = WC()->cart->get_cart_contents_count();

    // If product "LunchBox" is in the cart, we check the quantity to update it if needed
    if ( isset($lunchbox_key) && $lunchbox_qty != $total_items_in_cart ) {
        // Lunchbox total = total_items_in_cart 
        $lunchbox_total = $total_items_in_cart;

        // Isset lunchbox qty, lunchbox total - lunchbox qty
        if ( isset($lunchbox_qty) ) {
            $lunchbox_total = $lunchbox_total - $lunchbox_qty;
        }

        // Isset pakket qty, lunchbox total - pakket qty        
        if ( isset($pakket_qty) ) {
            $lunchbox_total = $lunchbox_total - $pakket_qty;
        } 

        // Set quantity, lunchbox
        $cart->set_quantity( $lunchbox_key, $lunchbox_total );

    } elseif ( !isset($lunchbox_key) && $total_items_in_cart > 0 ) {
        // Product "LunchBox" is not in cart, we add it
        $cart->add_to_cart( $lunchbox_id, $total_items_in_cart );
    }

    // Total items in cart greater than or equal to 3
    if ( $total_items_in_cart >= 3 ) {
        // Pakket total = total_items_in_cart 
        $pakket_total = $total_items_in_cart;

        // Isset lunchbox qty, pakket total - lunchbox qty
        if ( isset($lunchbox_qty) ) {
            $pakket_total = $pakket_total - $lunchbox_qty;
        }

        // Isset pakket qty, pakket total - pakket qty      
        if ( isset($pakket_qty) ) {
            $pakket_total = $pakket_total - $pakket_qty;
        }       


        // Pakket total = pakket_total / 3 = floor(result)
        // Floor = round fractions down, rounding result down
        $pakket_total = floor( $pakket_total / 3 );

        // If product "Pakket" is in cart
        if ( isset($pakket_key) ) {         
            $cart->set_quantity( $pakket_key, $pakket_total );
        } elseif ( !isset($pakket_key) ) {
            // Product "Pakket" is not in cart, we add it
            $cart->add_to_cart( $pakket_id, $pakket_total );
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'add_delivery_charge_to_cart', 10, 1 );

By default, the packaging is automatically added to all products. But for me this is wrong.

I need to exclude certain categories, such as "Drink" and "Bread" so that packaging is not added along with each product from these categories.

I know that can add the following code:

// Excluded product categories in this array (Can be IDs, slugs or names)
$excl_cats = array( 'drink', 'bread' ); 

and conditions:

if( ! has_term( $excl_cats, 'product_cat', $product_id ) )

Only I do not know how to do it correctly in the above code.

I will be happy for your help!


Solution

  • Whenever a product contains the particular category, the quantity of that product is added to the $category_qty_total variable. This total is subtracted afterwards from the number of total items in the shopping cart

    /**
     * Calculate the number of lunchboxes and package, based on the number of products in cart.
     */ 
    function add_delivery_charge_to_cart( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
            return;
    
        /********** SETTINGS **********/
    
        $lunchbox_id  = 5737; // "LunchBox ID" to be added to cart
        $pakket_id = 5738; // "Pakket ID" to be added to cart
        $exclude_categories = array( 'drink', 'bread' ); // Exclude these categories
    
        $category_qty_total = 0; // Total of category quantity items, Don't edit!!
    
        /********** LOOP THROUGH CART ITEMS **********/
    
        foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
            // Get product id
            $product_id = $cart_item['data']->get_id();
    
            // Get product quantity
            $product_qty = $cart_item['quantity'];
    
            // Check if "LunchBox" product is already in cart
            if( $product_id == $lunchbox_id ) {
                $lunchbox_key = $cart_item_key;
                $lunchbox_qty = $product_qty;
            }
    
            // Check if "Pakket" product is already in cart
            if( $product_id == $pakket_id ) {
                $pakket_key = $cart_item_key;
                $pakket_qty = $product_qty;
            }
    
            // Check if product belongs to a certain category
            if( has_term( $exclude_categories, 'product_cat', $product_id ) ) {
                $category_qty_total += $product_qty;
            }
        }
    
        /********** CALCULATE THE TOTALS, SO "LUNCHBOX", "PAKKET" & CATEGORIES ARE NOT USED IN THE TOTALS **********/
    
        // Get total items in cart, counts number of products & quantity per product
        $total_items_in_cart = $cart->get_cart_contents_count();
    
        // Total items in cart - category quantity total
        $total_items_in_cart -= $category_qty_total;
    
        // Lunchbox total = total_items_in_cart & pakket total = total_items_in_cart 
        $lunchbox_total = $total_items_in_cart;
        $pakket_total = $total_items_in_cart;
    
        // Isset lunchbox qty -> lunchbox total - lunchbox qty & pakket total - lunchbox qty
        if ( isset($lunchbox_qty) ) {
            $lunchbox_total -= $lunchbox_qty;
            $pakket_total -= $lunchbox_qty;     
        }
    
        // Isset pakket qty -> lunchbox total - pakket qty & pakket total - pakket qty   
        if ( isset($pakket_qty) ) {
            $lunchbox_total -= $pakket_qty;
            $pakket_total = $pakket_total - $pakket_qty;
        }
    
        /********** APPLY NEW TOTALS TO LUNCHBOX & PAKKET **********/
    
        // If product "LunchBox" is in cart, we check the quantity to update it if needed
        if ( isset($lunchbox_key) && $lunchbox_qty != $total_items_in_cart ) {
            // Set quantity, lunchbox
            $cart->set_quantity( $lunchbox_key, $lunchbox_total );
    
        } elseif ( !isset($lunchbox_key) && $total_items_in_cart > 0 ) {
            // Product "LunchBox" is not in cart, we add it
            $cart->add_to_cart( $lunchbox_id, $total_items_in_cart );
        }
    
        // Total items in cart greater than or equal to 3
        if ( $total_items_in_cart >= 3 ) {
            // Pakket total = pakket_total / 3 = floor(result)
            // Floor = round fractions down, rounding result down
            $pakket_total = floor( $pakket_total / 3 );
    
            // If product "Pakket" is in cart
            if ( isset($pakket_key) ) {
                // Set quantity, pakket
                $cart->set_quantity( $pakket_key, $pakket_total );
    
            } elseif ( !isset($pakket_key) ) {
                // Product "Pakket" is not in cart, we add it
                $cart->add_to_cart( $pakket_id, $pakket_total );
            }
        }
    }
    add_action( 'woocommerce_before_calculate_totals', 'add_delivery_charge_to_cart', 10, 1 );