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. Per 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/1.4 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(); // invio di un'email all'affiliato $message = $this->getMailer()->compose( array('jobeet@example.com' => 'Jobeet Bot'), $affiliate->getEmail(), 'Jobeet affiliate token', <<<EOF Your Jobeet affiliate account has been activated. Your token is {$affiliate->getToken()}. The Jobeet Bot. EOF ); $this->getMailer()->send($message); $this->redirect('jobeet_affiliate'); } // ... }
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()
acceetta quattro parametri e restituisce un oggetto 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 parametro. 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 ad esempio
allegare un 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 degli oggetti principali 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 factory principali, 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 nucleo 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 web debug toolbar.
Trasporto della mail
I messaggi mail vengono inviati effettivamente da un mezzo di trasporto. 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 email
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
), che
facilita il test delle mail nei test funzionali.
Innanzitutto, sostituire la configurazione del factory mailer
per l'ambiente test
,
se il proprio server web non disponde in un server locale SMTP. Occorre sostituire
la classe Swift_SmtpTransport
con Swift_MailTransport
:
# apps/backend/config/factories.yml test: # ... mailer: param: delivery_strategy: none transport: class: Swift_MailTransport
Poi, aggiungere un nuovo file test/fixtures/administrators.yml
, con le seguenti
definizioni YAML:
sfGuardUser: admin: email_address: admin@example.com username: admin password: admin first_name: Fabien last_name: Potencier is_super_admin: true
Infine, 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() ;
Ogni email inviata può essere testata con l'aiuto dei metodi checkHeader()
e
checkBody()
. Il secondo parametro di checkHeader()
e il primo
parametro di checkBody()
possono essere uno dei seguenti:
- una stringa su cui verificare una corrispondenza esatta
- un'espressione regolare su cui verificare il valore
- un'espressione regolare negata (un'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()
accetta un destinatario come primo parametro.
Accetta anche un secondo parametro 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 sorgente, chiamando il
metodo debug()
.
Ci vediamo domani
Domani implementeremo l'ultima caratteristica mancante al sito web di Jobeet, il motore di ricerca.
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.