Account Controller um Action erweitern *best practice*

Hallo zusammen, ich habe zwar grob ein paar Threads zu dem Thema gefunden, aber die waren meist recht alt und nicht ganz das was ich wollte. Mein Ziel ist es den Account-Controller um eine oder mehrere Actions zu erweitern. Wie ist die optimale Vorgehensweise? Ich hatte das Ganze in etwa wie folgt versucht: Account-Controller “überschreiben” $this-\>subscribeEvent( 'Enlight\_Controller\_Dispatcher\_ControllerPath\_Frontend\_Account', 'onGetAccountController' ); public function onGetAccountController() { return $this-\>Path() . 'Controllers/Frontend/ExtAccount.php'; } Und dann den eigenen Controller von der Account Klasse erben lassen und eigene Actions hinzufügen. Hat so aber nicht funktioniert und ich habe meine Zweifel, ob das so im Sinne des Erfinders ist. Besten Dank schonmal für eure Hilfe!

Warum möchtest du das überhaupt tun?! Gib mal bitte ein sinnvolles praktisches Beispiel. Viele Grüße

Hauptziel ist es, dass bestimmte Nutzer (z.B. eines Unternehmens) Einkäufer anlegen können. Um diese Einkäufer zu verwalten, sollen Sie im „Mein Konto“-Bereich einen zusätzlichen Navigationspunkt bekommen über den sie diese verwalten können. Da es sich um ein Account-Thema handelt, würde ich das Ganze auch gern über den entsprechenden Controller laufen lassen und nicht mit einem separaten arbeiten.

Warum sollte das zwingend in den Account controller müssen? Es ist vollkommen legitim, wenn die Logik deines Plugins auch in deinem Plugin controller steckt und dementsprechend angesprochen wird. Viele Grüße

Ja das mag sein, aber ich würde dennoch gern wissen, ob und wie die Erweiterung vorhandener Controller funktioniert.

http://community.shopware.com/Shopware- … 0_866.html

Ich dachte man könnte den nicht vorhandenen Methoden hooken, geht aber wohl doch nicht :frowning:

Ja das würde gehen, für das angesprochene Thema wäre ein eigener Controller doch ok, welcher einfach als post/pre dispatch beim Account Controller gefeuert wird. http://community.shopware.com/Shopware- … html#Hooks

Vielleicht könnte man den dispatch kapern: $this-\>subscribeEvent( 'Shopware\_Controllers\_Frontend\_Account::dispatch::replace', 'myDispatch' ); Und dann seine eigenen Actions ausführen: public function myDispatch(Enlight\_Hook\_HookArgs $args) { /\*\* @var Enlight\_Controller\_Action $subject \*/ $subject = $args-\>getSubject(); $action = $args-\>get('action'); if ($action == "meineEigeneAction") { $subject-\>executeParent('preDispatch'); if ($subject-\>Request()-\>isDispatched()) { $this-\>meineEigeneAction($args); $subject-\>executeParent('postDispatch', array()); } } else { $subject-\>executeParent( $args-\>getMethod(), $args-\>getArgs() ); } } Dabei vielleicht drauf achten, dass man weitergeleitet wird, wenn man nicht eingeloggt ist und die Action nicht ‚login‘, ‚logout‘, ‚password‘, ‚ajax_login‘ oder ‚ajax_logout‘ heißt.

Ja, das geht doch ganz einfach mit einem Event: (ohne Hooks!) Siehe: http://community.shopware.com/Shopware- … er_Actions Hooks auf Controller empfehlen wir überhaupt nicht bzw. braucht man auch nicht :slight_smile: Gruß Heiner

1 Like

Ich stehe immer noch vor der Lösung dieser Aufgabe: ich möchte innerhalb des Accounts meines Shops eine neue Seite erschaffen, welche Kundenspezifische Daten ausgeben. Die Soll mit einer neuen Action innerhalb des Account Controllers passieren. http://www.meineUrl.de/account/accountstatistics Der Aufruf Funktioniert auch soweit, nur leider wird der Controller ignoriert: folgendes steht in der Funktion install: $this-\>subscribeEvent('Enlight\_Controller\_Action\_Frontend\_Account\_AccountStatistics', 'onGetAccountControllerAction'); die Funktion onGetAccountControllerAction public function onGetAccountControllerAction(Enlight\_Event\_EventArgs $args) { $subject = $args-\>getSubject(); $request = $subject-\>Request(); $action = $request-\>getActionName(); error\_log("action: ".$action); // output:accountstatistics error\_log("function: onGetControllerPath"); $path\_to\_controller=$this-\>Path().'Controllers/Frontend/Account/AccountStatistics.php'; return $path\_to\_controller; } Der Controller in der AccountStatistics.php: class Shopware\_Controllers\_Frontend\_AccountStatistics extends Enlight\_Controller\_Action { public function init(){ error\_log("init"); $this-\>View()-\>addTemplateDir($this-\>Path().'Views/frontend/account/'); } public function indexAction(){ error\_log("index\_Action Fallback"); $this-\>View()-\>addTemplateDir($this-\>Path().'Views/frontend/account/'); $this-\>View()-\>loadTemplate('accountstatistics.tpl'); } public function accountstatisticsAction(){ error\_log("accountstatisticsAction"); $this-\>View()-\>addTemplateDir($this-\>Path().'Views/frontend/account/'); $this-\>View()-\>loadTemplate('accountstatistics.tpl'); } Die class Shopware_Controllers_Frontend_AccountStatistics wird komplett ignoriert. Daher kommt dort auch nicht irgendein error_log zustande. Kann jemand helfen ?

Hat das jemand hinbekommen?

Hi, das Controller-Dispatching in engine/Library/Enlight/Controller/Action.php:153 sollte euch (wie HL schon gesagt hat) tatsächlich erlauben, eigene Actions nach diesem Schema zu registrieren: “Enlight_Controller_Action_Frontend_CONTROLLER_ACTION”. Auch wenn das in anderen Systemen wohl üblich ist: Es wurde ja bereits gesagt, dass wir eigentlich eher dazu raten, eigene Controller anzulegen, die ihr dann bspw. via Ajax ansprecht. Das “virtuelle” Hinzufügen von Actions zu existierenden Controllern ist in SW kein übliches Vorgehen, wenn ihr also drum herum kommt, würde ich dazu raten, es zu vermeiden. Besten Gruß, Daniel

1 Like

Mit den folgenden Snippet hat es bei mir einwandfrei funktioniert. :-)

public static function getSubscribedEvents()
{
    return [
        'Enlight_Controller_Action_Frontend_Account_Test' => 'onAccountTestAction'
    ];
}

 

public function onAccountTestAction(\Enlight_Event_EventArgs $args)
{
    /** @var Enlight_Controller_Action $subject */
    $subject = $args->getSubject();

    $subject->View()->loadTemplate( __DIR__. '/../../Views/frontend/account/test.tpl');

    $args->setReturn(true);
    return true;
}

 

Hallo Thomas,

das ist ziemlich genau das was ich brauche. Ich würde allerdings gerne noch auf die Funktionen des core-Controllers zugreifen. In meinem Fall würde ich gerne den Register Controller um eine weitere ajaxValidate Action erweitern. Die beiden vorhandenen Funktionen greifen ja  z.B. auf die getPostData() Funktion zu. Kann ich das in meiner eigenen ControllerAction Funktion irgendwie erreichen ?

Gruß
Georg

Auf die getPostData() kannst Du nicht zugreifen da diese private ist.

Hi Thomas,

danke für die flotte Antwort. Was ist denn deine Empfehlung um ein weiteres Feld überprüfen zu können ?

 

Gruß

Georg