Установить сообщение об ошибке один раз на страницу запроса
-
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());
}
Проблема в том, что когда вы обновляете корзину со страницы корзины, сообщение об ошибке отображается дважды. Я думаю, что это событие происходит несколько раз.
Я пытался проверить, было ли сообщение ранее установлено с помощью пользовательской переменной сеанса
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);
}