Envoi d'e-mails
Vous vous apprêtez à envoyer des e-mails, par exemple des newsletters ou des confirmations de commande ? Nette Framework fournit les outils nécessaires avec une API très agréable. Nous allons vous montrer :
- comment créer un e-mail, y compris les pièces jointes
- comment l'envoyer
- comment combiner e-mails et templates
Installation
Vous pouvez télécharger et installer la bibliothèque à l'aide de Composer :
composer require nette/mail
Création d'un e-mail
L'e-mail est un objet de la classe Nette\Mail\Message. Créons-le comme ceci :
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->addTo('jirka@example.com')
->setSubject('Confirmation de commande')
->setBody("Bonjour,\nvotre commande a été acceptée.");
Tous les paramètres saisis doivent être en UTF-8.
En plus d'indiquer le destinataire avec la méthode addTo()
, vous pouvez également indiquer le destinataire en
copie addCc()
, ou le destinataire en copie cachée addBcc()
. Dans toutes ces méthodes, y compris
setFrom()
, nous pouvons écrire l'adresse de trois manières :
$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');
Le corps de l'e-mail écrit en HTML est transmis via la méthode setHtmlBody()
:
$mail->setHtmlBody('<p>Bonjour,</p><p>votre commande a été acceptée.</p>');
Vous n'avez pas besoin de créer l'alternative texte, Nette la générera automatiquement pour vous. Et si l'e-mail n'a pas de
sujet défini, il essaiera de le récupérer à partir de l'élément <title>
.
Il est également extraordinairement facile d'insérer des images dans le corps HTML. Il suffit de passer le chemin où se trouvent physiquement les images comme deuxième paramètre, et Nette les inclura automatiquement dans l'e-mail :
// ajoute automatiquement /path/to/images/background.gif à l'e-mail
$mail->setHtmlBody(
'<b>Bonjour</b> <img src="background.gif">',
'/path/to/images',
);
L'algorithme d'insertion d'images recherche ces motifs : <img src=...>
,
<body background=...>
, url(...)
à l'intérieur de l'attribut HTML style
et la
syntaxe spéciale [[...]]
.
L'envoi d'e-mails peut-il être encore plus simple ?
Un e-mail est comme une carte postale. N'envoyez jamais de mots de passe ou d'autres informations d'identification par e-mail.
Pièces jointes
Il est bien sûr possible d'ajouter des pièces jointes à l'e-mail. La méthode
addAttachment(string $file, ?string $content = null, ?string $contentType = null)
est utilisée à cet effet.
// insère le fichier /path/to/example.zip dans l'e-mail sous le nom example.zip
$mail->addAttachment('/path/to/example.zip');
// insère le fichier /path/to/example.zip nommé info.zip dans l'e-mail
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));
// insère le fichier example.txt avec le contenu "Bonjour John !" dans l'e-mail
$mail->addAttachment('example.txt', 'Bonjour John !');
Templates
Si vous envoyez des e-mails HTML, il est naturel de les écrire dans le système de templates Latte. Comment faire ?
$latte = new Latte\Engine;
$params = [
'orderId' => 123,
];
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->setHtmlBody(
$latte->renderToString('/path/to/email.latte', $params),
'/path/to/images',
);
Fichier email.latte
:
<html>
<head>
<meta charset="utf-8">
<title>Confirmation de commande</title>
<style>
body {
background: url("background.png")
}
</style>
</head>
<body>
<p>Bonjour,</p>
<p>Votre commande numéro {$orderId} a été acceptée.</p>
</body>
</html>
Nette insère automatiquement toutes les images, définit le sujet en fonction de l'élément <title>
et
génère une alternative texte au HTML.
Utilisation dans Nette Application
Si vous utilisez les e-mails conjointement avec Nette Application, c'est-à-dire avec des presenters, vous voudrez peut-être
créer des liens dans les templates en utilisant l'attribut n:href
ou la balise {link}
. Latte ne les
connaît pas par défaut, mais il est très facile de les ajouter. L'objet Nette\Application\LinkGenerator
, capable
de créer des liens, peut être obtenu en le demandant via l'injection de dépendances :
use Nette;
class MailSender
{
public function __construct(
private Nette\Application\LinkGenerator $linkGenerator,
private Nette\Bridges\ApplicationLatte\TemplateFactory $templateFactory,
) {
}
private function createTemplate(): Nette\Application\UI\Template
{
$template = $this->templateFactory->createTemplate();
$template->getLatte()->addProvider('uiControl', $this->linkGenerator);
return $template;
}
public function createEmail(): Nette\Mail\Message
{
$template = $this->createTemplate();
$html = $template->renderToString('/path/to/email.latte', $params);
$mail = new Nette\Mail\Message;
$mail->setHtmlBody($html);
// ...
return $mail;
}
}
Dans le template, nous créons ensuite les liens comme nous en avons l'habitude. Tous les liens créés via LinkGenerator seront absolus.
<a n:href="Presenter:action">Lien</a>
Envoi de l'e-mail
Mailer est la classe responsable de l'envoi des e-mails. Elle implémente l'interface Nette\Mail\Mailer et plusieurs mailers pré-faits sont disponibles, que nous allons présenter.
Le framework ajoute automatiquement au conteneur DI un service de type Nette\Mail\Mailer
construit sur la base de
la configuration, auquel vous pouvez accéder en le demandant via l'injection de dépendances.
SendmailMailer
Le mailer par défaut est SendmailMailer, qui utilise la fonction PHP mail. Exemple d'utilisation :
$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);
Si vous souhaitez définir le returnPath
et que votre serveur le réécrit constamment, utilisez
$mailer->commandArgs = '-fmon@email.fr'
.
SmtpMailer
Pour envoyer du courrier via un serveur SMTP, utilisez SmtpMailer
.
$mailer = new Nette\Mail\SmtpMailer(
host: 'smtp.gmail.com',
username: 'franta@gmail.com',
password: '*****',
encryption: 'ssl',
);
$mailer->send($mail);
Les paramètres supplémentaires suivants peuvent être passés au constructeur :
port
– s'il n'est pas défini, le port par défaut 25 ou 465 pourssl
sera utilisétimeout
– timeout pour la connexion SMTPpersistent
– utiliser une connexion persistanteclientHost
– définir l'en-tête Host du clientstreamOptions
– permet de définir les options de contexte SSL pour la connexion
FallbackMailer
Il n'envoie pas directement les e-mails, mais relaie l'envoi via un ensemble de mailers. Si un mailer échoue, il réessaie avec le suivant. Si le dernier échoue également, il recommence depuis le premier.
$mailer = new Nette\Mail\FallbackMailer([
$smtpMailer,
$backupSmtpMailer,
$sendmailMailer,
]);
$mailer->send($mail);
Comme paramètres supplémentaires dans le constructeur, nous pouvons indiquer le nombre de tentatives et le temps d'attente en millisecondes.
DKIM
DKIM (DomainKeys Identified Mail) est une technologie visant à accroître la fiabilité des e-mails, qui aide également à détecter les messages falsifiés. Le message envoyé est signé avec la clé privée du domaine de l'expéditeur et cette signature est stockée dans l'en-tête de l'e-mail. Le serveur du destinataire compare cette signature avec la clé publique stockée dans les enregistrements DNS du domaine. Si la signature correspond, cela prouve que l'e-mail provient réellement du domaine de l'expéditeur et qu'il n'a pas été modifié pendant la transmission.
Vous pouvez configurer la signature des e-mails pour le mailer directement dans la configuration. Si vous n'utilisez pas l'injection de dépendances, elle est utilisée de cette manière :
$signer = new Nette\Mail\DkimSigner(
domain: 'nette.org',
selector: 'dkim',
privateKey: file_get_contents('../dkim/dkim.key'),
passPhrase: '****',
);
$mailer = new Nette\Mail\SendmailMailer; // ou SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);
Configuration
Aperçu des options de configuration pour Nette Mail. Si vous n'utilisez pas l'ensemble du framework, mais seulement cette bibliothèque, lisez comment charger la configuration.
Pour l'envoi d'e-mails, le mailer Nette\Mail\SendmailMailer
est utilisé par défaut, qui n'est pas configuré
davantage. Cependant, nous pouvons le basculer vers Nette\Mail\SmtpMailer
:
mail:
# utilise SmtpMailer
smtp: true # (bool) la valeur par défaut est false
host: ... # (string)
port: ... # (int)
username: ... # (string)
password: ... # (string)
timeout: ... # (int)
encryption: ... # (ssl|tls|null) la valeur par défaut est null (a l'alias 'secure')
clientHost: ... # (string) la valeur par défaut est $_SERVER['HTTP_HOST']
persistent: ... # (bool) la valeur par défaut est false
# contexte pour la connexion au serveur SMTP, la valeur par défaut est stream_context_get_default()
context:
ssl: # aperçu des options sur https://www.php.net/manual/fr/context.ssl.php
allow_self_signed: ...
...
http: # aperçu des options sur https://www.php.net/manual/fr/context.http.php
header: ...
...
Avec l'option context › ssl › verify_peer: false
, vous pouvez désactiver la vérification des certificats
SSL. Nous déconseillons fortement de le faire, car l'application deviendrait vulnérable. Ajoutez plutôt les certificats au magasin.
Pour augmenter la fiabilité, nous pouvons signer les e-mails en utilisant la technologie DKIM :
mail:
dkim:
domain: myweb.com
selector: lovenette
privateKey: %appDir%/cert/dkim.priv
passPhrase: ...
Services DI
Ces services sont ajoutés au conteneur DI :
Nom | Type | Description |
---|---|---|
mail.mailer |
Nette\Mail\Mailer | classe envoyant les e-mails |
mail.signer |
Nette\Mail\Signer | signature DKIM |