In this and subsequent posts we’re going to look at how to change the quantity of a product added to the cart. Our first solution will be a rewrite of a model class. Second – lighter touch – we’ll look at using an observer to do the same. Along the way, we’ll discuss ways to approach a problem such as this. Ready?
To be specific the client’s requirement was this. For the product selected, add the same quantity of a related product. The related product in this example was a warranty. So for each main product selected (we’ll call this the main product to protect the anonymity of the client), should the customer choose warranty, then the same number of warranties would be added to the cart as the number of main products. But the customer must have the ability to change these quantities in the cart itself.
Here’s an early screen shot with key client data removed.
Out of the box Magento displays the related product without the option to specify the number required. So only one related product is added to the cart regardless of how many ‘Blessthemoon 1’ products are added. As an aside there are a number of other things going on in this requirement which we may look at in a later post (monthly direct debit for example).
Ok, so where do we start. We’re looking for a controller which processes the request when the customer clicks ‘Add to Cart’. We may already know the name and location of the controller and method which renders the cart view, i.e. what we see when all cart processing is complete. We can see that in the url for the cart view: www.mysite.com/checkout/cart. This tells us that the controller is Mage_Checkout_CartController and the method indexAction(). We’ll find this controller in app/code/core/Mage/Checkout/controllers/CartController.php. The default method, when nothing is displayed after the controller name in the url ‘/checkout/cart’, is always indexAction().
And we can find the controller and method which processes ‘Add to Cart’ before indexAction() is invoked by inspecting the ‘form action’ tag for this single product view page in the browser. In this case, we can see it’s /checkout/cart/add/. In other words, we’re looking for the method addAction() in Mage_Checkout_CartController. It’s in this method and those called by it that we expect to find the code that we need to target in order to change the quantity of related product added to the cart.
In this series of posts I’m going to be using PhpStorm as my IDE, because I want to be able to track where in program flow the related product quantity needs to be changed. That’s not to say that any IDE can’t be used, but it should provide debugging so that we can pause and resume program execution and note the values of the variables along the way. I’ve integrated Xdebug with PhpStorm, and I’m running the Xdebug Helper in Chrome. (I’m also using bookmarklets in Firefox to control program execution.) With debug mode enabled in Xdebug Helper and PhpStorm set to listen for PHP Debug connections, I’m ready to control program execution. (If you’re interested, this is a Magento CE 1.8 development site running locally on MAMP.) Explaining how debugging is set up and configured will require a separate post (its on my to-do-list!).
Here’s a screenshot of PhpStorm which shows a ‘breakpoint’ set on one of the first lines of code in the addAction() method of Mage_Checkout_CartController: ‘$cart = $this->_getCart();’.
Take a look at the Frames listed in the ‘Debugger’ tab, all the way from index.php through CartController.php addAction(). And in the Variables window we can see the variables with their values for this frame. In this screenshot you can see both program and superglobal variables. In $_POST we can see that ‘Add to Cart’ has posted values for product and related product (IDs) and quantity (qty) for the main product. This debugging facility will enable us to pinpoint where we need to make a change when we rewrite some code, which is what we’ll do in the next post. And it will allow us to pinpoint the ‘right’ event when we code an observer to do the same job, in the post after that.