Do not allow free and paid products to be bought together in WooCommerce

Viewed 51

My intention is that free and paid products cannot be bought together in WooCommerce.

If there is a free product or a zero price product in the basket, all paid products should be removed from the basket OR the opposite situation.

In short, paid and free products cannot be ordered at the same time.

The code below is an approximation of what I want to work towards, but it doesn't fully answer my question. How should I handle this?

add_action( 'template_redirect', 'test_cart_values' );
function test_cart_values(){
    $ic_cart = false;

    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $product = $cart_item['data'];
        $price = WC()->cart->get_product_price( $product );

        if ( $price == 0 || $price === '') {
            $ic_cart = true;
            break;  
        }
    }

    if ( $ic_cart ) {
        foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
            $product = $cart_item['data'];
            $price = WC()->cart->get_product_price( $product );
            
            if ( $price != 0 || $price !== '') {
                WC()->cart->remove_cart_item( $cart_item_key );     
                break;
            }
        }
    }
}
1 Answers

You can use the woocommerce_add_to_cart hook opposite the template_redirect hook.

When a product is added to the cart, compare the current product price with the price of the product in the cart. If the price does not match, remove the product from cart, this via a loop so that it is applied for all products in cart.

So you get:

function action_woocommerce_add_to_cart( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {
    // Get current product
    $current_product = wc_get_product( $product_id );

    // Get current product price
    $current_product_price = $current_product->get_price();

    // Initialize
    $is_free = false;
    $notice = false;

    // When current product price = 0
    if ( $current_product_price == 0 ) {
        // Make true
        $is_free = true;
    }

    // Loop through cart contents
    foreach ( WC()->cart->get_cart_contents() as $item_key => $cart_item ) {
        // Get price
        $product_price = $cart_item['data']->get_price();

        // Product price is NOT equal to 0 and current product is free
        if ( $product_price != 0 && $is_free ) {
            // Remove product from cart
            WC()->cart->remove_cart_item( $item_key );

            // Make true
            $notice = true;
        // Product price is equal to 0 and current product is NOT free
        } elseif ( $product_price == 0 && ! $is_free ) {
            // Remove product from cart
            WC()->cart->remove_cart_item( $item_key );

            // Make true
            $notice = true;
        }
    }

    // Optionaly displaying a notice
    if ( $notice ) {
        wc_add_notice( __( 'Some products have been removed from the cart because free and paid products cannot be bought together', 'woocommerce' ), 'notice' );
    }
}
add_action( 'woocommerce_add_to_cart', 'action_woocommerce_add_to_cart', 10, 6 );
Related