Verwenden und Erweitern der Drupal 8-Mail-API Teil 1

In dieser zweiteiligen Serie werden wir uns mit der Mail-API in Drupal 8 beschäftigen. Dabei werden wir zwei Hauptaspekte abdecken: Wie können Sie das Programm programmatisch für das Versenden von E-Mails verwenden und wie Sie es für die Verwendung eines externen Dienstes wie Mandrill erweitern können.

Um dies zu demonstrieren, erstellen wir im ersten Teil eine benutzerdefinierte E-Mail Vorlage Wird verwendet, um E-Mails an den aktuellen Benutzer zu senden, wenn er / sie einen neuen Artikel-Knoten speichert. Außerdem werden wir sehen, wie andere das ändern können Vorlage um die HTML-Darstellung des E-Mail-Textes anstelle des Standard-Klartextes zu ermöglichen.

Im zweiten Teil werden wir uns mit der Erweiterung des Mail-Systems und der Integration einer externen API für die E-Mail-Zustellung beschäftigen. Dazu verwenden wir Mandrill und seine PHP-Bibliothek, die eine gute Grundlage für die Interaktion mit der API bietet.

Alle Arbeiten, die wir durchlaufen, finden Sie in diesem Git-Repository als Teil eines benutzerdefinierten Drupal 8-Moduls, das wir hier schreiben werden. Fühlen Sie sich frei, dies zu überprüfen, wenn Sie mitverfolgen möchten. Lass uns anfangen.

Die erste Voraussetzung für dieses Modul ist sein .Info Datei:

d8mail.info.yml:

Name: Drupal 8 Mailer-Beschreibung: 'Demonstriert die Verwendung der Mail-API in Drupal 8.' Kern: 8.x Typ: Modul 

Auf diese Weise können wir das Modul auf unserer Website bereits aktivieren, wenn wir möchten.

Wie senden wir eine E-Mail??

Es gibt zwei Hauptschritte, um eine E-Mail programmgesteuert mit Drupal 8 zu senden. Zuerst müssen Sie hook_mail () implementieren, um eine oder mehrere E-Mails zu definieren Vorlagen. Der zweite Schritt besteht darin, den Mail-Manager zum Senden von E-Mails mit einem dieser E-Mails zu verwenden Vorlagen.

Obwohl ein Haken genannt, hook_mail () ist kein typischer Hook, sondern eher eine reguläre Funktion, die im Allgemeinen nur von dem Modul aufgerufen wird, das sie implementiert. Mit anderen Worten, wenn Sie eine E-Mail programmgesteuert senden, müssen Sie den implementierenden Modulnamen angeben hook_mail () und das Vorlage ID, die Sie verwenden möchten und die durch diesen Hook definiert wird. Aber wir werden das gleich sehen. Erstens, wie setzen wir es um?

d8mail.module:

/ ** * Implementiert hook_mail (). * / function d8mail_mail ($ key, & $ message, $ params) $ options = array ('langcode' => $ message ['langcode'],); switch ($ key) case 'node_insert': $ message ['from'] = \ Drupal :: config ('system.site') -> get ('mail'); $ message ['subject'] = t ('Knoten erstellt: @title', array ('@ title' => $ params ['node_title']), $ options); $ message ['body'] [] = SafeMarkup :: checkPlain ($ params ['message']); brechen;  

Dies ist eine sehr einfache Implementierung, die eine definiert Vorlage erkannt als node_insert (das $ -Taste). Die anderen zwei Funktionsargumente sind:

  • $ message: als Referenz übergeben, und innerhalb dieser fügen wir so viel Boilerplate zu unserer E-Mail hinzu, wie wir benötigen 
  • $ params: Ein Array zusätzlicher Daten, die in die E-Mail aufgenommen werden müssen und vom E-Mail-Manager übergeben werden, wenn wir versuchen, die E-Mail zu senden

Wie Sie sehen, bauen wir das auf $ message Array mit Werten, die diese E-Mail in alle Anrufe aufnehmen soll. Wir setzen einen Standard von Wert, der aus dem Konfigurationssystem abgerufen wird und der E-Mail-Adresse der Hauptsite entspricht. Wir legen eine E-Mail für die Boilerplate fest Gegenstand Auf diese Weise kann der Empfänger wissen, dass ein neuer Knoten erstellt wurde, gefolgt vom Namen des Knotens (der über den Knoten übergeben wird) $ params Array). Das Thema kann auch in die Sprache übersetzt werden, die vom Anrufer weitergegeben wird. 

Zuletzt führen wir die Nachricht aus Karosserie durch den String-Sanitizer, da der Text möglicherweise HTML enthält und abgeschnitten wird, wenn die HTML-Elemente nicht codiert werden. Und da benutzen wir die SafeMarkup Klasse müssen wir benutzen es an der Spitze:

Verwenden Sie Drupal \ Component \ Utility \ SafeMarkup. 

Darüber hinaus ist der Nachrichtentext ein Array, das später sein wird implodiert in eine Schnur Natürlich gibt es noch viele andere Parameter, wie zum Beispiel Header, die für dieses Beispiel ausreichend sind.

Und das ist alles für die hook_mail () Implementierung. Wenden wir uns nun dem Code zu, der jedes Mal ausgeführt wird, wenn ein neuer Knoten erstellt wird: hook_entity_insert ():

/ ** * Implementiert hook_entity_insert (). * / function d8mail_entity_insert (Drupal \ Core \ Entity \ EntityInterface $ entity) if ($ entity-> getEntityTypeId ()! == 'node' || ($ entity-> getEntityTypeId () === 'node' && $ entity.) -> bundle ()! == 'article')) return;  $ mailManager = \ Drupal :: Dienst ('plugin.manager.mail'); $ module = 'd8mail'; $ key = 'node_insert'; $ to = \ Drupal :: currentUser () -> getEmail (); $ params ['message'] = $ entity-> get ('body') -> value; $ params ['node_title'] = $ entity-> label (); $ langcode = \ Drupal :: currentUser () -> getPreferredLangcode (); $ send = wahr; $ result = $ mailManager-> mail ($ module, $ key, $ to, $ langcode, $ params, NULL, $ send); if ($ result ['result']! == true) $ message = t ('Beim Senden Ihrer E-Mail-Benachrichtigung an @email ist ein Fehler aufgetreten, weil Knoten @id erstellt wurde.', array ('@ email' => $ to , '@id' => $ entity-> id ())); drupal_set_message ($ message, 'error'); \ Drupal :: logger ('d8mail') -> Fehler ($ message); Rückkehr;  $ message = t ('Eine E-Mail-Benachrichtigung wurde zum Erstellen des Knotens @id an @email gesendet.', array ('@ email' => $ an, '@id' => $ entity-> id ())) ; drupal_set_message ($ message); \ Drupal :: logger ('d8mail') -> notice ($ message);  

Dieser Hook wird nach jedem Speichern eines Knotens ausgelöst, und wir müssen nur sicherstellen, dass wir auf den richtigen Knoten zielen und unsere Logik einbeziehen.

Nach der Überprüfung, dass die Knotenentität vom Typ ist Artikel, Wir laden den Drupal Mail Manager-Dienst und legen einige Werte für die E-Mail fest. Wir benötigen folgende Informationen:

  • Der Modulname, der implementiert wird hook_mail () und definiert unser Vorlage (was ich oben erwähnt habe)
  • das Vorlage id (die $ -Taste)
  • die E-Mail-Adresse des Empfängers (im aktuellen Benutzerkonto angegeben)
  • die Sprache ($ langcode) was in das geht $ params Array und das wird verwendet, um die Betreffnachricht zu übersetzen
  • Der Knotentitel, der dem E-Mail-Betreff hinzugefügt wird
  • Der E-Mail-Text, der in unserem Fall der Wert des Felds des Knotens ist
  • Der boolesche Wert gibt an, ob die E-Mail tatsächlich gesendet werden soll

Wir übergeben dann alle diese Werte an die mail () Methode des Mail-Managers. Letzterer ist für das Erstellen der E-Mail verantwortlich (Aufruf des Rechts) hook_mail () Implementierung ist ein Aspekt davon) und schließlich die tatsächliche Lieferung an das zuständige Plugin zu delegieren. Standardmäßig ist dies PHPMail, das den Standard verwendet mail () Funktion, die mit PHP geliefert wird.

Wenn der Mail-Manager die E-Mail erfolgreich versendet hat (die tatsächliche Zustellung wird nicht berücksichtigt, sondern eine erfolgreiche PHP-Aktion), wird die mail () Die Methode gibt ein Array zurück, das eine Ergebnis Schlüssel mit dem, was das Mail-Plugin zurückgibt. Bei der Überprüfung dieses Werts können wir feststellen, ob die E-Mail-Aktion erfolgreich war, und den Benutzer darüber informieren, dass wir ihn über seine Aktion informiert haben. Ansonsten drucken und protokollieren wir eine Fehlermeldung.

Und das ist es auch schon. Wenn Sie den Cache leeren und einen Artikelknoten erstellen, wird eine E-Mail in Ihrem Posteingang abgelegt. Wenn Sie nichts erhalten und keine Fehlersignale auf Ihrem Bildschirm angezeigt werden, überprüfen Sie Ihre Serverprotokolle und Ihre Mail-Warteschlange, um zu überprüfen, ob E-Mails gesendet werden.

Bevor ich fortfahre, möchte ich eine kurze Notiz bezüglich dieser Hook-Implementierung machen. In diesem Beispiel habe ich die gesamte Logik direkt in sie eingefügt. Außerdem habe ich oben eine frühe Rückkehr verwendet, was im Wesentlichen bedeutet, dass keine andere Logik als die für die Artikelknoten spezifische hinzugefügt werden kann. In realen Anwendungen empfehle ich, die Mailing-Logik in eine separate Funktion oder Klasse umzuwandeln und darauf zu verzichten. Darüber hinaus sollten Sie keine vorzeitigen Rückgaben in Hook-Implementierungen verwenden, sondern andere Funktionen aufrufen, wenn die Bedingungen erfüllt sind. 

Wie ändern wir eine E-Mail??

Sobald all dies vorhanden ist, steht uns ein weiteres Werkzeug zur Verfügung, mit dem wir ein solches bestehendes Setup ändern können: hook_mail_alter (). Dieser Hook wird vom Mail-Manager aus aufgerufen, bevor das zuständige Mail-Plugin die E-Mail sendet. Der Zweck besteht darin, anderen Modulen die Möglichkeit zu geben, letzte Änderungen an einer vorhandenen E-Mail vorzunehmen, die versendet wird.

Obwohl dies auch von anderen Modulen verwendet werden kann, zeigen wir eine Beispielimplementierung innerhalb desselben Moduls, mit dem wir gearbeitet haben. Zu diesem Zweck ändern wir die E-Mail, indem sie einen ihrer Standardheader ändern, um sie von normalem Text in HTML umzuwandeln. Und so können wir das machen:

/ ** * Implementiert hook_mail_alter (). * / function d8mail_mail_alter (& $ message) switch ($ message ['key']) 'case' node_insert ': $ message [' headers '] [' Content-Type '] =' text / html; Zeichensatz = UTF-8; Format = fließt; delsp = yes '; brechen;  

Wie Sie sehen, ist dies eine einfache Änderung der Inhaltstyp Header, der die E-Mail in HTML umwandelt. Auf diese Weise werden Klartext-HTML-Entitäten von Mail-Clients als HTML analysiert. Und mit dem Schalterfall stellen wir sicher, dass dies nur für die E-Mail geschieht Vorlage Wir haben früher definiert.

Hierbei ist zu beachten, dass der Alter Hook nach dem relevanten aufgerufen wird hook_mail () Implementierung. Danach wird die einzige Verarbeitung, die für die E-Mail ausgeführt wird, in der E-Mail durchgeführt Format() Methode des Mail-Plugins (durch seine Schnittstelle erzwungen).

Fazit

Und das ist so ziemlich alles, was man braucht, um E-Mails programmatisch mit Drupal 8 zu versenden. Wir haben die Schritte gesehen, die zur programmgesteuerten Einrichtung von E-Mails erforderlich sind Vorlagen Das wird vom Mail-Manager immer dann hydratisiert, wenn wir es wollen. Wir haben auch das Standard-Plug-In für die E-Mail-Übermittlung erwähnt, das zum Versenden von E-Mails in Drupal 8 verwendet wird. Und schließlich haben wir gesehen, wie andere Module unsere E-Mail jetzt ändern können, indem sie neue Header hinzufügen, den Betreff ändern und Werte mit dem E-Mail-Text verbinden , usw.

Im nächsten Artikel werden wir das standardmäßige PHPMail-Plugin durch unsere eigene benutzerdefinierte Implementierung ersetzen. Wir werden einen Mailer einrichten, der Mandrill mithilfe seiner PHP-Bibliothek verwendet. Ziel ist es, dass unser eigenes Modul diesen Mailer verwenden kann, während der Rest der Anwendung weiterhin den Standard-PHPMailer verwendet.