I would like to set a quote's shipping method based on the items selected in the quote (only if there is not already a shipping method selected) and unset the quote's shipping method when there are no more items in the cart/quote.
However, I'm having difficulty with part 2 of this problem. I have tried observing sales_quote_address_save_before
, sales_quote_save_after
and checkout_cart_save_after
and they all exhibit a very odd behavior:
If I add or remove items from the cart, these events fire twice with the new number of items in the cart (so for example, if I had 1 item and added 1 item, it would fire twice with 2 items in the model).
However, if I remove all items from the cart, all three events only fire once with the old number of items in the cart (for example, if I had 1 item in the cart and delete it, the event fires once with 1 item in the model, not 0).
Is there an event that I can use to tell when I have no items in the cart?
Best Answer
What works well for me to react on cart changes is a combination of these events:
You are probably looking at the wrong data. When items are removed from the cart, the objects get a
deleted
flag but stay in the collection. If you use$cart->getItems()
or$cart->getItemsCollection()
these deleted items are included. Use$cart->getQuote()->getAllItems()
or$cart->getQuote()->getAllVisibleItems()
instead.I explained the difference between these methods in: How to get all items in cart currently?