Überschreiben der preDispatch-Methode eines Core-Controllers

7

Ich muss die preDispatch-Methode eines Core-Controllers überschreiben. Der Core-Controller erbt von Mage_Checkout_Controller_Action, der selbst über eine PreDispatch-Methode verfügt, die aufgerufen werden muss. Da ich von dem Core-Controller ausgehe, den ich überschreiben möchte, kann ich nicht einfach anrufen parent::preDispatch(), da dies die Funktionalität beeinträchtigen würde, die ich vermeiden möchte.

Meine Frage ist: Wie kann ich eine überschriebene Methode aufrufen, die zwei Ebenen höher in der Vererbungskette liegt, oder gehe ich einfach falsch vor?

Aktualisieren

Anscheinend funktioniert das:

Mage_Checkout_Controller_Action::preDispatch(); (Obwohl diese Methode nicht statisch ist, lernst du jeden Tag etwas Neues.)

Meine Frage lautet nun: Gibt es eine bessere Möglichkeit, dies zu tun, ohne alle Funktionen aus der Klasse kopieren zu müssen, die ich überschreibe?

Der Grund, warum ich dies versuche, ist, dass ich diesen Weg eingeschlagen habe und versucht habe, Magento zu zwingen, sich an Adresszuweisungen zu erinnern, wenn Kunden die Multishipping-Kasse durchlaufen und anschließend gehen. (FWIW, ich fand den verlinkten Artikel großartig, um mich in die richtige Richtung zu bringen, aber es scheint viel zu fehlen, was die Schritte angeht, die unternommen werden müssen, damit dies funktioniert).

Der Controller, den ich überschreibe, ist der Core MultiShippingController, der eine Umleitung zurück zur Multishipping IndexAction hat, die vermieden werden muss. Nebenbei bemerkt, ich habe diese Funktionalität größtenteils vollständig erhalten, abgesehen von einigen Problemen (im Zusammenhang mit dem Hinzufügen des ersten Artikels zum Warenkorb und dem Mage_Sales_Model_Quote_Item-> getQuoteItem (), das in der Adresse address.phtml null zurückgibt das ist eine ganz andere Diskussion).

Jeff Lambert
quelle
1
Nur für den Fall, dass jemand anderes später darauf eingeht und sich fragt, wie / warum die (scheinbar) statische Syntax funktioniert. Ich verweise Sie auf diese StackOverflow-Antwort, die es sehr gut erklärt. Kurz gesagt, es ist nicht "statisch", genauso wie parent::someMethod()es nicht statisch ist, sondern gibt einen Teil des Vererbungsbaums an, der durchlaufen werden soll, bevor eine Methode im richtigen $thisKontext der Instanz der aktuellen Klasse aufgerufen wird.
Brian

Antworten:

8

Ich denke, es wäre interessant, genau zu wissen, was Sie erreichen wollen, aber ich kann Ihnen ein paar Hinweise geben, ohne Details zu kennen:

In den meisten Fällen können Sie die Methode, auf die Sie verweisen möchten $this, sicher statisch aufrufen:

Mage_Checkout_Controller_Action::preDispatch()

Aber Sie sollten dies wahrscheinlich über einen Controller-Predispatch-Beobachter tun. Magento bietet Ihnen die Möglichkeit, dies zu tun in Mage_Core_Controller_Varien_Action:

abstract class Mage_Core_Controller_Varien_Action
{
    // [...]
    public function preDispatch()
    {
        // [...]
        if ($this->_rewrite()) {
            return; // [What is the purpose if this?]
        }
        // [...]

        // [This is where my event needs to be firing, but this code never gets 
        // executed because the controller is rewritten]
        Mage::dispatchEvent(
            'controller_action_predispatch_'.$this->getFullActionName(),
            array('controller_action'=>$this)
        );

    }
    // [...]
}

Sie müssen lediglich den vollständigen Aktionsnamen am Ende von hinzufügen controller_action_predispatch. Ein Beispiel für die Shoehorning-Funktionalität in Onepage Savebilling:

    <events>
        <controller_action_predispatch_checkout_onepage_saveBilling>
            <observers>
                <some_unique_name_for_this_event>
                    <class>yourmodel/observer</class>
                    <method>myPredispatchObserver</method>
                </some_unique_name_for_this_event>
            </observers>
        </controller_action_predispatch_checkout_onepage_saveBilling>
    </events>

Darüber hinaus müssen Sie bei Ihrer Beobachtermethode den Beobachter akzeptieren, und Sie können den Controller selbst erhalten von getEvent:

<?php

class MyCompany_MyModule_Model_Observer
{

    public function myPredispatchObserver($observer)
    {
        $controller = $observer->getEvent()->getControllerAction();
    }
}
philwinkle
quelle
1
Danke für den Einblick. Ich habe meine Frage aktualisiert, warum ich das mache.
Jeff Lambert
1

Ich bin auf meinem Telefon, aber ich würde denken, dass Sie eines von mehreren Ereignissen verwenden könnten, um die Umleitung aus dem Antwortobjekt zu entfernen.

Benmarks
quelle