Ieri abbiamo aggiunto un web service di sola lettura a Jobeet. Gli affiliati ora possono creare un account, ma quest'ultimo ha bisogno di essere attivato dall'amministratore prima di poter essere utilizzato. Pe far si che l'affiliato ottenga il suo token, abbiamo ancora bisogno di implementare la notifica via email. Questo è quello che inizieremo a fare oggi.
Il framework symfony comprende una delle migliori soluzioni PHP per le email: SwiftMailer. Naturalmente la libreria è pienamente integrata con symfony e comprende alcune interessanti caratteristiche aggiunte sopra a quelle standard.
note
Symfony 1.3 usa la versione 4.1 di Swift Mailer.
Invio semplice delle email
Iniziamo inviando una semplice mail per notificare all'affiliato quando il suo account è stato confermato e per dargli il token dell'affiliato.
Modifichiamo l'azione activate
con il seguente codice:
// apps/backend/modules/affiliate/actions/actions.class.php class affiliateActions extends autoAffiliateActions { public function executeListActivate() { $affiliate = $this->getRoute()->getObject(); $affiliate->activate(); // send an email to the affiliate $message = $this->getMailer()->compose( array('jobeet@example.com' => 'Jobeet Bot'), $affiliate->getEmail(), 'Jobeet affiliate token', <<<EOF Il tuo account affiliato di Jobeet è stato attivato. Il tuo token è {$affiliate->getToken()}. Il Bot di Jobeet. EOF ); $this->getMailer()->send($message);
// ... }
note
Per far funzionare il codice, occorre cambiare jobeet@example.com
in un
indirizzo email esistente.
La gestione delle email in symfony è incentrata intorno a un oggetto mailer, che può essere
recuperato da una azione con il metodo getMailer()
.
Il metodo compose()
prende quattro argomenti e ritorna un oggetto di messaggio
email:
- l'indirizzo email del mittente (
from
); - l'indirizzo email del destinatario o dei destinatari (
to
); - l'oggetto del messaggio;
- il corpo del messaggio.
L'invio del messaggio è semplice come chiamare il metodo send()
sull'istanza
di mailer, passando il messaggio come argomento. Come scorciatoia, si può
comporre e inviare una mail in un unico passo utilizzando il metodo
composeAndSend()
.
tip
Il messaggio email è una istanza della classe Swift_Message
. Fare riferimento
alla documentazione ufficiale di Swift Mailer
per imparare di più su questo oggetto, e per fare cose più avanzate come
allegare file.
Configurazione
Per impostazione predefinita, il metodo send()
prova a usare un server locale SMTP per inviare il
messaggio al destinatario. Naturalmente, come molte altre cose in symfony, questo è
completamente configurabile.
Factories
Nei giorni precedenti, abbiamo già parlato riguardo gli oggetti core di symfony
come user
, request
, response
, o il routing
. Questi oggetti sono
creati, configurati e gestiti automaticamente dal framework symfony. Inoltre
sono sempre accessibili dall'oggetto sfContext
e come molte cose nel
framework, sono configurabili attraverso un file di configurazione:
factories.yml
. Questo file è configurabile per l'ambiente.
Quando sfContext
inizializza i factorie del core, legge il
file factories.yml
per i nomi della classe (class
) e i parametri
(param
) da passare al costruttore:
response: class: sfWebResponse param: send_http_headers: false
In questo frammento di codice, per creare il factory di risposta, symfony istanzia
un oggetto sfWebResponse
e passa l'opzione send_http_headers
come parametro.
Strategia di consegna
Come molti altri oggetti del core di symfony, il mailer è un factory. Quindi è
configurato nel file di configurazione factories.yml
. La configurazione
predefinita è la seguente:
mailer: class: sfMailer param: logging: %SF_LOGGING_ENABLED% charset: %SF_CHARSET% delivery_strategy: realtime transport: class: Swift_SmtpTransport param: host: localhost port: 25 encryption: ~ username: ~ password: ~
Quando si crea una nuova applicazione, il file di configurazione locale factories.yml
sovrascrive la configurazione predefinita con alcuni ragionevoli valori predefiniti per gli
ambienti env
e test
:
test: mailer: param: delivery_strategy: none dev: mailer: param: delivery_strategy: none
L'impostazione delivery_strategy
dice a symfony come inviare le email. Per
impostazione predefinita, symfony ha quattro differenti strategie:
realtime
: I messaggi sono inviati in tempo reale.single_address
: I messaggi sono inviati a un unico indirizzo.spool
: I messaggi sono memorizzati in una coda.none
: I messaggi sono semplicemente ignorati.
Qualunque sia la strategia, le email sono sempre salvate in un log e disponibili nel pannello "mailer" della barra web con gli strumenti di debug.
Il mezzo della mail
I messaggi mail vengono inviati effettivamente da un mezzo. Il mezzo è configurato nel
file di configurazione factories.yml
e la configurazione predefinita utilizza il
server SMTP della macchina locale:
transport: class: Swift_SmtpTransport param: host: localhost port: 25 encryption: ~ username: ~ password: ~
Swift Mailer è fornito con tre differenti classi per il trasporto:
Swift_SmtpTransport
: Usa un server SMTP per l'invio dei messaggi.Swift_SendmailTransport
: Usasendmail
per l'invio dei messaggi.Swift_MailTransport
: Usa la funzione PHP nativamail()
per l'invio dei messaggi.
tip
La sezione "Tipi di trasporto" della documentazione ufficiale di Swift Mailer descrive tutto quello che c'è da sapere sulle classi e i loro diversi parametri.
Testare le emails
Ora che abbiamo visto come inviare una email con il mailer di symfony,
scriviamo alcuni test funzionali per assicurarci di aver fatto bene le cose. Per
impostazione predefinita, symfony registra un tester mailer
(sfMailerTester
) cheto ease mail testing
facilita il test delle mail nei test funzionali.
Sostituire il file del test funzionale affiliate
per l'applicazione di backend con
il seguente codice:
// test/functional/backend/affiliateActionsTest.php include(dirname(__FILE__).'/../../bootstrap/functional.php'); $browser = new JobeetTestFunctional(new sfBrowser()); $browser->loadData(); $browser-> info('1 - When validating an affiliate, an email must be sent with its token')-> get('/affiliate/new')-> click('activate', array(), array('position' => 1))-> with('mailer')->begin()-> checkHeader('Subject', '/Jobeet affiliate token/')-> checkBody('/Your token is symfony/')-> end() ;
Perchè il codice precedente funzioni, è necessario copiare il file delle fixture di ieri
(data/fixtures/030_affiliates.yml
) nella cartella test/fixtures/
.
Ogni email inviata, può essere testata con l'aiuto dei metodi checkHeader()
e
checkBody()
. Il secondo argomento di checkHeader()
e il primo
argomento di checkBody()
può essere uno dei seguenti:
una stringa su cui verificare una corrispondenza esatta
una espressione regolare su cui verificare il valore
una espressione regolare negata (una espressione regolare che inizia con un
!
) per verificare che il valore non corrisponda.
note
Per impostazione predefinita, i controlli vengono effettuati sulla prima e-mail inviata.
Se sono state inviate varie email, è possibile scegliere quella che si vuole testare
con il metodo withMessage()
. withMessage()
prende un destinatario come primo argomento. Prende
anche un secondo argomento per indicare quale email si vuole testare se allo stesso
destinatario ne sono state inviate più di una.
tip
Come altri tester disponibili, è possibile vedere il messaggio "grezzo" chiamando il
metodo debug()
.
Ci vediamo domani
Domani, implementeremo l'ultima caratterisitica mancante al sito web di Jobeet, il motore di ricerca.
ORM
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.