Shopware Backend - Bestellbestätigungs-E-Mail

Flexible Bestellbestätigungsmail in Shopware

Das Anpassen der Bestätigungsmail, die im Anschluss einer Bestellung verschickt wird ist bei Shopware absolut kein Problem. Wenn Sie einigermaßen HTML verstehen und mit Smarty-Variablen umgehen können, dann gehen Sie im Backend zu den Einstellungen->E-Mail-Vorlagen, klappen die System-E-Mails auf und passen den Eintrag, mit dem Namen „sORDER“ an. Dort können Sie Layout-Anpassungen vornehmen oder Informationen aus den, zur Verfügung stehenden Smarty-Variablen auswerten und zur Anzeige bringen.

Was ist aber wenn ihnen die zur Verfügung stehenden Variablen nicht ausreichen? Was ist wenn Sie Kundendaten auswerten möchten und daraufhin die E-Mail ganz unterschiedlich gestallten müssen? Im diesem Fall müssten Sie Ihre eigenen Smarty-Variablen in die Email-Vorlage einschleusen. Das Einschleusen von eigenen Variablen in bei Shopware normalerweise kein Problem - man meldet sich bei einem entsprechenden Event an, beschafft sich den Controller und fügt seiner View beliebig viele PHP-Objekte zu. Diese Objekte können dann im Template ausgelesen werden. Hier sieht die Sache allerdings etwas anders aus.

Wie wird die Bestätigungsmail ausgelöst

Wenn der Kunde seine Bestellung abgeschlossen hat, wird die Action „finish“ des „Checkout“-Controllers ausgelöst. Diese wiederrum ruft die Methode „saveOrder“ auf, in der ein Shopware-Modul „Order“ geladen wird. Mit dem Modul wird die Bestellung gespeichert und anschließen die Bestellbestätigung verschickt. Die Anmeldung beim Checkout-Event „Enlight_Controller_Action_PostDispatch_Frontend_Checkout“ mit einer anschließenden Abfrage auf die Action „finish“ bringt leider nichts, denn hier können wir keinerlei Einfluss auf die Erzeugung der Email nehmen.

Also müssen wir uns näher mit dem „Order“-Modul (engine\Shopware\Core\sOrder.php) auseinandersetzen. Wir betrachten genauer seine Methode „SendMail“.

Welche Events stehen zur Verfügung

Beim Betrachten der Methode „SendMail“ fallen einem einige, potenziell nutzbare Events auf. Als erstes wird das Event „Shopware_Modules_Order_SendMail_FilterVariables“ vom Typ „Filter“ geworfen:

        $variables = $this->eventManager->filter(
            'Shopware_Modules_Order_SendMail_FilterVariables',
            $variables,
            array('subject' => $this)
        );

Die Endung „Variables“ sieht zunächst vielversprechend aus und tatsächlich sind mit „Variables“ Smarty-Variablen gemeint. Als angemeldeter Eventteilnehmer kriegt man ein Array „$variables“, das alle Smarty-Variablen, die in der Bestätigungsmail verwendet werden beinhaltet. Leider kann man hier nur bestehende Variablen anpassen, denn neue Einträge werden später einfach ignoriert und nicht an das Email-Template weitergeleitet:

        $context = array(
            'sOrderDetails' => $variables["sOrderDetails"],

            'billingaddress'  => $variables["billingaddress"],
            'shippingaddress' => $variables["shippingaddress"],
            'additional'      => $variables["additional"],

            'sTaxRates'      => $variables["sTaxRates"],
            'sShippingCosts' => $variables["sShippingCosts"],
            'sAmount'        => $variables["sAmount"],
            'sAmountNet'     => $variables["sAmountNet"],

            'sOrderNumber' => $variables["ordernumber"],
            'sOrderDay'    => $variables["sOrderDay"],
            'sOrderTime'   => $variables["sOrderTime"],
            'sComment'     => $variables["sComment"],

            'attributes'     => $variables["attributes"],
            'sCurrency'    => $this->sSYSTEM->sCurrency["currency"],

            'sLanguage'    => $shopContext->getShop()->getId(),

            'sSubShop'     => $shopContext->getShop()->getId(),

            'sEsd'    => $variables["sEsd"],
            'sNet'    => $this->sNet,
        );

Man kann allerdings die eigenen Variablen an die Bestehenden anhängen. Beispielsweise kann man den Eintrag „additional“ nehmen und seine Variable drunter platzieren. Dadurch käme man sicher zum Ziel, allerdings hat es den Nachteil, dass es in dem Email-Template die eigene Variable mit einem langen Präfix beginnt, wodurch die Lesbarkeit, zumindest etwas drunter leidet. Außerdem gibt eine bessere Möglichkeit.

Als nächstes wird das „Shopware_Modules_Order_SendMail_Create“-Event geworfen:

      
        if ($event = $this->eventManager->notifyUntil(
            'Shopware_Modules_Order_SendMail_Create',
            array(
                'subject'   => $this,
                'context'   => $context,
                'variables' => $variables,
            )
        )) {
            $mail = $event->getReturn();
        }

Dieser Event gibt uns scheinbar eine Möglichkeit, die E-Mail im eigenen Eventhändler zu erzeugen und als Return-Wert zurückzugeben. Jedoch ist dieser Event vom Typ „notifyUntil“, was laut Shopware-Doku dazu verwendet wird um ein Abbruch zu bewirken. Wir halten uns an die Vorgaben von Shopware und schauen uns den nächsten Event an:

      
$mail = $this->eventManager->filter('Shopware_Modules_Order_SendMail_Filter',
    $mail, array(
            'subject'   => $this,
            'context'   => $context,
            'variables' => $variables,
));

Das ist ein Event vom Typ „filter“ und er scheint alles zu bieten was wir brauchen, also nehmen wir ihn. Als erstes registrieren wir uns auf diesem Event:

      
$this->subscribeEvent (
   'Shopware_Modules_Order_SendMail_Filter',  'modifySOrderMail'
);

Und das entsprechende Eventhandler:

public function modifySOrderMail(Enlight_Event_EventArgs $args){
  $context = $args->get('context');
  $context['customerData'] = $this->loadCustomerData();
  $mail = Shopware()->TemplateMail()->createMail('sORDER', $context);

  $config = $args->get('subject')->getConfig();
  $mail->addTo($args->get('subject')->sUserData["additional"]["user"]["email"]);
  if (!$config->get("sNO_ORDER_MAIL")) {
    $mail->addBcc($config->get('sMAIL'));
  }
  return $mail;
}

In der ModifySOrderMail holen wir uns den „Context“. Das ist ein Array das alle bestehen Variablen beinhaltet. Also fügen wir dort unsere „customerData“ hinzu. Als nächstes müssen wir die Email, unter Verwendung unserer Neuen „customerData“-Variablen erzeugen. Was noch bleibt ist das Setzen von Empfänger und die Rückgabe der E-Mail als Return-Wert. Wie die direkten Adressaten und die BCC-Empfänger richtig gesetzt werden schauen beim „Order“-Modul ab und machen es genau nach.

Nun kann die Variable „{$customerData}“ im Template verwendet werden. Im Übrigen kann anstelle von „Shopware()->TemplateMail()->createMail('sORDER', $context)“ beliebiges anderes E-Mail-Template aufgerufen werden. Dadurch haben Sie nicht nur die Möglichkeit eigene Variablen einzuschleusen, sondern sogar Ihre eigene E-Mail-Templates.