When a bundle product is in cart remove child components from cart in Woocommerce

Viewed 1083
2 Answers

For the first condition you can indeed use the woocommerce_add_to_cart hook, for the 2nd condition you better use the woocommerce_add_to_cart_validation hook.

So we apply both conditions together and we get

function filter_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
    // Set ID's
    $product_a = 30;
    $product_b_c_d = array ( 813, 815, 817 );
    
    // Get current product id
    $product_id = $variation_id > 0 ? $variation_id : $product_id;
    
    // Product A is added
    if ( $product_a == $product_id ) {
        // Loop trough cart items
        foreach( WC()->cart->get_cart() as $key => $item ) {
            // Product ID is in array
            if ( in_array( $item['product_id'], $product_b_c_d ) ) {
                // Remove cart item(s)
                WC()->cart->remove_cart_item( $key );
            }       
        }
        
        // Optionaly displaying a notice
        wc_add_notice( __( 'Product A is added, Product B, C or D has been removed from cart.', 'woocommperce' ), 'notice' );
    }
    // Product B, C or D is added
    elseif ( in_array( $product_id, $product_b_c_d ) ) {
        // Generate card id
        $product_cart_id = WC()->cart->generate_cart_id( $product_a );
        
        // Check if product A in the cart
        $item_key = WC()->cart->find_product_in_cart( $product_cart_id );
        
        // if item_key true
        if ( $item_key ) {
            // Optionaly displaying a notice
            wc_add_notice( __( 'Product A is in cart, Product B, C or D are not allowed', 'woocommerce' ), 'error' );
            $passed = false;
        }

    }

    // Return
    return $passed;
}
add_filter( 'woocommerce_add_to_cart_validation', 'filter_woocommerce_add_to_cart_validation', 10, 5 );

For a specific bundled product, the code below will:

  • remove any individual child products when bundle product is added to cart
  • avoid individual child products to be added to cart when the bundle product is already in cart.

So one hooked function for each case, will be a lighter process:

// When the bunddle product is added to cart remove single components from cart
add_action( 'woocommerce_add_to_cart', 'on_bundled_product_added_to_cart', 10, 4 );
function on_bundled_product_added_to_cart( $cart_item_key, $product_id, $quantity, $variation_id ) {

    // SETTINGS
    $bundled_product_id = 83; // Set HERE your bundled product ID
    $item_ids_to_remove = array(37, 53, 31); // Set HERE the  product ID(s) to remove(s)

    $removed_items = 0; // Initializing

    // When the bundled product is added to cart
    if( $bundled_product_id == $product_id ) {
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $item_key => $cart_item ){
            // Get the cart item keys of the items to be removed
            if( array_intersect( array($cart_item['product_id'], $cart_item['variation_id']), $item_ids_to_remove ) ) {
                WC()->cart->remove_cart_item($item_key);
                $removed_items++;
            }
        }
    }

    // Optionaly displaying a notice for the removed items
    if( ! empty($removed_item_names) ){
        wc_add_notice( sprintf( __( 'Some products have been removed from cart as they are already bundled in your cart', 'woocommerce' ), $items_text ), 'notice' );
    }
}

// Add to cart validation for bundled components
add_filter( 'woocommerce_add_to_cart_validation', 'check_cart_items_for_bundle_product', 9999, 4 );
function check_cart_items_for_bundle_product( $passed, $product_id, $quantity, $variation_id = 0 ) {
    // SETTINGS
    $bundled_product_id = 83; // Set HERE your bundled product ID
    $bundled_items_ids  = array(37, 53, 31); // Set HERE the bundled items ID(s) from the bundled product
    $bundled_in_cart = false;

    if( ! WC()->cart->is_empty() ) {
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $cart_item ){
            // check for bundled product
            if( $bundled_product_id == $cart_item['product_id'] ) {
                $bundled_in_cart = true;
                break;
            }
        }
        if( $bundled_in_cart && array_intersect(array($product_id, $variation_id), $bundled_items_ids) ) {
            // Add a custom notice
            wc_add_notice( __( 'This product is already a component of the bundled product in your cart', 'woocommerce' ), 'error' );
            return false;
        }
    }
    return $passed;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.


The message error when trying to add to cart a component of a bundled product when it's in cart already:

enter image description here


The message when components of a bundled product are in cart and they are removed when adding the parent bundled product (in cart page):

enter image description here

Related