[wp-trac] [WordPress Trac] #38102: Email header Content-Type: multipart boundary ignored by wp_mail
WordPress Trac
noreply at wordpress.org
Tue Sep 20 07:29:16 UTC 2016
#38102: Email header Content-Type: multipart boundary ignored by wp_mail
--------------------------+-----------------------------
Reporter: drtonyb | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Mail | Version: 4.6
Severity: normal | Keywords:
Focuses: |
--------------------------+-----------------------------
I have a requirement to send a multipart email with a csv attachment via
wp_mail. The code I am using worked prior to upgrading to Wordpress 4.6.
Following the upgrade, emails sent by my code appear to have no content
when received. Examining the email source shows that both the content and
attachment are present, but the header field Content-Type:
multipart/mixed; boundary=... is missing, so the email client can't
determine the content.
Here is a simplified example of code that sends a multipart (text and
html) email demonstrating the problem:
{{{#!php
<?php
$multipart_boundary = 'frontier';
$headers = array(
"From: $from",
"Reply-To: $from",
"Content-Type: multipart/alternative;
boundary=\"$multipart_boundary\""
);
$body = "--$multipart_boundary\r\n"
. "Content-Type: text/plain; charset=ISO-8859-1;
format=flowed\r\n"
. "Content-Transfer-Encoding: 7bit\r\n"
. "\r\n"
. "This is not a red paragrph\r\n"
. "--$multipart_boundary\r\n"
. "Content-Type: text/html charset=utf-8\r\n"
. "Content-Transfer-Encoding: 8bit\r\n"
. "\r\n"
. "<!DOCTYPE html>\r\n"
. "<html>\r\n"
. "<head>\r\n"
. "<meta charset=\"utf-8\" />\r\n"
. "<style>\r\n"
. "p {color:#ff0000;}\r\n"
. "</style>\r\n"
. "</head>\r\n"
. "<body>\r\n"
. "<p>This is a red paragraph</p>\r\n"
. "</body>\r\n"
. "</html>\r\n"
. "--$multipart_boundary--";
wp_mail( 'whoever at example.com', 'Multipart email test', $body,
$headers );
}}}
The email sent by this code should show either the text part or the html
part, depending on the email client. I use Thunderbird and it shows no
content at all.
The source of the problem is in the Wordpress file
/includes/pluggable.php, function wp_mail().
The function argument $headers array/string supplied by the user is
assigned to a variable $tempheaders and then $headers is set to an empty
array. $tempheaders is then processed in a switch statement block starting
at line 251 to extract the header fields From, Content_Type, Cc, Bcc and
Reply-To. Any other header fields are considered 'custom headers' and are
added back into the $headers array by the default case of the switch
block. At the end of processing $tempheaders, if there are no 'custom
header' fields present, then the $headers variable remains an empty array.
At line 441, the $headers variable is tested to see if any 'custom
headers' need setting.
{{{#!php
<?php
// Set custom headers
if ( !empty( $headers ) ) {
foreach ( (array) $headers as $name => $content ) {
$phpmailer->AddCustomHeader( sprintf( '%1$s:
%2$s', $name, $content ) );
}
if ( false !== stripos( $content_type, 'multipart' ) && !
empty($boundary) )
$phpmailer->AddCustomHeader( sprintf( "Content-
Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
}
}}}
Strangely, not only does this if statement block set the 'custom headers'
($headers) when they exist, it also sets the Content-Type: multipart/...;
boundary=... Hence, if $headers is empty, as is the case for my example
above, the multipart boundary is not set.
The question is: why is setting the multipart boundary dependent on there
being these so called 'custom headers'?
I have only noticed this problem since Wordpress 4.6+. Since version 4.6,
the header field Reply-To was added to Wordpress' list of 'non-custom
headers'. Prior to version 4.6, Reply-To was considered a 'custom header'
and so, $headers was not empty and my code worked.
As a work-around, if I add Return-Path: ... to my headers, then everything
works and my emails are readable again. However, I shouldn't need to do
this.
I think this problem needs some serious attention.
Tony
--
Ticket URL: <https://core.trac.wordpress.org/ticket/38102>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list