Envoyer des e-mails avec Symfony 4

Par Nouvelle-Techno.fr le 4 février 2020 - Catégories : Tutoriel Symfony

Lire l'article sur le site d'origine

Que ce soit pour un formulaire de contact, une validation de commande, ou de nombreuses autres situations, il est très souvent nécessaire d'échanger avec les utilisateurs par e-mail.

Nous allons traiter dans ce tutoriel de la façon la plus simple de gérer l'envoi de ces e-mails, au moyen d'un composant appelé SwiftMailer.

Une autre façon au moyen de notifications fera l'objet d'un autre tutoriel.

L'exemple ci-dessous traite de la création et de la gestion d'un formulaire de contact.

ATTENTION : La configuration de l'envoi d'e-mails diffère fortement en fonction des hébergeurs, nous ne traiterons pas cette partie, habituellement documentée par les hébergeurs eux-mêmes.

Installation de SwiftMailer

Comme la plupart des composants, SwiftMailer s'installera au moyen de la commande Composer ci-dessous

composer require symfony/swiftmailer-bundle

Une fois exécutée, cette commande crée un fichier "swiftmailer.yaml" dans le dossier "config/packages"

Ce fichier contient le code suivant, que nous ne modifierons pas

swiftmailer:
    url: '%env(MAILER_URL)%'
    spool: { type: 'memory' }

Nous allons également devoir configurer la variable d'environnement "MAILER_URL" dans le fichier ".env" en fonction de notre configuration. Dans ce tutoriel, nous allons laisser cette variable comme ceci

MAILER_URL=null://localhost

Intercepter les e-mails (mode développement)

Durant la phase de développement, nous allons devoir vérifier si les e-mails sont bien envoyés.

Plusieurs solutions s'offrent à nous en fonction du serveur :

Nous allons utiliser Symfony Profiler dans notre exemple.

Pour intercepter les e-mails, nous avons besoin de désactiver les redirections de pages pour que la navigation s'arrête lors de l'envoi de l'e-mail.

Nous allons configurer cette option dans le fichier "web_profiler.yaml" situé dans "config/packages/dev"

Dans ce fichier nous allons modifier une ligne comme suit

intercept_redirects: true

A partir de cet instant, toutes les redirections sont interceptées. N'oubliez pas de remettre "false" par la suite.

Créer le formulaire de contact

Pour créer le formulaire de contact, nous allons utiliser la même procédure que dans le tutoriel "Utiliser les formulaires", en nommant le formulaire "ContactType" et le contrôleur "ContactController".

Le fichier "ContactType.php" contiendra le code suivant

<?php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ContactType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nom')
            ->add('email', EmailType::class)
            ->add('message', TextareaType::class)
            ->add('envoyer', SubmitType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            // Configure your form options here
        ]);
    }
}

Notre contrôleur "ContactController.php" contiendra le code suivant

<?php

namespace App\Controller;

use App\Form\ContactType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class ContactController extends AbstractController
{
    /**
     * @Route("/contact", name="contact")
     */
    public function index(Request $request)
    {
        $form = $this->createForm(ContactType::class);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $contact = $form->getData();

            // Ici nous enverrons l'e-mail

            $this->addFlash('message', 'Votre message a été transmis, nous vous répondrons dans les meilleurs délais.'); // Permet un message flash de renvoi
        }
        return $this->render('contact/index.html.twig',['contactForm' => $form->createView()]);
    }

}

Nous avons donc maintenant un formulaire fonctionnel, mais celui-ci n'envoie pas encore l'e-mail.

Envoyer l'e-mail

Préparer les données

Avant d'envoyer l'e-mail, nous allons préparer les données qu'il va contenir.

Nous avons besoin de plusieurs informations :

Certaines de ces informations sont données par l'utilisateur, d'autres sont connues.

Pour commencer, nous avons déjà récupéré sous forme de tableau l'ensemble des données du formulaire à la ligne

$contact = $form->getData();

Nous allons devoir définir le nom de l'expéditeur (le visiteur), le destinataire (nous), et le titre (Nouveau contact, par exemple).

Préparer la vue

Comme pour les pages web, l'e-mail sera construit à partir d'une vue Twig dans laquelle nous écrirons notre texte ou code html.

Dans notre cas, nous allons créer un dossier "emails" dans "templates".

Dans ce dossier, nous allons créer un fichier "contact.html.twig" qui contiendra le code HTML de notre message, et utilisera une variable "contact" pour les données.

Le code de cette page sera le suivant

<h1>Nouveau contact</h1>
<p>Nom : {{contact.nom}}</p>
<p>e-mail : {{contact.email}}</p>
<p>Message : {{contact.message|raw}}</p>

Envoyer le message

Pour terminer, nous allons envoyer le message depuis le contrôleur.

Nous allons commencer par ajouter un paramètre dans notre méthode qui donnera accès à SwiftMailer sous le nom "$mailer"

public function index(Request $request,\Swift_Mailer $mailer)

Nous allons ensuite créer le message et transmettre les données à la vue

$message = (new \Swift_Message('Nouveau contact'))
    // On attribue l'expéditeur
    ->setFrom($contact['email'])

    // On attribue le destinataire
    ->setTo('votre@adresse.fr')

    // On crée le texte avec la vue
    ->setBody(
        $this->renderView(
            'emails/contact.html.twig', compact('contact')
        ),
        'text/html'
    )
;

Et enfin, on envoie le message

$mailer->send($message);

Le contrôleur terminé sera donc celui-ci

<?php

namespace App\Controller;

use App\Form\ContactType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class ContactController extends AbstractController
{
    /**
     * @Route("/contact", name="contact")
     */
    public function index(Request $request,\Swift_Mailer $mailer)
    {
        $form = $this->createForm(ContactType::class);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $contact = $form->getData();

            // On crée le message
            $message = (new \Swift_Message('Nouveau contact'))
                // On attribue l'expéditeur
                ->setFrom($contact['email'])
                // On attribue le destinataire
                ->setTo('votre@adresse.fr')
                // On crée le texte avec la vue
                ->setBody(
                    $this->renderView(
                        'emails/contact.html.twig', compact('contact')
                    ),
                    'text/html'
                )
            ;
            $mailer->send($message);

            $this->addFlash('message', 'Votre message a été transmis, nous vous répondrons dans les meilleurs délais.'); // Permet un message flash de renvoi
        }
        return $this->render('contact/index.html.twig',['contactForm' => $form->createView()]);
    }

}

Et voilà, c'est terminé !!

Obtenir de l'aide

Pour obtenir de l'aide, vous pouvez accéder aux forums de Nouvelle-Techno.fr ou au serveur Discord pour une entraide par chat

#Tutoriel #Utilisateurs #Symfony