2

I have an requirement to allow products to add to the cart from an external link, like in an email campaign. I've created an observer to allow a form key to be added to the url if it doesn't exist, however it only adds if the session already exists (if I visit the site then use the URL it works) otherwise I get a cms no cookies url. Am I using the correct event to hook into for pre-cart but post-session start?

The URL I'm tyring to get working is:

/checkout/cart/add?product=1&qty=1

config.ml:

<?xml version="1.0"?>
<config>
<modules>
    <Vendor_GenerateFormKey>
        <version>1.0.0</version>
    </Vendor_GenerateFormKey>
</modules>
<frontend>
    <events>
        <controller_action_predispatch_checkout_cart_add>
            <observers>
                <Vendor_GenerateFormKey_Model_Observer>
                    <type>singleton</type>
                    <class>Vendor_GenerateFormKey_Model_Observer</class>
                    <method>GenerateFormKey</method>
                </Vendor_GenerateFormKey_Model_Observer>
            </observers>
        </controller_action_predispatch_checkout_cart_add>
    </events>
</frontend>
</config>

Observer.php

<?php

class Vendor_GenerateFormKey_Model_Observer
{
//Put any event as per your requirement
public function GenerateFormKey() {

    $oldkey = Mage::app()->getRequest()->getParam('form_key');

    $domain = Mage::getBaseUrl();

    if (empty($oldkey) && ($domain == 'http://site1.co.uk/' || $domain = 'http:///site2.co.uk/')) {

        Mage::getSingleton("core/session", array("name" => "frontend"));

        $product = Mage::app()->getRequest()->getParam('product');
        $qty = Mage::app()->getRequest()->getParam('qty');

        $key = Mage::getSingleton('core/session')->getFormKey();

        if (empty($product)) { //if no product id, redirect to homepage
            Mage::app()->_redirect('');
        } else { //redirect to the add to cart with the form key

            $url = 'add/product/' . $product . '/qty/' . $qty . '/form_key/' . $key;

            Mage::app()->getRequest()->setParam('return_url', $url);
        }

    }

}
}

I had a look at several 'how tos' for this but I can't seem to find a solution that wants to work with Magento 1.9.2.3. I know the form key doesn't last past the user session, hence the observer to add the form key only once the user is on the site.

  • why you want to add formkey to external link? form key will get expire after some time. you can return link of cart for product by <?php echo $this->helper('checkout/cart')->getAddUrl($product);?> – Gopal Patel Oct 31 '16 at 11:54
  • This is due to an email campaign requirement, so as it's going from an email URL straight into the cart it's going to have to grab the form key every time, hence the observer. This was easily do-able before they added the form_key, so I just need some help with the observer. I don't think what you're suggesting will work for what I am asking. – Aravona Oct 31 '16 at 12:03
1

Please, try using the code below for the observer. It works fine for me.

public function GenerateFormKey() 
{
    $oldkey = Mage::app()->getRequest()->getParam('form_key');

    $domain = Mage::getBaseUrl();

    if (empty($oldkey) && ($domain == 'http://site1.co.uk/' || $domain = 'http:///site2.co.uk/')) {
        Mage::getSingleton("core/session", array("name" => "frontend"));

        $product = Mage::app()->getRequest()->getParam('product');
        $qty = Mage::app()->getRequest()->getParam('qty');

        $key = Mage::getSingleton('core/session')->getFormKey();

        // Just add the new form key to request params instead of redirecting
        Mage::app()->getRequest()->setParam('form_key', $key);
    }
}

In case you are still receiving "Please enable cookies" error for the action then you have to remove the 'add' action from Mage_Checkout_CartController::$_cookieCheckActions class member.

  • Does this work for you if you're not on the site at all? – Aravona Oct 31 '16 at 12:16
  • Or you can just disable form keys validation in magento admin panel: System > Configuration > System > SCRF protection > Add Secret Key to Url – MagestyApps Oct 31 '16 at 12:18
  • The code still doesn't work when you don't have a session started. I'd rather not turn off the form key though. Thank you for answering. – Aravona Oct 31 '16 at 12:19
  • What error do you get when you have no session started? – MagestyApps Oct 31 '16 at 12:21
  • As I put in my original post, I get pinged to the cms index no cookies page. – Aravona Oct 31 '16 at 12:21
0

I think you can make this work in a different way.
Instead of having the link to add to cart directly to the cart url, you can create you own controller action that does not validate the form key.
And in this action, do any additional checks you have to do (like referrer if needed), then generate the form key and from this action redirect to the add to cart url with the form key added.
But this will defeat the purpose of having a form key for add to cart.
So maybe you can encode somehow the product id and quantity when generating your custom url, decode it in your controller action and send it further to the cart url.

Something like this:

public function mycustomAction()
{
     $id = this->getRequest()->getParam('id');
     $qty = this->getRequest()->getParam('qty'); 
     //additional checks here if needed.  
     $id = decode $id somehow.
     $qty = decode $qty somehow.  
     //validate here $id and $qty
     $formKey = Mage::getSingleton('core/session')->getFormKey();
     $addUrl = Mage::getUrl('checkout/cart/add', array('product'=>$id, 'qty' => $qty, 'form_key' => $formKey));
     $this->redirect($addUrl);
     $this->redirect()
}

and the url you send in your campaign should look like this:

'module/controller/mycustom/id/{encoded_product_id_here}/qty/{encoded_qty_here}'.

  • Can you explain a bit clearer, this doesn't make a lot of sense to me. – Aravona Oct 31 '16 at 12:17
  • I also have already have an extension which overrides the cart controller. – Aravona Oct 31 '16 at 12:21
  • I added 2 more lines to the answer. I don't have anything else I can explain. that's the best I can do. – Marius Oct 31 '16 at 12:28
  • How would I get this to work though if I already have a cart override that's doing it's own thing? I've tried to extend / override it but it doesn't ever seem to work. I kind of have to use the requested url. – Aravona Oct 31 '16 at 12:45
  • this does not involve overwriting. you should create a new custom controller and action that redirects to the cart controller when everything is ok. – Marius Oct 31 '16 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.