Вопрос

Как перенаправить на модуль/контроллер/действие, когда я нахожусь в методе наблюдателя? Мне нужно перенаправить на myrouter/adminhtml_test/validate.

Зачем мне это: я пытаюсь запустить действие моего контроллера, который должен выполнить некоторые дополнительные расчеты после "Сохранить конфигурацию" был щелкнул System -> Configuration -> Mysection. Анкет Я зарегистрировал наблюдатель на мероприятии admin_system_config_changed_section _ {$ раздел}.

В моем методе handle_adminSystemConfigChangedSection() в Model/stemver.php Я пытаюсь уволить свое действие, но это не перенаправляет на это действие:

class My_Module_Model_Observer
{
    public function handle_adminSystemConfigChangedSection()
    {
        //I tried this code but it doesn't trigger the action:
        $url = Mage::helper('adminhtml')->getUrl("myrouter/adminhtml_test/validate");
        Mage::log($url); //To check if URL is correct (and it is correct)
        Mage::app()->getResponse()->setRedirect($url);
    }
}

Метод наблюдателя и контроллер работают нормально (ниже приведены подробности конфигурации). Я заменил метод наблюдателя этим кодом (от Форум Magento) с использованием header() И это работает:

public function handle_adminSystemConfigChangedSection()
{
    $url = Mage::helper('adminhtml')->getUrl("myrouter/adminhtml_test/validate");
    Mage::log($url);
    header( 'Location: ' . $url );
    exit();
}

Но это не является правильным способом перенаправления на действие. Как это должно быть сделано?

Детали конфигурации:

Конфигурация наблюдателя и маршрутизатора в config.xml:

<config>
...
    <global>
        ...
        <events>
            <admin_system_config_changed_section_mysection>
                <observers>
                    <mymodule>
                        <type>singleton</type>
                        <class>mymodule/observer</class>
                        <method>handle_adminSystemConfigChangedSection</method>
                    </mymodule>
                </observers>
            </admin_system_config_changed_section_mysection>
        </events>
    </global>
    <admin>
        <routers>
            <mymodule>
                <use>admin</use>
                <args>
                    <module>My_Module</module>
                    <frontName>myrouter</frontName>
                </args>
            </mymodule>
        </routers>
    </admin>
...
</config>

Контроллер в контроллерах/adminhtml/testcontroller.php:

class My_Module_Adminhtml_TestController extends Mage_Adminhtml_Controller_Action
{   
    public function validateAction()
    {
        Mage::log('Test: action is working!'); //To check if action is working
        //do something here...
    }
}
Это было полезно?

Решение

Опять же, что вы пытаетесь делать? Передача кого -то из SysConfig на ваш контроллер в лучшем случае нечетный UX, даже если вы перенаправляете обратно в SysConfig после выполнения вашего кода. Если это все, что вы делаете, вы должны употреблять пост и позволить Sysconfig вести себя как обычно.

Причина, по которой ваш (первый) перенаправление не работает, заключается в том, что после Это событие стреляет, выполнение возвращается в действие контроллера, который затем устанавливает свой собственный перенаправление в обычном:

class Mage_Adminhtml_System_ConfigController extends Mage_Adminhtml_Controller_Action
{
    public function saveAction()
    {
        // snip ...
        try {
            // snip ...
            Mage::dispatchEvent("admin_system_config_changed_section_{$section}",
                array('website' => $website, 'store' => $store)
            );
            // snip ...            }
        catch (Mage_Core_Exception $e) {
            // snip ...
        }
        catch (Exception $e) {
            // snip ...
        }
            // snip ...

        $this->_redirect('*/*/edit', array('_current' => array('section', 'website', 'store')));
    }

Вы можете обойти это пару способов:

  1. (не идеален) промыть ответ после установки перенаправления в браузере; Хотя это подчиняется вашим текущим намерениям, знайте, что вы не позволяете последующему нативному коду выполнять как в действии, так и в postDispatch().
  2. (Лучше, но все еще довольно уродливая) создайте создание вашего наблюдателя как синглтона, установите флаг, а затем установите этот класс наблюдателя, чтобы также потреблять controller_action_postdispatch_adminhtml_system_config_save Событие с использованием другого метода, который установит ваш перенаправление.

Например

public function checkShouldRedirect()
{
    $response = Mage::app()->getResponse();

    //use 'mysection' to check we are in correct section
    if (self::$flag==true && $this->getRequest()->getParam('section') == 'mysection') {
        $response->setRedirect(
            Mage::helper('adminhtml')->getUrl('myrouter/adminhtml_test/validate')
        );
        //below is only necessary for option 1
        //$response->sendResponse();
    }
}

Если вы собираетесь принять участие во втором варианте - и при условии, что вы не против действия действия, сохраняя состояние открытой панели - вы можете просто настроить своего наблюдателя на потребление Только Событие PostDispatch, так как вы можете проверить, что сохраняете свой раздел, протестируя section парамет

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top