Action abbrechen

Hallo, ich möchte eine Action abbrechen, sobald etwas bestimmtes aufgetreten ist. Im originalen Quellcode von Shopware wird hierfür Return verwenden , allerdings funktioniert dies bei mir nicht. Des Weiteren stelle ich mir die Frage, warum sonst alles klappt, wenn ich ein PostDispatch Event nehmen , aber wiederum nicht, wenn ich ein PreDispatch Event verwende.

 "onBackendOrder"
			];
		}	
		
		public function onBackendOrder(\Enlight_Event_EventArgs $args)
		{
			$controller = $args->getSubject();
			$request = $controller->Request();
			
			if($request->getActionName() == "save")
			{
				$params = $controller->Request()->getParams();
				
				 // Bestellstatus "zur Lieferung bereit" und kein Trackingcode angegeben ? 
				if($params["status"] == 7 && empty(trim($params["trackingCode"])))
				{
					$controller->View()->assign([
						'success' => false,
						'message' => "Es muss vorher ein Trackingcode hinterlegt werden !!!",
					]);
					return; // Abbruch
				}
			}
		}	
	}

 

Du kannst hier sehen in welcher Reihenfolge die Events gefeuert werden: shopware/Action.php at 5.3 · shopware/shopware · GitHub

Wenn du eine Action abrechen möchtest, musst du hierfür direkt das zugehörige Event nehmen. Du hast ein sehr allgemeins Event genommen, welches bei jeder Action des Controllers gefeuert wird. Das richtige Event wäre: Enlight_Controller_Action_Backend_Order_Save  

1 „Gefällt mir“

@arnebecker schrieb:

Du kannst hier sehen in welcher Reihenfolge die Events gefeuert werden: https://github.com/shopware/shopware/blob/5.3/engine/Library/Enlight/Controller/Action.php#L135

Wenn du eine Action abrechen möchtest, musst du hierfür direkt das zugehörige Event nehmen. Du hast ein sehr allgemeins Event genommen, welches bei jeder Action des Controllers gefeuert wird. Das richtige Event wäre: Enlight_Controller_Action_Backend_Order_Save  

 "onBackendOrder"
			];
		}	
		
		public function onBackendOrder(\Enlight_Event_EventArgs $args)
		{
			
			$controller = $args->getSubject();
			
			$params = $controller->Request()->getParams();
			
			if($params["status"] == 7 && empty(trim($params["trackingCode"])))
			{
				mail("asdasdasd@web.de","so nicht","so geht das nicht");
				
				
				$controller->View()->assign([
						'success' => false,
						'message' => "geht nicht !!! hier!!",
				]);
				return;
				
			}
		}	
	}

Die Testemail wird nun verschickt, allerdings funktioniert der Abbruch nicht, also das mit assign und return.

Was heißt es, wenn kein PostDispatch oder PreDispatch davor steht ?

Moin @Fensterscheibe‍,

ich hole hier mal ein wenig aus, um dir den Sachverhalt komplett zu erklären.

Ein PreDispatch Event findet  vor  der Ausführung der originalen Action statt, ist aber lediglich als “Benachrichtigung” anzusehen.
Das heißt, dass du durch ein PreDispatch Event nicht die Möglichkeit hast die Ausführung der originalen Action zu unterbinden oder genutzte Variablen irgendwie zu manipulieren.
Ähnlich bei einem PostDispatch Event, bloß, dass dein Code dann  nach  der originalen Action ausgeführt wird.
Bei dem Pre- und PostDispatch Events kannst du im Eventnamen auch keine genaue Action angeben.

Sollten weder “PreDispatch” noch “PostDispatch” im Namen des Events vorkommen, so kannst du eine genaue Action angeben.
Hier wird dein Code ebenfalls  vor  der originalen Action ausgeführt.
Was ist nun der Unterschied zum PreDispatch Event?
Du kannst die Ausführung der originalen Action unterbinden in dem du ein  true  zurückgibst.

Genau anschauen kannst du dir dies hier.
Von Zeile 135 bis Zeile 148 siehst du die möglichen PreDispatch Events, sogenannte  notify  Events, die dich lediglich darauf hinweisen, dass der Code an einer bestimmten Stelle ist, du aber sonst nicht eingreifen kannst.

Von Zeile 172 - 186 siehst du die PostDispatch Events, ebenfalls  notify  Events.

Dazwischen, in Zeile 154 bis 160, siehst du ein sogenanntes  notifyUntil  Event - diese benachrichtigen dich ebenfalls darüber, dass der Code an einer bestimmten Stelle angekommen ist, jedoch hast du darüber hinaus die Möglichkeit die weitere Ausführung des darauffolgenden Codes zu verhindern.

Vielleicht hilft dir das ein wenig weiter zu verstehen, was genau da eigentlich passiert! :slight_smile:
Mehr Informationen zu den verschiedenen Event Typen, wie bspw. einem filter  Event, findest du übrigens in diesem Tutorial.
Gruß,
Patrick 

2 „Gefällt mir“

@Patrick Stahl schrieb:

Moin @Fensterscheibe‍,

ich hole hier mal ein wenig aus, um dir den Sachverhalt komplett zu erklären.

Ein PreDispatch Event findet  vor  der Ausführung der originalen Action statt, ist aber lediglich als „Benachrichtigung“ anzusehen.
Das heißt, dass du durch ein PreDispatch Event nicht die Möglichkeit hast die Ausführung der originalen Action zu unterbinden oder genutzte Variablen irgendwie zu manipulieren.
Ähnlich bei einem PostDispatch Event, bloß, dass dein Code dann  nach  der originalen Action ausgeführt wird.
Bei dem Pre- und PostDispatch Events kannst du im Eventnamen auch keine genaue Action angeben.

Sollten weder „PreDispatch“ noch „PostDispatch“ im Namen des Events vorkommen, so kannst du eine genaue Action angeben.
Hier wird dein Code ebenfalls  vor  der originalen Action ausgeführt.
Was ist nun der Unterschied zum PreDispatch Event?
Du kannst die Ausführung der originalen Action unterbinden in dem du ein  true  zurückgibst.

Genau anschauen kannst du dir dies hier.
Von Zeile 135 bis Zeile 148 siehst du die möglichen PreDispatch Events, sogenannte  notify  Events, die dich lediglich darauf hinweisen, dass der Code an einer bestimmten Stelle ist, du aber sonst nicht eingreifen kannst.

Von Zeile 172 - 186 siehst du die PostDispatch Events, ebenfalls  notify  Events.

Dazwischen, in Zeile 154 bis 160, siehst du ein sogenanntes  notifyUntil  Event - diese benachrichtigen dich ebenfalls darüber, dass der Code an einer bestimmten Stelle angekommen ist, jedoch hast du darüber hinaus die Möglichkeit die weitere Ausführung des darauffolgenden Codes zu verhindern.

Vielleicht hilft dir das ein wenig weiter zu verstehen, was genau da eigentlich passiert! :slight_smile:
Mehr Informationen zu den verschiedenen Event Typen, wie bspw. einem filter  Event, findest du übrigens in diesem Tutorial.
Gruß,
Patrick  Shopware

Danke für die ausführliche Erklärung. Da kein PreDispatch oder PostDispatch in dem Namen meines Events vorkommt , kann ich ja eine genaue Action angeben und diese dann mit true verhindern, wenn ich soweit alles richtig von dir verstanden habe.

Allerdings passiert das nicht, wenn ich mein folgendes Skript teste :

 "onBackendOrder"
			];
		}	
		
		public function onBackendOrder(\Enlight_Event_EventArgs $args)
		{
			
			return true;

		}	
	}

 

Moin @Fensterscheibe‍,

wenn ich deinen Code 1 zu 1 in ein kleines Beispiel-Plugin bei mir einbaue, funktioniert das einwandfrei.
Die Save-Methode im Bestellungs-Modul wird bei mir nicht mehr aufgerufen und der Klick auf den “Save” Button hat keinen Effekt mehr.

Da muss irgendwas bei dir lokal im Argen sein.

Auch wenn das bei dem Subscriber-Muster nicht notwendig sein sollte:
Hast du mal das Plugin neuinstalliert?
Ggf. mal den Cache geleert?
Wird die Methode “getSubscribedEvents” bei dir aufgerufen?
Wird der Listener “onBackendOrder” aufgerufen?

Das müsste so wirklich funktionieren.

Gruß,
Patrick  Shopware

1 „Gefällt mir“

Hi Patrick/Fensterscheibe,

man kann sehr wohl die Action im predispatch abrechen. Einfach ein Forward auf eine andere Action machen.

Gruß Heiner 

@Patrick Stahl schrieb:

Moin @Fensterscheibe‍,

wenn ich deinen Code 1 zu 1 in ein kleines Beispiel-Plugin bei mir einbaue, funktioniert das einwandfrei.
Die Save-Methode im Bestellungs-Modul wird bei mir nicht mehr aufgerufen und der Klick auf den „Save“ Button hat keinen Effekt mehr.

Da muss irgendwas bei dir lokal im Argen sein.

Auch wenn das bei dem Subscriber-Muster nicht notwendig sein sollte:
Hast du mal das Plugin neuinstalliert?
Ggf. mal den Cache geleert?
Wird die Methode „getSubscribedEvents“ bei dir aufgerufen?
Wird der Listener „onBackendOrder“ aufgerufen?

Das müsste so wirklich funktionieren.

Gruß,
Patrick  Shopware

Nachdem ich meinen Bitnami Stack neu gestartet habe, funktioniert es. Komischerweise habe ich sowieso einige Bugs dort, ich denke ich werde mich mal mit der Vagrant Variante beschäftigen, da es ja Problem mit Shopware unter Windows gibt. Vielen Dank !