Bruke og utvide Drupal 8 Mail API Del 1

I denne to delserien skal vi utforske Mail API i Drupal 8. Da skal vi dekke to hovedaspekter: hvordan du bruker det programatisk for å sende e-post og hvordan å forlenge det for å bruke en ekstern tjeneste som Mandrill.

For å demonstrere dette, vil vi i første del lage en egendefinert e-post mal som blir brukt til å sende e-post til den nåværende brukeren når han / hun sparer en ny artikkelnode. I tillegg vil vi se hvordan andre kan endre det mal for å tillate HTML-gjengivelse av e-postkroppen i stedet for standard vanlig tekst.

I den andre delen skal vi se på å utvide postsystemet og integrere en ekstern API for e-postlevering. For dette vil vi bruke Mandrill og dets PHP-bibliotek som gir et godt grunnlag for å samhandle med API-en.

Alt arbeidet vi gjennomgår, finnes i dette Git-depotet som en del av en tilpasset Drupal 8-modul som vi skal begynne å skrive her. Så vær så snill å sjekke det ut hvis du vil følge med. La oss komme i gang.

Den første forutsetningen for denne modulen er dens .info fil:

d8mail.info.yml:

navn: Drupal 8 Mailer beskrivelse: 'Demonstrerer bruken av Mail API i Drupal 8.' kjernen: 8.x type: modul 

Med dette ut av veien, kan vi allerede aktivere modulen på vår side hvis vi vil.

Hvordan sender vi en e-post?

Det er to hovedtrinn som trengs for å sende en e-post programmatisk med Drupal 8. Vi må først implementere hook_mail () for å kunne definere en eller flere e-poster maler. Det andre trinnet er å bruke postbehandleren til å sende e-post med en av disse maler.

Selv kalt en krok, hook_mail () er ikke en typisk krok, men mer av en vanlig funksjon som vanligvis blir kalt bare av samme modul som implementerer den. Med andre ord, når du sender en e-post programmatisk, må du spesifisere modulnavnet implementering hook_mail () og mal ID du vil bruke, og som er definert av denne kroken. Men vi ser det om et minutt. Først, hvordan implementerer vi det?

d8mail.module:

/ ** * Utfører hook_mail (). * / funksjon d8mail_mail ($ key, & $ message, $ params) $ options = array ('langcode' => $ melding ['langcode'],); bytte ($ key) case 'node_insert': $ message ['from'] = \ Drupal :: config ('system.site') -> få ('mail'); $ message ['subject'] = t ('Node opprettet: @title', array ('@ title' => $ params ['node_title']), $ opsjoner); $ melding ['body'] [] = SafeMarkup :: checkPlain ($ params ['message']); gå i stykker;  

Dette er en veldig enkel implementering som definerer en mal identifisert som node_insert (de $ nøkkel). De to andre funksjonsargumentene er:

  • $ melding: Passert ved referanse, og innenfor som vi legger til så mye boilerplate om vår e-post som vi trenger 
  • $ params: En rekke ekstra data som må gå i e-posten, og det er sendt fra postbehandleren når vi prøver å sende e-posten

Som du ser, bygger vi opp $ melding array med verdier vi vil at denne e-posten skal inkludere i samtaleene. Vi setter en standard fra verdien som hentes fra konfigurasjonssystemet, og som representerer e-postadressen til hovedsiden. Vi setter en boilerplate-e-post Emne som lar mottakeren vite at en ny node ble opprettet, etterfulgt av nodens navn (som vil bli sendt inn gjennom $ params array). Emnet kan også oversettes til språket som blir sendt fra den som ringer. 

Til slutt løper vi meldingen kropp gjennom strengen sanitiser fordi teksten kan inneholde HTML og det kan bli avkortet hvis vi ikke koder HTML-elementene. Og siden vi bruker SafeMarkup klasse, må vi bruk det øverst:

bruk Drupal \ Component \ Utility \ SafeMarkup; 

I tillegg er meldingslegemet et oppsett som senere vil være implodert inn i en streng. Og selvfølgelig er det mange andre parametere vi kan angi, for eksempel overskrifter, men dette vil være tilstrekkelig for dette eksempelet.

Og det er alt for hook_mail () gjennomføring. La oss nå slå på koden som blir kjørt hver gang en ny node er opprettet, hook_entity_insert ():

/ ** * Implementerer hook_entity_insert (). * / funksjon d8mail_entity_insert (Drupal \ Core \ Entity \ EntityInterface $ entity) hvis ($ entity-> getEntityTypeId ()! == 'node' || ($ entity-> getEntityTypeId () === 'node' && $ enhet -> bunt ()! == 'artikkel')) return;  $ mailManager = \ Drupal :: service ('plugin.manager.mail'); $ module = 'd8mail'; $ key = 'node_insert'; $ til = \ Drupal :: currentUser () -> getEmail (); $ params ['message'] = $ entity-> get ('body') -> verdi; $ params ['node_title'] = $ entity-> label (); $ langcode = \ Drupal :: currentUser () -> getPreferredLangcode (); $ send = true; $ result = $ mailManager-> mail ($ modul, $ key, $ til, $ langcode, $ params, NULL, $ send); hvis $ result ['result']! == true) $ message = t ('Det oppsto et problem med å sende e-postvarsling til @email for å opprette node @id.', array ('@ email' => $ til , '@id' => $ entity-> id ())); drupal_set_message ($ message, 'error'); \ Drupal :: logger ( 'd8mail') -> feil ($ melding); komme tilbake;  $ message = t ('Et e-postvarsel er sendt til @email for å opprette node @id.', array ('@ email' => $ til, '@id' => $ entity-> id ())) ; drupal_set_message ($ melding); \ Drupal :: logger ( 'd8mail') -> varsel ($ melding);  

Denne kroken blir utløst etter hver knapt lagring, og alt vi trenger å gjøre er å sørge for at vi målretter mot riktig knutepunkt og inkluderer vår logikk.

Etter å ha kontrollert at nodenheten er av typen artikkel, vi laster opp Drupal-postbehandling og starter med å angi noen verdier for e-posten. Vi trenger følgende informasjon:

  • modulnavnet som implementerer hook_mail () og definerer vår mal (det jeg nevnte ovenfor)
  • de mal id (den $ nøkkel)
  • mottakerens e-postadresse (den som er funnet på den nåværende brukerkontoen)
  • språket ($ langcode) som går inn i $ params array og som vil bli brukt til å oversette emnemeldingen
  • noden tittelen som vil bli lagt til e-postfaget
  • e-postkroppen, som i vårt tilfelle vil være verdien av nodens kroppsfelt
  • Den boolske verdien indikerer om e-posten faktisk skal sendes

Vi sender så alle disse verdiene til post() metode for postleder. Sistnevnte er ansvarlig for å bygge e-posten (ringer til høyre hook_mail () implementering er ett aspekt av dette) og til slutt delegere selve leveransen til ansvarlig plugin. Som standard vil dette være PHPMail, som bruker standard post() funksjon som følger med PHP.

Hvis postbehandleren lykkes ved å sende e-postadressen (faktisk levering ikke er tatt i betraktning, men snarere en vellykket PHP-handling), post() Metoden vil returnere en matrise som inneholder a resultat nøkkel med hva posttillegget returnerer. Når vi sjekker for den verdien, kan vi lære om e-posthandlingen var vellykket og informere brukeren om at vi har varslet dem om handlingen. Ellers skriver vi ut og logger en feilmelding.

Og det handler om det. Å fjerne cachen og opprette en artikkelnode skal lande en e-post i innboksen din. Hvis du ikke får noe og det ikke er noen feilskilt på skjermen, må du sjekke serverloggene og postkøen for å bekrefte at e-postmeldinger sendes ut.

Før jeg går videre, vil jeg gjerne gjøre et kort notat om denne krokimplementeringen. I dette eksempelet plasserte jeg all logikken inne i den direkte. I tillegg brukte jeg en tidlig retur på toppen, noe som i hovedsak betyr at ingen annen logikk kan legges til, men den som er spesifikk for artikkeldokumenter. I ekte applikasjoner anbefaler jeg å refactoring mailing logikken inn i en egen funksjon eller klasse og utsette det. Videre bør du ikke bruke tidlig retur i krokimplementeringer, men i stedet ringe til andre funksjoner dersom vilkårene er oppfylt. 

Hvordan endrer vi en e-post?

Når alt dette er på plass, har vi et annet verktøy til disposisjon som gjør at vi kan endre et slikt eksisterende oppsett: hook_mail_alter (). Denne kroken kalles fra postbehandleren før den ansvarlige postpluggen sender e-posten. Hensikten er å tillate andre moduler å utføre endelige endringer i en eksisterende e-post som sendes ut.

Selv om dette også kan brukes av andre moduler, vil vi illustrere et eksempel implementering fra samme modul som vi har jobbet med. Til dette formål endrer vi e-posten ved å endre en av standardhodene for å forvandle den fra vanlig tekst til HTML. Og slik kan vi gjøre dette:

/ ** * Implementerer hook_mail_alter (). * / funksjon d8mail_mail_alter (& $ melding) switch ($ message ['key']) tilfelle 'node_insert': $ message ['headers'] ['Content-Type'] = 'text / html; charset = UTF-8; format = strømmet; delsp = yes'; gå i stykker;  

Som du kan se, er dette en enkel endring av Innholdstype header som forvandler e-posten til HTML. På denne måten blir HTML-enheter med enkel tekst analysert som HTML via e-postklienter. Og ved å bruke bryteren, sørger vi for at dette bare skjer for e-posten mal vi definerte tidligere.

En ting å merke seg her er at alterkroken blir kalt etter det aktuelle hook_mail () gjennomføring. Så etter dette er den eneste behandlingen som skjer på e-posten gjort inne i format() Metode for post-plugin (håndhevet av grensesnittet).

Konklusjon

Og det er stort sett alt som er å sende e-postprogrammatisk ved hjelp av Drupal 8. Vi har sett trinnene som kreves for å programmere sette opp e-post maler som blir hydrert av postlederen når vi vil ha det. Vi har også nevnt standard e-postleverandørplugin som brukes til å sende e-postmeldinger i Drupal 8. Og endelig har vi sett hvordan andre moduler nå kan endre e-posten vår ved å legge til nye overskrifter, endre emnet, sammenkoble verdier til postkroppen , etc.

I neste artikkel skal vi se på å erstatte standard PHPMail-plugin med vår egen tilpassede implementering. Vi vil sette opp en mailer som bruker Mandrill ved hjelp av PHP-biblioteket. Målet er å la vår egen modul bruke denne maileren mens resten av applikasjonen fortsetter å bruke standard PHPMailer.