Espace tutos dev’ & informatique 🐧

5 méthodes pour modifier l’expéditeur des emails WordPress (sans plugin)

Publié le
Article sur comment changer l'adresse email par défaut d'un site WordPress

Introduction

Les mails jouent un rôle important dans la perception du sérieux d’un site internet par les visiteurs. Qui ferait confiance à un site dont les communications sont remplies de fautes d’orthographe, de liens inexistants ou envoyées depuis une adresse méconnaissable ?

« Tiens, j’ai reçu un courriel de www-mailerdaemon26b4 ! Mon vieux copain ! » – Personne

L’article d’aujourd’hui concerne le remplacement de l’adresse expéditeur utilisée par défaut sur les sites WordPress. En effet, le CMS utilise – depuis ses débuts et malgré les remarques des développeurs – un expéditeur email assez improbable, sous la forme de WordPress <wordpress@domaine.com>.

Mettons nous 2 secondes à la place du visiteur qui reçoit un courriel de ce genre : sa première réaction sera de supprimer le mail (« qui est ce WordPress qui m’écrit, sans doute un spam ») ; et si jamais il tentait d’y répondre, il est probable que la boite mail wordpress@domaine.com n’existe pas.

Nous allons donc voir comment remplacer cette adresse par quelque chose de plus commun.

Comme d’habitude sur le blog du colibri, on travaillera sans plugin (vive la légèreté) et le code sera facile à copier/coller dans tous vos projets 😉

On va d’abord (re)-voir comment WordPress choisit l’expéditeur des courriels. Si vous êtes pressé vous pouvez aller directement à la section sur le remplacement de l’expéditeur.

Note : le code a été testé sur une installation WordPress 5.8 et PHP 7.4. N’oubliez pas que les modifications du code d’un site WordPress doivent toujours s’effectuer soit dans un thème enfant soit dans un thème / plugin maison, afin de ne rien perdre lors des mises à jour !

Comment WordPress détermine l’expéditeur

Le meilleur moyen de comprendre comment WordPress choisit l’expéditeur des courriels sortants est d’aller consulter la source de la fonction wp_mail(). J’ai résumé le processus de sélection dans l’infographie suivante.

Infographie expliquant comment changer l'expéditeur des emails WordPress
Les différentes étapes dans le choix de l’expéditeur des emails de WordPress


Nous pouvons intervenir sur 3 points pour modifier l’adresse de l’expéditeur : lors de l’appel à la fonction, et dans les deux filtres qui suivent. Voici quelques détails bons à savoir :

⚙️  L’entête From peut prendre deux formes. La première (recommandée) est From: Nom <email@site.com> qui indique à la fois l’adresse et le nom de l’expéditeur. La seconde est From: email@site.com qui indique uniquement l’adresse email.

⚙️  Si seule l’adresse de l’expéditeur est fournie en entête, le nom WordPress sera utilisé. On peut ainsi se retrouver avec des courriels qui ont pour expéditeur WordPress <votre.nom@domaine.com>. Les clients mail risquent alors de considérer que le nom associé à votre adresse est WordPress, ce qui peut causer des erreurs humaines lors des échanges ultérieurs. A éviter.

Passons maintenant aux différentes méthodes de modification de l’expéditeur.

Modification de l’expéditeur de tous les emails

Première méthode : on va voir comment remplacer l’expéditeur de tous les emails envoyés par WordPress, y compris ceux pour lesquels un expéditeur a été explicitement spécifié. Cela peut sembler un peu overkill mais c’est pourtant suffisant pour de nombreux sites vitrines, dont les seuls mails sont les notifications aux administrateurs et les accusés de réception aux demandes de contact. Cela permet aussi d’écraser une adresse incorrecte utilisée par un plugin défectueux qui ne nous laisserait pas la modifier.

On utilise pour cela les filtres wp_mail_from et wp_mail_from_name pour modifier respectivement l’adresse et le nom de l’expéditeur.

Le code ci-dessous permet d’utiliser Nom du site <noreply@domaine.com>.
Il est à insérer dans le fichier functions.php de votre thème enfant.
Evidemment, si vous attendez des réponses à vos mails, remplacez noreply par une adresse réelle, contact par exemple.

/* Modifier l'expéditeur de tous les emails */

add_filter("wp_mail_from", function($from){
  // Adresse email : noreply@domaine

  $domain = wp_parse_url(network_home_url(), PHP_URL_HOST);
  if(strpos($domain, "www.") === 0) $domain = substr($domain, 4);
  
  return "noreply@".$domain;
});

add_filter("wp_mail_from_name", function($name){
  // Nom : nom_du_site

  return get_bloginfo("name");
});

Modification de l’expéditeur par défaut

Utiliser les hooks wp_mail_from pour remplacer les valeurs par défaut

Deuxième méthode : on va utiliser les mêmes filtres que précédemment, mais en ne modifiant les informations de l’expéditeur que si elles correspondent aux valeurs par défaut utilisées par WordPress. Comme ça, plus d’effet de bord, on ne risque plus d’écraser les adresses utilisées par les plugins par exemple.

Cette méthode est préférable à la première, mais pose un souci tout de même : si un jour WordPress change sa façon de déterminer l’expéditeur par défaut, notre code sera obsolète. Cela a peu de chance d’arriver, mais il vaut mieux le savoir.

Le code ci-dessous est à insérer dans le fichier functions.php du thème enfant.
Comme précédemment, si vous attendez des réponses à vos mails, remplacez noreply par une adresse réelle, telle que contact.

/* Modifier l'expéditeur email par défaut */

add_filter("wp_mail_from", function($from){
  // Adresse email : wordpress@domaine -> noreply@domaine

  $domain = wp_parse_url(network_home_url(), PHP_URL_HOST);
  if(strpos($domain, "www.") === 0) $domain = substr($domain, 4);

  if($from == "wordpress@".$domain)
    return "noreply@".$domain;
  else
    return $from;
});

add_filter("wp_mail_from_name", function($name){
  // Nom : wordpress -> nom_du_site

  if(strtolower($name) == "wordpress")
    return get_bloginfo("name");
  else
    return $name;
});

Ajouter l’entête From par défaut avec le hook wp_mail

Troisième méthode : on va voir comment modifier uniquement l’expéditeur par défaut en ajoutant notre propre entête From quand aucune entête From n’a été spécifiée. C’est la meilleure méthode si tous les thèmes et les plugins installés respectent les standards de WordPress. Comme la méthode précédente, elle n’a pas d’effet de bord.

On utilise le filtre wp_mail pour modifier les arguments transmis à la fonction wp_mail() avant leur traitement. Ca nous permet de détecter si une entête From a été transmise, et de rajouter la nôtre si ca n’est pas le cas. Rien de très compliqué, si ce n’est que les entêtes peuvent être fournies soit sous la forme d’un tableau, soit sous la forme d’une chaine de caractères avec des retours à la ligne pour chaque entête, et qu’il faut gérer tous les cas.

Le code ci-dessous est à insérer dans le fichier functions.php du thème enfant.
Comme précédemment, si vous attendez des réponses à vos mails, remplacez noreply par une vraie adresse, comme contact.

/* Modifier l'expéditeur email par défaut */

add_filter("wp_mail", function($args){
  $headers = $args["headers"];
  $headersIsArray = is_array($headers);
  $headersLineEnding = ! $headersIsArray && strpos($headers, "\r\n") >= 0 ? "\r\n" : "\n";
  $headersEndsWithLineEnding = ! $headersIsArray && substr($headers, -1) == "\n";

  // Recherche du header From existant
  $hasFromHeader = false;
  if($headersIsArray){
    $hasFromHeader = preg_match("/^\s*from\s*:/im", implode("\n", $headers));
  }
  else{
    $hasFromHeader = preg_match("/^\s*from\s*:/im", $headers);
  }

  // Ajout du header From par défaut si manquant
  // From: nom_du_site <noreply@domaine>
  if(! $hasFromHeader){
    $name = get_bloginfo("name");

    $domain = wp_parse_url(network_home_url(), PHP_URL_HOST);
    if(strpos($domain, "www.") === 0) $domain = substr($domain, 4);

    $email = "noreply@".$domain;

    $from = "From:".$name." <".$email.">";

    if($headersIsArray){
      $headers[] = $from;
    }
    else{
      if($headers != "" && ! $headersEndsWithLineEnding) $headers .= $headersLineEnding;
      $headers .= $from;
      if($headersEndsWithLineEnding) $headers .= $headersLineEnding;
    }
  }

  $args["headers"] = $headers;
  return $args;
});

Pour les développeurs : utiliser wp_mail()

Passer un entête From à la fonction wp_mail()

Quatrième méthode : si vous êtes développeur WordPress et travaillez avec des thèmes sur-mesure et des plugins maison, vous avez sans doute besoin d’appeler la fonction wp_mail() vous-même. Dans ce cas, si vous voulez spécifier un expéditeur différent de celui par défaut (mis en place par l’une des 3 méthodes précédentes), vous pouvez l’inclure dans les entêtes passées en paramètre à la fonction.

Le code ci-dessous présente un exemple du passage de l’entête From.
Il est là uniquement pour les développeurs qui savent ce qu’ils font, ne le copiez pas tel quel dans les fichiers de votre thème enfant.

/* Modifier l'expéditeur email avec wp_mail() */

// From: nom_du_site <contact@domaine>
$name = get_bloginfo("name");
$domain = wp_parse_url(network_home_url(), PHP_URL_HOST);
if(strpos($domain, "www.") === 0) $domain = substr($domain, 4);
$email = "contact@".$domain;
$from = "From:".$name." <".$email.">";

wp_mail("destination@example.com", "Sujet", "Message", array($from));

Utiliser temporairement les hooks wp_mail_from avec wp_mail()

Cinquième méthode : vous devez utiliser wp_mail() manuellement mais n’avez pas envie de fabriquer vous-même l’entête From ? Vous pouvez facilement utiliser les filtres wp_mail_from et wp_mail_from_name en one-shot grâce aux fonctions anonymes (appelées aussi simplement fonctions dans une variable) de PHP !

Le code ci-dessous est un bon exemple, à revoir selon votre situation évidemment.
Uniquement pour les développeurs qui savent ce qu’ils font, ne le copiez pas tel quel dans les fichiers de votre thème enfant.

/* Modifier l'expéditeur email avec wp_mail() */

// Adresse email : contact@domaine
$setFromEmail = function(){
  $domain = wp_parse_url(network_home_url(), PHP_URL_HOST);
  if(strpos($domain, "www.") === 0) $domain = substr($domain, 4);
  return "contact@".$domain;
};

// Nom : nom_du_site
$setFromName = function(){ return get_bloginfo("name"); };

add_filter("wp_mail_from", $setFromEmail);
add_filter("wp_mail_from_name", $setFromName);
wp_mail("destination@example.com", "Sujet", "Message");
remove_filter("wp_mail_from", $setFromEmail);
remove_filter("wp_mail_from_name", $setFromName);

Conclusion

Cinq méthodes de remplacement de l’expéditeur, lesquelles choisirez-vous ?

De mon côté, sur les sites WordPress codés sur-mesure je met en place l’expéditeur par défaut avec la méthode n°3, et quand j’appelle la fonction wp_mail() et que j’ai besoin d’indiquer un expéditeur j’utilise la méthode n°4.

Ca se complique sur les sites avec un thème générique et de nombreux plugins, dans ce cas je joue la carte de la sécurité en changeant l’expéditeur par défaut avec la méthode n°2

Si vous avez besoin d’aide pour modifier le code de votre site, écrivez-moi depuis le formulaire de contact du site.

C’est tout pour aujourd’hui, bon code et à la prochaine !

Références

La fonction wp_mail – WordPress Developers
Le hook wp_mail – WordPress Developers
Le hook wp_mail_from – WordPress Developers
Le hook wp_mail_from_name – WordPress Developers

Partagez cet article  =>