Как добавить заголовки в исходящую электронную почту?


Я хочу добавить дополнительный заголовок к исходящим электронным письмам на моих сайтах, чтобы я мог легко определить, какой сайт отправил данное электронное письмо. (Я установил стандартный функциональный плагин на все свои сайты, так что это достаточно легко сделать, и настройка моего почтового клиента для фильтрации и других действий с этим заголовком позволила бы значительно сэкономить время.)

Я думал, что это будет простой вопрос подключения к функции wp_mail, но, очевидно, это не так.

Сначала я попытался это:

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

Здесь мой массив имел приоритет над всем остальным, что изменяло настройки почты (скажем, формы гравитации), поэтому электронные письма в формате HTML начали отображаться как голый HTML и не в хорошем формате. Имеет смысл, так как заголовок Content-type:, добавленный GF, был удален. Но мой заголовок был добавлен в электронное письмо. Поскольку другие также зависят от получения красивых электронных писем (среди прочих, я уверен, разработчики контента всех моих сайтов и конечные пользователи), это неприемлемо.

Тогда один из моих коллег предложил перенаправить мои материалы через wp_parse_args(), таким образом:

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

При этом, как будто моя функция не существует - мой заголовок не добавляется, но и заголовки других пользователей и настройки почты не удаляются.

Как правильно добавить заголовок в исходящее электронное письмо, не скремблируя какие-либо другие фильтры, которые могут существовать?

Author: David E. Smith, 2016-03-25

3 answers

Благодаря вышесказанному я осознал свою главную ошибку - я не совсем понимал, что передаваемые аргументы представляют собой многомерный массив.

На данный момент я повторно реализовал функцию таким образом:

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

Мое чтение источника wp_mail() (см.: https://core.trac.wordpress.org/browser/tags/4.4.2/src/wp-includes/pluggable.php#L235 ) наводит меня на мысль, что компонент заголовков может быть массивом, или большой строкой, или, возможно, какой-то ужасной мешаниной два, но использование массива, вероятно, является более безопасным/более правильным вариантом.

Мне нравятся различные ответы на phpmailer, но просто кажется немного чище пытаться что-то делать с помощью встроенных модулей WordPress.

 7
Author: David E. Smith, 2016-03-25 21:39:44

Вот альтернатива, использующая непосредственно метод AddCustomHeader экземпляра 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);
    }
}

Здесь мы видим, что есть два способа его использования:

Пример № 1:

Здесь мы передаем только информацию заголовка во входной строке $name, которая разделена :

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

Пример №2:

Здесь оба $name и $value непустые:

add_action( 'phpmailer_init', function( $phpmailer )
{   
    $phpmailer->AddCustomHeader( 
       'X-WU-Site', parse_url( get_site_url(), PHP_URL_HOST ) 
    );  
} );
 6
Author: birgire, 2016-03-25 17:14:35

PHP headers являются строками. Вы не можете анализировать их как массив. Вам нужно добавить дополнительный заголовок в виде строки с \r\n, чтобы убедиться, что он добавлен в следующей строке.

Пример:

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

Также, пожалуйста, обратите внимание, добавьте вам дополнительные заголовки наконец с приоритетом 99, чтобы никакой другой плагин не мог заменить его, если он не проверяет, что заголовки уже присутствуют. При необходимости сделайте это 999.

 3
Author: Sumit, 2016-03-25 17:36:43