Magento – Session messages not showing

global-messagesmessagesredirectsession

I've created a custom module (in Magento CE 1.9.3.1) where users can participate in a competition to win something. Everything so far works flawlessly and the module is nearly done. However now I want to show a success message when people post the form and redirect to the same page, but the messages don't show and I don't know why.

Here's the My_Competition_IndexController:

public function indexAction()
{
    $helper = Mage::helper('competition');

    $request = $this->getRequest();
    $postData = $request->getPost();
    $cSession = Mage::getSingleton('customer/session');

    $competitor = Mage::getModel('competition/competitor')->loadByHash(Mage::helper('competition')->getHash());

    /** redirect to landing page if no data is found */
    if (!$competitor) {
        $cSession->addError($this->__('The url is not correct, please check the url and try again.'));
        return $this->_redirect('competition/landingpage');
    }

    if ($postData) {
        try {
            Mage::getModel('competition/competitor')->saveCompetitor($postData);

            $competitor = Mage::getModel('competition/competitor')->loadByHash(Mage::helper('competition')->getHash());
            $cSession->addSuccess($this->__('Thanks for participating, your entry has been registered.'));
        } catch (Exception $e) {
            $cSession->addError($e->getMessage());
        }

        $this->_redirectReferer();

        if ($helper->canParticipate($competitor)) {
            $this->loadLayout();
            $this->_initLayoutMessages('core/session');
            $this->renderLayout();
        }
    } else {
        if ($helper->canParticipate($competitor)) {
            $this->loadLayout();
            $this->_initLayoutMessages('core/session');
            $this->renderLayout();
        } 
    }
}

Here's My_Competition_Helper_Data:

private $_hash;

/**
 * Get the hash from url (= .../id/#hash)
 *
 * @return string $hash
 */
public function getHash()
{
    $hash = Mage::app()->getRequest()->getParam('id');

    if (!isset($this->_hash)) {
        $this->_hash = $hash;
    }

    return $hash;
}

/**
 * Check if the competitor can still participate
 *
 * @param $competitor
 * @return bool
 */
public function canParticipate($competitor)
{
    if (isset($competitor['AantalDeelnames']) && isset($competitor['ReedsDeelgenomen']) && (int)$competitor['ReedsDeelgenomen'] < (int)$competitor['AantalDeelnames']) {
        return true;
    }

    return false;
}

Everything is loaded inside the page/1column.phtml (so it should automatically work with displaying messages), as seen in my_competition.xml:

<competition_index_index>
    <reference name="root">
        <action method="setTemplate">
            <template>page/1column.phtml</template>
        </action>
    </reference>
    <reference name="head">
        <action method="addItem">
            <type>js_css</type>
            <name>calendar/calendar-win2k-1.css</name>
        </action>
        <action method="addItem">
            <type>js</type>
            <name>calendar/calendar.js</name>
        </action>
        <action method="addItem">
            <type>js</type>
            <name>calendar/calendar-setup.js</name>
        </action>
        <block type="core/html_calendar" name="head.calendar" as="calendar" template="page/js/calendar.phtml" />
    </reference>
    <reference name="content">
        <block type="core/messages" name="global_messages" as="global_messages"/>
        <block type="core/messages" name="messages" as="messages"/>
        <block type="competition/main" name="competition-main" template="my/competition/main.phtml">
            <block type="cms/block" name="competition-header">
                <action method="setBlockId">
                    <block_id>competition-header</block_id>
                </action>
            </block>
            <block type="cms/block" name="competition-message">
                <action method="setBlockId">
                    <block_id>competition-message</block_id>
                </action>
            </block>
            <block type="cms/block" name="competition-footer">
                <action method="setBlockId">
                    <block_id>competition-footer</block_id>
                </action>
            </block>
        </block>
    </reference>
</competition_index_index>

What happens now is you can enter multiple times, but never is the 'thanks for participating' message shown, until it redirects to a thank-you page, which is a cms page, there it shows the messages the number of times you've played. So if you've entered the competition 4 times in a row, it doesn't show on the competition page, but after the 4th time it redirects you to the thank-you page and there it shows 4 times.

I've tried several things already and haven't gotten this to work properly, which leads me to believe I'm somehow redirecting wrong, or if that's not the case, I still need to add the proper message div or I'm using the wrong session singleton or something…?

Does anyone see what I'm missing here? (If you need more info, let me know)

Thanks.

Best Answer

Okay, so after even more digging online and consulting some Magento guides/courses, I've found out the problem myself, namely:

  1. I had to add the messages block to my layout.xml, like so:

    <reference name="content">
        <block type="core/messages" name="messages" as="messages"?>
        // rest of code here
    </reference>
    
  2. I had to edit my indexController, so it renders and loads the layout, including the messages (and do this earlier), like so:

    public function indexAction()
    {
        // rest of code here
    
        if (!$competitor) {
            $cSession->addError($this->__('The url is not correct, please check the url and try again.'));
            return $this->_redirect('competition/landingpage');
        }
    
        $this->loadLayout();
        $this->_initLayoutMessages('customer/session');
        $this->renderLayout();
    
        if ($postData) {
            try {
                Mage::getModel('competition/competitor')->saveCompetitor($postData);
    
                $competitor = Mage::getModel('competition/competitor')->loadByHash(Mage::helper('competition')->getHash());
                $cSession->addSuccess($this->__('Thanks for participating, your entry has been registered.'));
            } catch (Exception $e) {
                $cSession->addError($e->getMessage());
            }
    
            $this->_redirectReferer();
        }
    }
    

So if anyone else bumps into a similar problem, hopefully this might help you.

Related Topic