zen of coding

Intercepting “add to cart” action in Magento

(Nuts and bolts of Magento? Maybe…)

Magento EE 1.11

Once in a while we’d like to intercept Magento’s “add to cart” event and do some fun things with that. Maybe apply a discount or add a specialty product, or as I’ll show in this case, block a user from adding a product to the cart.

As I usually like to show specific examples, let’s consider the following problem:
Using Magento’s EE customer segments we’d like to ensure that a person can purchase some “restricted” product only once, while they are in the given segment.
If they try to add this restricted product to the cart again, while being in our previously-designated segment, we’ll block that action and redirect them back to the cart with an error message.

The best way to handle these sorts of tasks is by employing Magento’s Event/Observer pattern.

First, we need to listen to (or properly phrased “Observe”) an “add to cart” event. In Magento it happens to be checkout_cart_product_add_after.
Shouldn’t we listen to the “*_before” event? Well, yeah… but in the often-crazy Magento world the checkout_cart_product_add_after event actually occurs before the product is added to the cart. (My only guess at this bizarre naming convention, is that the above event is dispatched after the Cart Model is called, but before the cart is actually saved.)

So with that in mind, we’ll adjust our module’s config.xml to tell Magento that we are ready to listen to the above event:

//let's get all segments for this customer ID and website ID$segments= Mage::getModel('enterprise_customersegment/customer')->getCustomerSegmentIdsForWebsite($customer->getId(),$websiteId);

/**
* If customer is in segment of "designated" and is trying to add another
* "restricted" product (based on attribute set ID) we block "add to cart"
* and redirect back with an error message.
*/if(in_array($segmentId,$segments)&&($attSetId==10)){//set error message in session
Mage::getSingleton('core/session')->addError('Sorry, you cannot add this product to cart');

I’m going to keep this post purposely light on details, as there are countless tutorials out there explaining the Event/Observer and configuration setup of Magento.
The code is also pretty straight-forward and well commented, so I’ll just summarize the outcome:

We’ve created an observer in Teknoid/Coolmodule/Model/Observer.php (This matches the namespace designation in config.xml)

We’ve added a method catchAddToCart() as defined in configuration

We are loading the product recieved by the observer

We are checking if the current customer is in our “designated” segment and our “restricted” product matches a given attribute set.

If so, we set the error message to the session and redirect the customer back to cart

That’s it for now. I hope to publish a couple more posts in the near future about Magento’s Event/Observer strategies and some examples of the things we can do using this powerful way to extend Magento’s functionality.

Like this:

LikeLoading...

Related

Timon Davis

Thank you for sharing! I’ve looked at a few solutions for the interception of the add to cart event (or some idea like it) and all of them seem to invoke the _after_ hook. Wouldn’t it be better to terminate the process _before_ anything is committed to the database ( it seems correct to want to execute 0 transactions instead of 2 )? Is there any way to _prevent_ the action from being executed?

**Ah, I just read your middle paragraph a little more closely. Thank you for being specific in your reasoning!

Consulting

During the last twenty years I have helped many startups build amazing technology stacks. Once in a while I consult on a few high-profile projects for Fortune 50 companies.
Let's chat about your next project or
check out our consulting services.