From 21b09c134f287d8738c3b6b51cad36170d7891dc Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 9 Feb 2015 12:41:27 -0800 Subject: [PATCH] CRM-15856 - Mailing API - Enforce required mail-merge tokens. --- CRM/Mailing/BAO/Mailing.php | 22 ++++++++++++- tests/phpunit/CiviTest/CiviUnitTestCase.php | 2 +- .../phpunit/api/v3/JobProcessMailingTest.php | 2 +- tests/phpunit/api/v3/MailingTest.php | 32 ++++++++++++++++--- 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/CRM/Mailing/BAO/Mailing.php b/CRM/Mailing/BAO/Mailing.php index 1d762bb07d..ee427d4c97 100644 --- a/CRM/Mailing/BAO/Mailing.php +++ b/CRM/Mailing/BAO/Mailing.php @@ -1708,7 +1708,7 @@ ORDER BY civicrm_email.is_bulkmail DESC $errors = static::checkSendable($mailing); if (!empty($errors)) { $fields = implode(',', array_keys($errors)); - throw new CRM_Core_Exception("Mailing cannot be sent. There are missing fields ($fields).", 'cannot-send', $errors); + throw new CRM_Core_Exception("Mailing cannot be sent. There are missing or invalid fields ($fields).", 'cannot-send', $errors); } } @@ -1754,6 +1754,26 @@ ORDER BY civicrm_email.is_bulkmail DESC if (empty($mailing->body_html) && empty($mailing->body_text)) { $errors['body'] = ts('Field "body_html" or "body_text" is required.'); } + + if (!CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME, 'disable_mandatory_tokens_check')) { + $header = $mailing->header_id && $mailing->header_id != 'null' ? CRM_Mailing_BAO_Component::findById($mailing->header_id) : NULL; + $footer = $mailing->footer_id && $mailing->footer_id != 'null' ? CRM_Mailing_BAO_Component::findById($mailing->footer_id) : NULL; + foreach (array('body_html', 'body_text') as $field) { + if (empty($mailing->{$field})) { + continue; + } + $str = ($header ? $header->{$field} : '') . $mailing->{$field} . ($footer ? $footer->{$field} : ''); + $err = CRM_Utils_Token::requiredTokens($str); + if ($err !== TRUE) { + foreach ($err as $token => $desc) { + $errors["{$field}:{$token}"] = ts('This message is missing a required token - {%1}: %2', + array(1 => $token, 2 => $desc) + ); + } + } + } + } + return $errors; } diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index 7f4f3b5090..48d9874df6 100755 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -3226,7 +3226,7 @@ AND ( TABLE_NAME LIKE 'civicrm_value_%' ) public function createMailing() { $params = array( 'subject' => 'maild' . rand(), - 'body_text' => 'bdkfhdskfhduew', + 'body_text' => 'bdkfhdskfhduew{domain.address}{action.optOutUrl}', 'name' => 'mailing name' . rand(), 'created_id' => 1, ); diff --git a/tests/phpunit/api/v3/JobProcessMailingTest.php b/tests/phpunit/api/v3/JobProcessMailingTest.php index 1dcb37b551..aa1641fa9e 100644 --- a/tests/phpunit/api/v3/JobProcessMailingTest.php +++ b/tests/phpunit/api/v3/JobProcessMailingTest.php @@ -64,7 +64,7 @@ class api_v3_JobProcessMailingTest extends CiviUnitTestCase { $this->_email = 'test@test.test'; $this->_params = array( 'subject' => 'Accidents in cars cause children', - 'body_text' => 'BEWARE children need regular infusions of toys', + 'body_text' => 'BEWARE children need regular infusions of toys. Santa knows your {domain.address}. There is no {action.optOutUrl}.', 'name' => 'mailing name', 'created_id' => 1, 'groups' => array('include' => array($this->_groupID)), diff --git a/tests/phpunit/api/v3/MailingTest.php b/tests/phpunit/api/v3/MailingTest.php index aadcc8bac7..0ded316411 100755 --- a/tests/phpunit/api/v3/MailingTest.php +++ b/tests/phpunit/api/v3/MailingTest.php @@ -48,8 +48,8 @@ class api_v3_MailingTest extends CiviUnitTestCase { $this->_email = 'test@test.test'; $this->_params = array( 'subject' => 'Hello {contact.display_name}', - 'body_text' => "This is {contact.display_name}", - 'body_html' => "

This is {contact.display_name}

", + 'body_text' => "This is {contact.display_name}.\n{domain.address}{action.optOutUrl}", + 'body_html' => "

This is {contact.display_name}.

{domain.address}{action.optOutUrl}

", 'name' => 'mailing name', 'created_id' => $this->_contactID, 'header_id' => '', @@ -171,8 +171,8 @@ class api_v3_MailingTest extends CiviUnitTestCase { $previewResult = $result['values'][$result['id']]['api.Mailing.preview']; $this->assertEquals("Hello $displayName", $previewResult['values']['subject']); - $this->assertEquals("This is $displayName", $previewResult['values']['body_text']); - $this->assertContains("

This is $displayName

", $previewResult['values']['body_html']); + $this->assertContains("This is $displayName", $previewResult['values']['body_text']); + $this->assertContains("

This is $displayName.

", $previewResult['values']['body_html']); } public function testMailerPreviewRecipients() { @@ -348,9 +348,31 @@ class api_v3_MailingTest extends CiviUnitTestCase { TRUE, //useLogin array('name' => ''), // createParams array('scheduled_date' => '2014-12-13 10:00:00', 'approval_date' => '2014-12-13 00:00:00'), - "/Mailing cannot be sent. There are missing fields \\(name\\)./", // expectedFailure + "/Mailing cannot be sent. There are missing or invalid fields \\(name\\)./", // expectedFailure 0, // expectedJobCount ); + $cases[] = array( + TRUE, //useLogin + array('body_html' => '', 'body_text' => ''), // createParams + array('scheduled_date' => '2014-12-13 10:00:00', 'approval_date' => '2014-12-13 00:00:00'), + "/Mailing cannot be sent. There are missing or invalid fields \\(body\\)./", // expectedFailure + 0, // expectedJobCount + ); + $cases[] = array( + TRUE, //useLogin + array('body_html' => 'Oops, did I leave my tokens at home?'), // createParams + array('scheduled_date' => '2014-12-13 10:00:00', 'approval_date' => '2014-12-13 00:00:00'), + "/Mailing cannot be sent. There are missing or invalid fields \\(.*body_html.*optOut.*\\)./", // expectedFailure + 0, // expectedJobCount + ); + $cases[] = array( + TRUE, //useLogin + array('body_text' => 'Oops, did I leave my tokens at home?'), // createParams + array('scheduled_date' => '2014-12-13 10:00:00', 'approval_date' => '2014-12-13 00:00:00'), + "/Mailing cannot be sent. There are missing or invalid fields \\(.*body_text.*optOut.*\\)./", // expectedFailure + 0, // expectedJobCount + ); + return $cases; } -- 2.25.1