Я использовал подобный подход ранее, хотя я использовал методы Mage :: register () / Mage :: registry (), а не настройки в сеансе. Но вы действительно должны быть осторожны с этим способом ведения дел. Основная проблема заключается в том, что обычные методы также изменяют данные в сеансе. Например, этот фрагмент находится в saveShippingMethodAction () ... $ this-> getCheckout () -> setStepData ('shipping_method', 'complete', true) -> setStepData ('payment', 'allow', true);

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

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

Ответы на вопрос(3)

Решение Вопроса

как всегда, информативен и поучителен. Но в этой ситуации одностраничная проверка в основном 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);
}
 rennat19 янв. 2011 г., 22:50
к сожалению, я перераспределяю код :( это модуль для провайдера доставки, чтобы дать клиентам
 Alan Storm19 янв. 2011 г., 02:38
Ах, я бы неправильно понял, к какому событию подключился ОП. Я думал, что это было окончательное представление. Мои инстинкты говорят, что все еще есть способ сделать это без переопределения, хотя переопределение может быть лучшим путем, если вы не перераспределяете код.
 Alan Storm20 янв. 2011 г., 00:15
@rennat: Это не то, что я имел в виду под перераспределением. Вы даете это клиентам. Это означает, что у вас есть существующие отношения с ними, и, по малой вероятности, у них есть другой модуль, который также пытается переопределить вашу функцию, вы можете помочь им справиться с этим. Кроме того, только потому, чтоIмы пришли к выводу, что переопределения классов не должны использоваться в распространяемом коде, безусловно, не помешали разработчикам расширений сделать это.

но концепции должны привести вас туда, куда вам нужно)

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'));
 Alan Storm06 апр. 2016 г., 21:40
@NicholasGraziano Исправлено, и спасибо!
 Alan Storm20 янв. 2011 г., 00:12
См. Ответ ниже, выше может работать в рамках ajax-системы оформления одной страницы.
 Alan Storm22 янв. 2011 г., 00:24
BY ниже, что означает @ clockworkgeek's, который сейчас выше.
 nick.graziano06 апр. 2016 г., 01:07
Для любого копирования / вставки -Mage::app()->getResponse()->setRedirct(Mage::getUrl('checkout/cart')); должно бытьMage::app()->getResponse()->setRedirect(Mage::getUrl('checkout/cart')); Я бы отредактировал, но это менее 6 символов. Спасибо Алан!

без необходимости переопределять контроллер. В основном я делаю то же самое, но только в методах наблюдателя. Поэтому я использую 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.

 shaune12 мар. 2011 г., 03:03
Я использовал подобный подход ранее, хотя я использовал методы Mage :: register () / Mage :: registry (), а не настройки в сеансе. Но вы действительно должны быть осторожны с этим способом ведения дел. Основная проблема заключается в том, что обычные методы также изменяют данные в сеансе. Например, этот фрагмент находится в saveShippingMethodAction () ... $ this-> getCheckout () -> setStepData ('shipping_method', 'complete', true) -> setStepData ('payment', 'allow', true);

Ваш ответ на вопрос