7

I'm having an issue with session variables saving after a redirect. Here's a mock of the relevant code:

class Company_X_Model_Session extends Mage_Core_Model_Session_Abstract {
    const KEY_QUOTE = 'quote';

    protected function _construct() {
        $this->init('company_x');
    }

    public function getQuote() {
        if (!$this->hasData(self::KEY_QUOTE)) {

            $quote = Mage::getModel('sales/quote')->setStoreId(Mage::app()->getStore()->getId());
            /* @var $quote Mage_Sales_Model_Quote */

            if ($this->getQuoteId()) {
                $quote->load($this->getQuoteId());
            }
            $this->setData(self::KEY_QUOTE, $quote);
        }
        return $this->getData(self::KEY_QUOTE);
    }

    public function clear() {
        $this->_quote = null;
        $this->setQuoteId(null);
        $this->setLastSuccessQuoteId(null);
        return parent::clear();
    }
}

In the controller class:

class Company_X_SomeController extends Other_Company_SomeController {

    protected function relevantAction() {

        $session = Mage::getSingleton('company_x/session');
        /* @var $session Company_X_Model_Session */

        $quote = $session->getQuote();
        /* @var $quote Mage_Sales_Model_Quote */

        $payment = $quote->getPayment();
        $payment->importData(array('method' => 'paypal_express'));

        /// all sorts of interesting quote-setting-up code here         

        $quote->collectTotals()->save();

        /// This variable is not saving properly
        $session->setQuoteId($quote->getId());

        $this->_redirectUrl($quote->getPayment()->getCheckoutRedirectUrl());
    }
}

Controller that the redirect hits:

class Company_X_ExpressController extends Mage_Paypal_ExpressController {

    protected function _getQuote() {
        if(!$this->_quote) {
            $this->_quote = $this->_getCheckoutSession()->getQuote();
        }
        return $this->_quote;
    }

    protected function _getCheckoutSession() {

        /// quote_id is not printed here.
        print_r(Mage::getSingleton('company_x/session')->getData());

        return Mage::getSingleton('company_x/session');
    }

}

Can anyone shed some light on why the quote_id variable is not persisting after the redirect?

Edit 1:

In the first controller:

Company_X_Model_Session Object
(
    [_skipSessionIdFlag:protected] => 
    [_sessionHosts:protected] => Array
        (
            [company.x.local] => 1
        )

    [_data:protected] => Array
        (
            [_session_validator_data] => Array
                (
                    [remote_addr] => 10.0.2.21
                    [http_via] => 
                    [http_x_forwarded_for] => 
                    [http_user_agent] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
                )

            [quote_id] => 445
        )

    [_hasDataChanges:protected] => 
    [_origData:protected] => 
    [_idFieldName:protected] => 
    [_isDeleted:protected] => 
    [_oldFieldsMap:protected] => Array
        (
        )

    [_syncFieldsMap:protected] => Array
        (
        )

)

In the redirect controller:

Company_X_Model_Session Object
(
    [_skipSessionIdFlag:protected] => 
    [_sessionHosts:protected] => Array
        (
            [company.x.local] => 1
        )

    [_data:protected] => Array
        (
            [_session_validator_data] => Array
                (
                    [remote_addr] => 10.0.2.21
                    [http_via] => 
                    [http_x_forwarded_for] => 
                    [http_user_agent] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
                )

        )

    [_hasDataChanges:protected] => 
    [_origData:protected] => 
    [_idFieldName:protected] => 
    [_isDeleted:protected] => 
    [_oldFieldsMap:protected] => Array
        (
        )

    [_syncFieldsMap:protected] => Array
        (
        )

)

Resolution:

The Other_Company_SomeController class had overridden the preDispatch method and did not properly call through to the parent class.

7
  • Is Mage::getSingleton('company_x/session') returning a Company_X_Model_Session object? Sep 23, 2016 at 13:47
  • Yes, I'll modify the question to include the print_r of the object. Sep 23, 2016 at 13:50
  • Have you tried setting something like setFoo('bar') and retrieve it later successfully? Sep 23, 2016 at 13:54
  • I don't see how changing the variable names would affect the outcome (as the ultimate base class is a Varien_Object), but setting the 'foo' variable to 'bar' does not work either. Sep 23, 2016 at 13:58
  • Just in case there would have been an issue when using the Quote. Sep 23, 2016 at 13:59

2 Answers 2

2

I've come to the conclusion that the Other_Company_SomeController class had its preDispatch method overridden and was not properly calling through to the parent method.

This caused the entire problem. Thanks to those who've invested their time and effort into helping me figure this out.

2
  • Hi Luke, can you add the class name here instead (Other_Company_SomeController). Yes your right Magento is creating another session, I think you need to track the whole routing to check where Magento is creating another session on redirected page. Add a class name here so that I may help you somehow. Thanks Sep 28, 2016 at 12:59
  • Hi Ashish, I am unable to do that because of licensing restrictions that would put my employers in violation of the EULA that we've agreed to. I've created a local override of the troublesome controller and this has resolved the issue. Sep 28, 2016 at 13:50
0
+100

So as we found out in the comment using $session->getSessionId();, you have two different session ids in your controller.

After checking your code again, the error is so small it's hard to find it.

The reason behind that is because your constructor is missing an underscore, so instead of:

protected function _construct() {
    $this->init('company_x');
}

It should be:

protected function __construct() {
    $this->init('company_x');
}
4
  • Hi Raphael, thanks for the answer. I was under the impression that all subclasses of Varien_Object were supposed to use the _construct method (as __construct calls the _construct method internally). I took your advice and changed it to __construct, however the issue is not resolved. SID Before: si0v5vff4e3uaht49g4lqud3o5 SID After: sj4rlife1bb070npb3se8hjki7 I'm beginning to think that there's a deeper issue here, as even a Mage_Core_Model_Session is regenerating the session as well. Oddly enough, this is the only place in the code that sessions are misbehaving... Sep 27, 2016 at 13:50
  • @LukeA.Leber my guess is that someone is happening in the controllers that deletes the previously set sessions. Do you have any custom modules observing a controller_action_predispatch_* event maybe ? Sep 28, 2016 at 10:37
  • Hi Raphael, I threw the bounty in your direction because your suggestion regarding checking the session IDs lead me to find the answer that I posted here. It turns out that a third-party controller failed to call through to the parent preDispatch method which resulted the session not being properly instantiated. Sep 28, 2016 at 19:47
  • @LukeA.Leber thanks for that I'm glad you figured it out Sep 28, 2016 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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