For EKWB we have created landing page Predator EKWB. It’s a nice pre-sales page, but not built on Magento (WordPress is so much nicer for these things :)) How to connect external page (predator.ekwb.com) to Magento? Simple, custom “add to cart” function.

One problem. Controllers can not be extended, this means copy pasting whole Magento Cart controller. Not a really nice solution at all. On Magento upgrade you would need to copy paste everything and implement your customer logic again. Not something we want. Let’s solve that later and go to simple things first.

First, defining new Cart Controller

Solution is create a new module where we say we want to route Checkout Cart to our new Controller. Sample XML config:


0.1.0
Optiweb_MultipleAddToCart_Checkout

Over-ride controller

We found nice solution of Magento Stack Exchange. Over-ride controller and only add custom logic you need. No problems on Magento upgrade. No need to copy paste base class. Superb!

Add to cart and redirect to checkout!

Awsome, we have controller ready. Let’s add new Controller action (URL action). We will accept product SKU and quantity as parameter. For example, http://shop.ekwb.com/checkout/cart/addsingle/products/3831109863343=1. 3831109863343 is SKU of product, 1 is quantity. If we want multiple products added to cart, we use 3831109863343=1,1831109863343=2. Products are de-limited by “,”.

All other logic is quite explanatory trough code bellow. Important note though. After adding product to cart, you have to also call proper events if you have custom logic. At EKWB, we have:

getRequest()->getParams();
if(isset($params['products'])) {
// RM: Products are exploded by ","
$products = explode(",", $params['products']);
$product_ids = array();
foreach($products as $product) {
// For quantity, we want =
$p = explode("=", $product);
//p[0] = SKU article; p[1] = qty
$id = Mage::getModel('catalog/product')->getIdBySku($p[0]);
if ($id != ""){
$product_ids[$id] = $p[1];
}
}
// RM: Add new products - single
$extra_msg = "";
try {
$cart = Mage::getModel('checkout/cart');
foreach($product_ids as $prod_id=>$prod_qty) {
$_product = Mage::getModel('catalog/product')
->setStoreId(Mage::app()->getStore()->getId())
->load($prod_id);
// RM: Can this product be added to cart?
if(!$_product->isSuper() && $_product->getHasOptions() == 0 && $_product->isSalable() == 1) {
$cart->addProduct($_product, array('qty'=>$prod_qty));
$cart->save();
// RM: Very important
Mage::dispatchEvent('checkout_cart_add_product', array('product'=>$product));
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
Mage::dispatchEvent('checkout_cart_save_before', array('event'=>$this));
}else{
$extra_msg .= '
'.$_product->getName().'
';
}
}

if ($extra_msg != “”){
$message = $message.”The items below could not be added to your shopping cart because they require extra parameters. Please, add each item manually:

    “.$extra_msg.”

“;
}
} catch(Exception $e) {
$extra_msg = $message = $e->getMessage();
}

// RM: Error msg? Redirect to cart so user will see the overview of errors, which products has been added and which not
if (!empty($extra_msg)) {
Mage::getSingleton(‘checkout/session’)->addSuccess($message);
$this->_redirect(‘checkout/cart’);
return true;
}
}

// RM: All well? Redirect to checkout
$this->_redirect(‘firecheckout’);
return true;
}

The same solution can be used if you want to over-ride Account controller, for example changing functionality for forgotten password, saving shipping address where telephone is not required.