Hilfe, mein Magento-Controller wird nicht geladen – warum?

Magento-Controller sind manchmal eine verzwickte Sache. Ich möchte am Beispiel einer Frage zu „Tipps für die Entwicklung mit Magento: Teil 3 (Controller erweitern)“ zeigen, wie man hier debuggen und somit Fehlern auf die Schliche kommen kann.

Das Problem

Aufgabenstellung war, für die Extension „Company_Extension“ einen eigenen Controller zu erstellen (Punkt 6.1 laut Link) und einen bestehenden Controller zu erweitern (Punkt 6.2).

Nehmen wir an, der Onepage-Controller soll erweitert werden, dann stand in config.xml:

Der Controller liegt in app/code/[codepool]/Company/Extension/controllers/Checkout/OnePageController.php, wird aber nicht verwendet. Warum?

Von Controllern und Routern

So genannte Router im Code (nicht zu verwechseln mit den Hardware-Routern ;-)) sind dafür zuständig, anhand einer URL herauszufinden, welcher Controller und welche Action aufgerufen werden muss.

In Magento gibt es ein paar wenige Router. In den allermeisten Fällen kommt der Standard-Router Mage_Core_Controller_Varien_Router_Standard zum Einsatz. So auch hier. Im obigen Beispiel wird das für die Route „Company_Extension“ mit der Konfiguration „use“ definiert.

Die zwei wichtigsten Methoden des Standard-Routers für uns sind heute collectRoutes() und match(). Erstere sammelt aus den XML-Dateien alle „standard“-Routen zusammen und legt für Rewrites wie in unserem Beispiel die Reihenfolge der Module fest, zweitere versucht anhand des Requests den richtigen Controller zu finden.

Debugging des Controllers

Man hal also wie im Artikel angegeben alles konfiguriert, ruft die Seite auf und – nichts hat sich geändert. Kopfkratzen. Warum?

Jetzt könnte man lange überlegen. In der Praxis hat es sich aber bewährt, die Router-Klasse mit verschiedenen Debug-Ausgaben zu versehen um zu überprüfen, was sich im Code abspielt. [Wer über seine IDE debuggen/profilen kann, hat es umso besser.]

In diesem gist habe ich einige neuralgische Punte mit Debug-Ausgaben versehen (Magento CE 1.7.0.2):

Debug-Ausgabe deuten

Ruft man die Seite auf, erhält man diese Debug-Ausgabe:

Zuerst wird wie gewünscht nach einem Controller „Company_Extension_Checkout_OnepageController“ gesucht (siehe „Mage_Core_Controller_Varien_Router_Standard::match“).

Allerdings wird der Controller im Pfad „/path/to/magento/app/code/local/Extension/Company/controllers/Checkout/OnepageController/OnepageController.php“ gesucht („$controllerFileName“).

Die Datei existiert dort nicht: da steht einmal „OnepageController“ zu viel. Deswegen gibt die Methode _validateControllerClassName()  keinen Klassennamen („false“) zurück („$controllerClassName“). Magento setzt mit dem nächsten Modul fort und wird bei Mage_Checkout fündig.

Hinweise zu den Debug-Ausgaben

Einige Hinweise zu meinen Debug-Ausgaben:

  • Mage_Core_Controller_Varien_Router_Standard::match: checking module string
    Gibt aus, welche Controller-Klassen Magento aufgrund der Router-Konfiguration sucht.
    Taucht die eigene Extension schon hier nicht auf, kann man mittels der Ausgabe

    in Zeile 67 überprüfen, welche Konfiguration sich Magento aus den XML-Dateien für die Routen zusammenreimt.
  • $module, $controller, $action
    Modul, Controller und Action, die Magento aus den vorhandenen Informationen deutet.
  • $controllerFileName
    Pfad zur Controller-Datei, die Magento sucht. Er ergibt sich folgendermaßen:

    • den Wert aus der XML-Konfiguration heranziehen => „Company_Extension_Checkout_OnepageController
    • die ersten zwei Teile (Extensionname) extrahieren => „Company_Extension
    • den Pfad zum Controller-Directory dieser Extension generieren => „/path/to/magento/app/code/[codepool]/Company/Extension/controllers
    • die restlichen Teile des XML-Konfigurations-Wertes anhängen => „/path/to/magento/app/code/[codepool]/Company/Extension/controllers/Checkout/OnepageController
    • den Namen des ermittelten Controllers („onepage“) mit großem ersten Buchstaben sowie „Controller.php“ anhängen => „/path/to/magento/app/code/[codepool]/Company/Extension/controllers/Checkout/OnepageController/OnepageController.php
  • $controllerClassName
    Der Name der Controller-Klasse, die in $controllerFileName gesucht wird
  • $found
    Ist „true“, wenn ein Controller gefunden wurde, der die gewünschte Action besitzt.

Fehler beheben: das richtige Verzeichnis angeben

Wie sich zeigt, ist die Angabe „Company_Extension_Checkout_OnepageController“ falsch, denn der generierte $controllerFileName stimmt nicht. Wird „Company_Extension_Checkout“ angegeben, funktioniert es:

Magento kann einen $controllerClassName eruieren und gibt letztendlich „found bool(true)“ zurück.

Fehler beheben: den richtigen Wert in „before“ eintragen

Die Extension funktioniert jetzt – obwohl im before-Attribut ein falscher Wert steht (er stand auch in meinem Blog-Beitrag falsch, scheinbar hat das nie jemanden gestört ;-)).

Statt „Mage_Checkout_OnepageController“ muss hier „Mage_Checkout“ stehen. Die Lade-Reihenfolge wird nämlich auf Modul-Ebene, nicht auf Controller-Ebene angegeben. Funktioniert hat es trotzdem, weil Magento in der Methode collectRoutes() einen Eintrag ganz vorne anreiht, falls er das angegebene Modul nicht findet.

Fazit

Fazit: der Artikel macht die Arbeit mit Controllern hoffentlich etwas leichter. 😉

Das könnte Ihnen auch gefallen...