2

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.

4

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.

  • Or you can tell it which area to initiate – Shaughn May 14 '15 at 21:57
2

As per my comment you can tell which session to initiate. Heres my mix:

In the observer:

public function test(Varien_Event_Observer $observer)
{
    /** @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") {
        $this->setMarketingData(array(
            'state' => true
        ));
    }
}

/**
 * Get core session
 *
 * @return Mage_Core_Model_Session
 */
protected function _getSession()
{
    $session = Mage::getSingleton ('core/session', array ('name' => 'frontend'));
    return $session;
}

/**
 * Set marketing session data
 *
 * @param array $data
 */
public function setMarketingData(array $data)
{
    $session = $this->_getSession();
    $sessionData = $session->getMarketingData();

    if (!$sessionData) {
        $sessionData = $data;
    } else {
        if(is_array($sessionData)) {
            $sessionData = array_merge($sessionData, $data);
        } else {
            $sessionData = $data;
        }
    }

    try {
        $session->setMarketingData($sessionData);
    } catch(Exception $e) {
        Mage::log($e->getMessage());
    }
}

And to retrieve data, in block or template or just about anywhere:

<?php
$session = Mage::getSingleton('core/session', array ('name' => 'frontend'));
$d = $session->getMarketingData();
Mage::log($d);
?>

The key bit is: Mage::getSingleton('core/session', array ('name' => 'frontend'));

  • Thanks! I just ended up changing it to observe controller_action_predispatch event instead, which is dispatched after Magento instantiates the core/session singleton. – Nick Rolando May 14 '15 at 22:37

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.