dev/core#2119 Fix mailig code to exclude deleted recipients
authoreileen <emcnaughton@wikimedia.org>
Wed, 14 Oct 2020 01:51:04 +0000 (14:51 +1300)
committereileen <emcnaughton@wikimedia.org>
Wed, 14 Oct 2020 01:56:58 +0000 (14:56 +1300)
CRM/Mailing/BAO/Recipients.php
tests/phpunit/api/v3/JobProcessMailingTest.php

index 14820ed84cf19e35450e17770867f781be48d62c..53cf1802078d84d3bac14729e816bbbc4160b98c 100644 (file)
@@ -57,28 +57,23 @@ WHERE  mailing_id = %1
       $limitString = "LIMIT $offset, $limit";
     }
 
-    $isSMSmode = CRM_Core_DAO::getFieldValue('CRM_Mailing_BAO_Mailing', $mailingID, 'sms_provider_id', 'id');
-    $additionalJoin = '';
-    if (!$isSMSmode) {
-      // mailing_recipients added when mailing is submitted in UI by user.
-      // if any email is marked on_hold =1 or contact is deceased after mailing is submitted
-      // then it should be get skipped while preparing event_queue
-      // event_queue list is prepared when mailing job gets started.
-      $additionalJoin = " INNER JOIN civicrm_email e ON (r.email_id = e.id AND e.on_hold = 0)
-                          INNER JOIN civicrm_contact c on (c.id = r.contact_id AND c.is_deceased <> 1 AND c.do_not_email = 0 AND c.is_opt_out = 0)
-";
-    }
-    else {
-      $additionalJoin = "INNER JOIN civicrm_contact c on (c.id = r.contact_id AND c.is_deceased <> 1 AND c.do_not_sms = 0 AND c.is_opt_out = 0)";
-    }
+    $isSMSMode = CRM_Core_DAO::getFieldValue('CRM_Mailing_BAO_Mailing', $mailingID, 'sms_provider_id', 'id');
+    $additionalJoin = $isSMSMode ? '' : " INNER JOIN civicrm_email e ON (r.email_id = e.id AND e.on_hold = 0)";
 
     $sql = "
-SELECT r.contact_id, r.email_id, r.phone_id
-FROM   civicrm_mailing_recipients r
-{$additionalJoin}
-WHERE  r.mailing_id = %1
-       $limitString
-";
+      SELECT r.contact_id, r.email_id, r.phone_id
+      FROM   civicrm_mailing_recipients r
+      INNER JOIN civicrm_contact c on
+        (c.id = r.contact_id
+          AND c.is_deleted = 0
+          AND c.is_deceased = 0
+          AND c.do_not_" . ($isSMSMode ? 'sms' : 'email') . " = 0
+          AND c.is_opt_out = 0
+        )
+      {$additionalJoin}
+      WHERE  r.mailing_id = %1
+        $limitString
+      ";
     $params = [1 => [$mailingID, 'Integer']];
 
     return CRM_Core_DAO::executeQuery($sql, $params);
index 71d18540772e086214903b309041eaf58bb387a2..163ef35b212b2ce6ecc6dbe61bffe4a0b37c5eb2 100644 (file)
@@ -16,7 +16,6 @@
  * @subpackage API_Job
  *
  * @copyright CiviCRM LLC https://civicrm.org/licensing
- * @version $Id: Job.php 30879 2010-11-22 15:45:55Z shot $
  *
  */
 
@@ -100,10 +99,23 @@ class api_v3_JobProcessMailingTest extends CiviUnitTestCase {
     $this->_mut->assertRecipients($this->getRecipients(1, 2));
   }
 
+  /**
+   * Test that a contact deleted after the mailing is queued is not emailed.
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testDeletedRecipient() {
+    $this->createContactsInGroup(2, $this->_groupID);
+    $this->callAPISuccess('Mailing', 'create', $this->_params);
+    $this->callAPISuccess('Contact', 'delete', ['id' => $this->callAPISuccessGetValue('GroupContact', ['return' => 'contact_id', 'options' => ['limit' => 1, 'sort' => 'id DESC']])]);
+    $this->callAPISuccess('job', 'process_mailing');
+    $this->_mut->assertRecipients($this->getRecipients(1, 1));
+  }
+
   /**
    * Test what happens when a contact is set to decesaed
    */
-  public function testDecesasedRecepient() {
+  public function testDeceasedRecipient() {
     $contactID = $this->individualCreate(['first_name' => 'test dead recipeint', 'email' => 'mailtestdead@civicrm.org']);
     $this->callAPISuccess('group_contact', 'create', [
       'contact_id' => $contactID,
@@ -571,6 +583,7 @@ class api_v3_JobProcessMailingTest extends CiviUnitTestCase {
       'civicrm_activity_contact',
       'civicrm_activity',
     ]);
+    Civi::settings()->set('mailerBatchLimit', 0);
   }
 
   /**