Mail an Admin nach Datenänderung: Event oder Hook?

Hallo, ich bin noch sehr neu im Umgang mit Shopware und prüfe gerade, wie ich das System an ein paar spezifische Anforderungen anpassen kann. Ich verwende hierfür die aktuelle Community Edition in der Version 4.0.8. Eine dieser Anforderungen ist, dass der Admin eine E-Mail bekommen soll wenn ein Kunde seine Stammdaten im Shop (Rechnungsadresse oder Lieferadresse) ändert. Ich bin mir nun sehr unsicher wie ich das Implementieren soll. Ich habe zum Testen ein kleines Plugin unter shopware/engine/Shopware/Plugins/Local/Frontend/myHook/Bootstrap.php hinterlegt und dieses im Plugin-Manager aktiviert. Nun möchte ich den Mailversand nach den Aktionen implementieren. Ich weiß aber nicht genau, ob dies über einen Event oder einen Hook am besten durchgeführt wird. Und ich bin mir auch unsicher, wo und wie ich die Anbindung hinterlegen muss. Hier mein Code: <?php class Shopware_Plugins_Frontend_myHook_Bootstrap extends Shopware_Components_Plugin_Bootstrap { public function install() { // so? $this->subscribeEvent( 'sAdmin::sUpdatePayment::before', 'mailAdminInfo' ); // oder doch so? $this-\>subscribeEvent( 'Enlight\_Controller\_Action\_PostDispatch\_Account\_Payment', 'mailAdminInfo' ); return true; } public static function mailAdminInfo(Enlight\_Hook\_HookArgs $args) { mail('mail@admin.de', 'Nur ein Test', 'Inhalt'); } } Ich bin mir in zwei Punkten sehr unsicher: 1.) Ist mein Grundaufbau überhaupt richtig (Plugin, install()-Methode etc.)? 2.) Woran wird meine Aktion am besten gekoppelt? Ist die Verwendung von Konstrukten wie ‚sAdmin::sUpdatePayment::before‘ richtig oder deprecated? Vielen Dank für Tipps und Hilfe bei meinen Newbie-Fragen… Viele Grüße Timo

Hallo, ich habe die Funktionalität nun als Hook wie folgt vorbereitet: $this-\>subscribeEvent( 'sAdmin::sUpdateBilling::after', 'mailAdminInfo' ); $this-\>subscribeEvent( 'sAdmin::sUpdateAccount::after', 'mailAdminInfo' ); $this-\>subscribeEvent( 'sAdmin::sUpdateShipping::after', 'mailAdminInfo' ); $this-\>subscribeEvent( 'sAdmin::sUpdatePayment::after', 'mailAdminInfo' ); Nun stellt sich für mich noch die Frage wie ich den Versand einer E-Mail einbinden kann/soll. Unter http://wiki.shopware.de/Beispiel-Plugin … l_572.html habe ich ein Beispiel für den Mailversand gefunden. Hier läuft der Mailversand wie folgt: //erstellt ein neues Mail Objekt damit die Mailfunktion keine alten Daten beinhaltet. $mail = new Enlight\_Components\_Mail(); $mail-\>IsHTML(0); $mail-\>From = Shopware()-\>Config()-\>Mail; // Absender = Mail Shopbetreiber $mail-\>FromName = Shopware()-\>Config()-\>Mail; // Absender = Mail Shopbetreiber $mail-\>Subject = "Ihre Rechnung zur Bestellung $ordernumber"; // Betreff $mail-\>Body = "Im Anhang finden Sie Ihre Rechnung"; // Inhalt $mail-\>ClearAddresses(); // Vorherige Adressen entfernen // Die in der Plugin-Konfiguration eingetragene Adresse als Empfänger nehmen $mail-\>AddAddress($email, ''); $mail-\>addAttachment(Shopware()-\>DocPath() . "files/documents/" . $getDocument["hash"] . ".pdf", $getDocument["docID"] . ".pdf"); // Mail versenden $mail-\>Send(); Ich frage mich nun jedoch, ob die Verwendung von Enlight_Components_Mail() der richtige Weg ist oder ob dies mittlerweile veraltet ist? Was sollte in Shopware 4 verwendet werden? Vielen Dank für Tipps und Hilfe. Timo

Hallo, mühsam ernährt sich das Eichhörnchen ;-). Also ich habe es jetzt geschafft die Mail auf Basis einer E-Mail Vorlage zu versenden: $mail = Shopware()-\>TemplateMail()-\>createMail('uDATACHANGED', $this-\>mail\_context); $email = 't.haehne@ipark-media.de'; $mail-\>addTo($email); Hier stellt sich für mich jetzt noch die Frage, wie ich im Rahmen der Plugin-Installation meine Mailvorlage erstellen kann. Dies sollte doch irgendwie möglich sein, oder? Leider habe ich kein Beispiel oder keine Doku dazu gefunden. Zudem habe ich noch das Problem, dass in der E-Mail nur die alten Werte ausgegeben werden. Mein Ansatz ist eigentlich folgender: Ich habe einen before und einen after-Hook. Mit dem before-Hook möchte ich die alten Daten vor der Speicherung ermitteln und im after-Hook die neuen Daten nach der Änderung. Folgende Methode verwende ich hierfür: // Merken der Kundendaten. Aufruf before und after für Vergleich der Daten public function prepareCustomerValues(Enlight\_Hook\_HookArgs $args, $prefix = 'old') { // Get customer by Id $customerId = Shopware()-\>Session()-\>sUserId; if($customerId === null) { return; } /\*\* @var $customer \Shopware\Models\Customer\Customer \*/ $customer = Shopware()-\>Models()-\>find('Shopware\Models\Customer\Customer', $customerId); if (!$customer) { return; } // Daten vom Kunden für Mail aufbereiten $this-\>mail\_context[$prefix.'.firstname'] = $customer-\>getBilling()-\>getFirstName(); $this-\>mail\_context[$prefix.'.lastname'] = $customer-\>getBilling()-\>getLastName(); $this-\>mail\_context[$prefix.'.customernumber'] = $customer-\>getBilling()-\>getNumber(); $this-\>mail\_context[$prefix.'.street'] = $customer-\>getBilling()-\>getStreet(); $this-\>mail\_context[$prefix.'.streetnumber'] = $customer-\>getBilling()-\>getStreetNumber(); $this-\>mail\_context[$prefix.'.zipcode'] = $customer-\>getBilling()-\>getZipCode(); $this-\>mail\_context[$prefix.'.city'] = $customer-\>getBilling()-\>getCity(); $this-\>mail\_context[$prefix.'.phone'] = $customer-\>getBilling()-\>getPhone(); $this-\>mail\_context[$prefix.'.email'] = $customer-\>getEmail(); } Das Array $this->mail_context übergebe ich dann an die E-Mail. Leider habe ich nun das Problem, dass in beiden Hooks die gleichen Werte ermittelt werden, nämlich die alten. Es wirkt für mich so, dass im after-Hook die Speicherung der neuen Daten (das flushen) noch nicht stattgefunden hat. Kann das sein? Wie komme ich an die neuen Daten des Kunden? Ich möchte nur ungern auf die Post-Werte zugreifen. Danke für Tipps und Hilfe. Viele Grüße Timo

1 „Gefällt mir“

Wenn ich es richtig sehe liegt dies daran, dass in der sUpdateBilling-Methode nicht mit dem Doctrine-Objekt gearbeitet wird und die Änderung direkt in die Datenbank geschrieben wird. Da Doctrine das Objekt nur einmal holt sind alt und neu identisch. Irgendwie blöd - mir fällt gerade noch keine Lösung dafür ein…

Eine Möglichkeit wäre es, dass Objekt über den EntityManager zu aktualisieren ($em->refresh($customer)). Problem ist nur, dass ich noch nicht weiß wie ich an den EntityManager rankomme… EDIT: Ok - ich habs gefunden: Mit Shopware()->Models()->refresh($customer); geht es. Dieser Aufruf ist erforderlich, damit das after-Objekt auch die aktuellen Werte beinhaltet.

Danke für deinen Code. Den kann ich demnächst auch noch gebrauchen. :slight_smile: