Как правильно остановить оформление покупки у наблюдателя событий в Magento? - PullRequest
2 голосов
/ 19 января 2011

Я проверяю квоты доставки во время события checkout_controller_onepage_save_shipping_method, и если проверка не удалась, я хочу отправить пользователя обратно к выбору метода доставки, но я также хотел бы отобразить сообщение о том, почему это не удалось. Есть ли у Magento способ сделать это встроенным?

Я уже проверяю данные, мне просто не хватает перенаправления на способы доставки и способ отображения сообщения.

Ответы [ 3 ]

9 голосов
/ 19 января 2011

Ответ Алана Шторма, как всегда, информативен и поучителен. Но в этой ситуации одностраничная проверка в основном AJAX, которая игнорирует сообщение об ошибке сеанса, вы не увидите его, пока не покинете страницу проверки.

В saveShippingMethodAction есть следующая строка:

$result = $this->getOnepage()->saveShippingMethod($data);

... и затем $ result кодируется в формате JSON. Если вы переопределяете Mage_Checkout_Model_Type_Onepage::saveShippingMethod для выполнения проверки, а затем для контроля того, что возвращается, вы можете вставить сообщение об ошибке, которое будет возвращено браузеру и показано пользователю во всплывающем окне.

Ваше переопределение может выглядеть примерно так:

public function saveShippingMethod($shippingMethod)
{
    if ($this->doesntApplyHere()) {
        return array('error' => -1, 'message' => $this->_helper->__('Explain the problem here.'));
    }
    return parent::saveShippingMethod($shippingMethod);
}
9 голосов
/ 19 января 2011

(Ничто из этого не является проверенным кодом, но концепции должны привести вас туда, куда вам нужно идти)

Magento - это проект, осуществляемый группой разработчиков программного обеспечения.Когда вы работаете с группой инженеров-программистов, документация - это код.

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

Взгляните на одностраничный метод IndexAction контроллера проверки

app/code/core/Mage/Checkout/controllers/OnepageController.php
public function indexAction()
{
    if (!Mage::helper('checkout')->canOnepageCheckout()) {
        Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));
        $this->_redirect('checkout/cart');
        return;
    }
    ... 

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

Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));

То, что обрабатывает ошибку.Далее есть перенаправление.Это происходит здесь

$this->_redirect('checkout/cart');

Поскольку вы вызываете этот код от наблюдателя, у вас не будет доступа к этому методу.Однако, если вы исследуете контроллер

/**
 * Retrieve request object
 *
 * @return Mage_Core_Controller_Request_Http
 */
public function getRequest()
{
    return $this->_request;
}
...
protected function _redirect($path, $arguments=array())
{
    $this->getResponse()->setRedirect(Mage::getUrl($path, $arguments));
    return $this;
}

Вы можете увидеть его с помощью объекта ответа.Magento использует глобальный объект ответа (похожий на Zend и другие веб-фреймворки) для обработки того, что отправляется обратно в браузер (т.е. перенаправления заголовков).Вы можете получить ссылку на тот же объект через

Mage::app()->getResponse()

и можете выполнить перенаправление с чем-то вроде

Mage::app()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'));
3 голосов
/ 21 января 2011

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

 $error = array('error' => -1, 'message' => Mage::helper('core')->__("Message here"));
 Mage::getSingleton('checkout/session')->setSavedMethodError($error);

Тогда вы можете для каждого действия применять другого наблюдателя к 'controller_action_postdispatch_'.$this->getFullActionName()

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

$error =  Mage::getSingleton('checkout/session')->getSavedMethodError();
if($error){
   Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($error));
}
Mage::getSingleton('checkout/session')->setSavedMethodError(false);

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

Это работает, потому что вы переопределяете тело ответа, которое было установлено в saveShippingMethodдействие.

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