Magento – Set New Cookie Value

cookie

This is driving me nuts! I'm trying to set a new cookie value:

protected function setCookie($cookieName = null, $cookieVal = null)
{
    $model = Mage::getModel('core/cookie');
    $cookieVal = Mage::app()->getRequest()->getParam('source');
    var_dump('Value: ' . $cookieVal);
    $theCookie = $model->set($cookieName, $cookieVal);
    return $this;
}

The var_dump spits out: string(17) "Value: testpeanut". However, the cookie is never created.

I'm obviously looking for a URL query string like so: domain.com?source=testpeanut. If I replace the $cookieVal = line with the following:

$cookieVal = 'hardcoded_values_work';

Then it works as expected and the cookie is set. What the problem is? Thanks.

~ Edit ~

This code is part of a model observer class. Obviously, I haven't included all of my code here for cleanliness sake. If I get all the params and dump the array, my param is present and has a value:

$cookieVal = Mage::app()->getRequest()->getParams();
var_dump($cookieVal);

Also, if I pass a non-null parameter as a second argument to the getParam() method, it also works:

Mage::app()->getRequest()->getParam($param, 'i_can_see_this');

I need to check if the param is supplied in the URL, which is why that method won't work long-term. I've been tailing all the logs – no errors or warnings at all.

Best Answer

First, security:

This pattern is extremely dangerous:

$cookieVal = Mage::app()->getRequest()->getParam('source');
$theCookie = $model->set($cookieName, $cookieVal);

You should never accept user input and shove to a cookie - it gives a would-be attacker the instant ability to set any cookie they want from your domain.

Secondly, cookies:

[Insert "How do they work" meme here]

Cookies are sent back to a user session with the Response object. If you try to set a cookie after the header of the response you'll likely get this warning in the system.log or the general PHP log:

Cannot modify header information - headers already sent by //...

The only place you should be setting cookies is from within a controller action and before it loads the layout. If you're attempting to set cookies from anywhere else in the application you may have unexpected results.

Finally, your real issue:

Okay, so enough browbeating.

getParam is a method returned from Zend_Controller_Request_Http and does a series of tests:

public function getParam($key, $default = null)
{
    $keyName = (null !== ($alias = $this->getAlias($key))) ? $alias : $key;

    $paramSources = $this->getParamSources();
    if (isset($this->_params[$keyName])) {
        return $this->_params[$keyName];
    } elseif (in_array('_GET', $paramSources) && (isset($_GET[$keyName]))) {
        return $_GET[$keyName];
    } elseif (in_array('_POST', $paramSources) && (isset($_POST[$keyName]))) {
        return $_POST[$keyName];
    }

    return $default;
}

As you can see, the $default return value is null but you can change this with the second parameter. Try testing your return value. If it's null, pass a second parameter to getParam.

Alternatively, use of getParams (plural) will return all set parameters in the current request, regardless of the set method - e.g. GET or POST. Try doing a var_dump of getParams to test if your value is set.

I would also advise against using Mage::app()->getRequest() if you are within the scope of a controller action - instead use $this->getRequest().

Edit:

As @vinai pointed out in your other question, var_dump and echo push content to the browser and thus preclude your ability to set cookies.

Related Topic