Search code examples
phpwordpresswoocommercecarthook-woocommerce

Require simple products in WooCommerce cart for product variations before checkout


After adding some product variations to the cart, some simple products are required to match the product variations in cart.

If there are no correct simple products in cart, a message will display and user cannot proceed to checkout.

If product variations in cart, and required simple products are not in cart, then the notice should display.

add_action('woocommerce_before_cart', 'product_cart_check');

function product_cart_check() {
    foreach (WC()->cart->get_cart() as $cart_item) {
        // Target product variation
        $product_variation_ids = array(27741);
        // Simple products should match the product variation
        $simple_product_ids = array(26924, 26925);

        if (in_array($cart_item['variation_id'], $product_variation_ids)) {
            if (!in_array($cart_item['product_id'], $simple_product_ids)) {
            // Display message
            wc_print_notice('Please add required simple products to your cart', 'notice');
            }
        }
    }
}

I have the code above, but it doesn't work as expected. The notice will always display even though I added required simple products to cart. Any advice?


Solution

  • To require simple products in cart for (a) product variation(s):

    • Use the woocommerce_check_cart_items hook instead
    • Use array_diff() to compares array against one or more other arrays and returns the values in array that are not present in any of the other arrays.
    • To remove the proceed to checkout button, you can use the woocommerce_proceed_to_checkout hook

    So you get, for a specific variation ID:

    function get_cart_item_ids() {
        // Initialize
        $ids = array();
    
        // WC Cart NOT null
        if ( ! is_null( WC()->cart ) ) {
            // Loop through cart contents
            foreach ( WC()->cart->get_cart_contents() as $cart_item ) {
                // Push to array
                $ids[] = $cart_item['data']->get_id();
            }
        }
        
        return $ids;
    }
    
    function action_woocommerce_check_cart_items() {
        // Get cart item ids
        $cart_item_ids = get_cart_item_ids();
        
        // Target product variation
        $product_variation_id = 27741;
        
        // Simple products should match the product variation
        $simple_product_ids = array( 26924, 26925 );
        
        // Checks if a value exists in an array
        if ( in_array( $product_variation_id, $cart_item_ids ) ) {
            // Computes the difference of arrays
            if ( array_diff( $simple_product_ids, $cart_item_ids ) ) {
                // Notice
                wc_print_notice( __( 'Please add required simple products to your cart', 'woocommerce' ), 'notice' ); 
                
                // Remove proceed to checkout button
                remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
            }
        }
    }   
    add_action( 'woocommerce_check_cart_items' , 'action_woocommerce_check_cart_items', 10, 0 );
    

    OR to apply the same for multiple product variation IDs:

    function get_cart_item_ids() {
        // Initialize
        $ids = array();
    
        // WC Cart NOT null
        if ( ! is_null( WC()->cart ) ) {
            // Loop through cart contents
            foreach ( WC()->cart->get_cart_contents() as $cart_item ) {
                // Push to array
                $ids[] = $cart_item['data']->get_id();
            }
        }
        
        return $ids;
    }
    
    function action_woocommerce_check_cart_items() {
        // Get cart item ids
        $cart_item_ids = get_cart_item_ids();
        
        // Target product variations
        $product_variation_ids = array( 27741, 56 );
        
        // Simple products should match the product variation
        $simple_product_ids = array( 26924, 26925 );
        
        // Initialize
        $flag = false;
        
        // Loop through
        foreach ( $product_variation_ids as $product_variation_id ) {   
            // Checks if a value exists in an array
            if ( in_array( $product_variation_id, $cart_item_ids ) ) {
                // Computes the difference of arrays
                if ( array_diff( $simple_product_ids, $cart_item_ids ) ) {
                    $flag = true;
                    break;
                }
            }
        }
        
        // True
        if ( $flag ) {
            // Notice
            wc_print_notice( __( 'Please add required simple products to your cart', 'woocommerce' ), 'notice' ); 
    
            // Remove proceed to checkout button
            remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );   
        }   
    }   
    add_action( 'woocommerce_check_cart_items' , 'action_woocommerce_check_cart_items', 10, 0 );