
L'envoi de courriels peut être simple et efficace avec Laravel. Grâce à son API de messagerie électronique, claire et intuitive, basée sur le composant Symfony Mailer, Laravel facilite l'intégration de fonctionnalités d'envoi de courriels. Laravel et Symfony Mailer prennent en charge divers pilotes pour l'envoi de courriels via SMTP, Mailgun, Postmark, Resend, Amazon SES et sendmail, vous permettant de choisir le service local ou cloud qui convient le mieux à vos besoins.
Dans ce chapitre, nous allons enrichir l'exemple précédent du formulaire de contact en ajoutant une fonctionnalité d'envoi d'email à l'administrateur du site lorsqu'un utilisateur soumet une demande de contact.
Nous reprendrons le code tel que nous l'avons laissé dans le chapitre précédent et le compléterons en conséquence.
Plus tard, nous explorerons également le système complet de notifications de Laravel, qui inclut, entre autres, l'envoi d'emails.
Le scénario
Le scénario est donc le même que pour le précédent chapitre avec l’ajout d’une action :
On va avoir les mêmes routes et vues, c’est uniquement au niveau du contrôleur que le code va évoluer pour intégrer cette action complémentaire.
Configuration
Si vous regardez dans le fichier .env vous trouvez une section qui concerne les emails :
MAIL_MAILER=log
MAIL_SCHEME=null
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
Les premières valeurs correspondent au prestataire utilisé.
Au niveau du driver, le plus classique est certainement le SMTP, mais vous pouvez aussi utiliser sendmail, Mailgun (gratuit jusqu’à 100 envois par jour), Postmark, Resend (gratuit jusqu'à 3000 emails par mois), ses …
Vous devez correctement renseigner les paramètres pour que ça fonctionne selon votre contexte (en local avec le SMTP de votre prestataire, en production avec la fonction mail de PHP ou d’un autre système…). Vous trouvez le détail pour chaque driver dans la documentation officielle.
La classe Mailable
Dans le développement d'applications Laravel, chaque type de courriel envoyé par votre application est encapsulé dans une classe "mailable". Ces classes sont organisées dans le répertoire app/Mail
. Si ce répertoire n'est pas visible dans votre application, ne vous inquiétez pas : il sera automatiquement créé dès que vous générerez votre première classe mailable.
Encore une fois, c'est Artisan qui va nous permettre de créer notre classe :
php artisan make:mail Contact
Comme le dossier n’existe pas, il est créé en même temps que le fichier de la classe :
Par défaut, on a ce code :
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class Contact extends Mailable
{
use Queueable, SerializesModels;
/**
* Create a new message instance.
*/
public function __construct()
{
//
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: 'Contact',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'view.name',
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}
L'expéditeur
La fonction envelope est là pour désigner l'expéditeur (le from) et le sujet. On peut donc coder ces renseignements ici :
use Illuminate\Mail\Mailables\Address;
...
public function envelope(): Envelope
{
return new Envelope(
from: new Address('admin@contact.com', 'John Lennon'),
subject: 'Contact',
);
}
Mais si tous les mails doivent avoir le même expéditeur, autant le préciser dans le fichier .env :
MAIL_FROM_ADDRESS="admin@contact.com"
MAIL_FROM_NAME="John Lennon"
Ou encore dans le fichier de configuration config/mail.php :
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
Le contenu
Pour le contenu du mail, ça se passe dans la méthode content. On voit qu’on retourne une vue, celle-ci doit comporter le code pour le contenu de l’email.
On commence par changer le nom de la vue :
view: 'emails.contact',
On va créer le dossier emails et cette vue (resources/views/emails/contact.blade.php) :
Avec ce code :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>Prise de contact sur mon beau site</h2>
<p>Réception d'une prise de contact avec les éléments suivants :</p>
<ul>
<li><strong>Nom</strong> : {{ $contact['nom'] }}</li>
<li><strong>Email</strong> : {{ $contact['email'] }}</li>
<li><strong>Message</strong> : {{ $contact['message'] }}</li>
</ul>
</body>
</html>
Pour que ça fonctionne, on doit transmettre à cette vue les entrées de l’utilisateur. Il faut donc passer les informations à la classe Contact à partir du contrôleur.
On peut aussi créer des email en Markdown.
Transmission des informations à la vue
Il y a deux façons de procéder pour transmettre les informations, nous allons utiliser la plus simple. Il suffit de créer une propriété obligatoirement publique dans la classe Mailable et celle-ci sera automatiquement transmise à la vue. Voici le nouveau code de notre classe :
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use Illuminate\Mail\Mailables\Address;
class Contact extends Mailable
{
use Queueable, SerializesModels;
/**
* Elements de contact
* @var array
*/
public $contact;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(Array $contact)
{
$this->contact = $contact;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
from: new Address('admin@contact.com', 'John Lennon'),
subject: 'Contact',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'emails.contact',
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}
On pourrait attacher un document avec attach, faire une copie avec cc…
J’ai créé la propriété publique $contact qui sera renseignée par l’intermédiaire du constructeur.
Il ne reste plus qu’à modifier le contrôleur pour envoyer cet email avec les données nécessaires :
<?php
namespace App\Http\Controllers;
use Illuminate\View\View;
use App\Http\Requests\ContactRequest;
use Illuminate\Support\Facades\Mail;
use App\Mail\Contact;
class ContactController extends Controller
{
public function create(): View
{
return view('contact');
}
public function store(ContactRequest $request): view
{
Mail::to('administrateur@chezmoi.com')
->send(new Contact($request->except('_token')));
return view('confirm');
}
}
Tout se passe sur cette ligne :
Mail::to('administrateur@chezmoi.com')
->send(new Contact($request->except('_token')));
On a :
- l’adresse de l’administrateur (to),
- l’envoi avec la méthode send,
- la création d’une instance de la classe Contact avec la transmission des données saisies (mis à part le token pour la protection CSRF qui ne sert pas).
Et si tout se passe bien, le message doit arriver jusqu’à l’administrateur :
Comme l'envoi d'emails peut prendre beaucoup de temps, on utilise en général une file d'attente (queue). Il faut changer ainsi le code dans le contrôleur :
Mail::to('administrateur@chezmoi.com')
->queue(new Contact($request->except('_token')));
Mais évidemment, pour que ça fonctionne, il faut avoir paramétré et lancé un système de file d'attente. J'en parlerai sans doute dans un chapitre ultérieur.
Test de l'email
Quand on crée la vue pour l'email, il est intéressant de voir l'aspect final avant de faire un envoi réel. Pour le faire, il suffit de créer une simple route :
Route::get('/test-contact', function () {
return new App\Mail\Contact([
'nom' => 'Durand',
'email' => 'durand@chezlui.com',
'message' => 'Je voulais vous dire que votre site est magnifique !'
]);
});
Maintenant en utilisant l'URL monsite/test-contact, on obtient l'aperçu directement dans le navigateur !
Envoyer des emails en phase développement
Le mode Log
Lorsqu’on est en phase de développement, il n’est pas forcément pratique ou judicieux d’envoyer réellement des emails. Une solution simple consiste à passer en mode Log en renseignant le driver dans le fichier .env :
MAIL_MAILER=log
Les emails ne seront pas envoyés, mais le code en sera mémorisé dans le fichier des logs :
Vous allez y trouver par exemple ce contenu :
[2025-02-15 12:29:01] local.DEBUG: From: John Lennon <admin@contact.com>
To: administrateur@chezmoi.com
Subject: Contact
MIME-Version: 1.0
Date: Fri, 15 Mar 2024 12:29:01 +0000
Message-ID: <a58c3c9ab995e439b3690ff81b9aa70e@contact.com>
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>Prise de contact sur mon beau site</h2>
<p>Réception d'une prise de contact avec les éléments suivants :</p>
<ul>
<li><strong>Nom</strong> : Dupont</li>
<li><strong>Email</strong> : dupont@plop.fr</li>
<li><strong>Message</strong> : Super !</li>
</ul>
</body>
</html>
Ce qui vous permet de vérifier que tout se passe correctement (hormis l’envoi).
MailTrap
Une autre possibilité très utilisée est MailTrap qui a une option gratuite avec 1000 emails par mois (une boîte, avec 50 messages au maximum et 2 messages par seconde). Vous avez un tableau de bord et une boîte de messages :
J’ai fait apparaître les configurations pour Laravel. Il est ainsi facile de renseigner le fichier .env :
MAIL_DRIVER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=login
MAIL_PASSWORD=passe
MAIL_ENCRYPTION=null
Mettez l'encryption à null si vous avez des soucis à ce niveau.
Avec cette configuration, lorsque j’envoie un email, je le vois arriver :
Vous pouvez analyser l’email avec précision, je vous laisse découvrir toutes les options.
En résumé
- Laravel simplifie l'envoi d'emails : grâce à une API intuitive, l'envoi de courriels devient une tâche aisée.
- Configuration requise : assurez-vous de configurer correctement les paramètres d'envoi d'emails dans votre application.
- Classes "mailable" : pour chaque type de courriel, créez une classe "mailable" qui sera stockée dans le répertoire
app/Mail
. - Transmission de données : vous pouvez passer des informations à vos emails en définissant des propriétés publiques dans la classe "mailable".
- Mode de développement : en phase de développement, utilisez le mode Log ou un service comme MailTrap pour tester l'envoi d'emails sans les envoyer réellement.
Par bestmomo
Aucun commentaire