Frage

Obwohl ich mit der Registrierung mit einem Front-End-Controller vertraut bin, kann ich diesen Front-End-Controller anscheinend nicht aus meiner Router-Klasse verwenden, ohne zuvor ein PHP-Include der Controller-Klasse fest zu codieren. Was meiner Meinung nach nicht notwendig sein sollte, wenn alles richtig konfiguriert ist. Ich möchte diese Router-Klasse verwenden, um festzustellen, ob die angeforderte URL mit meiner Nebenstelle übereinstimmt, und in diesem Fall den entsprechenden Controller / die entsprechende Aktion aufrufen.Mein aktuelles Setup ist wie folgt:

In der etc / config meiner Erweiterung.xml-Datei Ich habe sowohl meinen Router als auch meinen Controller registriert:

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

Hier ist meine Router-Klasse:

Beachten Sie die require_once aussage hier drin.Ich bin überzeugt, dass diese Codezeile ist nicht notwendig wenn meine Erweiterung richtig eingerichtet wäre.Zum Beispiel macht Mage_Cms_Controller_Router so etwas nicht.

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

}

Mein Frontend-Controller:

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

}

Offensichtlich bin ich mit der Entwicklung für diesen Controller noch nicht fertig.Der Punkt dieses Beitrags konzentrierte sich jedoch nicht auf den Inhalt der Aktionen dieses Controllers.Es greift einfach von meinem Router auf diese Aktionen zu, ohne vorher speziell eine require-Anweisung dazu machen zu müssen.

Der Front-End-Controller selbst funktioniert einwandfrei.Diese URL-Pfade geben die Methodennamen tatsächlich wie erwartet wieder:

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

Außerdem funktioniert meine aktuelle Konfiguration.Wie ich erwarte, funktionieren diese URL-Pfade auch wie erwartet:

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

Und schließlich, /parts-manual/ANYTHING_HERE/ANYTHING_HERE_ALSO/longer_url/ ergebnisse auf der 404-Seite von Magento.

Einige Beobachtungen:

Mein Router erweitert sich Mage_Core_Controller_Varien_Router_Standard während der Mage_Cms-Router erweitert wird Mage_Core_Controller_Varien_Router_Abstract.Ich habe versucht, meinen Router auf die gleiche Weise zu registrieren, wie es Magento getan hat:

class DoALL_Manual_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract

Fügte dies meinem hinzu etc/config.xml datei und kommentierte meine ursprüngliche Registrierung des Routers von aus 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>

Dann in dieser Methode zu meinem Router hinzugefügt:

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

Dieser Ansatz löst, obwohl er funktioniert, meine ursprüngliche Frage immer noch nicht warum muss ich eine fest codierte Require-Anweisung für meine Controller-Klasse ausführen.

War es hilfreich?

Lösung

Gut...nachdem ich fast eine Stunde gebraucht hatte, um diese Frage aufzuschreiben, löste ich sie buchstäblich, als ich mit dem Schreiben fertig war.Um zumindest diese Stunde nicht zu verschwenden, habe ich beschlossen, es zu posten, damit es vielleicht etwas zur Community beitragen kann.

Das hier war völlig unnötig:

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

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

Diese Zeilen hatte ich hinzugefügt, während ich mich inspirieren ließ von Inchoos Beitrag von 2012.

Die endgültige Konfiguration ist wie folgt:

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>

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

        return true;
    }

}

Controller:

(keine Änderungen notwendig)

So viele Stunden damit verbracht, dass ich diese eine Codezeile (die require-Anweisung) eliminieren konnte...

Vielleicht..nur vielleicht erspart dieser Beitrag eines Tages jemand anderem Stunden der Frustration :)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top