В методе Observer, как вы говорите Magento не обрабатывать код после отправленного события - PullRequest
13 голосов
/ 13 марта 2011

У меня есть код в кассе, где я устанавливаю ключ в сеансе, если в любом месте кассы этот ключ имеет значение 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 Ответ

27 голосов
/ 14 марта 2011

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

Вы можете замкнуть этот поток в Обозревателе, подключившись к событию 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 (прародителю всех контроллеров) обойти вызванное действие (просмотрите строку 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 , чтобы увидеть, как вы обходите разделы Макет / Блок / Шаблон потока.

...