![]() |
|
Practical symfonyJour 16 : L'Envoi d'email |
|
You are currently reading "Practical symfony" which is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.

|
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License. |
Hier, nous avons ajouté à Jobeet un service web en lecture seule. Les affiliés peuvent désormais créer un compte mais il a besoin d'être activé par l'administrateur avant de pouvoir l'utiliser. Pour que l'affilié obtienne son jeton, il nous faut encore mettre en œuvre l'email de notification. C'est ce que nous allons commencer à faire aujourd'hui.
Le framework symfony est livré avec l'une des meilleures solutions d'email PHP : Swift Mailer. Bien sûr, la bibliothèque est entièrement intégré avec symfony, avec quelques fonctionnalités ajoutées à ses fonctionnalités par défaut.
Symfony 1.3/1.4 utilise Swift Mailer version 4.1.
Commençons par envoyer un simple email pour notifier à l'affiliée lorsque son compte a été confirmé et pour lui donner le jeton de l'affiliée.
Remplacez l'action activate avec le code suivant :
// 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 Your Jobeet affiliate account has been activated. Your token is {$affiliate->getToken()}. The Jobeet Bot. EOF ); $this->getMailer()->send($message); $this->redirect('jobeet_affiliate'); } // ... }
Pour que le code fonctionne correctement, vous devez changer l'adresse email
jobeet@example.compar une réelle.
La gestion des emails dans symfony est centrée autour d'un objet mailer, qui peut
être récupéré à partir d'une action avec la méthode getMailer().
La méthode compose() prend quatre arguments et retourne un objet de message
email :
from);to);L'envoi du message est donc aussi simple que d'appeler la méthode send send()
sur l'instance mailer et en passant le message comme un argument. Comme un raccourci,
vous pouvez composer et envoyer un email en une seule fois en utilisant la méthode
composeAndSend().
Le message email est une instance de la classe
Swift_Message. Référez vous à la documentation officielle de Swift Mailer pour ven savoir plus sur cet objet, et la façon de faire des choses plus avancées comme joindre des fichiers.
Par défaut, la méthode send() essaie d'utiliser un serveur SMTP local pour envoyer
le message au destinataire. Bien entendu, comme beaucoup de choses dans symfony, ceci
est totalement configurable.
Au cours des jours précédents, nous avons déjà parlé des objets du noyau de symfony
comme user, request, response ou routing. Ces objets sont automatiquement
créés, configurés et gérés par le framework symfony. Ils sont toujours accessibles
à partir de l'objet sfContext, et comme beaucoup de choses dans le framework,
ils sont configurables via un fichier de configuration : factories.yml. Ce
fichier est configurable par environnement.
Lorsque le sfContext initialise les factories du noyau, il lit le
fichier factories.yml pour passer au constructeur les noms des classes
(class) et des paramètres (param) :
response:
class: sfWebResponse
param:
send_http_headers: false
Dans l'extrait ci-dessus, pour créer le factory response, symfony instancie
un objet sfWebResponse et passe l'option send_http_headers comme un
paramètre.
La classe
sfContextL'objet
sfContextcontient des références à des objets du noyau de symfony comme la requête, la réponse, l'utilisateur et ainsi de suite. CommesfContextagit comme un singleton, vous pouvez utiliser l'instructionsfContext::getInstance()pour l'obtenir n'importe où et ensuite avoir accès à tous les objets du noyau de symfony :$mailer = sfContext::getInstance()->getMailer();Chaque fois que vous voulez utiliser le
sfContext::getInstance()dans l'une de vos classes, réfléchissez à deux fois, car elle introduit un couplage fort. Il est toujours mieux de passer l'objet dont vous avez besoin en tant qu'argument.Vous pouvez même utiliser
sfContextcomme un registre et ajoutez vos propres objets en utilisant les méthodesset(). Il prend un nom et un objet comme arguments et la méthodeget()peut être utilisée plus tard pour récupérer un objet par son nom :sfContext::getInstance()->set('job', $job); $job = sfContext::getInstance()->get('job');
Comme beaucoup d'autres objets du noyau de symfony, le logiciel de courrier est
un factory. Donc, il est configuré dans le fichier de configuration factories.yml.
La configuration par défaut se lit comme suit :
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: ~
Lorsque vous créez une nouvelle application, le fichier de configuration locale factories.yml
remplace la configuration par défaut avec certaines valeurs adaptées pour les environnements
env et test :
test:
mailer:
param:
delivery_strategy: none
dev:
mailer:
param:
delivery_strategy: none
Le paramètre delivery_strategy explique comment envoyer des emails. Par
défaut, symfony vient avec quatre stratégies différentes :
realtime: Les messages sont envoyés en temps réel.single_address: Les messages sont envoyés à une seule adresse.spool: Les messages sont stockés dans une file d'attente.none: Les messages sont simplement ignorés.Quelle que soit la stratégie, les emails sont toujours journalisés et disponibles dans le panneau "mailer" de la barre d'outils de débogage web.
Les messages emails sont effectivement envoyés par un transport. Le transport est
configuré dans le fichier de configuration factories.yml et la configuration par
défaut utilise le serveur SMTP de la machine locale :
transport:
class: Swift_SmtpTransport
param:
host: localhost
port: 25
encryption: ~
username: ~
password: ~
Swift Mailer st livré avec trois classes de transport différents :
Swift_SmtpTransport: Utilise le serveur SMTP pour envoyer les messages.
Swift_SendmailTransport: Utilise sendmail pour envoyer les messages.
Swift_MailTransport: Utilise la fonction native PHP mail() pour envoyer
les messages.
La section "Transport Types" de la documentation officielle Swift Mailer décrit tout ce que vous devez savoir sur les classes intégrées de transport et leurs différents paramètres.
Maintenant que nous avons vu comment envoyer un email avec le mailer de symfony,
écrivons des tests fonctionnels afin de nous assurer du bon déroulement. Par défaut,
symfony recense un testeur mailer (sfMailerTester) pour faciliter les tests
de messagerie dans les tests fonctionnels.
Tout d'abord, changez la configuration de l'objet mailer pour l'environnement de test si le serveur web local n'est pas équipé d'un service SMTP. Nous devons remplacer l'actuelle classe de transport Swift_SmtpTransport par la classe Swift_MailTransport:
# apps/backend/config/factories.yml
test:
# ...
mailer:
param:
delivery_strategy: none
transport:
class: Swift_MailTransport
Ensuite, ajoutez un nouveau fichier test/fixtures/administrators.yml contenant la définition YAML suivante:
sfGuardUser:
admin:
email_address: admin@example.com
username: admin
password: admin
first_name: Fabien
last_name: Potencier
is_super_admin: true
Enfin, remplacez le fichier de test fonctionnel affiliate de l'application backend avec le code suivant:
// test/functional/backend/affiliateActionsTest.php include(dirname(__FILE__).'/../../bootstrap/functional.php'); $browser = new JobeetTestFunctional(new sfBrowser()); $browser->loadData(); $browser-> info('1 - Authentication')-> get('/affiliate')-> click('Signin', array( 'signin' => array('username' => 'admin', 'password' => 'admin'), array('_with_csrf' => true) ))-> with('response')->isRedirected()-> followRedirect()-> info('2 - When validating an affiliate, an email must be sent with its token')-> click('Activate', array(), array('position' => 1))-> with('mailer')->begin()-> checkHeader('Subject', '/Jobeet affiliate token/')-> checkBody('/Your token is symfony/')-> end() ;
Chaque message envoyé peut être testé à l'aide des méthodes checkHeader()
et checkBody(). Le deuxième argument de checkHeader() et le premier argument
de checkBody() peuvent être un des éléments suivants :
une chaîne pour vérifier une correspondance exacte;
une expression régulière pour vérifier la valeur à son encontre;
une expression régulière négative (une expression régulière commençant avec !)
pour vérifier que la valeur ne correspond pas.
Par défaut, les contrôles sont faits sur le premier email envoyé. Si plusieurs emails ont été envoyés, vous pouvez choisir celui que vous voulez tester avec la méthode
withMessage(). LawithMessage()prend un destinataire pour son premier argument. Elle prend également un second argument pour indiquer quel email vous souhaitez tester si plusieurs ont été envoyés au un même destinataire.
Comme d'autres testeurs intégrés, vous pouvez voir le message brut en appelant la méthode
debug().
Demain, nous allons mettre en œuvre la dernière fonctionnalité manquante du site Jobeet : le moteur de recherche.
If you find a typo or an error, please register and open a ticket.
If you need support or have a technical question, please post to the official user mailing-list.