În articolul precedent ne-am uitat la modul în care putem trimite e-mailuri programatic în Drupal 8. De asemenea, am văzut cum alte module pot modifica aceste mesaje trimise. Astăzi, vom examina modul în care putem utiliza API-ul Mail pentru a extinde acest comportament implicit. Scopul este de a utiliza un serviciu extern ca mijloc de livrare prin e-mail.
Pentru aceasta, vom folosi Mandrill, deși nu va fi subiectul său API sau cum să lucrați cu el, ci mai degrabă partea Drupal a lucrurilor. Și rețineți că modulul de lucru poate fi găsit în acest depozit Git.
Așa cum am văzut în articolul precedent, trimiterea unui e-mail în Drupal 8 se întâmplă prin solicitarea managerului de mail, trecerea unor parametri către Poștă()
metodă și crearea unui a șablon în interiorul a hook_mail ()
punerea în aplicare. Ceea ce face managerul de corespondență pe plan intern este încărcarea pluginului corespunzător pentru mesaje, construirea e-mailului și apoi delegarea acestuia Poștă()
metoda de orice plugin a fost încărcat.
Dar la cine face, de fapt, delega?
Un lucru important de înțeles înainte de a scrie propriul plugin este procesul de selecție al managerului de e-mail pentru încărcarea pluginurilor. Cu alte cuvinte, cum știm ce plugin se va încărca și cum putem să-l încărcăm pe propriul nostru?
system.mail.interface
matricea de configurații conține toate răspunsurile. Acesta conține id-urile pluginurilor disponibile, tastate de contextul în care sunt utilizate. În mod implicit, tot ceea ce avem în interiorul acestei configurații este implicit => phpmail
. Aceasta înseamnă că plugin-ul cu id-ul phpmail
(clasa PHPMail) este folosită ca rezervă pentru toate contextele care nu sunt specificate altfel, adică implicit.
Dacă vrem să scriem propriul nostru plugin, trebuie să adăugăm un alt element în matricea respectivă, cu valoarea id-ului plugin-ului ca valoare. Cheia pentru această valoare poate fi una din două lucruri: numele mașinii modulului nostru (pentru a încărca pluginul ori de câte ori modulul nostru trimite e-mailuri) sau o combinație de nume de modul și e-mail șablon cheie (pentru a încărca plugin-ul de fiecare dată când modulul nostru trimite un e-mail utilizând acea cheie specifică).
Un exemplu de construcție din urmă este d8mail_node_insert
, Unde d8mail
este numele modulului nostru pe care am început să îl construim în articolul precedent și node_insert
este e-mailul șablon cheie pe care am definit-o.
Deci, acum că știm cum se face selecția pluginului de mail, trebuie să ne asigurăm că această matrice de configurare conține informațiile necesare pentru ca e-mailurile trimise cu d8mail
modulul utilizează noul plugin pe care îl vom construi. Putem face acest lucru într-o implementare hook_install () care se declanșează o singură dată când modulul se instalează:
d8mail.install:
/ ** * Implementează hook_install (). * / funcția d8mail_install () $ config = \ Drupal :: configFactory () -> getEditable ('system.mail'); $ mail_plugins = $ config-> get ("interfață"); dacă (in_array ('d8mail', array_keys ($ mail_plugins))) retur; $ mail_plugins ['d8mail'] = 'mandrill_mail'; $ config-> set ('interfață', $ mail_plugins) -> save ();
Nu este prea complicat ce se întâmplă mai sus. Încărcăm obiectul config de editare reprezentând system.mail
configurați și adăugați un nou element la interfață
matrice: d8mail => mandrill_mail
. Vom crea în curând un plugin de poștă cu ID-ul de mandrill_mail
care va fi utilizat pentru toate e-mailurile trimise de către d8mail
modul. Si asta e.
Dar, înainte de a merge mai departe, trebuie să ne asigurăm că această schimbare este reluată atunci când modulul este dezinstalat. Pentru aceasta, putem folosi omologul hook_uninstall () care este sunat când un modul este dezinstalat (nu mai există nici un modul de dezactivare în Drupal 8).
În interiorul aceluiași fișier:
/ ** * Implementează hook_uninstall (). * / funcția d8mail_uninstall () $ config = \ Drupal :: configFactory () -> getEditable ('system.mail'); $ mail_plugins = $ config-> get ("interfață"); dacă (! in_array ('d8mail', array_keys ($ mail_plugins))) retur; dezactivat ($ mail_plugins ['d8mail']); $ config-> set ('interfață', $ mail_plugins) -> save ();
Cu hook_uninstall ()
punerea în aplicare facem opusul anterior: eliminăm ID-ul pluginului, dacă acesta este setat.
Scenariul de instalare / dezinstalare este doar o modalitate de a merge. Puteți crea, de asemenea, un formular de administrare care permite utilizatorilor să selecteze pluginul pe care îl doresc și în ce context. Dar trebuie să vă asigurați că atunci când dezactivați modulul care definește un anumit plugin, configurația nu va mai păstra o referință la pluginul respectiv. Altfel, managerul de mail poate încerca să utilizeze o clasă inexistentă și să arunce tot felul de erori.
După cum am menționat mai sus, vom colabora cu Mandrill API pentru a ilustra sarcina noastră. Deci, să încărcăm biblioteca PHP Mandrill și să o punem la dispoziție în mediul nostru. Există trei pași pe care trebuie să le facem pentru acest lucru.
În primul rând, trebuie să luăm de fapt biblioteca în interiorul Drupal. La momentul redactării, aceasta înseamnă, în principiu, adăugarea "mandrill / mandrill": "1.0. *"
dependența de rădăcină composer.json
fișier și rularea compozitorul instala
. Țineți minte, totuși, că acest lucru va elimina, de asemenea, instalarea Drupal din interiorul core /
și descărcați ulterior cea mai recentă versiune stabilă. Apoi, va trebui să editați rădăcina index.php
fișier și modificați calea către autoloader conform acestor instrucțiuni. Sperăm că această ultimă acțiune nu va fi necesară în curând și vă încurajez să urmați discuțiile despre viitorul compozitorului din Drupal 8 pentru gestionarea bibliotecilor externe.
În al doilea rând, trebuie să obținem o cheie API de la Mandrill. Din fericire, putem genera cu ușurință din paginile lor de administrare. Odată ce avem acest lucru, îl putem stoca într-un fișier nou creat pe serverul nostru, în oricare locație:
~ / .mandrill.key /etc/mandrill.key
De asemenea, putem trece cheia ca parametru constructor în principal Mandril
clasa, dar în acest fel nu va trebui să-l codificăm în codul nostru.
În al treilea rând, trebuie să creăm un serviciu pentru a putea folosi injecția de dependență pentru a trece Mandril
clasă în pluginul nostru:
d8mail.services.yml:
servicii: d8mail.mandrill: clasa: Mandrill
În funcție de modul în care ați încărcat Mandril
în aplicația dvs., va trebui să modificați valoarea după clasă
. Prin utilizarea funcției composer.json
abordare, acest lucru este suficient.
În cele din urmă, este momentul să creați pluginul nostru. În Drupal 8, clasele de plugin-uri intră în interiorul src / Plugin
dosarul modulului nostru. În funcție de tipul lor, cu toate acestea, ele sunt plasate mai jos în alte directoare (în cazul nostru Poștă
). Să scriem clasa noastră care va depinde de biblioteca API Mandrill pentru a trimite e-mailuri:
src / Plugin / Mail / MandrillMail.php:
mandrill = $ mandrill; / ** * @inheritdoc * / crearea funcției statice publice (ContainerInterface $ container, array $ configuration, $ plugin_id, $ plugin_definition) retur static nou ($ container-> get ('d8mail.mandrill')); / ** * @inheritdoc * / formatul funcției publice (array $ message) // Alăturați-vă corpului într-un șir. $ message ['corpul'] = implode ("\ n \ n", $ message ['body']); // Convertiți orice HTML în text simplu. $ message ['corpul'] = MailFormatHelper :: htmlToText ($ message ['body']); // Înfășurați corpul poștal pentru trimitere. $ message ['corpul'] = MailFormatHelper :: wrapMail ($ message ['body']); returnează mesajul $; / ** * @inheritdoc * / mail public funcția (array $ message) încercați $ vars = ['html' => $ message ['body'], ], 'from_email' => $ message ['din'], 'to' => array (array ('email' => $ message ['to'])); $ result = $ this-> mandrill-> mesaje-> trimite ($ vars); dacă ($ rezultat [0] ['status']! == 'trimis') return false; retur $ rezultat; captură (Mandrill_Error $ e) return false;
Există câteva lucruri de remarcat înainte de a intra în ceea ce face clasa.
Mai întâi, adnotările de deasupra clasei. Acesta este doar cel mai frecvent mecanism de descoperire a plugin-urilor pentru Drupal 8. The id
cheie se potrivește cu valoarea pe care am adăugat-o system.mail.interface
matricea de configurație mai devreme, în timp ce restul sunt elemente de bază pentru definirea pluginurilor.
În al doilea rând, punerea în aplicare a ContainerFactoryPluginInterface
interfața prin care definim crea()
metodă. Aceasta din urmă face parte din procesul de injectare a dependenței prin care putem încărca serviciul Mandrill pe care l-am definit în services.yml
fișier mai devreme. Acest lucru face ca testarea să fie mult mai ușoară și este considerată cea mai bună practică.
După cum am menționat, pluginurile de e-mail trebuie să implementeze MailInterface
care impune existența format()
și Poștă()
metode. În cazul nostru, primul face exact același lucru ca și PHPMail
plugin: un pic de procesare a corpului mesajului. Deci, puteți adăuga propria logică aici dacă doriți. Ultima metodă, pe de altă parte, este responsabilă pentru trimiterea corespondenței, în cazul nostru, folosind Mandrill API.
După cum instruiește documentația Mandrill, vom construi un mesaj de e-mail în interiorul $ Vars
array utilizând valorile trecute de la managerul de e - mail prin $ mesaj
parametru. Acestea vor fi deja filtrate hook_mail ()
, hook_mail_alter ()
și pluginul propriu format()
metodă. Tot ce a mai rămas este de a trimite de fapt e-mailul. Nu voi intra în detaliile utilizării API-ului Mandrill, deoarece puteți consulta documentația pentru toate opțiunile pe care le puteți utiliza.
După trimiterea e-mailului și returnarea lui Mandrill a trimis
, vom returna întreaga matrice de răspuns, care conține mai multe informații. Acest matrice se adaugă apoi de managerul de e-mail la propria sa matrice de returnare, tastată ca rezultat
. Dacă Mandrill are o problemă, respinge e-mailul sau aruncă o excepție, ne întoarcem fals
. Acest lucru va face managerul de mail să se ocupe de această situație prin logarea incidentului și printarea unui mesaj de stare.
Și asta este destul de mult. Putem șterge memoria cache și încercăm să creăm un alt nod al articolului. De data aceasta, e-mailul de notificare ar trebui să fie trimis de Mandrill în loc de PHP Poștă()
. Cu acest lucru în loc, deși, hook_mail_alter ()
implementarea a devenit superfluă deoarece nu există anteturi pe care le trimitem de fapt la Mandrill (și textul este HTML deja). Și, de altfel, o mulțime de muncă a managerului de corespondență nu este folosită, deoarece nu facem asta lui Mandrill. Dar acest lucru este doar menit să ilustreze procesul în care puteți face acest lucru. Detaliile implementării rămân în funcție de dvs. și de nevoile dvs..
Și acolo o avem. Am implementat propriul plugin de mail pentru a fi utilizat de către d8module
am început în articolul precedent. Și datorită naturii extensibile a lui Drupal 8, nu a făcut prea mult efort.
Ceea ce a mai rămas pentru tine este să perfecționezi logica de trimitere a poștei și să o adaptezi situației tale. Aceasta poate însemna integrarea ulterioară între Mandrill și instanța dvs. Drupal, construirea de șabloane frumoase sau ce aveți. În plus, o importantă sarcină rămasă este scrierea testelor automate pentru această funcție. Și Drupal 8 oferă și un set de instrumente pentru asta.