ルーター クラスからダイレクトするときにフロント エンド コントローラー クラスが見つかりません

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 ステートメントを実行する必要があるのはなぜですか.

役に立ちましたか?

解決

良い...この質問を書き出すのに1時間近くかかりましたが、書き終えた瞬間に文字通り解決しました。そこで、少なくともこの時間を無駄にしないようにと、コミュニティに何か貢献できるように投稿することにしました。

これはまったく不要でした。

$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;
    }

}

コントローラ:

(変更の必要はありません)

その 1 行のコード (require ステートメント) を削除するために、非常に多くの時間を費やしました...

多分..おそらく、この投稿はいつか他の誰かの何時間ものイライラを救うでしょう :)

ライセンス: CC-BY-SA帰属
所属していません magento.stackexchange
scroll top