Skip to content

Commit

Permalink
CRM-21197 - improved generation of plain text emails
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelmcandrew committed Aug 8, 2018
1 parent 04659e5 commit a0521e2
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 53 deletions.
39 changes: 22 additions & 17 deletions CRM/Mailing/BAO/Mailing.php
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ public function getTemplates() {
if (!$this->templates) {
$this->getHeaderFooter();
$this->templates = array();
if ($this->body_text || !empty($this->header)) {
if ($this->body_text) {
$template = array();
if (!empty($this->header->body_text)) {
$template[] = $this->header->body_text;
Expand All @@ -627,12 +627,7 @@ public function getTemplates() {
$template[] = CRM_Utils_String::htmlToText($this->header->body_html);
}

if ($this->body_text) {
$template[] = $this->body_text;
}
else {
$template[] = CRM_Utils_String::htmlToText($this->body_html);
}
$template[] = $this->body_text;

if (!empty($this->footer->body_text)) {
$template[] = $this->footer->body_text;
Expand Down Expand Up @@ -660,12 +655,6 @@ public function getTemplates() {

$this->templates['html'] = implode("\n", $template);

// this is where we create a text template from the html template if the text template did not exist
// this way we ensure that every recipient will receive an email even if the pref is set to text and the
// user uploads an html email only
if (empty($this->templates['text'])) {
$this->templates['text'] = CRM_Utils_String::htmlToText($this->templates['html']);
}
}

if ($this->subject) {
Expand Down Expand Up @@ -1129,7 +1118,6 @@ public function compose(
array_push($pEmail, $template[($idx + 1)]);
}
}

$html = NULL;
if (isset($pEmails['html']) && is_array($pEmails['html']) && count($pEmails['html'])) {
$html = &$pEmails['html'];
Expand Down Expand Up @@ -1157,15 +1145,33 @@ public function compose(
}

$mailParams = $headers;
if ($text && ($test || $contact['preferred_mail_format'] == 'Text' ||

// If we should be sending a text version of the email
if (($test || $contact['preferred_mail_format'] == 'Text' ||
$contact['preferred_mail_format'] == 'Both' ||
($contact['preferred_mail_format'] == 'HTML' && !array_key_exists('html', $pEmails))
)
) {
$textBody = implode('', $text);

// The following if elseif allows us to ensure that people who have a
// preference for text emails will get one even when the person composing
// the email has not uploaded a text version.

if ($text) {
// If the text version exists, use it
$textBody = implode('', $text);
}
elseif ($html) {
// Else if it doesn't exist and the html version exists, use it
$textBody = implode('', $html);
$textBody = htmlspecialchars_decode(htmlspecialchars_decode($textBody)); // Some &s have become 'really encoded'
$textBody = CRM_Utils_String::htmlToText($textBody);
}

if ($useSmarty) {
$textBody = $smarty->fetch("string:$textBody");
}

$mailParams['text'] = $textBody;
}

Expand All @@ -1189,7 +1195,6 @@ public function compose(
$res = NULL;
return $res;
}

$mailParams['attachments'] = $attachments;

$mailParams['Subject'] = CRM_Utils_Array::value('subject', $pEmails);
Expand Down
57 changes: 24 additions & 33 deletions tests/phpunit/CRM/Mailing/BaseMailingSystemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public function testText() {
";" .
"Sample Header for TEXT formatted content.\n" . // Default header
"BEWARE children need regular infusions of toys. Santa knows your .*\\. There is no http.*civicrm/mailing/optout.*\\.\n" .
"to unsubscribe: http.*civicrm/mailing/optout" . // Default footer
"Unsubscribe: http.*civicrm/mailing/optout" . // Default footer
";",
$message->body->text
);
Expand All @@ -140,7 +140,7 @@ public function testText() {
public function testHtmlWithOpenTracking() {
$allMessages = $this->runMailingSuccess(array(
'subject' => 'Example Subject',
'body_html' => '<p>You can go to <a href="http://example.net/first?{contact.checksum}">Google</a> or <a href="{action.optOutUrl}">opt out</a>.</p>',
'body_html' => '<p>You can go to <a href="http://example.net/first?{contact.checksum}">Google</a> or <a href="{action.optOutUrl}">opt out</a>.</p><br />',
'open_tracking' => 1,
'url_tracking' => 0,
));
Expand All @@ -156,29 +156,26 @@ public function testHtmlWithOpenTracking() {
$this->assertEquals('html', $htmlPart->subType);
$this->assertRegExp(
";" .
"Sample Header for HTML formatted content.\n" . // Default header
"Sample Header for HTML formatted content\..*" . // Default header
// FIXME: CiviMail puts double " after hyperlink!
"<p>You can go to <a href=\"http://example.net/first\\?cs=[0-9a-f_]+\"\"?>Google</a> or <a href=\"http.*civicrm/mailing/optout.*\">opt out</a>.</p>\n" . // body_html
"Sample Footer for HTML formatted content" . // Default footer
".*\n" .
"<p>You can go to <a href=\"http://example.net/first\\?cs=[0-9a-f_]+\"\"?>Google</a> or <a href=\"http.*civicrm/mailing/optout.*\">opt out</a>.</p>.*" . // body_html
".*Sample Footer for HTML formatted content.*" . // Default footer
"<img src=\".*extern/open.php.*\"" .
";",
";s",
$htmlPart->text
);

$this->assertEquals('plain', $textPart->subType);
$this->assertRegExp(
";" .
"Sample Header for TEXT formatted content.\n" . // Default header
"You can go to Google \\[1\\] or opt out \\[2\\]\\.\n" . // body_html, filtered
"\n" .
"Links:\n" .
"------\n" .
"\\[1\\] http://example.net/first\\?cs=[0-9a-f_]+\n" .
"\\[2\\] http.*civicrm/mailing/optout.*\n" .
"\n" .
"to unsubscribe: http.*civicrm/mailing/optout" . // Default footer
";",
"Sample Header for HTML formatted content\\..*" . // Default header (converted from HTML as it was not supplied)
"You can go to Google \\[1\\] or opt out \\[2\\]\\..*" . // Text body (converted from HTML as it was not supplied)
"Sample Footer for HTML formatted content.*" . // Footer footer (converted from HTML as it was not supplied)
"Unsubscribe \\[2\\].*" . // Text body (converted from HTML as it was not supplied)
"Links:.*" .
"------.*" .
"\\[1\\] http://example.net/first\\?cs=[0-9a-f_]+.*" .
"\\[2\\] http.*civicrm/mailing/optout.*" .
";s",
$textPart->text
);
}
Expand Down Expand Up @@ -207,31 +204,26 @@ public function testHtmlWithOpenAndUrlTracking() {
$this->assertRegExp(
";" .
// body_html
"<p>You can go to <a href=['\"].*extern/url\.php\?u=\d+&amp\\;qid=\d+['\"] rel='nofollow'>Google</a>" .
"<p>You can go to <a href=['\"].*extern/url\.php\?u=\d+&amp\\;qid=\d+['\"]>Google</a>" .
" or <a href=\"http.*civicrm/mailing/optout.*\">opt out</a>.</p>\n" .
// Default footer
"Sample Footer for HTML formatted content" .
"<p>Sample Footer for HTML formatted content\.</p>" .
".*\n" .
// Open-tracking code
"<img src=\".*extern/open.php.*\"" .
";",
$htmlPart->text
);

$this->assertEquals('plain', $textPart->subType);
$this->assertRegExp(
";" .
// body_html, filtered
"You can go to Google \\[1\\] or opt out \\[2\\]\\.\n" .
"\n" .
"You can go to Google \\[1\\] or opt out \\[2\\]\\..*" .
"Unsubscribe \\[2\\].*" .
"Links:\n" .
"------\n" .
"\\[1\\] .*extern/url\.php\?u=\d+&qid=\d+\n" .
"\\[2\\] http.*civicrm/mailing/optout.*\n" .
"\n" .
// Default footer
"to unsubscribe: http.*civicrm/mailing/optout" .
";",
"\\[1\\] .*extern/url\.php\?u=\d+&qid=\d+.*" .
"\\[2\\] http.*civicrm/mailing/optout.*" .
";s",
$textPart->text
);
}
Expand Down Expand Up @@ -314,11 +306,10 @@ public function urlTrackingExamples() {
array('url_tracking' => 1),
);
$cases[] = array(
// Plain-text URL's are tracked in plain-text emails...
// but not in HTML emails.
// Plain-text URLs are not tracked.
"<p>Please go to: http://example.net/</p>",
";<p>Please go to: http://example\.net/</p>;",
';Please go to: .*extern/url.php\?u=\d+&qid=\d+;',
';Please go to: http://example\.net/;',
array('url_tracking' => 1),
);

Expand Down
5 changes: 2 additions & 3 deletions xml/templates/civicrm_data.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,8 @@ INSERT INTO civicrm_tag( name, description, parent_id,used_for )
INSERT INTO civicrm_mailing_component
(name,component_type,subject,body_html,body_text,is_default,is_active)
VALUES
('{ts escape="sql"}Mailing Header{/ts}','Header','{ts escape="sql"}Descriptive Title for this Header{/ts}','{ts escape="sql"}Sample Header for HTML formatted content.{/ts}','{ts escape="sql"}Sample Header for TEXT formatted content.{/ts}',1,1),
('{ts escape="sql"}Mailing Footer{/ts}','Footer','{ts escape="sql"}Descriptive Title for this Footer.{/ts}','{ts escape="sql"}Sample Footer for HTML formatted content<br/><a href="{ldelim}action.optOutUrl{rdelim}">Unsubscribe</a> <br/> {ldelim}domain.address{rdelim}{/ts}','{ts escape="sql"}to unsubscribe: {ldelim}action.optOutUrl{rdelim}
{ldelim}domain.address{rdelim}{/ts}',1,1),
('{ts escape="sql"}Mailing Header{/ts}','Header','{ts escape="sql"}Descriptive Title for this Header{/ts}','{ts escape="sql"}<p>Sample Header for HTML formatted content.</p>{/ts}','{ts escape="sql"}Sample Header for TEXT formatted content.{/ts}',1,1),
('{ts escape="sql"}Mailing Footer{/ts}','Footer','{ts escape="sql"}Descriptive Title for this Footer.{/ts}','{ts escape="sql"}<p>Sample Footer for HTML formatted content.</p><p><a href="{ldelim}action.optOutUrl{rdelim}">Unsubscribe</a>.</p><p>{ldelim}domain.address{rdelim}</p>{/ts}','{ts escape="sql"}Unsubscribe: {ldelim}action.optOutUrl{rdelim}{"\n"}{ldelim}domain.address{rdelim}.{/ts}',1,1),
('{ts escape="sql"}Subscribe Message{/ts}','Subscribe','{ts escape="sql"}Subscription Confirmation Request{/ts}','{ts escape="sql" 1=$subgroup 2=$suburl}You have a pending subscription to the %1 mailing list. To confirm this subscription, reply to this email or click <a href="%2">here</a>.{/ts}','{ts escape="sql" 1=$subgroup 2=$suburl}You have a pending subscription to the %1 mailing list. To confirm this subscription, reply to this email or click on this link: %2{/ts}',1,1),
('{ts escape="sql"}Welcome Message{/ts}','Welcome','{ts escape="sql"}Your Subscription has been Activated{/ts}','{ts escape="sql" 1=$welgroup}Welcome. Your subscription to the %1 mailing list has been activated.{/ts}','{ts escape="sql" 1=$welgroup}Welcome. Your subscription to the %1 mailing list has been activated.{/ts}',1,1),
('{ts escape="sql"}Unsubscribe Message{/ts}','Unsubscribe','{ts escape="sql"}Un-subscribe Confirmation{/ts}','{ts escape="sql" 1=$unsubgroup 2=$actresub 3=$actresuburl}You have been un-subscribed from the following groups: %1. You can re-subscribe by mailing %2 or clicking <a href="%3">here</a>.{/ts}','{ts escape="sql" 1=$unsubgroup 2=$actresub}You have been un-subscribed from the following groups: %1. You can re-subscribe by mailing %2 or clicking %3{/ts}',1,1),
Expand Down

0 comments on commit a0521e2

Please sign in to comment.