Classe de contrôleur frontal introuvable lors de la direction à partir de la classe de routeur

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

Question

Bien que je sois familier avec l'enregistrement à l'aide d'un contrôleur frontal, je n'arrive pas à utiliser ce contrôleur frontal de ma classe de routeur sans d'abord coder en dur une inclusion PHP de la classe de contrôleur. Ce qui, à mon avis, ne devrait pas être nécessaire si tout est configuré correctement. J'aimerais utiliser cette classe de routeur pour voir si l'URL demandée correspond à mon extension et, si c'est le cas, appeler le contrôleur/l'action appropriée.Ma configuration actuelle est la suivante :

Dans le fichier etc/config.xml de mon extension, j'ai enregistré mon routeur et mon contrôleur :

<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>

Voici ma classe de routeur :

Remarquez le require_once déclaration ici.Je suis convaincu que cette ligne de code est pas nécessaire si mon extension était configurée correctement.Par exemple, Mage_Cms_Controller_Router ne fait rien de tel.

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

}

Mon contrôleur frontal :

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

}

Je n'ai évidemment pas fini le développement de ce contrôleur.Cependant, le but de cet article n'est pas centré sur le contenu des actions de ce contrôleur.Il s'agit simplement d'accéder à ces actions depuis mon routeur, sans avoir à faire spécifiquement une instruction require dessus au préalable.

Le contrôleur frontal lui-même fonctionne très bien.Ces chemins d'URL feront en fait écho aux noms de méthodes comme prévu :

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

De plus, ma configuration actuelle fonctionne.Comme je m'y attendais, ces chemins d'URL fonctionnent également comme prévu :

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

Et enfin,/parts-manual/ANYTHING_HERE/ANYTHING_HERE_ALSO/longer_url/ résultats dans la page 404 de Magento.

Quelques observations :

Mon routeur s'étend Mage_Core_Controller_Varien_Router_Standard alors que le routeur Mage_Cms s'étend Mage_Core_Controller_Varien_Router_Abstract.J'ai essayé d'enregistrer mon routeur de la même manière que Magento :

class DoALL_Manual_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract

J'ai ajouté ceci à mon etc/config.xml fichier et j'ai commenté mon enregistrement original du routeur à partir de 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>

Puis ajouté cette méthode à mon routeur :

/**
 * 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);
}

Cette approche, même si elle fonctionne, ne résout toujours pas ma question initiale quant à pourquoi dois-je effectuer une instruction require codée en dur sur ma classe de contrôleur.

Était-ce utile?

La solution

Bien...après avoir pris près d'une heure pour rédiger cette question, je l'ai résolue littéralement au moment où j'avais fini de l'écrire.Donc, dans un effort pour ne pas au moins perdre cette heure, j'ai décidé de la publier afin qu'elle puisse peut-être apporter quelque chose à la communauté.

Ici, c'était totalement inutile :

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

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

Ces lignes que j'avais ajoutées, en m'inspirant de Message d'Inchoo de 2012.

La configuration finale est la suivante :

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>

Routeur :

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

}

Manette:

(aucun changement nécessaire)

Tant d'heures passées pour que je puisse éliminer cette seule ligne de code (l'instruction require)...

Peut être..peut-être que cet article épargnera à quelqu'un d'autre des heures de frustration un jour :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top