Установить сообщение об ошибке один раз на страницу запроса

magento.stackexchange https://magento.stackexchange.com/questions/6499

  •  16-10-2019
  •  | 
  •  

Вопрос

Я пытаюсь создать минимальный общий модуль оформления заказа, который не позволит кому -то проверить с общим количеством настраиваемой суммы.

Я использую мероприятие sales_quote_save_before Чтобы отобразить ошибку на странице оформления/корзины при ее открытии.

<?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>

И в наблюдателе

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());
}

Проблема в том, что когда вы обновляете корзину со страницы корзины, сообщение об ошибке отображается дважды. Я думаю, что это событие происходит несколько раз.

enter image description here

Я пытался проверить, было ли сообщение ранее установлено с помощью пользовательской переменной сеанса

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

Но это тоже не сработало. Как я могу убедиться, что сообщение об ошибке отображается только один раз на страницу запроса?


Соответствующие файлы модуля

Более

Это было полезно?

Решение

Ваше мышление было здоровым, но ваше понимание магических методов Magento немного шатко. А hasX Не сеттер, он только проверяет наличие свойства данных. Итак, вы хотели бы изменить

$session->hasErrorMessage(true);

к

$session->setErrorMessage(true);

Также, если b2b/session это фактический объект сеанса (то есть он сохраняет вещи для PHP -сессии для последующего поиска) Я буду опасаться использовать его для чего -то подобного. Если вы случайно сохраняете свойство 'error_message` на сеанс, что означает, что пользователь будет видеть это сообщение об ошибке только один раз за сеанс, когда (он появляется), ваше желание состоит в том, чтобы они увидели это один раз за попытки потери заказа.

Я обычно предпочитаю статическую переменную класса PHP для чего -то подобного

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

Другие советы

Давайте рассмотрим addError момент. addError это удобный метод для того, чтобы не делать звонки сообщений об ошибке так:

Mage::getModel('core/message_collection')->add(Mage::getSingleton('core/message')->error($message));

Как видите, это действительно грязно.

Большая часть реализации addError, включая это в Mage_core_model_session_abstract, иметь метод под названием addMessage, которые по сути делают то, что указано выше. Он использует локальный метод под названием getMessages который реализует шаблон сбора сообщений, уже описанный. Смотри ниже:

public function getMessages($clear=false)
{
    //....stuff
    if ($clear) {
        $messages = clone $this->getData('messages');
        $this->getData('messages')->clear();
        Mage::dispatchEvent('core_session_abstract_clear_messages');
        return $messages;
    }
    //...stuff
}

Так как это вам поможет?

Вы можете предоставить addMessage Метод в вашей собственной модели B2B/Session для условного прохода true к getMessages Чтобы очистить его, эффективно отображая только последний набор сообщений:

public function addMessage(Mage_Core_Model_Message_Abstract $message, $clear=false)
{

    $this->getMessages($clear)->add($message);
    Mage::dispatchEvent('core_session_abstract_add_message');
    return $this;   
}

Одно решение, которое я использовал (думал, что это не так красиво), - это пройти через сообщения для сеанса и посмотреть, существует ли эта строка.

/**
 * @var Mage_Checkout_Model_Session $_checkout
 */
protected $_checkout;
protected function _addMessage($message)
{
    $messages = array_values((array)$this->_checkout->getMessages());

    foreach ($messages[0] as $existingMessages) {
        foreach($existingMessages as $existingMessage) {
            $existingMessage = array_values((array)$existingMessage);

            if ($existingMessage[1] == $message) {
                // If the message is already set, stop here
                return;
            }
        }
    }

    // Add this message to the session/checkout
    $this->_checkout->addError($message);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top