CRM-15856 - Mailing API - Enforce required mail-merge tokens.
authorTim Otten <totten@civicrm.org>
Mon, 9 Feb 2015 20:41:27 +0000 (12:41 -0800)
committerTim Otten <totten@civicrm.org>
Wed, 11 Feb 2015 16:50:53 +0000 (08:50 -0800)
CRM/Mailing/BAO/Mailing.php
tests/phpunit/CiviTest/CiviUnitTestCase.php
tests/phpunit/api/v3/JobProcessMailingTest.php
tests/phpunit/api/v3/MailingTest.php

index 1d762bb07dc2f16dc96da32509eea2572583af20..ee427d4c9756cd68f240a9a2bf8e50c164a77347 100644 (file)
@@ -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;
   }
 
index 7f4f3b509050f0f5d3a22aeb6daf82ce6c9ca03c..48d9874df6fd0c387f9ae02a335ddb5502ab59a1 100755 (executable)
@@ -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,
     );
index 1dcb37b551cf51627ea7542f814f9e538c5f284b..aa1641fa9eb46d2f80620c5d09735fb902f12fab 100644 (file)
@@ -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)),
index aadcc8bac73879518cb475ae7176fc54b9f3ab25..0ded3164112f093cae34eb0efc2931c0569704c8 100755 (executable)
@@ -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' => "<p>This is {contact.display_name}</p>",
+      'body_text' => "This is {contact.display_name}.\n{domain.address}{action.optOutUrl}",
+      'body_html' => "<p>This is {contact.display_name}.</p><p>{domain.address}{action.optOutUrl}</p>",
       '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("<p>This is $displayName</p>", $previewResult['values']['body_html']);
+    $this->assertContains("This is $displayName", $previewResult['values']['body_text']);
+    $this->assertContains("<p>This is $displayName.</p>", $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;
   }