Comment ajouter des en-têtes aux e-mails sortants?

8

Je souhaite ajouter un en-tête supplémentaire aux e-mails sortants sur mes sites, afin de pouvoir facilement déterminer quel site a envoyé un e-mail donné. (J'ai mis un plugin de fonctionnalité standard sur tous mes sites, donc c'est assez facile à faire, et configurer mon client de messagerie pour filtrer et autrement agir sur cet en-tête serait un gain de temps incroyable.)

Je pensais que ce serait une simple question de se connecter à la wp_mailfonction, mais ce n'est évidemment pas le cas.

Tout d'abord, j'ai essayé ceci:

add_filter('wp_mail', 'ws_add_site_header');
function ws_add_site_header() {
    return array('headers' => 'X-WU-Site: ' . parse_url(get_site_url(), PHP_URL_HOST));
}

Ici, mon tableau a pris le pas sur tout ce qui a modifié les paramètres de messagerie (par exemple, Gravity Forms), donc les e-mails HTML ont commencé à apparaître sous forme de code HTML brut et pas correctement formatés. Cela a du sens, car l'en-tête Content-type: que GF a ajouté a été nettoyé. Mais mon en-tête a été ajouté à l'e-mail. Étant donné que d'autres dépendent également de la réception de jolis e-mails (tous les développeurs de contenu et les utilisateurs finaux de mes sites, entre autres, je suis sûr), ce n'est pas acceptable.

Un de mes collègues a ensuite suggéré d'acheminer mes affaires via wp_parse_args (), ainsi:

add_filter('wp_mail', 'ws_add_site_header');
function ws_add_site_header($args) {
    $new_header = array('headers' => 'X-WU-Site: ' . parse_url(get_site_url(), PHP_URL_HOST));
    return wp_parse_args($args, $new_header);
}

Avec cela, c'est comme si ma fonction n'existait pas - mon en-tête n'est pas ajouté, mais les en-têtes et les paramètres de messagerie des autres ne sont pas supprimés.

Quelle est la bonne façon d'ajouter un en-tête à un e-mail sortant, sans brouiller les autres filtres qui pourraient exister?

David E. Smith
la source
Si vous souhaitez une solution simple, veuillez utiliser Email Header Footer Plugin Wordpress gratuit
Prashant Baldha
Ce plugin ne résout pas réellement le problème. Il ajoute un "en-tête" au corps des e-mails générés par WordPress; J'essayais d'ajouter un en-tête SMTP, ce qui est complètement différent.
David E. Smith

Réponses:

7

Grâce à ce qui précède, j'ai réalisé mon erreur centrale - je ne savais pas très bien que les arguments transmis étaient un tableau multidimensionnel.

Pour l'instant, j'ai ré-implémenté la fonction ainsi:

function ws_add_site_header($email) {
    $email['headers'][] = 'X-WU-Site: ' . parse_url(get_site_url(), PHP_URL_HOST) ;
    return $email;               
}

Ma lecture de la source wp_mail () (voir: https://core.trac.wordpress.org/browser/tags/4.4.2/src/wp-includes/pluggable.php#L235 ) me porte à croire que les en-têtes Le composant peut être un tableau, ou une grosse chaîne, ou peut-être un méli-mélo horrible des deux, mais l'utilisation d'un tableau est probablement l'option la plus sûre / la plus correcte.

J'aime les différentes réponses de phpmailer, mais il semble juste un peu plus propre d'essayer de faire des choses en utilisant les fonctionnalités intégrées de WordPress.

David E. Smith
la source
6

Voici une alternative utilisant directement la AddCustomHeaderméthode de l' PHPMailerinstance:

/**
 * Add a custom header.
 * $name value can be overloaded to contain
 * both header name and value (name:value)
 * @access public
 * @param string $name Custom header name
 * @param string $value Header value
 * @return void
 */
public function addCustomHeader($name, $value = null)
{
    if ($value === null) {
        // Value passed in as name:value
        $this->CustomHeader[] = explode(':', $name, 2);
    } else {
        $this->CustomHeader[] = array($name, $value);
    }
}

Ici, nous pouvons voir qu'il y a deux façons de l'utiliser:

Exemple 1:

Ici, nous transmettons uniquement les informations d'en-tête dans la $namechaîne d'entrée, qui sont séparées par:

add_action( 'phpmailer_init', function( $phpmailer )
{   
    $phpmailer->AddCustomHeader( 
       'X-WU-Site: ' . parse_url( get_site_url(), PHP_URL_HOST ) 
    );  
} );

Exemple # 2:

Voici les deux $nameet $valuenon vides:

add_action( 'phpmailer_init', function( $phpmailer )
{   
    $phpmailer->AddCustomHeader( 
       'X-WU-Site', parse_url( get_site_url(), PHP_URL_HOST ) 
    );  
} );
Birgire
la source
C'est bien de connaître cette réponse :) Mais je suis curieux de savoir quel effet cela aura si quelqu'un l'a réglé $args['headers'] = 'key: value'via des filtres WP?
Sumit
Le phpmailer_initcrochet se déclenche plus tard que lorsque le wp_mailfiltre est appliqué et les en-têtes personnalisés de ce filtre sont également ajoutés via la AddCustomHeader()méthode, si je comprends bien. @sumit
birgire
3

PHP headerssont des chaînes. Vous ne pouvez pas les analyser en tant que tableau. Vous devez ajouter votre en-tête supplémentaire sous forme de chaîne avec \r\npour vous assurer qu'il est ajouté à la ligne suivante.

Exemple:

add_filter('wp_mail', 'ws_add_site_header', 99);
function ws_add_site_header($args) {
    $args['headers'] .= !empty($args['headers']) ? "\r\n" : '';
    $args['headers'] .= 'X-WU-Site: ' . parse_url(get_site_url(), PHP_URL_HOST);
    return $args;
}

Veuillez également noter que vous ajoutez enfin des en-têtes supplémentaires avec priorité 99afin qu'aucun autre plugin ne puisse le remplacer s'il ne vérifie pas que les en-têtes sont déjà présents. Si nécessaire, faites-le 999.

Sumit
la source
1
J'ai fouillé la source de wp_mail () et il est apparemment censé pouvoir accepter les en-têtes soit comme des tableaux, soit comme de gros morceaux de texte, et peut-être parfois les deux mélangés. Je ne conseillerais pas de le faire en général, mais c'est toujours une option.
David E. Smith
@ DavidE.Smith a raison. wp_mailaccepte un tableau pour l'argument d'en-tête et WP se chargera d'ajouter \ r \ n
Jan Beck
Veuillez noter que je n'ai PHP headerspas mentionné ce que wp_mailj'accepte. Enfin, les en-têtes sont des chaînes. Ce qui wp_mailaccepte n'était pas la question! @JanBeck
Sumit
1
Oui, telle était la question. Pourquoi faites-vous apparaître des en-têtes PHP?
Jan Beck