);
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'])) {
->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)
->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)
$mailingGroup->reset();
$mailingGroup->query(" DROP TEMPORARY TABLE $excludeTempTablename ");
$mailingGroup->query(" DROP TEMPORARY TABLE $includedTempTablename ");
+
+ CRM_Utils_Hook::alterMailingRecipients($mailingObj, $params, 'post');
}
/**
* 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'
);
}
$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');
+ }
+ }
+
}