라우터 클래스에서 지시할 때 프런트엔드 컨트롤러 클래스를 찾을 수 없음

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

문제

프런트 엔드 컨트롤러를 사용하여 등록하는 데 익숙하지만 컨트롤러 클래스의 PHP 포함을 먼저 하드 코딩하지 않으면 라우터 클래스에서 이 프런트 엔드 컨트롤러를 활용할 수 없는 것 같습니다. 모든 것이 올바르게 구성되면 필요하지 않다고 생각합니다. 이 라우터 클래스를 활용하여 요청된 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