E-Mail Benachrichtigung unter FLOW3

Möchte man unter FLOW3 nach gewissen Aktionen eine Benachrichtigung per E-Mail verschicken so nutzt man dafür am besten Signals & Slots.

Unter FLOW3 „feuert“ man in seinen Klassen Signale ab. Diese Signale werden, richtig konfiguriert, dann von FLOW3 abgefangen und führen anschließend Funktionen (Slots) aus.

In den Klassen in denen man Signale setzen möchte definiert man eine Funktion, die nichts ausführt und auch nichts zurück gibt. Wir nehmen hier mal als beispiel eine Benutzer Registrierung in einem Controller.

/**
 * @param \TYPO3\FLOW3\Security\Account $account
 * @return void
 * @FLOW3\Signal
 */
protected function emitAccountCreated(\TYPO3\FLOW3\Security\Account $account) {}

Nun kann man in seiner „createAction“ das Signal „abfeuern“:

/**
 * @param \TYPO3\FLOW3\Security\Account $account
 * @return void
 */
public function createAction(\TYPO3\FLOW3\Security\Account $account) {
  ...
  $this->emitAccountCreated($account);
  ...
}

Natürlich muss das System nun auch wissen was er mit diesem Signal machen soll. Dazu erstellen wir nun Slots die die Befehle ausführen. Wir erstellen einen Order „Service“ unter dem Ordner „Classes“ und legen dort eine Datei mit dem Namen „Notification.php“ an:

namespace My\Package\Service;

use TYPO3\FLOW3\Annotations as FLOW3;

class Notification {
  /**
   * @param \TYPO3\FLOW3\Security\Account $account
   */
  public function sendNewRegistrationNotification(\TYPO3\FLOW3\Security\Account $account) {
    $mail = new \TYPO3\SwiftMailer\Message();
    $mail->setFrom(array('meine@domain.tld ' => 'FLOW3 System'))
         ->setTo(array('meine@email.tld ' => 'Max Müller'))
         ->setSubject('New registration')
         ->setBody('New user registration: '.$account->getAccountIdentifier())
         ->send();
  }
}

Nun müssen wir dem Signal auch einen Slot zuweisen. Dazu editieren wir die Package.php in unserem Paket („My.Package/Classes/Package.php“) und überschreibt die geerbte Funktion „boot“ wenn man diese noch nicht haben sollte.

namespace My\Package;

use TYPO3\FLOW3\Package\Package as BasePackage;
use TYPO3\FLOW3\Annotations as FLOW3;

/**
 * Package base class of the My.Package package.
 *
 * @FLOW3\Scope("singleton")
 */
class Package extends BasePackage {

  /**
   * Invokes custom PHP code directly after the package manager has been initialized.
   *
   * @param \TYPO3\FLOW3\Core\Bootstrap $bootstrap The current bootstrap
   * @return void
   */
  public function boot(\TYPO3\FLOW3\Core\Bootstrap $bootstrap) {
    $dispatcher = $bootstrap->getSignalSlotDispatcher();

    /*
     * NOTIFICATIONS TO BE SEND
     */
    $dispatcher->connect(
      'My\Package\Controller\StandardController', 'accountCreated',
      'My\Package\Service\Notification', 'sendNewRegistrationNotification'
    );
  }

}

Nun sind die Signale mit den Slots verbunden und funktionieren bereits. Sobald sich ein Neuer Benutzer registriert erhalten wir eine E-Mail. Diese ist zwar nicht schön, aber lieft uns die gewünschten Informationen.

Wie bekommt man es nun hin das man auch hier mit Templates arbeiten kann? Wie wir wissen sollten wir ja Code und Layout trennen. Und selbstverständlich würden wir auch gerne weiterhin im Modernen Fluid Template arbeiten. Die Lösung hierfür ist die Klasse „StandaloneView“. Sie macht es uns möglich einen View in jeglicher Klasse zu bekommen.

Wir legen nun also erstmal unser Template dafür an und bearbeiten die Datei „My.Package/Resources/Private/Templates/Notification/NewRegistration.html“. Da wir ja alles Ordentlich machen wollen, und außerdem für kommende Übersetzungen gewappnet sein wollen, definieren wir hier drei Sektionen: eine für die Überschrift, eine für die HTML Variante und schließlich noch eine für die Nur Text Version:

<f:section name="subject">
  New registration
</f:section>

<f:section name="html">
  A new Registration has been incoming:<br/>
  <br/>
  Data:<br/>
  <tabel>
    <tr><th>Identifier:</th><td>{account.accountIdentifier}</td></tr>
    <tr><th>First name:</th><td>{account.party.name.firstName}</td></tr>
    <tr><th>Middle name:</th><td>{account.party.name.middleName}</td></tr>
    <tr><th>Last name:</th><td>{account.party.name.lastName}</td></tr>

    <f:for each="{account.party.electronicAddress}" as="electronicAddress">
      <tr><th>{electronicAddress.type}:</th><td>electronicAddress.identifier</td></tr>
    </f:for>
  </tabel>
</f:section>

<f:section name="plain">
A new Registration has been incoming:

Data:

<f:format.padding padLength="17">*Identifier:*</f:format.padding> {account.accountIdentifier}
<f:format.padding padLength="17">*First name:*</f:format.padding> {account.party.name.firstName}
<f:format.padding padLength="17">*Middle name:*</f:format.padding> {account.party.name.middleName}
<f:format.padding padLength="17">*Last name:*</f:format.padding> {account.party.name.lastName}
<f:for each="{account.party.electronicAddress}" as="electronicAddress">
<f:format.padding padLength="17">*{electronicAddress.type}:*</f:format.padding> {electronicAddress.identifier}
</f:for>

</f:section>

Bei der Nur Text Version sollte natürlich drauf geachtet werden das jedes Tab, jedes Leerzeichen und jeder Zeilenumbruch genauso übernommen wird. Aus diesem Grund sollte man auf schicke Einrückungen verzichten 😉

Um nun das Template in unserem Slot zu nutzen verwenden wir nun folgende Funktion:

  class Notification {
    /**
     * @param \TYPO3\FLOW3\Security\Account $account
     */
    public function sendNewRegistrationNotification(\TYPO3\FLOW3\Security\Account $account) {
      $template = new \TYPO3\Fluid\View\StandaloneView();
      $template->setTemplatePathAndFilename('resource://My.Package/Private/Templates/Notification/NewRegistration.html');
      $template->assaign('account', $account);
	  
      $subject = trim($template->renderSection('subject'));
      $html = trim($template->renderSection('html'));
      $plain = trim($template->renderSection('plain'));
	  
      $mail = new \TYPO3\SwiftMailer\Message();
      $mail->setFrom(array('meine@domain.tld ' => 'FLOW3 System'))
      $mail->setTo(array('meine@email.tld ' => 'Max Müller'))
      $mail->setSubject($subject);
      if ($html) $mail->addPart($html,'text/html','utf-8');
      if ($plain) $mail->addPart($plain,'text/plain','utf-8');
      $mail->send();
    }
  }

Sollte man nun natürlich mehrere E-Mail Benachrichtigungen haben sollte man versuchen die Einzelnen Funktionen entsprechend auszulagern um diese nicht mehrmals verändern zu müssen. Aber dieser Artikel soll ja auch nur zur Veranschaulichung dienen und die Grundlage für neue Inspirationen geben 😉

Ein Gedanke zu „E-Mail Benachrichtigung unter FLOW3

  1. Hi und danke für deine Anleitung. Ich habe alles genau so gemacht wie du beschrieben hast, bis darauf das ich aus FLOW3 Flow gemacht habe, da es das ab Version 2 nicht mehr gibt. Ich entwickle Lokal bei mir hab den Postfix eingerichtet und mit der PHP mail() Funktion läuft der Mail Versand auch einwandfrei. Wenn ich Swiftmailer nutze, wird keine Mail verschickt. Liegt es daran das ich Lokal arbeite oder hättest du evtl. noch eine Idee woran es liegen kann?

    Schon mal danke und Gruß,
    LittleHoopoe

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.