Gebruik en uitbreiding van de Drupal 8 Mail API deel 1

In deze tweedelige serie gaan we de Mail API in Drupal 8 verkennen. Hierbij gaan we in op twee hoofdaspecten: hoe je dit programatically gebruikt voor het verzenden van e-mails en hoe je het kunt uitbreiden voor het gebruik van een externe service zoals Mandrill.

Om dit aan te tonen, zullen we in het eerste deel een aangepaste e-mail maken sjabloon die wordt gebruikt voor het verzenden van e-mails naar de huidige gebruiker wanneer hij / zij een nieuw artikelknooppunt opslaat. Bovendien zullen we zien hoe anderen dat kunnen veranderen sjabloon om HTML-weergave van de hoofdtekst van de e-mail mogelijk te maken in plaats van de standaard onbewerkte tekst.

In het tweede deel gaan we kijken naar het uitbreiden van het mailsysteem en het integreren van een externe API voor e-mailbezorging. Hiervoor gebruiken we Mandrill en zijn PHP-bibliotheek die een goede basis biedt voor de interactie met zijn API.

Al het werk dat we doormaken, is te vinden in deze Git-repository als onderdeel van een aangepaste Drupal 8-module die we hier zullen gaan schrijven. Dus voel je vrij om dat te controleren als je mee wilt doen. Laten we beginnen.

De eerste voorwaarde voor deze module is de .info het dossier:

d8mail.info.yml:

name: Drupal 8 Mailer description: 'Demonstreert het gebruik van de Mail API in Drupal 8.' kern: 8.x type: module 

Als dit uit de weg is, kunnen we de module op onze site al inschakelen als we dat willen.

Hoe sturen we een e-mail?

Er zijn twee belangrijke stappen nodig om een ​​e-mail programmatisch met Drupal 8 te verzenden. We moeten hook_mail () eerst implementeren om een ​​of meer e-mail te definiëren templates. De tweede stap is om de e-mailbeheerder te gebruiken om e-mails te verzenden met behulp van een van deze templates.

Hoewel een haak genoemd, hook_mail () is geen typische haak, maar meer een normale functie die doorgaans alleen wordt aangeroepen door dezelfde module die deze functie implementeert. Met andere woorden, wanneer u een e-mail programmatisch verzendt, moet u de naam van de module opgeven hook_mail () en de sjabloon id die je wilt gebruiken en die wordt gedefinieerd door deze haak. Maar dat zullen we zo meteen zien. Ten eerste, hoe kunnen we het implementeren?

d8mail.module:

/ ** * Implementeert 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 ('Node created: @title', array ('@ title' => $ params ['node_title']), $ options); $ message ['body'] [] = SafeMarkup :: checkPlain ($ params ['message']); breken;  

Dit is een heel eenvoudige implementatie die er een definieert sjabloon geïdentificeerd als node_insert (de $ key). De andere twee functieargumenten zijn:

  • $ message: doorgegeven door verwijzing, en waarbinnen we zoveel e-mail toevoegen over onze e-mail als we nodig hebben 
  • $ params: een reeks extra gegevens die in de e-mail moeten worden ingevoerd en die wordt doorgegeven vanuit de e-mailbeheerder wanneer we de e-mail proberen te verzenden

Zoals je ziet, bouwen we het $ message array met waarden die we met deze e-mail in alle oproepen willen opnemen. We stellen een standaard in van waarde die wordt opgehaald uit het configuratiesysteem en die het e-mailadres van de hoofdsite vertegenwoordigt. We hebben een standaard e-mail ingesteld onderwerpen waarmee de ontvanger weet dat er een nieuwe node is gemaakt, gevolgd door de naam van de node (die wordt doorgegeven via de $ params array). Het onderwerp kan ook worden vertaald in de taal die door de beller wordt doorgegeven. 

Ten slotte voeren we het bericht uit lichaam door de string-ontsmettingsmiddel omdat de tekst HTML kan bevatten en het kan worden afgekapt als we de HTML-elementen niet coderen. En omdat we de gebruiken SafeMarkup klasse, we moeten gebruik het aan de top:

gebruik Drupal \ Component \ Utility \ SafeMarkup; 

Bovendien is de berichttekst een array die later zal zijn implodeerde in een string. En natuurlijk zijn er nog vele andere parameters die we kunnen instellen, zoals headers, maar dit is voldoende voor dit voorbeeld.

En dat is alles voor de hook_mail () implementatie. Laten we nu kijken naar de code die wordt uitgevoerd telkens wanneer een nieuw knooppunt wordt gemaakt, hook_entity_insert ():

/ ** * Werktuigen hook_entity_insert (). * / functie d8mail_entity_insert (Drupal \ Core \ Entity \ EntityInterface $ entity) if ($ entity-> getEntityTypeId ()! == 'node' || ($ entity-> getEntityTypeId () === 'node' && $ entity -> bundle ()! == 'article')) return;  $ mailManager = \ Drupal :: service ('plugin.manager.mail'); $ module = 'd8mail'; $ key = 'node_insert'; $ to = \ Drupal :: currentUser () -> getEmail (); $ params ['message'] = $ entity-> get ('body') -> waarde; $ params ['node_title'] = $ entity-> label (); $ langcode = \ Drupal :: currentUser () -> getPreferredLangcode (); $ send = true; $ result = $ mailManager-> mail ($ module, $ key, $ to, $ langcode, $ params, NULL, $ send); if ($ result ['result']! == true) $ message = t ('Er was een probleem bij het verzenden van uw e-mailmelding naar @email voor het maken van node @id.', array ('@ email' => $ naar , '@id' => $ entity-> id ())); drupal_set_message ($ message, 'error'); \ Drupal :: logger ( 'd8mail') -> fout ($ message); terug te keren;  $ message = t ('Er is een e-mailmelding verzonden naar @email voor het maken van node @id.', array ('@ email' => $ to, '@id' => $ entity-> id ())) ; drupal_set_message ($ message); \ Drupal :: logger ( 'd8mail') -> bericht ($ message);  

Deze haak wordt geactiveerd na elke knooppunt-opslag, en alles wat we moeten doen is ervoor zorgen dat we ons richten op de juiste knoop en onze logica opnemen.

Na het controleren dat de knooppuntentiteit van het type is artikel, we laden de Drupal mail manager-service en beginnen met het instellen van enkele waarden voor de e-mail. We hebben de volgende informatie nodig:

  • de naam van de module die wordt gebruikt hook_mail () en definieert onze sjabloon (wat ik hierboven heb genoemd)
  • de sjabloon id (de $ key)
  • het e-mailadres van de ontvanger (het adres van het huidige gebruikersaccount)
  • de taal ($ langcode) die in de $ params array en die zal worden gebruikt om het onderwerpsbericht te vertalen
  • de knooppunttitel die wordt toegevoegd aan het e-mailonderwerp
  • de body van de e-mail, die in ons geval de waarde van het bodyveld van de knoop zal zijn
  • de Booleaanse waarde die aangeeft of de e-mail daadwerkelijk moet worden verzonden

Vervolgens geven we al deze waarden door aan de mail() methode van de mailmanager. Deze laatste is verantwoordelijk voor het bouwen van de e-mail (het recht oproept) hook_mail () implementatie is hier een aspect van) en de uiteindelijke levering uiteindelijk te delegeren naar de verantwoordelijke plug-in. Standaard is dit PHPMail, dat de standaard gebruikt mail() functie die wordt geleverd met PHP.

Als de e-mailbeheerder succesvol is in het verzenden van de e-mail (daadwerkelijke levering wordt niet in aanmerking genomen, maar eerder een succesvolle PHP-actie), de mail() methode retourneert een array met een resultaat sleutel met wat de mailplug-in oplevert. Als we naar die waarde zoeken, kunnen we leren of de e-mailactie succesvol was en de gebruiker laten weten dat we hen op de hoogte hebben gesteld van hun actie. Anders drukken en loggen we een foutmelding.

En dat is het zo'n beetje. Als u de cache leegmaakt en een artikelknooppunt maakt, moet u een e-mail in uw inbox plaatsen. Als u niets krijgt en er zijn geen foutmeldingen op uw scherm, controleer dan uw serverlogboeken en de wachtrij om te verifiëren dat e-mails worden verzonden.

Voordat ik verder ga, wil ik een korte opmerking maken over deze hook-implementatie. In dit voorbeeld heb ik alle logica erin geplaatst. Daarnaast heb ik bovenaan een vroege return gebruikt, wat betekent dat er geen andere logica kan worden toegevoegd dan de specifieke voor de artikelknooppunten. In echte toepassingen raad ik aan de maillogica te refactoren naar een afzonderlijke functie of klasse en daar op uit te gaan. Bovendien moet u geen vroege returns binnen hook-implementaties gebruiken, maar in plaats daarvan andere functies bellen als aan de voorwaarden is voldaan. 

Hoe veranderen we een email?

Zodra dit allemaal is gebeurd, hebben we een andere tool tot onze beschikking die ons in staat stelt om een ​​dergelijke bestaande setup te wijzigen: hook_mail_alter (). Deze haak wordt aangeroepen vanuit de e-mailbeheerder voordat de verantwoordelijke e-mailinvoegtoepassing de e-mail verzendt. Het doel is om andere modules toe te staan ​​definitieve wijzigingen aan te brengen in een bestaande e-mail die wordt verzonden.

Hoewel dit ook door andere modules kan worden gebruikt, zullen we een voorbeeldimplementatie illustreren vanuit dezelfde module waarmee we hebben gewerkt. Hiertoe wijzigen we de e-mail door een van de standaardkopteksten te wijzigen om deze van gewone tekst naar HTML te transformeren. En dit is hoe we dit kunnen doen:

/ ** * Implementeert hook_mail_alter (). * / function d8mail_mail_alter (& $ message) switch ($ message ['key']) case 'node_insert': $ message ['headers'] ['Content-type'] = 'text / html; charset = UTF-8; format = vloeide; delsp = yes; breken;  

Zoals u kunt zien, is dit een eenvoudige wijziging van de Content-Type header die de e-mail omzet in HTML. Op deze manier worden HTML-entiteiten met platte tekst door e-mailclients geparseerd als HTML. En met behulp van de switchcase zorgen we ervoor dat dit alleen gebeurt voor de e-mail sjabloon we hebben eerder gedefinieerd.

Een ding om op te merken is dat de haak wordt aangeroepen naar het relevante hook_mail () implementatie. Dus hierna wordt de enige verwerking die op de e-mail plaatsvindt gedaan binnen de formaat() methode van de mail plug-in (afgedwongen door de interface).

Conclusie

En dat is vrijwel alles om e-mails programmatisch te verzenden met Drupal 8. We hebben de stappen gezien die nodig zijn om een ​​e-mailprogramma te programmeren templates die gehydrateerd worden door de mailmanager wanneer we hem willen. We hebben ook de standaard plug-in voor e-mailbezorging genoemd die wordt gebruikt om e-mails te verzenden in Drupal 8. En ten slotte hebben we gezien hoe andere modules onze e-mail nu kunnen wijzigen door nieuwe headers toe te voegen, het onderwerp te wijzigen, waarden aan de e-mailgroep te koppelen , enz.

In het volgende artikel gaan we kijken naar het vervangen van de standaard PHPMail-plug-in door onze eigen aangepaste implementatie. We zullen een mailer opzetten die Mandrill gebruikt met behulp van zijn PHP-bibliotheek. Het doel is om onze eigen module deze mailer te laten gebruiken terwijl de rest van de applicatie de standaard PHPMailer blijft gebruiken.