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

8

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

Я думал, что это будет простой вопрос подключения к 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));
}

Здесь мой массив имел приоритет над всем остальным, что изменяло настройки почты (скажем, Gravity Forms), поэтому электронные письма в формате 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);
}

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

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

Дэвид Э. Смит
источник
Если вам нужно простое решение, воспользуйтесь
плагином
Этот плагин на самом деле не решает проблему. Он добавляет «заголовок» в тело письма, сгенерированного WordPress; Я пытался добавить заголовок SMTP, что совершенно другое.
Дэвид Э. Смит

Ответы:

7

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

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

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, немного чище.

Дэвид Э. Смит
источник
6

Вот альтернатива, использующая непосредственно 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 ) 
    );  
} );
birgire
источник
Приятно знать этот ответ :) Но мне любопытно узнать, какой эффект это даст, если кто-то установит его $args['headers'] = 'key: value'через WP-фильтры?
Sumit
На phpmailer_initкрючке срабатывает позднее , чем при wp_mailприменении фильтра и пользовательские заголовки из этого фильтра, также добавляются через AddCustomHeader()метод, насколько я понимаю. @sumit
birgire
3

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.

Sumit
источник
1
Я копался в источнике wp_mail (), и он, очевидно, должен был принимать заголовки как массивы или как большие куски текста, а иногда, возможно, и то, и другое вместе. Не советовал бы делать это вообще, но это всегда вариант.
Дэвид Э. Смит
@ DavidE.Smith правильно. wp_mailпринимает массив для аргумента заголовка, и WP позаботится о добавлении \ r \ n
Ян Бек
Обратите внимание, я упомянул PHP headersне то, что wp_mailпринять. Наконец, заголовки - это строки. То, что wp_mailпринимает, не было вопросом! @JanBeck
Sumit
1
Да, это был вопрос. Почему вы выводите заголовки PHP?
Ян Бек