Utilizzo ed estensione dell'API Drupal 8 Mail parte 1

In questa serie in due parti esploreremo l'API Mail in Drupal 8. In questo modo, verranno trattati due aspetti principali: come utilizzarlo in modo programmatico per l'invio di e-mail e come estenderlo per l'utilizzo di un servizio esterno come Mandrill.

Per dimostrarlo, nella prima parte creeremo un'e-mail personalizzata modello che viene utilizzato per l'invio di e-mail all'utente corrente quando salva un nuovo nodo Articolo. Inoltre, vedremo come altri possono alterarlo modello per consentire il rendering HTML del corpo dell'e-mail invece del testo normale predefinito.

Nella seconda parte esamineremo l'estensione del sistema di posta e l'integrazione di un'API esterna per il recapito della posta elettronica. Per questo, useremo Mandrill e la sua libreria PHP che fornisce una buona base per interagire con la sua API.

Tutto il lavoro che svolgiamo può essere trovato in questo repository Git come parte di un modulo Drupal 8 personalizzato che inizieremo a scrivere qui. Quindi sentiti libero di verificarlo se vuoi seguirlo. Iniziamo.

Il primo prerequisito di questo modulo è suo .Informazioni file:

d8mail.info.yml:

nome: Drupal 8 Descrizione del mailer: 'Dimostra l'uso dell'API Mail in Drupal 8.' core: 8.x tipo: modulo 

Con questo fuori mano, possiamo già abilitare il modulo sul nostro sito, se vogliamo.

Come possiamo inviare un'e-mail?

Ci sono due passaggi principali necessari per inviare una e-mail in modo programmatico con Drupal 8. Prima di tutto dobbiamo implementare hook_mail () per definire una o più e-mail modelli. Il secondo passo è utilizzare il gestore della posta per inviare e-mail usando uno di questi modelli.

Anche se chiamato un gancio, hook_mail () non è un hook tipico ma più di una funzione regolare che viene generalmente chiamata solo dallo stesso modulo che la implementa. In altre parole, quando si invia una e-mail a livello di programmazione, è necessario specificare il nome del modulo che implementa hook_mail () e il modello id che vuoi usare e che è definito da questo hook. Ma lo vedremo tra un minuto. Innanzitutto, come lo implementiamo?

d8mail.module:

/ ** * Implementa 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 ('Nodo creato: @title', array ('@ title' => $ params ['node_title']), $ options); $ message ['body'] [] = SafeMarkup :: checkPlain ($ params ['message']); rompere;  

Questa è un'implementazione molto semplice che ne definisce uno modello identificato come node_insert (il $ chiave). Gli altri due argomenti della funzione sono:

  • $ messaggio: passato per riferimento e all'interno del quale aggiungiamo tanto numero di informazioni sulla nostra email di cui abbiamo bisogno 
  • $ params: una serie di dati extra che devono essere inseriti nell'e-mail e che vengono inviati dal gestore della posta quando proviamo a inviare l'e-mail

Come puoi vedere, stiamo costruendo il $ messaggio array con valori che vogliamo includere in tutte le chiamate. Stiamo impostando un valore predefinito a partire dal valore che viene recuperato dal sistema di configurazione e che rappresenta l'indirizzo email del sito principale. Impostiamo una e-mail boilerplate soggetto che consente al destinatario di sapere che è stato creato un nuovo nodo, seguito dal nome del nodo (che verrà passato attraverso il $ params array). L'oggetto è anche traducibile nella lingua che viene passata dal chiamante. 

Infine, eseguiamo il messaggio corpo tramite l'igienizzatore di stringhe perché il testo potrebbe contenere HTML e potrebbe venire troncato se non codifichiamo gli elementi HTML. E dal momento che stiamo usando il SafeMarkup classe, abbiamo bisogno di uso in alto:

utilizzare Drupal \ Component \ Utility \ SafeMarkup; 

Inoltre, il corpo del messaggio è una matrice che sarà in seguito implosa in una stringa. E ovviamente ci sono molti altri parametri che possiamo impostare, come le intestazioni, ma questo sarà sufficiente per questo esempio.

E questo è tutto per il hook_mail () implementazione. Ora passiamo al codice che viene eseguito ogni volta che viene creato un nuovo nodo, hook_entity_insert ():

/ ** * Implementa 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 :: service ('plugin.manager.mail'); $ module = 'd8mail'; $ key = 'node_insert'; $ to = \ Drupal :: currentUser () -> getEmail (); $ params ['message'] = $ entity-> get ('body') -> valore; $ 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 ('Si è verificato un problema durante l'invio della notifica email a @email per la creazione di node @id.', array ('@ email' => $ per , '@id' => $ entity-> id ())); drupal_set_message ($ message, 'error'); \ Drupal :: logger ( 'd8mail') -> errore ($ messaggio); ritorno;  $ message = t ('Una notifica email è stata inviata a @email per la creazione di nodo @id.', array ('@ email' => $ a, '@id' => $ entity-> id ())) ; drupal_set_message ($ messaggio); \ Drupal :: logger ( 'd8mail') -> avviso ($ messaggio);  

Questo hook viene attivato dopo ogni salvataggio del nodo e tutto ciò che dobbiamo fare è assicurarsi che stiamo prendendo di mira il nodo corretto e includiamo la nostra logica.

Dopo aver verificato che l'entità nodo sia del tipo articolo, Carichiamo il servizio di gestione della posta Drupal e iniziamo ad impostare alcuni valori per l'e-mail. Abbiamo bisogno delle seguenti informazioni:

  • il nome del modulo che implementa hook_mail () e definisce il nostro modello (quello che ho menzionato sopra)
  • il modello id (il $ chiave)
  • l'indirizzo email del destinatario (quello trovato nell'account utente corrente)
  • la lingua ($ langcode) che entra nel $ params array e che verrà utilizzato per tradurre il messaggio dell'oggetto
  • il titolo del nodo che verrà aggiunto all'oggetto dell'email
  • il corpo dell'email, che nel nostro caso sarà il valore del campo del corpo del nodo
  • il valore booleano che indica se l'email deve essere effettivamente inviata

Quindi passiamo tutti questi valori a mail () metodo del gestore della posta. Quest'ultimo è responsabile della creazione dell'e-mail (chiamando il giusto hook_mail () l'implementazione è un aspetto di questo aspetto e infine delegare la consegna effettiva al plug-in responsabile. Per impostazione predefinita, questo sarà PHPMail, che utilizza l'impostazione predefinita mail () funzione fornita con PHP.

Se il gestore della posta riesce a inviare l'e-mail (la consegna effettiva non viene presa in considerazione, ma piuttosto un'azione PHP riuscita), il mail () il metodo restituirà un array contenente a risultato chiave con qualsiasi cosa ritorni il plugin di posta. Controllando tale valore, possiamo scoprire se l'azione e-mail ha avuto successo e informare l'utente che gli abbiamo notificato la sua azione. Altrimenti, stampiamo e registriamo un messaggio di errore.

E questo è tutto. Cancellare la cache e creare un nodo articolo dovrebbe inviare un'e-mail nella tua casella di posta. Se non ricevi nulla e non ci sono segni di errore sullo schermo, assicurati di controllare i log del server e la coda di posta per verificare che le email vengano inviate.

Prima di proseguire, vorrei fare una breve nota su questa implementazione del gancio. In questo esempio, ho inserito direttamente tutta la logica al suo interno. Inoltre, ho usato un ritorno anticipato all'inizio, il che significa essenzialmente che non è possibile aggiungere altra logica ma quella specifica per i nodi dell'articolo. Nelle applicazioni reali raccomando di refactoring la logica di mailing in una funzione o classe separata e di rimandare a ciò. Inoltre, non si dovrebbero utilizzare i ritorni anticipati nelle implementazioni degli hook, ma chiamare altre funzioni se le condizioni sono soddisfatte. 

Come modifichiamo un'e-mail?

Una volta implementato tutto questo, abbiamo a nostra disposizione un altro strumento che ci consente di modificare una configurazione esistente: hook_mail_alter (). Questo hook viene chiamato dall'interno del gestore della posta prima che il plugin di posta responsabile invii l'email. Lo scopo è quello di consentire ad altri moduli di eseguire le modifiche finali a un messaggio di posta elettronica esistente inviato.

Sebbene questo possa essere usato anche da altri moduli, illustreremo un'implementazione di esempio dallo stesso modulo con cui abbiamo lavorato. A tal fine, modificheremo l'e-mail cambiando una delle intestazioni predefinite per trasformarla da testo normale in HTML. Ed è così che possiamo fare questo:

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

Come puoi vedere, questa è una semplice alterazione del Tipo di contenuto intestazione che trasforma l'email in HTML. In questo modo le entità HTML in testo semplice verranno analizzate come HTML dai client di posta. E usando l'interruttore caso, ci assicuriamo che questo accada solo per l'e-mail modello abbiamo definito in precedenza.

Una cosa da notare qui è che l'alter hook viene chiamato dopo il relativo hook_mail () implementazione. Quindi, dopo questo, l'unica elaborazione che avviene sull'e-mail viene eseguita all'interno di formato() metodo del plugin di posta (applicato dalla sua interfaccia).

Conclusione

E questo è praticamente tutto quello che serve per inviare e-mail in modo programmatico usando Drupal 8. Abbiamo visto i passaggi necessari per impostare in modo programmato le e-mail modelli che vengono idratati dal gestore della posta ogni volta che lo vogliamo. Abbiamo anche menzionato il plug-in predefinito di consegna della posta che viene utilizzato per inviare e-mail in Drupal 8. E infine, abbiamo visto come altri moduli possono ora modificare la nostra posta elettronica aggiungendo nuove intestazioni, cambiando argomento, concatenando valori al corpo della posta , eccetera.

Nel prossimo articolo vedremo come sostituire il plug-in PHPMail predefinito con la nostra implementazione personalizzata. Creeremo un mailer che usa Mandrill con l'aiuto della sua libreria PHP. L'obiettivo è consentire al nostro modulo di utilizzare questo mailer mentre il resto dell'applicazione continua a utilizzare il PHPMailer predefinito.