'Limit WooCommerce products in cart only from one custom taxonomy

I'm trying to restrict customers on my Woocommerce store to only be allowed to order products from 1 "supplier" at a time. I am defining the "Supplier" by a custom taxonomy called "supplier". The code I am trying is just restricting everything for some reason.

function filter_woocommerce_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id = null, $variations = null ) {
// If passed
if ( $passed ) {
    
    // If cart is NOT empty when a product is added     
    if ( !WC()->cart->is_empty() ) {
        
        // Set vars
        $current_product_tag_ids = array();
        $in_cart_product_tag_ids = array();
        
        // Get current product categories via product_id
        $current_product_tag_ids = wc_get_product_term_ids( $product_id, 'supplier' );

        // Loop through cart items checking for product categories
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            // Get product categories from product in cart via cart item product id
            $in_cart_product_tag_ids = array_merge( $in_cart_product_tag_ids, wc_get_product_term_ids( $cart_item['product_id'], 'product_cat' ) );
        }
        
        // Removes duplicate values
        $in_cart_product_tag_ids = array_unique( $in_cart_product_tag_ids, SORT_NUMERIC );
        
        // Compare
        $compare = array_diff( $current_product_tag_ids, $in_cart_product_tag_ids );
        
        // Result is NOT empty
        if ( !empty ( $compare ) ) {
            wc_add_notice( 'This product is with a different supplier. Please only order from 1 supplier at a time.', 'error' );
            $passed = false;
        }
    }
}

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

I'm not trying to limit it to 1 product per supplier, I'm trying to restrict them so they can only order products from 1 supplier per order. Once they've added a product to their basket from the supplier "Supplier 1" for example, they then won't be able to add a product from any other supplier other than "Supplier 1".

I made a previous post trying to use categories instead of a custom taxonomy but I need them to be separate so we're not limited on categories. This post can be found here: One Category Per Order Woocomerce



Solution 1:[1]

The following will allow adding to cart items from one "supplier" only:

add_filter( 'woocommerce_add_to_cart_validation', 'only_one_supplier_by_order', 10, 2 );
function only_one_supplier_by_order( $passed, $product_id ) {
    if ( WC()->cart->is_empty() )  
        return $passed;
    
    $taxonomy = 'supplier';
    $term_ids = wp_get_post_terms( $product_id, $taxonomy, ['fields' => 'ids']);

    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if( ! has_term( $term_ids, $taxonomy, $cart_item['product_id'] ) ) {
            // Displaying a custom notice
            wc_add_notice( __('This product is with a different supplier. Please only order from 1 supplier at a time.'), 'error' );
            return false; // Avoid add to cart
        }
    }
    return $passed;
}

Now to be sure that customer can't checkout with different suppliers in cart, you can add this:

// To be sure (avoiding checkout)
add_action( 'woocommerce_check_cart_items', 'only_one_supplier_by_order_check' );
function only_one_supplier_by_order_check() {
    $taxonomy   = 'supplier';
    $term_names = []; // Initializing

    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $terms = wp_get_post_terms( $cart_item['product_id'], $taxonomy );
        if( ! empty($terms) ) {
            $term  = reset($terms);
            
            $term_names[$term->term_id] = $term->name;  
        }
    }

    // Allow only one supplier in cart (avoid checkout for more than one
    if( count( $term_names ) > 1 ) {

        // Displaying a custom notice
        wc_add_notice( __('Only items from one supplier at the time are allowed in cart'), 'error' );
    }
}

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 LoicTheAztec