Magento – Set Error Message Once Per Page Request

errorevent-observersession

I'm trying to create a minimum total checkout module that will prevent someone from checking out with a total less than a configurable amount.

I'm using the event sales_quote_save_before to display an error on the checkout/cart page when it's opened.

<?xml version="1.0"?>
<config>
    <frontend>
        <events>
            <sales_quote_save_before>
                <observers>
                    <b2b>
                        <class>b2b/observer</class>
                        <method>checkTotalsCart</method>
                    </b2b>
                </observers>
            </sales_quote_save_before>
        </events>
    </frontend>
</config>

And in the observer

public function checkTotalsCart()
{
    if ($this->_hasCartError()) { /* does some checks, returns bool */
        $this->_setErrorMessage();
    }
}
protected function _setErrorMessage()
{
    $session = Mage::getSingleton("b2b/session"); /* extends Mage_Core_Model_Session */
    $session->addError($this->helper->getErrorMessage());
}

The problem is that when you update the cart from the cart page, the error message is showing up twice. I guess that event is happening multiple times.

enter image description here

I've tried to check if the message was previously set with a custom session variable

protected function _setErrorMessage()
{
    $session = Mage::getSingleton("b2b/session");
    if ($session->isErrorMessageAdded()) {
        return;
    }
    $session->addError($this->helper->getErrorMessage());
    $session->isErrorMessageAdded(true);
}

But that didn't work either. How can I make sure an error message is only showing up once per page request?


Relevant Module files

More

Best Answer

Your thinking was sound, but your understanding of Magento's magic methods is a little shaky. The hasX isn't a setter, it only checks for the presence of a data property. So you'd want to change

$session->hasErrorMessage(true);

to

$session->setErrorMessage(true);

Also, if b2b/session is an actual session object (i.e. it persists things to the PHP session for later retrieval) I'd be wary of using it for something like this. If you accidentally persist the 'error_message` property to the session that means the user will only ever see this error message once per session, when (it appears) your desire is to have them see it once per invalid order attempts.

I usually prefer a static PHP class variable for something like this

static protected $_hasErrorMessage=false;
protected function _setErrorMessage()
{
    $session = Mage::getSingleton("b2b/session");
    if (self::$_hasErrorMessage) {
        return;
    }
    $session->addError($this->helper->getErrorMessage());
    self::$_hasErrorMessage = true;
}
Related Topic