Reputation: 95
I have found similar solutions to this, for example: "How to limit orders to one category". I have tried to modify the code but it's not specific enough.
In my case, each Vendor is defined by a product attribute value, 8 Terms at all. If the cart contains products from more than 3 different Terms, I need to set up a message that says "Sorry, you may only order from 3 different Vendors at a time".
This is what I'm using as a starting point:
add_action( 'woocommerce_add_to_cart', 'three_vendors' );
function three_vendors() {
if ATTRIBUTE = SELECT A VENDOR; NUMBER OF TERMS > 3 {
echo "Sorry! You can only order from 3 Vendors at a time.”;
}
}
The middle line is me filling in the blanks using non-php language.
I am looking for a way to define the amount of variations in the cart. If this is not possible to do with Attributes, I am open to use Categories instead.
Does anyone know how to do this?
Upvotes: 3
Views: 742
Reputation: 253978
Update: Is not possible to manage variations with
woocommerce_add_to_cart_valisation
hook
Instead we can use a custom function hooked in woocommerce_add_to_cart
filter hook, removing the last added cart item when more than 3 vendors (items) are in cart:
// Remove the cart item and display a notice when more than 3 values for "pa_vendor" attibute.
add_action( 'woocommerce_add_to_cart', 'no_more_than_three_vendors', 10, 6 );
function no_more_than_three_vendors( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {
// Check only when there is more than 3 cart items
if ( WC()->cart->get_cart_contents_count() < 4 ) return;
// SET BELOW your attribute slug… always begins by "pa_"
$attribute_slug = 'pa_vendor'; // (like for "Color" attribute the slug is "pa_color")
// The current product object
$product = wc_get_product( $variation_id );
// the current attribute value of the product
$curr_attr_value = $product->get_attribute( $attribute_slug );
// We store that value in an indexed array (as key /value)
$attribute_values[ $curr_attr_value ] = $curr_attr_value;
//Iterating through each cart item
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// The attribute value for the current cart item
$attr_value = $cart_item[ 'data' ]->get_attribute( $attribute_slug );
// We store the values in an array: Each different value will be stored only one time
$attribute_values[ $attr_value ] = $attr_value;
}
// We count the "different" values stored
$count = count($attribute_values);
// if there is more than 3 different values
if( $count > 3 ){
// We remove last cart item
WC()->cart->remove_cart_item( $cart_item_key );
// We display an error message
wc_clear_notices();
wc_add_notice( __( "Sorry, you may only order from 3 different Vendors at a time. This item has been removed", "woocommerce" ), 'error' );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and should works for you. It will check for the attribute values regarding your specific attribute and will remove last added cart item for more than 3 attribute values.
The only annoying thing is that I can't remove the classic added to cart notice for the moment. I will try to find another way…
Upvotes: 2