¿Cómo agregar encabezados al correo electrónico saliente?

8

Quiero agregar un encabezado adicional a los correos electrónicos salientes en mis sitios, para poder determinar fácilmente qué sitio envió un correo electrónico determinado. (Puse un complemento de funcionalidad estándar en todos mis sitios, por lo que es bastante fácil de hacer, y configurar mi cliente de correo electrónico para filtrar y, de lo contrario, actuar en este encabezado sería un ahorro de tiempo increíble).

Pensé que esto sería una simple cuestión de conectarse a la wp_mailfunción, pero evidentemente no lo es.

Primero, probé esto:

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

Aquí, mi matriz tenía prioridad sobre cualquier otra cosa que modificara la configuración del correo (por ejemplo, Gravity Forms), por lo que los correos electrónicos HTML comenzaron a aparecer como HTML simple y sin formato. Tiene sentido, ya que se eliminó el encabezado Content-type: que GF agregó. Pero mi encabezado fue agregado al correo electrónico. Dado que otros también dependen de recibir bonitos correos electrónicos (estoy seguro de que todos los desarrolladores de contenido y usuarios finales de mis sitios, entre otros), eso no es aceptable.

Uno de mis colegas sugirió enrutar mis cosas a través de wp_parse_args (), por lo tanto:

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

Con eso, es como si mi función no existiera: mi encabezado no se agrega, pero tampoco se eliminan los encabezados y la configuración de correo de los demás.

¿Cuál es la forma correcta de agregar un encabezado a un correo electrónico saliente, sin codificar ningún otro filtro que pueda existir?

David E. Smith
fuente
Si desea una solución simple, utilice el Encabezado de pie de página del correo electrónico Plugin gratuito de Wordpress
Prashant Baldha
Ese complemento en realidad no aborda el problema. Agrega un "encabezado" al cuerpo de correos electrónicos generados por WordPress; Estaba tratando de agregar un encabezado SMTP, que es algo completamente diferente.
David E. Smith

Respuestas:

7

Gracias a lo anterior, me di cuenta de mi error central: no me di cuenta de que los argumentos que se pasaban eran una matriz multidimensional.

Por ahora, he vuelto a implementar la función así:

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

Mi lectura de la fuente wp_mail () (ver: https://core.trac.wordpress.org/browser/tags/4.4.2/src/wp-includes/pluggable.php#L235 ) me lleva a creer que los encabezados El componente puede ser una matriz, o una cadena grande, o posiblemente una mezcla horrible de los dos, pero que usar una matriz es probablemente la opción más segura / correcta.

Me gustan las diversas respuestas de phpmailer, pero parece un poco más limpio tratar de hacer cosas usando las funciones integradas de WordPress.

David E. Smith
fuente
6

Aquí hay una alternativa usando directamente el AddCustomHeadermétodo de la PHPMailerinstancia:

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

Aquí podemos ver que hay dos formas de usarlo:

Ejemplo 1:

Aquí solo pasamos la información del encabezado en la $namecadena de entrada, que está separada con:

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

Ejemplo # 2:

Aquí están ambos $namey $valueno vacíos:

add_action( 'phpmailer_init', function( $phpmailer )
{   
    $phpmailer->AddCustomHeader( 
       'X-WU-Site', parse_url( get_site_url(), PHP_URL_HOST ) 
    );  
} );
Birgire
fuente
Es bueno saber esta respuesta :) Pero tengo curiosidad por saber qué efecto tendrá si alguien lo configura a $args['headers'] = 'key: value'través de filtros WP.
Sumit
El phpmailer_initgancho se activa más tarde que cuando wp_mailse aplica el filtro y los encabezados personalizados de ese filtro también se agregan a través del AddCustomHeader()método, por lo que yo entiendo. @sumit
birgire
3

PHP headersson cadenas. No puede analizarlos como matriz. Debe agregar un encabezado adicional como cadena \r\npara asegurarse de que se agregue en la siguiente línea.

Ejemplo:

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;
}

También tenga en cuenta agregar encabezados adicionales por fin con prioridad 99para que ningún otro complemento pueda reemplazarlo si no está verificando que los encabezados ya estén presentes. Si es necesario, hazlo 999.

Sumit
fuente
1
Busqué en la fuente de wp_mail () y aparentemente se supone que puede aceptar encabezados como matrices o como grandes fragmentos de texto, y tal vez a veces los dos se mezclan. No recomendaría hacerlo en general, pero siempre es una opción.
David E. Smith
@ DavidE.Smith es correcto. wp_mailacepta una matriz para el argumento del encabezado y WP se encargará de agregar \ r \ n
Jan Beck
Tenga en cuenta que no he mencionado PHP headerslo que wp_mailacepta. Por fin los encabezados son cadenas. ¡Lo que sí wp_mailacepta no era la pregunta! @ JanBeck
Sumit
1
Sí, esa era la pregunta. ¿Por qué aparecen los encabezados PHP?
Jan Beck