Commit 05cc9ae4 by Carsten Brandt

improved HTML to Text fallback in BaseMailer

fixes #6748
parent dd319803
...@@ -21,6 +21,7 @@ Yii Framework 2 Change Log ...@@ -21,6 +21,7 @@ Yii Framework 2 Change Log
- Enh #6488: Support changing `yii\base\Theme::basePath` during runtime (qiangxue) - Enh #6488: Support changing `yii\base\Theme::basePath` during runtime (qiangxue)
- Enh #6618: Added Model::addErrors() (slavcodev, pana1990) - Enh #6618: Added Model::addErrors() (slavcodev, pana1990)
- Enh #6739: Log `Target` now works also when there is no `Yii::$app` instance available, no message prefix will be added in this case (schmunk42) - Enh #6739: Log `Target` now works also when there is no `Yii::$app` instance available, no message prefix will be added in this case (schmunk42)
- Enh #6748: Improved HTML to Text converter in BaseMailer to generate more readable and correct text version of emails (cebe)
- Chg #6427: In case of invalid route web application now throws exception with "Page not found" instead of "Invalid Route" (cebe, samdark) - Chg #6427: In case of invalid route web application now throws exception with "Page not found" instead of "Invalid Route" (cebe, samdark)
- Chg #6641: removed zero padding from ETag strings (DaSourcerer) - Chg #6641: removed zero padding from ETag strings (DaSourcerer)
- Chg #6678: `yii\behaviors\SluggableBehavior` will generate a new slug only when the slug attribute is empty or the source attribute is changed (qiangxue) - Chg #6678: `yii\behaviors\SluggableBehavior` will generate a new slug only when the slug attribute is empty or the source attribute is changed (qiangxue)
......
...@@ -201,11 +201,17 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont ...@@ -201,11 +201,17 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont
if (isset($text)) { if (isset($text)) {
$message->setTextBody($text); $message->setTextBody($text);
} elseif (isset($html)) { } elseif (isset($html)) {
if (preg_match('|<body[^>]*>(.*?)</body>|is', $html, $match)) { if (preg_match('~<body[^>]*>(.*?)</body>~is', $html, $match)) {
$html = $match[1]; $html = $match[1];
} }
$html = preg_replace('|<style[^>]*>(.*?)</style>|is', '', $html); // remove style and script
$message->setTextBody(strip_tags($html)); $html = preg_replace('~<((style|script))[^>]*>(.*?)</\1>~is', '', $html);
// strip all HTML tags and decoded HTML entities
$text = html_entity_decode(strip_tags($html), ENT_QUOTES | ENT_HTML5, Yii::$app ? Yii::$app->charset : 'UTF-8');
// improve whitespace
$text = preg_replace("~^[ \t]+~m", '', trim($text));
$text = preg_replace('~\R\R+~mu', "\n\n", $text);
$message->setTextBody($text);
} }
return $message; return $message;
} }
......
...@@ -210,6 +210,62 @@ class BaseMailerTest extends TestCase ...@@ -210,6 +210,62 @@ class BaseMailerTest extends TestCase
$this->assertEquals(strip_tags($htmlViewFileContent), $message->_textBody, 'Unable to render text by direct view!'); $this->assertEquals(strip_tags($htmlViewFileContent), $message->_textBody, 'Unable to render text by direct view!');
} }
public function htmlAndPlainProvider()
{
return [
[
1,
'HTML <b>view file</b> content <a href="http://yiifresh.com/index.php?r=site%2Freset-password&amp;token=abcdef">http://yiifresh.com/index.php?r=site%2Freset-password&amp;token=abcdef</a>',
'HTML view file content http://yiifresh.com/index.php?r=site%2Freset-password&token=abcdef',
],
[
2, <<<HTML
<html><head><style type="text/css">.content{color: #112345;}</style><title>TEST</title></head>
<body>
<style type="text/css">.content{color: #112345;}</style>
<p> First paragraph
second line
<a href="http://yiifresh.com/index.php?r=site%2Freset-password&amp;token=abcdef">http://yiifresh.com/index.php?r=site%2Freset-password&amp;token=abcdef</a>
</p><script type="text/javascript">alert("hi")</script>
<p>Test Lorem ipsum...</p>
</body>
</html>
HTML
, <<<TEXT
First paragraph
second line
http://yiifresh.com/index.php?r=site%2Freset-password&token=abcdef
Test Lorem ipsum...
TEXT
],
];
}
/**
* @dataProvider htmlAndPlainProvider
*/
public function testComposePlainTextFallback($i, $htmlViewFileContent, $expectedTextRendering)
{
$mailer = $this->getTestMailComponent();
$mailer->htmlLayout = false;
$mailer->textLayout = false;
$htmlViewName = 'test_html_view' . $i; // $i is needed to generate different view files to ensure it works on HHVM
$htmlViewFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . $htmlViewName . '.php';
file_put_contents($htmlViewFileName, $htmlViewFileContent);
$message = $mailer->compose([
'html' => $htmlViewName,
]);
$this->assertEquals($htmlViewFileContent, $message->_htmlBody, 'Unable to render html!');
$this->assertEquals($expectedTextRendering, $message->_textBody, 'Unable to render text!');
}
public function testUseFileTransport() public function testUseFileTransport()
{ {
$mailer = new Mailer(); $mailer = new Mailer();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment