added unit test
authordeb.monish <monish.deb@jmaconsulting.biz>
Wed, 14 Feb 2018 12:16:51 +0000 (17:46 +0530)
committerdeb.monish <monish.deb@jmaconsulting.biz>
Tue, 19 Jun 2018 07:44:00 +0000 (13:14 +0530)
CRM/Mailing/BAO/Mailing.php
CRM/Utils/Hook.php
tests/phpunit/CRM/Mailing/BAO/MailingTest.php

index 27a46fd693200a7f6b863f5000402840db9351f6..2edcc32a8015b5cd38708f85b3a9a4f0671d556f 100644 (file)
@@ -228,35 +228,43 @@ class CRM_Mailing_BAO_Mailing extends CRM_Mailing_DAO_Mailing {
     );
 
     if ($isSMSmode) {
-      $includeFilters = array(
-        "mg.group_type = 'Include'",
-        'mg.search_id IS NULL',
-        "$contact.is_opt_out = 0",
-        "$contact.is_deceased <> 1",
-        "$entityTable.phone_type_id = " . CRM_Core_PseudoConstant::getKey('CRM_Core_DAO_Phone', 'phone_type_id', 'Mobile'),
-        "$entityTable.phone IS NOT NULL",
-        "$entityTable.phone != ''",
-        "$entityTable.is_primary = 1",
-        "mg.mailing_id = #mailingID",
-        'temp.contact_id IS null',
+      $params = array(
+        'filters' => array(
+          'is_opt_out' => "$contact.is_opt_out = 0",
+          'is_deceased' => "$contact.is_deceased <> 1",
+          'location_filter' => "$entityTable.phone_type_id = " . CRM_Core_PseudoConstant::getKey('CRM_Core_DAO_Phone', 'phone_type_id', 'Mobile'),
+          'phone_not_null' => "$entityTable.phone IS NOT NULL",
+          'phone_not_empty' => "$entityTable.phone != ''",
+          'is_primary' => "$entityTable.is_primary = 1",
+          'mailing_id' => "mg.mailing_id = #mailingID",
+          'temp_contact_null' => 'temp.contact_id IS null',
+        ),
+        'order_by' => array(
+          "$entityTable.is_primary = 1",
+        ),
       );
-      $order_by = array("$entityTable.is_primary = 1");
     }
     else {
       // Criterias to filter recipients that need to be included
-      $includeFilters = array(
-        "$contact.do_not_email = 0",
-        "$contact.is_opt_out = 0",
-        "$contact.is_deceased <> 1",
-        $location_filter,
-        "$entityTable.email IS NOT NULL",
-        "$entityTable.email != ''",
-        "$entityTable.on_hold = 0",
-        "mg.mailing_id = #mailingID",
-        'temp.contact_id IS NULL',
+      $params = array(
+        'filters' => array(
+          'do_not_email' => "$contact.do_not_email = 0",
+          'is_opt_out' => "$contact.is_opt_out = 0",
+          'is_deceased' => "$contact.is_deceased <> 1",
+          'location_filter' => $location_filter,
+          'email_not_null' => "$entityTable.email IS NOT NULL",
+          'email_not_empty' => "$entityTable.email != ''",
+          'mailing_id' => "mg.mailing_id = #mailingID",
+          'temp_contact_null' => 'temp.contact_id IS NULL',
+        ),
+        'order_by' => $order_by,
       );
     }
 
+    // Allow user to alter query responsible to fetch mailing recipients before build,
+    //   by changing the mail filters identified $params
+    CRM_Utils_Hook::alterMailingRecipients($mailingObj, $params, 'pre');
+
     // Get the group contacts, but only those which are not in the
     // exclusion temp table.
     if (!empty($recipientsGroup['Include'])) {
@@ -267,8 +275,9 @@ class CRM_Mailing_BAO_Mailing extends CRM_Mailing_DAO_Mailing {
         ->join('mg', " INNER JOIN civicrm_mailing_group mg  ON  gc.group_id = mg.entity_id AND mg.search_id IS NULL ")
         ->join('temp', " LEFT JOIN $excludeTempTablename temp ON $contact.id = temp.contact_id ")
         ->where('gc.group_id IN (#groups) AND gc.status = "Added"')
-        ->where($includeFilters)
+        ->where($params['filters'])
         ->groupBy(array("$contact.id", "$entityTable.id"))
+        ->orderBy($params['order_by'])
         ->replaceInto($includedTempTablename, array('contact_id', $entityColumn))
         ->param('#groups', $recipientsGroup['Include'])
         ->param('#mailingID', $mailingID)
@@ -293,8 +302,8 @@ class CRM_Mailing_BAO_Mailing extends CRM_Mailing_DAO_Mailing {
         ->join('mg', " INNER JOIN civicrm_mailing_group mg  ON  gc.group_id = mg.entity_id AND mg.search_id IS NULL ")
         ->join('temp', " LEFT JOIN $excludeTempTablename temp ON $contact.id = temp.contact_id ")
         ->where('gc.group_id IN (#groups)')
-        ->where($includeFilters)
-        ->orderBy($order_by)
+        ->where($params['filters'])
+        ->orderBy($params['order_by'])
         ->replaceInto($includedTempTablename, array('contact_id', $entityColumn))
         ->param('#groups', $includeSmartGroupIDs)
         ->param('#mailingID', $mailingID)
@@ -370,6 +379,8 @@ class CRM_Mailing_BAO_Mailing extends CRM_Mailing_DAO_Mailing {
     $mailingGroup->reset();
     $mailingGroup->query(" DROP TEMPORARY TABLE $excludeTempTablename ");
     $mailingGroup->query(" DROP TEMPORARY TABLE $includedTempTablename ");
+
+    CRM_Utils_Hook::alterMailingRecipients($mailingObj, $params, 'post');
   }
 
   /**
index caef0b11d0dc9ac947ef3e5285535f6b3e29efcc..082833e432edb4af21845657bc6248fab417157f 100644 (file)
@@ -2455,16 +2455,14 @@ abstract class CRM_Utils_Hook {
    *  Allows user to alter filter and/or search query to fetch mail recipients
    *
    * @param CRM_Mailing_DAO_Mailing $mailingObject
-   * @param CRM_Mailing_Event_BAO_Queue $mailingEventQueueObject
-   * @param int $mailingJobID
    * @param array $params
    * @param string $context
    *
    */
-  public static function alterMailingRecipients(&$mailingObject, &$mailingEventQueueObject, $mailingJobID, &$params, $context) {
-    return self::singleton()->invoke(array('mailingObject', 'mailingEventQueueObject', '$mailingJobID', 'params', 'context'),
-      $mailingObject, $mailingEventQueueObject, $mailingJobID, $params, $context,
-      self::$_nullObject,
+  public static function alterMailingRecipients(&$mailingObject, &$params, $context) {
+    return self::singleton()->invoke(array('mailingObject', 'params', 'context'),
+      $mailingObject, $params, $context,
+      self::$_nullObject, self::$_nullObject, self::$_nullObject,
       'civicrm_alterMailingRecipients'
     );
   }
index 0f9a49801c816e1d601988315df699729a8a005d..09a0044326c00c37c9b28b4f3c39a69e60685e7b 100644 (file)
@@ -456,4 +456,66 @@ class CRM_Mailing_BAO_MailingTest extends CiviUnitTestCase {
     $this->contactDelete($contactID2);
   }
 
+  /**
+   * Test alterMailingRecipients Hook which is called twice when we create a Mailing,
+   *  1. In the first call we will modify the mailing filter to include only deceased recipients
+   *  2. In the second call we will check if only deceased recipient is populated in MailingRecipient table
+   */
+  public function testAlterMailingRecipientsHook() {
+    $groupID = $this->groupCreate();
+
+    // Create deseased Contact 1 and add in group
+    $contactID1 = $this->individualCreate(array('email' => 'abc@test.com', 'is_deceased' => 1), 0);
+    // Create deseased Contact 2 and add in group
+    $contactID2 = $this->individualCreate(array('email' => 'def@test.com'), 1);
+    // Add both the created contacts in group
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupID,
+      'contact_id' => $contactID1,
+    ));
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupID,
+      'contact_id' => $contactID2,
+    ));
+    // trigger the alterMailingRecipients hook
+    $this->hookClass->setHook('civicrm_alterMailingRecipients', array($this, 'alterMailingRecipients'));
+
+    // create mailing that will trigger alterMailingRecipients hook
+    $params = array(
+      'name' => 'mailing name',
+      'subject' => 'Test Subject',
+      'body_html' => '<p>HTML Body</p>',
+      'text_html' => 'Text Body',
+      'created_id' => 1,
+      'groups' => array('include' => array($groupID)),
+      'scheduled_date' => 'now',
+    );
+    $this->callAPISuccess('Mailing', 'create', $params);
+  }
+
+  /**
+   * @implements CRM_Utils_Hook::alterMailingRecipients
+   *
+   * @param object $mailingObject
+   * @param array $params
+   * @param string $context
+   */
+  public function alterMailingRecipients(&$mailingObject, &$params, $context) {
+    if ($context == 'pre') {
+      // modify the filter to include only deceased recipient(s)
+      $params['filters']['is_deceased'] = 'civicrm_contact.is_deceased = 1';
+    }
+    else {
+      $mailingRecipients = $this->callAPISuccess('MailingRecipients', 'get', array(
+        'mailing_id' => $mailingObject->id,
+        'api.Email.getvalue' => array(
+          'id' => '$value.email_id',
+          'return' => 'email',
+        ),
+      ));
+      $this->assertEquals(1, $mailingRecipients['count'], 'Check recipient count');
+      $this->assertEquals('abc@test.com', $mailingRecipients['values'][$mailingRecipients['id']]['api.Email.getvalue'], 'Check if recipient email belong to deceased contact');
+    }
+  }
+
 }