Gehen wir mal davon aus wir hätten noch ein Legacy-Plugin mit einer Bootstrap-php, die einen Service registriert, den wir dekorieren wollen. Über die services.xml geht so etwas nicht.
class HprTest extends Plugin{
public static function getSubscribedEvents(){
return [
'Enlight_Bootstrap_AfterInitResource_hpr_legacy.the_service' => 'decorateService',
];
}
public function decorateService()
{
$coreService = Shopware()->Container()->get('hpr_legacy.the_service');
$refl = new \ReflectionClass(get_class($coreService));
$service = new TheNewService($config);
Shopware()->Container()->set('hpr_legacy.the_service', $service;
}
}
Sehr sehr unschön.. aber es funktioniert so. Der Weg über die XML ist natürlich sehr viel schöner, gerade weil die Injection der Constructor Arguments vom ursprünglichen Service übernommen werden man nicht diese per Reflections erst einmal wieder aus dem ursprünglichen Service heraus gepult werden müssen.
Oft will man irgendwelche Aufgaben erledigen, nach dem ein Artikel gespeichert wurde. Z.B. kann es sein, dass man diesen Artikel prüfen und zu irgendwas hinzufügen möchte oder auch einfach mit dem Artikel verknüpfte andere Artikel mit updaten muss.
Es gibt ein entsprechendes Event, um auf das Speichern eines Artikel im Backend zu reagieren. Dabei wird ein allgemeines Controller-Event verwendet, wie es für jeden Controller erzeugt wird und gegen die dort aufgerufene Action geprüft.
public static function getSubscribedEvents(){
return [
'Enlight_Controller_Action_PostDispatch_Backend_Article' => 'articleRefresh',
];
}
public function articleRefresh(\Enlight_Event_EventArgs $args){
/** @var $subject \Enlight_Controller_Action */
$subject = $args->getSubject();
$request = $subject->Request();
if ($request->getActionName() === 'save') {
$params = $request->getParams();
//TODO do something
}
}
Nun fehlt noch, dass wir auch Änderungen mit bekommen, wenn ein Artikel über die REST-API geändert wird.
Der Controller ist "Articles" und das Module ist "Api". Also ist unser Event "Enlight_Controller_Action_PostDispatch_Api_Articles". Die Action ändern sich natürlich auch, weil wir bei der REST-API Actions wie PUT und POST haben.
public static function getSubscribedEvents(){
return [
'Enlight_Controller_Action_PostDispatch_Backend_Article' => 'articleRefresh',
'Enlight_Controller_Action_PostDispatch_Api_Articles' => 'articleRefresh',
];
}
public function articleRefresh(\Enlight_Event_EventArgs $args){
/** @var $subject \Enlight_Controller_Action */
$subject = $args->getSubject();
$request = $subject->Request();
if (in_array($request->getActionName(), ['save', 'put', 'post'])) {
$params = $request->getParams();
//TODO do something
}
}
Damit sollte man jede Änderung an einem Artikel mitbekommen.
Das gleiche Prinzip sollte entsprechend auch für alle anderen Controller funktionieren.
foreach ($this->getListeners($event) as $listener) {
if (null !== ($return = $listener->execute($eventArgs))) {
$eventArgs->setReturn($return);
}
}
$eventArgs->setProcessed(true);
return $eventArgs->getReturn();
}
und da sehen wir
$eventArgs->setReturn($value);
Also ist die Lösung
public function eventMailListener(\Enlight_Event_EventArgs $args){
/** @var \Enlight_Components_Mail $mail */
$mail = $args->getReturn();
echo $mail->getPlainBodyText();
die();
}
Wenn man das erst einmal verstanden hat, ist alles plötzlich ganz einfach. Ach ja, wenn man das Subject überschreiben möchte erst einmal $mail->clearSubject(); ausführen.
Möchtest Du AdSense-Werbung erlauben und mir damit helfen die laufenden Kosten des Blogs tragen zu können?