В методе Observer, как вы сообщаете Magento не обрабатывать код после отправленного события

У меня есть код в кассе, где я устанавливаю ключ в сеансе, если этот ключ установлен на false в любом месте проверки, которую мне нужно отправить на страницу фактуры. У меня есть код для него, но у меня также не может быть кода, который обычно запускается после наблюдателя, потому что он вызовет службу третьей стороны и вернется как ошибочный из-за этого ключа, отсутствующего в сеансе

Вот мой код, у меня есть все, что я хочу, но мне нужно, чтобы ответ был незамедлительным и бесполезным после того, как отправленная строка события была запущена только в ответ, отправленный обратно в браузер.

public function checkForOrdKey(Varien_Event_Observer $observer)
    {
        $controllerAction = $observer->getControllerAction();
        $request = $controllerAction->getRequest();
        $controllerName = $request->getControllerName();
        $stepData = $this->_getCheckoutSession()->getStepData();
        $ordKeyRemoved = $this->_getCheckoutSession()->getOrdKeyRemoved();
        // if it is the checkout onepage controller or inventory controller don't do anything
        if (isset($controllerName) && $controllerName === "onepage" && $stepData['shipping']['complete'] && $ordKeyRemoved) {
            $this->_getCheckoutSession()->setStepData('shipping', 'complete', false);
            $result['goto_section'] = 'billing';
            Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
            $this->_getCheckoutSession()->setOrdKeyRemoved(false);

        }
    }

Ответы

Ответ 1

В основном вам нужно взять под контроль создание и отправку объекта Response. Нормальный поток контроллера будет обрабатывать всю логику встроенного метода, запускать события и собирать дополнения к ответу на этом пути, тогда инфраструктура Magento завершит и отправит ответ.

Вы можете закоротить этот поток в Observer, присоединив его к событию preDispatch (controller_action_predispatch_checkout_onepage_savebilling), а затем выполните следующее:

$request = Mage::app()->getRequest();
$action = $request->getActionName();
Mage::app()->getFrontController()->getAction()->setFlag($action, Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH, true);

В приведенных выше строках инструктируйте Mage_Core_Controller_Varien_Action (grandparent всех контроллеров) обойти действие, которое было вызвано (обзорная строка 414 в CE 1.4.2, чтобы увидеть, как это работает). Затем приступайте к созданию собственного ответа и отправке его обратно в браузер. Вам нужно будет исследовать правильный формат JSON для проверки класса JS, отображающего любые сообщения об ошибках, но что-то вроде этих строк...

$response = Mage::app()->getResponse();
$response->setHttpResponseCode(500);  //adjust to be whatever code is relevant
$json = Mage::helper('core')->jsonEncode($this->__('Your message here'));  //adjust
$response->setBody($json);
//don't need to sendResponse() as the framework will do this later

Таким образом, вы работаете в рамках Zend/Magento, и вам не нужно переопределять CheckoutController (пожалуйста, никогда...) или использовать "exit/die()" взлома. Причина, по которой выход/смерть плоха, заключается в том, что она препятствует любым последующим Наблюдателям, которые зарегистрировали интерес к этому Событию, способному действовать. Было бы очень неприятно, если разработчик зарегистрировал Наблюдателя, который никогда не будет вызван, потому что у другого разработчика есть выход из-за того, как вы попадете!

Обратите внимание, что установка флага no-dispatch выполняется только, если вы подключены к событию предварительной отправки.

Для получения дополнительной информации просмотрите диаграмму последовательности Magento чтобы увидеть, как вы обходите разделы Layout/Block/Template потока.