Класс интерфейсного контроллера не найден при перенаправлении из класса маршрутизатора

magento.stackexchange https://magento.stackexchange.com//questions/86750

Вопрос

Хотя я знаком с регистрацией с использованием интерфейсного контроллера, я, похоже, не могу использовать этот интерфейсный контроллер из моего класса router без предварительного жесткого кодирования PHP include класса controller. Что, я думаю, не должно быть необходимым, если все настроено правильно. Я хотел бы использовать этот класс маршрутизатора, чтобы увидеть, соответствует ли запрошенный URL-адрес моему расширению, и если да, то вызвать соответствующий контроллер/действие.Моя текущая настройка выглядит следующим образом:

В файле моего расширения etc/config.xml Я зарегистрировал как свой маршрутизатор, так и контроллер:

<frontend>
    <routers>
        <doall_manual>
            <use>standard</use>
            <args>
                <module>DoALL_Manual</module>
                <frontName>doall_manual</frontName>
            </args>
        </doall_manual>
    </routers>
</frontend>
<default>
    <web>
        <routers>
            <doall_manual>
                <area>frontend</area>
                <class>DoALL_Manual_Controller_Router</class>
            </doall_manual>
        </routers>
    </web>
</default>

Вот мой класс маршрутизатора:

Обратите внимание на require_once заявление здесь.Я убежден, что эта строка кода является в этом нет необходимости если бы мой добавочный номер был настроен правильно.Например, Mage_Cms_Controller_Router ничего подобного не делает.

class DoALL_Manual_Controller_Router extends Mage_Core_Controller_Varien_Router_Standard
{

    public function match(Zend_Controller_Request_Http $request)
    {
        // checking before even try to find out that current module
        // should use this router
        if (!$this->_beforeModuleMatch()) {
            return false;
        }

        $path = explode('/', trim($request->getPathInfo(), '/'));

        if ($path[0] != 'parts-manual') {
            return false;
        }

        $request
            ->setModuleName('doall_manual')
            ->setControllerName('manual');

        switch (count($path)) {
            case 1:
                $request->setActionName('index');
                break;

            case 2:
                $request->setActionName('manual');
                break;

            case 3:
                $request->setActionName('page');
                break;

            default:
                $request->setActionName('noroute');
                break;
        }

        // TODO: This line shouldn't be needed, but I'm unsure as to why it is not detecting the controller's location on it's own.
        require_once 'DoALL'.DS.'Manual'.DS.'controllers'.DS.'ManualController.php';

        $controllerInstance = Mage::getControllerInstance('DoALL_Manual_ManualController', $request, $this->getFront()->getResponse());

        // dispatch action
        $request->setDispatched(true);
        $controllerInstance->dispatch($request->getActionName());

        return true;
    }

}

Мой интерфейсный контроллер:

class DoALL_Manual_ManualController extends Mage_Core_Controller_Front_Action
{
    /**
     * Display all manuals
     */
    public function indexAction()
    {
        echo __METHOD__;
    }

    /**
     * Display a manual's index
     */
    public function manualAction()
    {
        echo __METHOD__;
    }

    /**
     * Display the parts from a manual's page.
     */
    public function pageAction()
    {
        echo __METHOD__;
    }

}

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

Сам интерфейсный контроллер работает просто отлично.Эти URL-пути фактически будут отображать имена методов, как и ожидалось:

/doall_manual/manual/
/doall_manual/manual/manual/
/doall_manual/manual/page/

Кроме того, моя текущая конфигурация работает.Как я и ожидал, эти URL-пути также работают должным образом:

/parts-manual/
/parts-manual/ANYTHING_HERE/
/parts-manual/ANYTHING_HERE/ANYTHING_HERE_ALSO/

И, наконец,, /parts-manual/ANYTHING_HERE/ANYTHING_HERE_ALSO/longer_url/ результаты на странице Magento 404.

Некоторые наблюдения:

Мой маршрутизатор расширяется Mage_Core_Controller_Varien_Router_Standard принимая во внимание, что маршрутизатор Mage_Cms расширяет Mage_Core_Controller_Varien_Router_Abstract.Я попытался зарегистрировать свой маршрутизатор таким же образом, как это сделал Magento:

class DoALL_Manual_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract

Добавил это к моему etc/config.xml файл и закомментировал мою первоначальную регистрацию маршрутизатора из default/web/routers:

<global>
    <events>
        <controller_front_init_routers>
            <observers>
                <doall_manual>
                    <class>DoALL_Manual_Controller_Router</class>
                    <method>initControllerRouters</method>
                </doall_manual>
            </observers>
        </controller_front_init_routers>
    </events>
<global>

Затем добавил этим методом к моему маршрутизатору:

/**
 * Initialize Controller Router
 *
 * @param Varien_Event_Observer $observer
 */
public function initControllerRouters($observer)
{
    /* @var $front Mage_Core_Controller_Varien_Front */
    $front = $observer->getEvent()->getFront();

    $front->addRouter('doall_manual', $this);
}

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

Это было полезно?

Решение

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

Это прямо здесь было совершенно не нужно:

$controllerInstance = Mage::getControllerInstance('DoALL_Manual_ManualController', $request, $this->getFront()->getResponse());

$request->setDispatched(true);
$controllerInstance->dispatch($request->getActionName());

Эти строки я добавил, черпая вдохновение из Пост Инчу от 2012 года.

Окончательная конфигурация выглядит следующим образом:

etc/config.xml

<frontend>
    <routers>
        <doall_manual>
            <use>standard</use>
            <args>
                <module>DoALL_Manual</module>
                <frontName>doall_manual</frontName>
            </args>
        </doall_manual>
    </routers>
</frontend>
<default>
    <web>
        <routers>
            <doall_manual>
                <area>frontend</area>
                <class>DoALL_Manual_Controller_Router</class>
            </doall_manual>
        </routers>
    </web>
</default>

Маршрутизатор:

class DoALL_Manual_Controller_Router extends Mage_Core_Controller_Varien_Router_Standard
{

    public function match(Zend_Controller_Request_Http $request)
    {
        // checking before even try to find out that current module
        // should use this router
        if (!$this->_beforeModuleMatch()) {
            return false;
        }

        $path = explode('/', trim($request->getPathInfo(), '/'));

        if ($path[0] != 'parts-manual') {
            return false;
        }

        $request
            ->setModuleName('doall_manual')
            ->setControllerName('manual');

        switch (count($path)) {
            case 1:
                $request->setActionName('index');
                break;

            case 2:
                $request->setActionName('manual');
                break;

            case 3:
                $request->setActionName('page');
                break;

            default:
                $request->setActionName('noroute');
                break;
        }

        return true;
    }

}

Контроллер:

(никаких изменений не требуется)

Так много часов было потрачено на то, чтобы я мог исключить эту одну строку кода (оператор require)...

Может быть..просто, может быть, этот пост когда-нибудь избавит кого-то еще от многих часов разочарования :)

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