Magento Session – Fix Variable Not Persisting to Next Request

blockscontrollerscore-sessionevent-observer

Every frontend page load, I need to check for a certain url parameter, and if it is found I set a session variable to true so that I know at one point during this session the customer had this parameter in their request. Needless to say, this session variable must persist for the lifetime of the session.

I'm observing event controller_front_init_before and triggering this code:

    /** @var Mage_Core_Controller_Varien_Front $front */
    $front = $observer->getEvent()->getFront();
    $params = $front->getRequest()->getParams();

    /* Only set session var to true */
    if(isset($params["testutm"]) && trim($params["testutm"]) == "email") {
        Mage::getSingleton('core/session')->setIsFromMarketingEmail(true);
    }

Then, for testing, I am trying to retrieve this in a cms page that adds a block/template to the content block via layout xml:

<reference name="content">
    <block type="gbicm/modal" name="gbicmmodal" template="gbicm/modal.phtml" />
</reference>

So in modal.phtml, I have this line:

<div><span>ifme - <?php var_dump(Mage::getSingleton('core/session')->getIsFromMarketingEmail());?></span></div>

This dumps null in every case, except if I request the cms page itself with the url parameter intact. Even if I take the parameter out of the URL and request again, I get null. Why is the session variable not persisting to the next page request?

On an interesting side note: I have a /test.php which the session variable does persist to:

require 'app/Mage.php';
umask(0);
Mage::setIsDeveloperMode(true);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
Mage::app()->loadArea('frontend');

var_dump(Mage::getSingleton('core/session')->getIsFromMarketingEmail());

This is always showing me my session variable as expected. Why does is it not set in my custom module block/template?

Update: Seems like the issue is where in the framework I'm setting the session variable. If I set it in the block, it persists as needed.

Best Answer

Well, I found my problem:

Early Session Instantiation
Magento doesn’t know which area it’s handling until the preDispatch method. Therefore, Magento can’t instantiate its session object until the preDispatch method. However, there are Magento system events that fire before pre-dispatch. If a Magento client programmer attempts to use a session in one of these events, some weird stuff can happen.

http://alanstorm.com/magento_sessions_early

I changed it to observe controller_action_predispatch instead, dispatched after Magento instantiates the core/session singleton with the named area, and it is working fine now.

Related Topic