ルーター クラスからダイレクトするときにフロント エンド コントローラー クラスが見つかりません
-
13-12-2019 - |
質問
フロントエンド コントローラーを使用した登録には慣れていますが、最初にコントローラー クラスの 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 ステートメント) を削除するために、非常に多くの時間を費やしました...
多分..おそらく、この投稿はいつか他の誰かの何時間ものイライラを救うでしょう :)