Envoyer un e-mail

Envoyer un e-mail

1 mai 2021

Symfony possède son propre composant nous permettant d'envoyer des e-mails depuis la version 4.3. Celui-ci est très pratique et très proche d'un bundle nommé SwiftMailer, largement utilisé aussi. Dans cet article, nous allons utiliser le composant Mailer intégré à Symfony.

Avant d'envoyer quoi que ce soit, il va falloir configurer Mailer.
Ouvrez votre fichier ".env" et dé-commentez la ligne MAILDER_DSN :

###> symfony/mailer ###
MAILER_DSN=smtp://localhost
###< symfony/mailer ###

Vous pouvez laisser cette configuration par défaut pour le moment. Les destinataires ne recevront pas les e-mails envoyés, mais ceux-ci seront interceptés par la barre de debug de Symfony pour en contrôler le contenu, très pratique. ?

Sachez qu'ensuite, vous pouvez modifier cette configuration pour utiliser Gmail, MailChimp...

Par exemple, pour Gmail, la configuration ressemblerait à ceci :

MAILER_DSN=gmail+smtp://USERNAME:PASSWORD@default

Créer et envoyer un message

Dans la méthode de votre choix, vous devez appliquer le code suivant afin de créer et d'envoyer un e-mail :

<?php

namespace App\Controller;

use Symfony\Component\Mime\Email;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Routing\Annotation\Route;

class HomeController extends AbstractController
{
   /**
    * @Route("/mail", name="email")
    */
   public function sendMail(MailerInterface $mailer)
   {
      // ...

      $mail = (new Email())
         ->from('expediteur@demo.test')
         ->to('destinataire@demo.test')
         ->subject('Mon beau sujet')
         ->html('<p>Ceci est mon message en HTML</p>')
      ;

      $mailer->send($mail);

      // ...
   }
}

Comme vous pouvez le constater, le code est facile à comprendre.
D'abord, injectez l'interface de Mailer dans votre méthode :

public function sendMail(MailerInterface $mailer)
{ 
    //...
}

N'oubliez pas d'inclure les namespaces qui vont avec :

use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;

Ensuite, créez le message en renseignant les différentes parties afin de compléter l'e-mail à envoyer : l'expéditeur, le destinataire, le sujet du message et le contenu du message.

Dans mon exemple, j'envoie un message au format HTML, mais si vous préférez un message au format texte, remplacez la ligne HTML par celle-ci :

->text('Ceci est mon message en HTML')

E-mail et template

Mailer nous permet aussi d'envoyer un e-mail en utilisant un template, une vue Twig.
Pour cela, nous allons modifier le code ci-dessus en modifiant une classe ainsi qu'une méthode :

// ...

$mail = (new TemplatedEmail())
   ->from('expediteur@demo.test')
   ->to('destinataire@demo.test')
   ->subject('Mon beau sujet')
   ->htmlTemplate('mail/template.html.twig')
;

$mailer->send($mail);

// ...

J'ai modifié la classe "Email()" par TemplateEmail(), sans oublier d'ajouter le namespace qui va bien :

use Symfony\Bridge\Twig\Mime\TemplatedEmail;

J'ai également modifié la méthode html() contenant le message par htmlTemplate() en lui passant la vue que je souhaite utiliser. Le passage de la vue se fait exactement sur le même principe que render() à la fin d'une méthode. Elle va aller chercher le fichier correspondant dans le dossier "templates" : à vous de lui dire où récupérer votre vue Twig.

Il reste alors à créer la vue dans votre dossier "templates" :

<p>Ceci est mon message</p>

Pour cet exemple, j'ai tout simplement mis du code HTML, mais rien ne vous empêche d'y mettre un layout si tous vos e-mails ont une base similaire :

{% extends 'base.html.twig' %}

{% block body %}
    <p>Ceci est mon message</p>
{% endblock %}

Template et variables

Vous pouvez aussi passer des variables à votre template afin qu'il soit personnalisé pour chaque utilisateur. Pour cela, nous allons ajouter la méthode context(), qui contiendra un tableau associatif et qui fonctionne sur le même principe que render(). On choisit le nom d'une variable pour la vue et on lui attribue une valeur :

// ...

$mail = (new TemplatedEmail())
   ->from('expediteur@demo.test')
   ->to('destinataire@demo.test')
   ->subject('Mon beau sujet')
   ->htmlTemplate('home/mail.html.twig')
   ->context([
      'firstname' => 'Joe'
   ])
;

$mailer->send($mail);

// ...

Dans ma vue, j'écris donc :

<p>Hello {{ firstname }} !</p>

Maintenant, le contenu de votre e-mail est personnalisable.

Adresse e-mail

Dans le code actuel, nous utilisons from() pour définir l'adresse e-mail de l'expéditeur. Justement, à la réception, seule l'adresse e-mail s'affichera. Pour rendre ça plus... joli, nous pouvons afficher un nom à la place de cette adresse au moment de sa réception. À l'intérieur de la méthode from(), ajoutez le code suivant :

->from(new Address('expediteur@demo.test', 'Mon nom'))

Comme toujours, n'oublions pas le namespace qui va avec :

use Symfony\Component\Mime\Address;

C'est plus sympa quand même. ?

Réception du message

Maintenant que votre message est prêt, il nous reste à vérifier si l'envoi fonctionne et si son contenu est correct. Au moment de l'envoi du message, comme nous n'avons pas configuré de serveur SMTP, c'est la barre de debug de Symfony qui interceptera celui-ci. Une nouvelle icône représentant une enveloppe apparaîtra avec le nombre d'e-mails non lus.

Attention ! Il ne s'agit pas d'une boite e-mail !

En cliquant sur cette icône, vous ouvrirez le profiler de Symfony et vous pourrez contempler votre message fraîchement reçu.