@@ -83,8 +83,11 @@ public function test_wp_mail_custom_boundaries() {
8383
8484 // We need some better assertions here but these catch the failure for now.
8585 $ this ->assertSameIgnoreEOL ( $ body , $ mailer ->get_sent ()->body );
86- $ this ->assertStringContainsString ( 'boundary="----=_Part_4892_25692638.1192452070893" ' , iconv_mime_decode_headers ( ( $ mailer ->get_sent ()->header ) )['Content-Type ' ][0 ] );
87- $ this ->assertStringContainsString ( 'charset= ' , $ mailer ->get_sent ()->header );
86+ $ headers = iconv_mime_decode_headers ( $ mailer ->get_sent ()->header );
87+ $ this ->assertArrayHasKey ( 'Content-Type ' , $ headers , 'Expected Content-Type header to be sent. ' );
88+ $ content_type_headers = (array ) $ headers ['Content-Type ' ];
89+ $ this ->assertCount ( 1 , $ content_type_headers , "Expected only one Content-Type header to be sent. Saw: \n" . implode ( "\n" , $ content_type_headers ) );
90+ $ this ->assertSame ( 'multipart/mixed; boundary="----=_Part_4892_25692638.1192452070893"; charset= ' , $ content_type_headers [0 ], 'Expected Content-Type to match. ' );
8891 }
8992
9093 /**
@@ -669,4 +672,86 @@ public function test_wp_mail_encoding_does_not_bleed() {
669672 $ mailer = tests_retrieve_phpmailer_instance ();
670673 $ this ->assertEquals ( '7bit ' , $ mailer ->Encoding );
671674 }
675+
676+ /**
677+ * Test that wp_mail() can send a multipart/alternative email with plain text and html versions.
678+ *
679+ * @ticket 15448
680+ */
681+ public function test_wp_mail_plain_and_html () {
682+ $ headers = 'Content-Type: multipart/alternative; boundary="TestBoundary" ' ;
683+ 684+ $ subject = 'Test email with plain text and html versions ' ;
685+ $ message = <<<EOT
686+ --TestBoundary
687+ Content-Type: text/plain; charset=us-ascii
688+
689+ Here is some plain text.
690+ --TestBoundary
691+ Content-Type: text/html; charset=UTF-8
692+ Content-Transfer-Encoding: 8bit
693+
694+ <html><head></head><body>Here is the HTML with UTF-8 γειά σου Κόσμε;-)<body></html>
695+ --TestBoundary--
696+ EOT ;
697+
698+ wp_mail ( $ to , $ subject , $ message , $ headers );
699+ $ mailer = tests_retrieve_phpmailer_instance ();
700+
701+ $ this ->assertSame ( 1 , preg_match ( '/boundary="(.*)"/ ' , $ mailer ->get_sent ()->header , $ matches ), 'Expected to match boundary directive in header. ' );
702+ $ boundary = $ matches [1 ];
703+ $ body = '-- ' . $ boundary . "\n" ;
704+ $ body .= 'Content-Type: text/plain; charset=us-ascii ' . "\n" ;
705+ $ body .= "\n" ;
706+ $ body .= 'Here is some plain text. ' . "\n" ;
707+ $ body .= '-- ' . $ boundary . "\n" ;
708+ $ body .= 'Content-Type: text/html; charset=UTF-8 ' . "\n" ;
709+ $ body .= 'Content-Transfer-Encoding: 8bit ' . "\n" ;
710+ $ body .= "\n" ;
711+ $ body .= '<html><head></head><body>Here is the HTML with UTF-8 γειά σου Κόσμε;-)<body></html> ' . "\n" ;
712+ $ body .= '-- ' . $ boundary . '-- ' . "\n" ;
713+
714+ $ this ->assertSameIgnoreEOL ( $ body , $ mailer ->get_sent ()->body , 'The body is not as expected. ' );
715+ $ this ->assertStringContainsString (
716+ 'Content-Type: multipart/alternative; ' ,
717+ $ mailer ->get_sent ()->header ,
718+ 'The multipart/alternative header is not present. '
719+ );
720+ }
721+
722+ /**
723+ * Check workarounds using phpmailer_init still work around.
724+ *
725+ * @ticket 15448
726+ */
727+ public function test_wp_mail_plain_and_html_workaround () {
728+ 729+ $ subject = 'Test email with plain text derived from html version ' ;
730+ $ message = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><p>Hello World! γειά σου Κόσμε</p></body></html> ' ;
731+
732+ $ set_alt_body = static function ( WP_PHPMailer $ mailer ) {
733+ $ mailer ->AltBody = strip_tags ( $ mailer ->Body );
734+ };
735+ add_action ( 'phpmailer_init ' , $ set_alt_body );
736+ wp_mail ( $ to , $ subject , $ message );
737+ remove_action ( 'phpmailer_init ' , $ set_alt_body );
738+
739+ $ mailer = tests_retrieve_phpmailer_instance ();
740+
741+ $ this ->assertStringContainsString (
742+ 'Content-Type: multipart/alternative; ' ,
743+ $ mailer ->get_sent ()->header ,
744+ 'The multipart/alternative header is not present. '
745+ );
746+ $ this ->assertStringContainsString (
747+ 'Content-Type: text/plain; charset=UTF-8 ' ,
748+ $ mailer ->get_sent ()->body ,
749+ 'The text/plain Content-Type header is not present. '
750+ );
751+ $ this ->assertStringContainsString (
752+ 'Content-Type: text/html; charset=UTF-8 ' ,
753+ $ mailer ->get_sent ()->body ,
754+ 'The text/html Content-Type header is not present. '
755+ );
756+ }
672757}
0 commit comments