Como adicionar cabeçalhos ao email de saída?

8

Desejo adicionar um cabeçalho adicional aos emails de saída em meus sites, para que eu possa determinar facilmente qual site enviou um determinado email. (Eu coloquei um plug-in de funcionalidade padrão em todos os meus sites, para que isso seja fácil o suficiente, e configurar meu cliente de email para filtrar e agir nesse cabeçalho seria uma economia de tempo incrível.)

Eu pensei que isso seria uma simples questão de conectar-se à wp_mailfunção, mas evidentemente não é.

Primeiro, tentei o seguinte:

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

Aqui, minha matriz teve precedência sobre qualquer outra coisa que modificasse as configurações de correio (por exemplo, Gravity Forms), de modo que os emails em HTML começaram a aparecer como HTML simples e não foram bem formatados. Faz sentido, uma vez que o cabeçalho Content-type: que a GF adicionou foi limpo. Mas meu cabeçalho foi adicionado ao email. Como outros também dependem de receber e-mails bonitos (todos os desenvolvedores de conteúdo e usuários finais dos meus sites, entre outros, tenho certeza), isso não é aceitável.

Um dos meus colegas sugeriu encaminhar minhas coisas por wp_parse_args (), assim:

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

Com isso, é como se minha função não existisse - meu cabeçalho não foi adicionado, mas os cabeçalhos e as configurações de email de outras pessoas não foram removidos.

Qual é a maneira correta de adicionar um cabeçalho a um email de saída, sem embaralhar outros filtros que possam existir?

David E. Smith
fonte
Se você quiser uma solução simples, use o Plug
Prashant Baldha
Na verdade, esse plug-in não resolve o problema. Ele adiciona um "cabeçalho" ao corpo dos emails gerados pelo WordPress; Eu estava tentando adicionar um cabeçalho SMTP, que é uma coisa completamente diferente.
David E. Smith

Respostas:

7

Graças ao exposto, percebi meu erro central - não percebi que os argumentos passados ​​eram uma matriz multidimensional.

Por enquanto, reimplementei a função assim:

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

Minha leitura da fonte wp_mail () (consulte: https://core.trac.wordpress.org/browser/tags/4.4.2/src/wp-includes/pluggable.php#L235 ) me leva a acreditar que os cabeçalhos O componente pode ser um array, ou uma string grande, ou possivelmente uma mistura horrível dos dois, mas o uso de um array é provavelmente a opção mais segura / correta.

Eu gosto das várias respostas do phpmailer, mas parece um pouco mais limpo tentar fazer as coisas usando os built-ins do WordPress.

David E. Smith
fonte
6

Aqui está uma alternativa usando diretamente o AddCustomHeadermétodo da PHPMailerinstância:

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

Aqui podemos ver que existem duas maneiras de usá-lo:

Exemplo 1:

Aqui, apenas passamos as informações do cabeçalho na $namestring de entrada, separadas por:

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

Exemplo 2:

Aqui estão ambos $namee $valuenão estão vazios:

add_action( 'phpmailer_init', function( $phpmailer )
{   
    $phpmailer->AddCustomHeader( 
       'X-WU-Site', parse_url( get_site_url(), PHP_URL_HOST ) 
    );  
} );
Birgire
fonte
É bom saber esta resposta :) Mas estou curioso para saber que efeito isso afetará se alguém configurá-lo $args['headers'] = 'key: value'por meio de filtros WP?
Sumit 25/03
O phpmailer_initgancho é acionado mais tarde do que quando o wp_mailfiltro é aplicado e os cabeçalhos personalizados desse filtro também são adicionados pelo AddCustomHeader()método, tanto quanto eu o entendo. @sumit
birgire
3

PHP headerssão strings. Você não pode analisá-los como matriz. Você precisa adicionar seu cabeçalho adicional como string \r\npara garantir que ele seja adicionado na próxima linha.

Exemplo:

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

Observe também que você finalmente adiciona cabeçalhos adicionais com prioridade, 99para que nenhum outro plug-in possa substituí-lo se não estiver verificando se os cabeçalhos já estão presentes. Se necessário, faça 999.

Sumit
fonte
1
Eu procurei na fonte wp_mail () e aparentemente ela deve aceitar cabeçalhos como matrizes ou como grandes pedaços de texto, e talvez às vezes os dois se misturassem. Não seria aconselhável fazer isso em geral, mas é sempre uma opção.
David E. Smith
@ DavidE.Smith está correto. wp_mailaceita uma matriz para o argumento de cabeçalho e WP vai cuidar de adicionar \ r \ n
Jan Beck
Observe que mencionei PHP headersnão o que wp_mailaceita. Finalmente, cabeçalhos são strings. O que wp_mailaceita não foi a questão! @JanBeck
Sumit
1
Sim, essa era a pergunta. Por que você abre os cabeçalhos PHP?
Jan Beck