web-dev-qa-db-ja.com

送信メールにヘッダを追加する方法

自分のサイトの送信メールに追加のヘッダーを追加したいので、どのサイトが特定のEメールを送信したのかを簡単に判断できます。 (私はすべてのサイトに標準機能プラグインを付けていますので、これを実行するのは簡単です。このヘッダーをフィルタリングし、それ以外の方法で処理するように電子メールクライアントを設定するのは驚くべき時間節約になります)

これは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形式のEメールは裸のHTML形式で表示され始めました。 GFが追加したContent-type:ヘッダが削除されたため、意味があります。しかし、私のヘッダは電子メールに追加されました。他の人もきれいなEメールを受信することに頼っているので(私のすべてのサイトのコンテンツ開発者とエンドユーザー、とりわけ私は確信しています)、それは受け入れられません。

私の同僚の一人はそれから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);
}

それで、あたかも私の関数が存在しないかのように - 私のヘッダは追加されませんが、他のヘッダやメール設定も削除されません。

他に存在する可能性のあるフィルタをスクランブルすることなく、送信電子メールにヘッダを追加する正しい方法は何ですか?

8
David E. Smith

上記のおかげで、私は私の中心的な間違いに気付きました - 渡された引数が多次元配列であることを私はあまり知りませんでした。

今のところ、私はこのように関数を再実装しました:

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 を見てください) headersコンポーネントは、配列、大きな文字列、あるいは恐らくはその2つのうちの恐ろしいmish-mashのいずれでもかまいませんが、配列を使用することがおそらくより安全でより正しいオプションであると考えます。

私は様々なphpmailerの答えが好きですが、WordPressのビルトインを使って物事をやろうとするのは少しきれいに思えます。

7
David E. Smith

これは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);
    }
}

ここでは、それを使用する方法が2つあることがわかります。

例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
birgire

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
Sumit