Giorno 16: Inviare ~email|Email~
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.
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('[email protected]' => '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'); } // ... }
Per far funzionare il codice, occorre cambiare
[email protected]
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()
~.
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|Factory~
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.
La classe
sfContext
L'oggetto ~
sfContext
~ contiene riferimenti a oggetti di symfony come request, response, user, ecc. Dal momento chesfContext
agisce come un singleton, si può utilizzaresfContext::getInstance()
da qualsiasi parte e quindi avere accesso a qualsiasi oggetto del core di symfony:$mailer = sfContext::getInstance()->getMailer();Ogni volta che si vuole utilizzare
sfContext::getInstance()
in una delle proprie classi, sarebbe meglio pensarci due volte, perché introduce un ~forte accoppiamento|Forte Accoppiamento~. È quasi sempre meglio passare l'oggetto necessario come parametro.È anche possibile utilizzare ~
sfContext
~ come un registro e aggiungere i propri oggetti usando i metodiset()
. Accetta un nome e un oggetto come parametri e il metodoget()
può essere usato in seguito per recuperare l'oggetto in base al nome:sfContext::getInstance()->set('job', $job); $job = sfContext::getInstance()->get('job');
~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 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.
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: [email protected]
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.
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.
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.
ORM
インデックス
Document Index
関連ページリスト
Related Pages
- Giorno 1: Impostare il progetto
- Giorno 2: Il progetto
- Giorno 3: Il ~Modello dei dati~
- Giorno 4: Il controllore e la vista
- Giorno 5: Il routing
- Giorno 6: Di più sul Modello
- Giorno 7: Giocare con la pagina delle categorie
- Giorno 8: I test unitari
- Giorno 9: I test funzionali
- Giorno 10: Form
- Giorno 11: Testare i Form
- Giorno 12: Admin Generator
- Giorno 13: L'utente
- Giorno 14: Feed
- Giorno 15: Web Service
- Giorno 16: Inviare ~email|Email~
- Giorno 17: Ricerca
- Giorno 18: ~AJAX~
- Giorno 19: Internazionalizzazione e Localizzazione
- Giorno 20: I plugin
- Giorno 21: La Cache
- Giorno 22: Il rilascio
- Giorno 23: Un altro sguardo a symfony
- Appendice B - Licenza
- Riconoscimenti
日本語ドキュメント
Japanese Documents
- 2011/01/18 Chapter 17 - Extending Symfony
- 2011/01/18 The generator.yml Configuration File
- 2011/01/18 Les tâches
- 2011/01/18 Emails
- 2010/11/26 blogチュートリアル(8) ビューの作成