Symfony2 : SMTP et SwiftMailer
L'envoi de mail est bien souvent nécessaire à la majorité des applications web, cependant, on peut vouloir envoyer des mails à la volée avec des paramètres différents selon la nature du message.
Pré-requis
Il ne faut pas oublier d'activer le bundle livré avec symfony, SwiftMailer dans appKernel.php
public function registerBundles()
{
$bundles = array(
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
);
}
L'envoi de mail classique
Ce type d'envoi est bien expliqué dans le cookbook symfony2 ( http://symfony.com/doc/2.0/cookbook/email/email.html ), Dans le fichier config.yml, on définit les paramètres par défaut :
# app/config/config.yml
swiftmailer:
transport: smtp
encryption: ssl # ssl, tls
auth_mode: login # login, plain ou cram-md5
host: smtp.ligams.com
username: your_username
password: your_passwordPour utiliser cette configuration par défaut et envoyer un email, il suffit d'instancier un objet Swift_Message que l'on enverra avec le service mailer :
namespace Newsfree\EmailBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FooController extends Controller
{
public function indexAction(){
$message = \Swift_Message::newInstance();
$message->setSubject("Objet");
$message->setFrom('ligamsATligams.com');
$message->setTo('destinataire@domaine.com');
// pour envoyer le message en HTML
$message->setBody('Hello world');
// pour envoyer le message en HTML
$message->setBody('<p>Hello world</p>','text/html');
//envoi du message
$this->get('mailer')->send($message);
}
}
Ainsi, vous utilisez les paramètres par défaut.
Modifier les paramètres d'envoi de mail à la volée
Vous ne pouvez peut être pas utiliser ces paramètres d'envoi systématiquement : vous devez alors changer créer de nouveaux paramètres à la volée : attention, si vous ne passez pas de 3e paramètres (ou null) en instanciant Swift_SmtpTransport, les méthodes setUsername et setPassword seront indéfinies (undefined method setUsernam) car aucune authentification n'est prévue :
namespace Newsfree\EmailBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FooController extends Controller
{
public function indexAction(){
//création d'un objet transport
$transport = \Swift_SmtpTransport::newInstance('smtp.ligams.com', 25, 'ssl' )
->setUsername('username')
->setPassword('password');
//création d'un objet mailer
$mailer = \Swift_Mailer::newInstance($transport);
$message = \Swift_Message::newInstance();
$message->setSubject("Objet");
$message->setFrom('ligamsATligams.com');
$message->setTo('destinataire@domaine.com');
// pour envoyer le message en HTML
$message->setBody('Hello world');
// pour envoyer le message en HTML
$message->setBody('<p>Hello world</p>','text/html');
//envoi du message
$mailer->send($message);
}
}
Envoi de mails en masse et personnalisation
C'est bien joli tout ça, mais dans un monde réel, on a besoin de personnaliser les messages et d'envoyer en masse ( bulk mails ), c'est pourquoi je vais aborder l'utilisation des plugins pour SwiftMailer suivants que je trouve particulièrement utiles :
- Swift_Plugins_DecoratorPlugin : Decorator va servir à personnaliser chaque message que vous allez envoyer dans une boucle, en remplaçant des tags que vous allez définir par des valeurs propres à chaque mails (en général, nom, prénom, identifiant quelconque...)
- Swift_Plugins_AntiFloodPlugin : comme son nom l'indique... les serveurs smtp se protègent souvent contre l'envoi massif, le plugin antiflood permet d'atténuer volontairement les envois afin de ne pas offenser les serveurs smtp.
- Swift_Plugins_ThrottlerPlugin : Un petit peu comme antiflood, il permet par exemple de définir un maximum d'envoi par minute, et un maximum de transit par minute.
Utilisons les 3 à la fois dans un exemple, imaginons un tableau $users comparable au résultat d'un findAll() avec fos_user :
<?php
namespace Newsfree\EmailBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FooController extends Controller
{
public function indexAction(){
//...
//création d'un objet transport
$transport = \Swift_SmtpTransport::newInstance('smtp.ligams.com', 25, 'ssl' )
->setUsername('username')
->setPassword('password');
//création d'un objet mailer
$mailer = \Swift_Mailer::newInstance($transport);
/**
* Création des objets de plugin
*/
//maximum 1000 mails par minute
$throttle = new \Swift_Plugins_ThrottlerPlugin(1000, \Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE);
//maximum 30 mégas de mails par minute
$throttle2 = new \Swift_Plugins_ThrottlerPlugin(1024*1024*30, \Swift_Plugins_ThrottlerPlugin::BYTES_PER_MINUTE);
// une seconde de pause tous les 100 mails
$antiflood = new \Swift_Plugins_AntiFloodPlugin(100,1);
foreach($users as $user)
{
$decoratorReplacement[$user->email] = array(
'#email#' => $user->email,
'#nom#' => $user->nom,
'#prenom#'=> $user->prenom,
);
}
$decorator = new \Swift_Plugins_DecoratorPlugin($decoratorReplacement);
//on enregistre les plugins
$mailer->registerPlugin($antiflood);
$mailer->registerPlugin($throttle);
$mailer->registerPlugin($throttle2);
$mailer->registerPlugin($decorator);
$message = \Swift_Message::newInstance();
$message->setSubject("Objet : #nom# #prenom#");
$message->setFrom('ligamsATligams.com');
$message->setBody('<p>Hello #nom# #prenom# #email#</p>','text/html');
foreach($users as $user){
$message->setTo($user->email);
if(!$mailer->send($message)){
//erreur d'envoi
}
}
}
}
Voilà, ça couvre à peu près tous les besoins, pour l'envoi de masse, il est possible d'utiliser un spooler de mail livré avec symfony2, ou de créer une commande (php app/console ...), il reste malvenu de placer des envois d'email de masse (newsletter) dans un contrôleur.













L'environnement ou est hébergé votre application ne change pas grand chose dans votre cas. Pour se logguer à votre application symphony, vous faites sans doute appel à un controleur de cette même appli, si l'authentification est un succès, envoyez un mail, c'est tout ;)
Mon application symfony2 est sur debian
Mes utilisateurs s'y Logge a travers AD server 2003
Voila mon problème :
Dans l'application quand l'utilisateur valide un formulaire, je veux qu'un mail lui soit automatiquement envoyé par l'application.
Quelqu'un peut m'aider sur ce cas
Merci à vous!