I den forrige artikkelen så vi på hvordan vi kan sende e-postmeldinger programmert i Drupal 8. Vi så også hvordan andre moduler kan endre disse utgående postene. I dag skal vi se på hvordan vi kan bruke Mail API for å utvide denne standardoppførelsen. Hensikten er å bruke en ekstern tjeneste som et middel for e-postlevering.
For dette vil vi bruke Mandrill, selv om artiklens fokus ikke vil være dets API eller hvordan du skal jobbe med det, men heller Drupal-siden av ting. Og husk, arbeidsmodulen finnes i dette Git-depotet.
Som vi har sett i forrige artikkel, skjer det å sende en epost i Drupal 8 ved å be om postbehandleren, og sende noen parametere til sin post()
metode, og sette opp en mal inne i a hook_mail ()
gjennomføring. Hva postbehandleren gjør internt, laster opp riktig e-posttillegg, konstruerer e-postadressen og deretter delegeres til post()
Metoden for hva som helst plugin ble lastet inn.
Men hvem overtar det faktisk til?
En viktig ting å forstå før du skriver vårt eget plugin er valgprosessen til postbehandleren for å laste inn plugins. Med andre ord, hvordan vet vi hvilket plugin det vil laste, og hvordan kan vi få det til å laste våre egne?
De system.mail.interface
konfigurasjonsarrangementet inneholder alle svarene. Den inneholder ids for de tilgjengelige pluginene, tastet av konteksten de er brukt i. Som standard er alt vi har inne i denne konfigurasjonen standard => phpmail
. Dette betyr at plugin med id phpmail
(PHPMail-klassen) brukes som tilbakebetaling for alle sammenhenger som ikke er angitt ellers, dvs. standard.
Hvis vi ønsker å skrive vår egen plugin, må vi legge til et annet element i det arrayet med plugin-ID som dets verdi. Nøkkelen for denne verdien kan være en av to ting: maskinens navn på modulen (for å laste inn plugin når modulen sender e-post) eller en kombinasjon av modulnavn og e-post mal nøkkel (for å laste inn plugin når modulen sender en e-post ved hjelp av den aktuelle nøkkelen).
Et eksempel på sistnevnte konstruksjon er d8mail_node_insert
, hvor d8mail
er vårt modulnavn vi begynte å bygge i forrige artikkel, og node_insert
er e-posten mal nøkkel vi definerte.
Så nå som vi vet hvordan valg av e-postplugin skjer, må vi sørge for at denne konfigurasjonsfeltet inneholder den nødvendige informasjonen slik at e-postmeldinger sendt med vår d8mail
Modulen bruker det nye pluginet vi skal bygge. Vi kan gjøre dette i en hook_install () implementering som blir utløst bare en gang når modulen blir installert:
d8mail.install:
/ ** * Implementerer hook_install (). * / funksjon d8mail_install () $ config = \ Drupal :: configFactory () -> getEditable ('system.mail'); $ mail_plugins = $ config-> get ('interface'); hvis (in_array ('d8mail', array_keys ($ mail_plugins))) return; $ mail_plugins ['d8mail'] = 'mandrill_mail'; $ config-> set ('interface', $ mail_plugins) -> lagre ();
Ikke super komplisert hva som skjer over. Vi laster det redigerbare konfigurasjonsobjektet som representerer system.mail
konfigurasjon, og legg til et nytt element i grensesnitt
matrise: d8mail => mandrill_mail
. Vi vil snart lage et mail-plugin med iden til mandrill_mail
som vil bli brukt til alle e-postmeldinger sendt av d8mail
modul. Og det er det.
Men før vi går videre, må vi sørge for at denne endringen vender tilbake når modulen avinstalleres. For dette kan vi bruke motparten hook_uninstall () som blir kalt når en modul blir avinstallert (det er ikke flere moduler deaktivere i Drupal 8).
Inne i samme fil:
/ ** * Implementerer hook_uninstall (). * / funksjon d8mail_uninstall () $ config = \ Drupal :: configFactory () -> getEditable ('system.mail'); $ mail_plugins = $ config-> get ('interface'); hvis (! in_array ('d8mail', array_keys ($ mail_plugins))) return; unset ($ mail_plugins ['d8mail']); $ config-> set ('interface', $ mail_plugins) -> lagre ();
Med hook_uninstall ()
implementering vi gjør det motsatte av før: vi fjerner vårt plugin-id hvis det er angitt.
Installasjons- / avinstalleringsscenariet er bare en vei å gå. Du kan også opprette et administrasjonsskjema som lar brukerne velge plugin de vil ha, og i hvilken sammenheng. Men du må fortsatt sørge for at når du deaktiverer modulen som definerer en bestemt plugin, vil konfigurasjonen ikke lenger holde en referanse til det aktuelle plugin. Ellers kan e-postbehandleren prøve å bruke en ikke-eksisterende klasse og kaste alle typer feil.
Som jeg nevnte tidligere, vil vi jobbe med Mandrill API for å illustrere vår oppgave. Så la oss laste opp Mandrills PHP-bibliotek og gjøre det tilgjengelig i vårt miljø. Det er tre trinn vi må gjøre for dette.
Først må vi faktisk få biblioteket inne i Drupal. På tidspunktet for skriving betyr dette i utgangspunktet å legge til "mandrill / mandrill": "1.0. *"
avhengighet til roten composer.json
fil og kjøring komponent installasjon
. Vær imidlertid oppmerksom på at dette også vil fjerne Drupal-installasjonen fra innsiden av kjerne/
mappe og last ned den siste stabile utgivelsen i stedet. Deretter må du redigere roten index.php
fil og endre banen til autoloaderen i henhold til disse instruksjonene. Forhåpentligvis vil denne siste handlingen ikke være nødvendig snart, og jeg oppfordrer deg til å følge diskusjonene om fremtiden til Composer i Drupal 8 for å administrere eksterne biblioteker.
For det andre må vi få en API-nøkkel fra Mandrill. Heldigvis kan dette lett genereres fra deres administrasjons sider. Når vi har det, kan vi lagre det inne i en ny fil opprettet på vår server, på begge steder:
~ / .mandrill.key /etc/mandrill.key
Vi kan også sende nøkkelen som en konstruktørparameter til hoveddelen mandrill
klasse, men på denne måten trenger vi ikke å kode det i vår kode.
For det tredje må vi opprette en tjeneste slik at vi kan bruke avhengighetsinjeksjon for å passere mandrill
klassen inn i plugin:
d8mail.services.yml:
tjenester: d8mail.mandrill: klasse: Mandrill
Avhengig av hvordan du har lastet inn mandrill
klassen i søknaden din, må du endre verdien etter klasse
. Ved å bruke composer.json
tilnærming, dette vil være tilstrekkelig.
Det er endelig tid til å lage vårt plugin. I Drupal 8 går pluginklasser inne i src / Plugin
mappe av modulen vår. Avhengig av deres type, plasseres de imidlertid lenger ned i andre kataloger (i vårt tilfelle Post
). La oss skrive vår klasse som vil avhenge av Mandrill API-biblioteket for å sende e-post:
src / Plugin / Mail / MandrillMail.php:
mandrill = $ mandrill; / ** * @inheritdoc * / offentlig statisk funksjon lage (ContainerInterface $ container, array $ konfigurasjon, $ plugin_id, $ plugin_definition) return new static ($ container-> get ('d8mail.mandrill')); / ** * @inheritdoc * / offentlige funksjonsformat (array $ message) // Bli med i gruppen array til en streng. $ melding ['body'] = implode ("\ n \ n", $ melding ['body']); // Konverter noen HTML til vanlig tekst. $ melding ['body'] = MailFormatHelper :: htmlToText ($ message ['body']); // Vik postkroppen for sending. $ melding ['body'] = MailFormatHelper :: wrapMail ($ message ['body']); returner $ message; / ** * @inheritdoc * / offentlig funksjon post (array $ melding) prøv $ vars = ['html' => $ melding ['body'], 'subject' => $ message ['subject' ], 'from_email' => $ melding ['fra'], 'til' => array (array ('email' => $ melding ['til']))]]; $ result = $ this-> mandrill-> messages-> send ($ vars); hvis ($ resultat [0] ['status']! == 'sendt') return false; returnere $ resultat; fangst (Mandrill_Error $ e) return false;
Det er et par ting å merke seg før du kommer inn i hva klassen gjør.
Først, merknadene over klassen. Dette er bare den vanligste plugin funnet mekanisme for Drupal 8. The id
nøkkelen samsvarer med verdien vi la til system.mail.interface
konfigurasjons array tidligere, mens resten er grunnleggende plugin-definisjon elementer.
For det andre, implementeringen av ContainerFactoryPluginInterface
grensesnitt som vi definerer skape()
metode. Sistnevnte er en del av avhengighetsinjeksjonsprosessen hvor vi kan laste opp Mandrill-tjenesten vi definerte i services.yml
filen tidligere. Dette gjør testing mye enklere og det anses best praksis.
Som nevnt, må posttilleggene implementere MailInterface
grensesnitt som styrker eksistensen av format()
og post()
metoder. I vårt tilfelle gjør den første nøyaktig det samme som PHPMail
plugin: litt behandling av meldingslegemet. Så du kan legge til din egen logikk her hvis du vil. Sistnevnte metode er derimot ansvarlig for å sende ut posten, i vårt tilfelle, ved hjelp av selve Mandrill API.
Som Mandrill-dokumentasjonen instruerer, konstruerer vi en e-postmelding inne i $ vars
array ved hjelp av verdier passert fra postbehandleren gjennom $ melding
parameter. Disse vil allerede bli filtrert gjennom hook_mail ()
, hook_mail_alter ()
og pluginets egne format()
metode. Alt som er igjen er å sende e-posten. Jeg vil ikke gå inn i detaljer om bruk av Mandrill API som du kan konsultere dokumentasjonen for alle alternativene du kan bruke.
Etter å ha sendt e-posten og komme tilbake fra Mandrill a sendt
status, returnerer vi hele respons-arrayet, som inneholder litt mer informasjon. Denne rekkefølgen blir deretter lagt til av e-postbehandleren til eget returarrangement som er tastet som resultat
. Hvis Mandrill har et problem, avviser e-posten eller kaster et unntak, kommer vi tilbake falsk
. Dette vil gjøre at postbehandleren håndterer denne situasjonen ved å logge hendelsen og skrive ut en statusmelding.
Og det er ganske mye det. Vi kan rydde hurtigbufferen og prøve å opprette en annen artikkel node. Denne gangen, varselmeldingen skal sendes av Mandrill i stedet for PHP post()
. Med dette på plass, skjønt, hook_mail_alter ()
implementeringen har blitt overflødig da det ikke er noen overskrifter vi faktisk sender til Mandrill (og teksten er HTML allerede). Og for den saks skyld er det ikke mye brukt av postansvarlig arbeid, da vi ikke overfører det til Mandrill. Men dette er bare ment å illustrere prosessen med hvordan du kan gå om å sette opp dette. Detaljer om implementeringen forblir opp til deg og dine behov.
Og der har vi det. Vi har implementert vårt eget e-postprogram som skal brukes av d8module
Vi startet i forrige artikkel. Og på grunn av den utvidbare naturen til Drupal 8, tok det ikke engang for mye innsats.
Det som er igjen for deg å gjøre, er å perfeksjonere postleverandørlogikken og tilpasse den til dine forhold. Dette kan bety ytterligere integrasjon mellom Mandrill og Drupal-forekomsten din, konstruere fine maler eller hva har du. I tillegg er en viktig gjenværende oppgave å skrive automatiserte tester for denne funksjonaliteten. Og Drupal 8 tilbyr ganske verktøysettet for det også.