web-dev-qa-db-fra.com

Comment ajouter des en-têtes aux emails sortants?

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é. (Je mets un plugin de fonctionnalités standard sur tous mes sites, donc c'est assez facile à faire, et configurer mon client de messagerie pour filtrer et agir autrement sur cet en-tête serait un gain de temps incroyable.)

Je pensais que ce serait une simple question de connexion à la fonction wp_mail, mais ce n’est évidemment pas le cas.

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 préséance sur tout ce qui modifie les paramètres de messagerie (par exemple, Gravity Forms). Les courriers HTML ont donc commencé à apparaître sous forme de code HTML vierge et non formatés correctement. Cela a du sens, puisque l’en-tête Content-type: ajouté par GF a été nettoyé. Mais mon en-tête a été ajouté à l'email. Etant donné que d'autres dépendent également de la réception de jolis e-mails (développeurs et utilisateurs finaux de tous les sites, entre autres, j'en suis sûr), cela n'est pas acceptable.

Un de mes collègues a ensuite suggéré de router mes données 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 courrier sortant, sans brouiller les autres filtres existants?

8
David E. Smith

Grâce à ce qui précède, j'ai compris mon erreur principale: je n'avais pas bien compris 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 conduit à croire que le composant d'en-tête peut être un tableau, ou une grosse chaîne, ou peut-être un horrible méli-mélo des deux, mais que l'utilisation d'un tableau est probablement l'option la plus sûre/la plus correcte.

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

7
David E. Smith

Voici une alternative utilisant directement la méthode AddCustomHeader de l'instance PHPMailer:

/**
 * 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);
    }
}

Nous pouvons voir ici qu'il y a deux façons de l'utiliser:

Exemple 1:

Ici, nous ne transmettons que les informations d'en-tête dans la chaîne de saisie $name, séparée de :

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

Exemple n ° 2:

Voici les deux codes $name et $value non vides:

add_action( 'phpmailer_init', function( $phpmailer )
{   
    $phpmailer->AddCustomHeader( 
       'X-WU-Site', parse_url( get_site_url(), PHP_URL_Host ) 
    );  
} );
6
birgire

PHP headers sont 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\n pour 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;
}

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

3
Sumit