Commit | Line | Data |
---|---|---|
9f0a25d7 J |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
2fe49090 | 4 | | CiviCRM version 5 | |
9f0a25d7 | 5 | +--------------------------------------------------------------------+ |
8c9251b3 | 6 | | Copyright CiviCRM LLC (c) 2004-2018 | |
9f0a25d7 J |
7 | +--------------------------------------------------------------------+ |
8 | | This file is a part of CiviCRM. | | |
9 | | | | |
10 | | CiviCRM is free software; you can copy, modify, and distribute it | | |
11 | | under the terms of the GNU Affero General Public License | | |
12 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | | |
13 | | | | |
14 | | CiviCRM is distributed in the hope that it will be useful, but | | |
15 | | WITHOUT ANY WARRANTY; without even the implied warranty of | | |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | |
17 | | See the GNU Affero General Public License for more details. | | |
18 | | | | |
19 | | You should have received a copy of the GNU Affero General Public | | |
20 | | License and the CiviCRM Licensing Exception along | | |
21 | | with this program; if not, contact CiviCRM LLC | | |
22 | | at info[AT]civicrm[DOT]org. If you have questions about the | | |
23 | | GNU Affero General Public License or the licensing of CiviCRM, | | |
24 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | | |
25 | +--------------------------------------------------------------------+ | |
26 | */ | |
27 | ||
28 | /** | |
29 | * Class CRM_Mailing_BAO_MailingTest | |
30 | */ | |
31 | class CRM_Mailing_BAO_MailingTest extends CiviUnitTestCase { | |
32 | ||
fae688ec | 33 | protected $allowedContactId = 0; |
34 | ||
9f0a25d7 J |
35 | public function setUp() { |
36 | parent::setUp(); | |
37 | } | |
38 | ||
df3320dc | 39 | public function tearDown() { |
40 | global $dbLocale; | |
41 | if ($dbLocale) { | |
42 | CRM_Core_I18n_Schema::makeSinglelingual('en_US'); | |
43 | } | |
44 | parent::tearDown(); | |
45 | } | |
46 | ||
6ff6f4f2 J |
47 | /** |
48 | * Helper function to assert whether the calculated recipients of a mailing | |
49 | * match the expected list | |
50 | * | |
51 | * @param $mailingID | |
52 | * @param $expectedRecipients array | |
53 | * Array of contact ID that should be in the recipient list. | |
54 | */ | |
55 | private function assertRecipientsCorrect($mailingID, $expectedRecipients) { | |
56 | ||
57 | // Reset keys to ensure match | |
58 | $expectedRecipients = array_values($expectedRecipients); | |
59 | ||
60 | // Load the recipients as a list of contact IDs | |
61 | CRM_Mailing_BAO_Mailing::getRecipients($mailingID); | |
62 | $recipients = $this->callAPISuccess('MailingRecipients', 'get', array('mailing_id' => $mailingID)); | |
63 | $contactIDs = array(); | |
64 | foreach ($recipients['values'] as $recipient) { | |
65 | $contactIDs[] = $recipient['contact_id']; | |
66 | } | |
67 | ||
68 | // Check the lists match | |
69 | $this->assertTreeEquals($expectedRecipients, $contactIDs); | |
70 | } | |
71 | ||
72 | /** | |
73 | * Helper function to create a mailing include/exclude group. | |
74 | * | |
75 | * @param $mailingID | |
76 | * @param $groupID | |
77 | * @param string $type | |
78 | * @return array|int | |
79 | */ | |
80 | private function createMailingGroup($mailingID, $groupID, $type = 'Include') { | |
81 | return $this->callAPISuccess('MailingGroup', 'create', array( | |
82 | 'mailing_id' => $mailingID, | |
83 | 'group_type' => $type, | |
df3320dc | 84 | 'entity_table' => CRM_Contact_BAO_Group::getTableName(), |
6ff6f4f2 J |
85 | 'entity_id' => $groupID, |
86 | )); | |
87 | } | |
88 | ||
fae688ec | 89 | /** |
90 | * Test to ensure that using ACL permitted contacts are correctly fetched for bulk mailing | |
91 | */ | |
92 | public function testgetRecipientsUsingACL() { | |
93 | $this->prepareForACLs(); | |
94 | $this->createLoggedInUser(); | |
95 | // create hook to build ACL where clause which choses $this->allowedContactId as the only contact to be considered as mail recipient | |
96 | $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereAllowedOnlyOne')); | |
97 | CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM', 'view my contact'); | |
98 | ||
99 | // Create dummy group and assign 2 contacts | |
100 | $name = 'Test static group ' . substr(sha1(rand()), 0, 7); | |
101 | $groupID = $this->groupCreate([ | |
102 | 'name' => $name, | |
103 | 'title' => $name, | |
104 | 'is_active' => 1, | |
105 | ]); | |
106 | // Create 2 contacts where one of them identified as $this->allowedContactId will be used in ACL where clause | |
107 | $contactID1 = $this->individualCreate(array(), 0); | |
108 | $this->allowedContactId = $this->individualCreate(array(), 1); | |
109 | $this->callAPISuccess('GroupContact', 'Create', array( | |
110 | 'group_id' => $groupID, | |
111 | 'contact_id' => $contactID1, | |
112 | )); | |
113 | $this->callAPISuccess('GroupContact', 'Create', array( | |
114 | 'group_id' => $groupID, | |
115 | 'contact_id' => $this->allowedContactId, | |
116 | )); | |
117 | ||
118 | // Create dummy mailing | |
119 | $mailingID = $this->callAPISuccess('Mailing', 'create', array())['id']; | |
120 | $this->createMailingGroup($mailingID, $groupID); | |
121 | ||
122 | // Check that the desired contact (identified as Contact ID - $this->allowedContactId) is the only | |
123 | // contact chosen as mail recipient | |
124 | $expectedContactIDs = [$this->allowedContactId]; | |
125 | $this->assertRecipientsCorrect($mailingID, $expectedContactIDs); | |
126 | ||
127 | $this->cleanUpAfterACLs(); | |
2acf8c58 | 128 | $this->callAPISuccess('Group', 'Delete', ['id' => $groupID]); |
fae688ec | 129 | $this->contactDelete($contactID1); |
130 | $this->contactDelete($this->allowedContactId); | |
131 | } | |
132 | ||
e3d924ca SL |
133 | /** |
134 | * Test mailing receipients when using previous mailing as include and contact is in exclude as well | |
135 | */ | |
136 | public function testMailingIncludePreviousMailingExcludeGroup() { | |
137 | $groupName = 'Test static group ' . substr(sha1(rand()), 0, 7); | |
138 | $groupName2 = 'Test static group 2' . substr(sha1(rand()), 0, 7); | |
139 | $groupID = $this->groupCreate([ | |
140 | 'name' => $groupName, | |
141 | 'title' => $groupName, | |
142 | 'is_active' => 1, | |
143 | ]); | |
144 | $groupID2 = $this->groupCreate([ | |
145 | 'name' => $groupName2, | |
146 | 'title' => $groupName2, | |
147 | 'is_active' => 1, | |
148 | ]); | |
149 | $contactID = $this->individualCreate(array(), 0); | |
150 | $contactID2 = $this->individualCreate(array(), 2); | |
151 | $this->callAPISuccess('GroupContact', 'Create', array( | |
152 | 'group_id' => $groupID, | |
153 | 'contact_id' => $contactID, | |
154 | )); | |
155 | $this->callAPISuccess('GroupContact', 'Create', array( | |
156 | 'group_id' => $groupID, | |
157 | 'contact_id' => $contactID2, | |
158 | )); | |
159 | $this->callAPISuccess('GroupContact', 'Create', array( | |
160 | 'group_id' => $groupID2, | |
161 | 'contact_id' => $contactID2, | |
162 | )); | |
163 | // Create dummy mailing | |
164 | $mailingID = $this->callAPISuccess('Mailing', 'create', array())['id']; | |
165 | $this->createMailingGroup($mailingID, $groupID); | |
166 | $expectedContactIDs = [$contactID, $contactID2]; | |
167 | $this->assertRecipientsCorrect($mailingID, $expectedContactIDs); | |
168 | $mailingID2 = $this->callAPISuccess('Mailing', 'create', array())['id']; | |
169 | $this->createMailingGroup($mailingID2, $groupID2, 'Exclude'); | |
170 | $this->callAPISuccess('MailingGroup', 'create', array( | |
171 | 'mailing_id' => $mailingID2, | |
172 | 'group_type' => 'Include', | |
173 | 'entity_table' => CRM_Mailing_BAO_Mailing::getTableName(), | |
174 | 'entity_id' => $mailingID, | |
175 | )); | |
176 | $expectedContactIDs = [$contactID]; | |
177 | $this->assertRecipientsCorrect($mailingID2, $expectedContactIDs); | |
178 | $this->callAPISuccess('mailing', 'delete', ['id' => $mailingID2]); | |
179 | $this->callAPISuccess('mailing', 'delete', ['id' => $mailingID]); | |
180 | $this->callAPISuccess('group', 'delete', ['id' => $groupID]); | |
181 | $this->callAPISuccess('group', 'delete', ['id' => $groupID2]); | |
182 | $this->callAPISuccess('contact', 'delete', ['id' => $contactID, 'skip_undelete' => TRUE]); | |
183 | $this->callAPISuccess('contact', 'delete', ['id' => $contactID2, 'skip_undelete' => TRUE]); | |
184 | } | |
185 | ||
2acf8c58 SL |
186 | /** |
187 | * Test verify that a disabled mailing group doesn't prvent access to the mailing generated with the group. | |
188 | */ | |
189 | public function testGetMailingDisabledGroup() { | |
190 | $this->prepareForACLs(); | |
191 | $this->createLoggedInUser(); | |
192 | // create hook to build ACL where clause which choses $this->allowedContactId as the only contact to be considered as mail recipient | |
193 | $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereAllowedOnlyOne')); | |
194 | $this->hookClass->setHook('civicrm_aclGroup', array($this, 'hook_civicrm_aclGroup')); | |
195 | CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM', 'edit groups'); | |
196 | // Create dummy group and assign 2 contacts | |
197 | $name = 'Test static group ' . substr(sha1(rand()), 0, 7); | |
198 | $groupID = $this->groupCreate([ | |
199 | 'name' => $name, | |
200 | 'title' => $name, | |
201 | 'is_active' => 1, | |
202 | ]); | |
203 | $contactID = $this->individualCreate(array(), 0); | |
204 | $this->callAPISuccess('GroupContact', 'Create', array( | |
205 | 'group_id' => $groupID, | |
206 | 'contact_id' => $contactID, | |
207 | )); | |
208 | ||
209 | // Create dummy mailing | |
210 | $mailingID = $this->callAPISuccess('Mailing', 'create', array())['id']; | |
211 | $this->createMailingGroup($mailingID, $groupID); | |
212 | // Now disable the group. | |
213 | $this->callAPISuccess('group', 'create', [ | |
214 | 'id' => $groupID, | |
215 | 'is_active' => 0, | |
216 | ]); | |
217 | $groups = CRM_Mailing_BAO_Mailing::mailingACLIDs(); | |
218 | $this->assertTrue(in_array($groupID, $groups)); | |
219 | $this->cleanUpAfterACLs(); | |
220 | $this->contactDelete($contactID); | |
221 | } | |
222 | ||
fae688ec | 223 | /** |
224 | * Build ACL where clause | |
225 | * | |
226 | * @implements CRM_Utils_Hook::aclWhereClause | |
227 | * | |
228 | * @param string $type | |
229 | * @param array $tables | |
230 | * @param array $whereTables | |
231 | * @param int $contactID | |
232 | * @param string $where | |
233 | */ | |
234 | public function aclWhereAllowedOnlyOne($type, &$tables, &$whereTables, &$contactID, &$where) { | |
235 | $where = " contact_a.id = " . $this->allowedContactId; | |
236 | } | |
237 | ||
2acf8c58 SL |
238 | /** |
239 | * Implements ACLGroup hook. | |
240 | * | |
241 | * @implements CRM_Utils_Hook::aclGroup | |
242 | * | |
243 | * aclGroup function returns a list of permitted groups | |
244 | * @param string $type | |
245 | * @param int $contactID | |
246 | * @param string $tableName | |
247 | * @param array $allGroups | |
248 | * @param array $currentGroups | |
249 | */ | |
250 | public function hook_civicrm_aclGroup($type, $contactID, $tableName, &$allGroups, &$currentGroups) { | |
251 | //don't use api - you will get a loop | |
252 | $sql = " SELECT * FROM civicrm_group"; | |
253 | $groups = array(); | |
254 | $dao = CRM_Core_DAO::executeQuery($sql); | |
255 | while ($dao->fetch()) { | |
256 | $groups[] = $dao->id; | |
257 | } | |
258 | if (!empty($allGroups)) { | |
259 | //all groups is empty if we really mean all groups but if a filter like 'is_disabled' is already applied | |
260 | // it is populated, ajax calls from Manage Groups will leave empty but calls from New Mailing pass in a filtered list | |
261 | $currentGroups = array_intersect($groups, array_flip($allGroups)); | |
262 | } | |
263 | else { | |
264 | $currentGroups = $groups; | |
265 | } | |
266 | } | |
267 | ||
268 | ||
251a8849 | 269 | /** |
7ff80daf J |
270 | * @todo Missing tests: |
271 | * - Ensure opt out emails are not mailed | |
272 | * - Ensure 'stop' emails are not mailed | |
273 | * - Ensure the deceased are not mailed | |
274 | * - Tests for getLocationFilterAndOrderBy (selecting correct 'type') | |
275 | * - ... | |
251a8849 J |
276 | */ |
277 | ||
7ff80daf J |
278 | /** |
279 | * Test to ensure that static and smart mailing groups can be added to an | |
280 | * email mailing as 'include' or 'exclude' groups - and the members are | |
281 | * included or excluded appropriately. | |
282 | * | |
283 | * contact 0 : static 0 (inc) + smart 5 (exc) | |
284 | * contact 1 : static 0 (inc) | |
285 | * contact 2 : static 1 (inc) | |
286 | * contact 3 : static 1 (inc) | |
287 | * contact 4 : static 2 (exc) + smart 3 (inc) | |
288 | * contact 5 : smart 3 (inc) | |
289 | * contact 6 : smart 4 (inc) | |
290 | * contact 7 : smart 4 (inc) | |
70170c4f | 291 | * contact 8 : smart 5 (base) |
292 | * | |
293 | * here 'contact 1 : static 0 (inc)' identified as static group $groupIDs[0] | |
294 | * that has 'contact 1' identified as $contactIDs[0] and Included in the mailing recipient list | |
7ff80daf J |
295 | */ |
296 | public function testgetRecipientsEmailGroupIncludeExclude() { | |
70170c4f | 297 | // Set up groups; 3 standard, 4 smart |
7ff80daf | 298 | $groupIDs = array(); |
70170c4f | 299 | for ($i = 0; $i < 7; $i++) { |
7ff80daf J |
300 | $params = array( |
301 | 'name' => 'Test static group ' . $i, | |
302 | 'title' => 'Test static group ' . $i, | |
303 | 'is_active' => 1, | |
304 | ); | |
305 | if ($i < 3) { | |
306 | $groupIDs[$i] = $this->groupCreate($params); | |
307 | } | |
308 | else { | |
309 | $groupIDs[$i] = $this->smartGroupCreate(array( | |
70170c4f | 310 | 'formValues' => ['last_name' => (($i == 6) ? 'smart5' : 'smart' . $i)], |
7ff80daf J |
311 | ), $params); |
312 | } | |
313 | } | |
314 | ||
315 | // Create contacts | |
316 | $contactIDs = array( | |
70170c4f | 317 | $this->individualCreate(array('last_name' => 'smart5'), 0), |
318 | $this->individualCreate(array(), 1), | |
319 | $this->individualCreate(array(), 2), | |
320 | $this->individualCreate(array(), 3), | |
321 | $this->individualCreate(array('last_name' => 'smart3'), 4), | |
322 | $this->individualCreate(array('last_name' => 'smart3'), 5), | |
323 | $this->individualCreate(array('last_name' => 'smart4'), 6), | |
324 | $this->individualCreate(array('last_name' => 'smart4'), 7), | |
325 | $this->individualCreate(array('last_name' => 'smart5'), 8), | |
7ff80daf J |
326 | ); |
327 | ||
328 | // Add contacts to static groups | |
329 | $this->callAPISuccess('GroupContact', 'Create', array( | |
330 | 'group_id' => $groupIDs[0], | |
331 | 'contact_id' => $contactIDs[0], | |
332 | )); | |
333 | $this->callAPISuccess('GroupContact', 'Create', array( | |
334 | 'group_id' => $groupIDs[0], | |
335 | 'contact_id' => $contactIDs[1], | |
336 | )); | |
337 | $this->callAPISuccess('GroupContact', 'Create', array( | |
338 | 'group_id' => $groupIDs[1], | |
339 | 'contact_id' => $contactIDs[2], | |
340 | )); | |
341 | $this->callAPISuccess('GroupContact', 'Create', array( | |
342 | 'group_id' => $groupIDs[1], | |
343 | 'contact_id' => $contactIDs[3], | |
344 | )); | |
345 | $this->callAPISuccess('GroupContact', 'Create', array( | |
346 | 'group_id' => $groupIDs[2], | |
347 | 'contact_id' => $contactIDs[4], | |
348 | )); | |
349 | ||
350 | // Force rebuild the smart groups | |
70170c4f | 351 | for ($i = 3; $i < 7; $i++) { |
7ff80daf J |
352 | $group = new CRM_Contact_DAO_Group(); |
353 | $group->id = $groupIDs[$i]; | |
354 | $group->find(TRUE); | |
355 | CRM_Contact_BAO_GroupContactCache::load($group, TRUE); | |
356 | } | |
357 | ||
358 | // Check that we can include static groups in the mailing. | |
359 | // Expected: Contacts [0-3] should be included. | |
360 | $mailing = $this->callAPISuccess('Mailing', 'create', array()); | |
361 | $this->createMailingGroup($mailing['id'], $groupIDs[0]); | |
362 | $this->createMailingGroup($mailing['id'], $groupIDs[1]); | |
70170c4f | 363 | $this->createMailingGroup($mailing['id'], $groupIDs[6], 'Base'); |
7ff80daf | 364 | $expected = $contactIDs; |
70170c4f | 365 | unset($expected[4], $expected[5], $expected[6], $expected[7], $expected[8]); |
7ff80daf J |
366 | $this->assertRecipientsCorrect($mailing['id'], $expected); |
367 | ||
368 | // Check that we can include smart groups in the mailing too. | |
369 | // Expected: All contacts should be included. | |
df3320dc | 370 | // Also (dev/mail/6): Enable multilingual mode to check that restructing group doesn't affect recipient rebuilding |
371 | $this->enableMultilingual(); | |
7ff80daf J |
372 | $this->createMailingGroup($mailing['id'], $groupIDs[3]); |
373 | $this->createMailingGroup($mailing['id'], $groupIDs[4]); | |
70170c4f | 374 | $this->createMailingGroup($mailing['id'], $groupIDs[5]); |
375 | // Check that all the contacts whould be present is recipient list as static group [0], [1] and [2] and | |
376 | // smart groups [3], [4] and [5] is included in the recipient listing. | |
377 | // NOTE: that contact[8] is present in both included smart group[5] and base smart group [6] so it will be | |
378 | // present in recipient list as contact(s) from Base smart groups are not excluded the list as per (dev/mail/13) | |
7ff80daf J |
379 | $this->assertRecipientsCorrect($mailing['id'], $contactIDs); |
380 | ||
381 | // Check we can exclude static groups from the mailing. | |
382 | // Expected: All contacts except [4] | |
383 | $this->createMailingGroup($mailing['id'], $groupIDs[2], 'Exclude'); | |
384 | $expected = $contactIDs; | |
385 | unset($expected[4]); | |
70170c4f | 386 | // NOTE: as per (dev/mail/13) if a contact A is present in smartGroup [5] which is Included in the mailing AND |
387 | // also present in another smartGroup [6] which is considered as Base group, then contact A should not be excluded from | |
388 | // the recipient list due to later | |
7ff80daf J |
389 | $this->assertRecipientsCorrect($mailing['id'], $expected); |
390 | ||
391 | // Check we can exclude smart groups from the mailing too. | |
70170c4f | 392 | // Expected: All contacts except [0], [4] and [8] |
7ff80daf J |
393 | $this->createMailingGroup($mailing['id'], $groupIDs[5], 'Exclude'); |
394 | $expected = $contactIDs; | |
70170c4f | 395 | // As contact [0] and [8] belongs to excluded smart group[5] and base smart group[6] respectively, |
396 | // both these contacts should not be present in the mailing list | |
397 | unset($expected[0], $expected[4], $expected[8]); | |
7ff80daf J |
398 | $this->assertRecipientsCorrect($mailing['id'], $expected); |
399 | ||
c6ad7d51 T |
400 | // Tear down: delete mailing, groups, contacts |
401 | $this->deleteMailing($mailing['id']); | |
402 | ||
403 | // Create a New mailing, Testing contacts removed from smart group. | |
404 | // In this case groupIDs6 will only pick up contacts[0] amd contacts[8] with it's | |
405 | // criteria. However we are deliberly going to remove contactIds[8] from the group | |
406 | // Which should mean the mainling only finds 1 contact that is contactIds[0] | |
407 | $mailing = $this->callAPISuccess('Mailing', 'create', array()); | |
408 | $this->callAPISuccess('GroupContact', 'Create', array( | |
409 | 'group_id' => $groupIDs[6], | |
410 | 'contact_id' => $contactIDs[8], | |
411 | 'status' => 'Removed', | |
412 | )); | |
413 | $this->createMailingGroup($mailing['id'], $groupIDs[6]); | |
414 | $this->assertRecipientsCorrect($mailing['id'], [$contactIDs[0]]); | |
7ff80daf J |
415 | // Tear down: delete mailing, groups, contacts |
416 | $this->deleteMailing($mailing['id']); | |
417 | foreach ($groupIDs as $groupID) { | |
418 | $this->groupDelete($groupID); | |
419 | } | |
420 | foreach ($contactIDs as $contactID) { | |
421 | $this->contactDelete($contactID); | |
422 | } | |
7ff80daf J |
423 | } |
424 | ||
9f0a25d7 | 425 | /** |
6f3a35e0 | 426 | * Test CRM_Mailing_BAO_Mailing::getRecipients() on sms mode |
9f0a25d7 | 427 | */ |
7ff80daf | 428 | public function testgetRecipientsSMS() { |
9f0a25d7 J |
429 | // Tests for SMS bulk mailing recipients |
430 | // +CRM-21320 Ensure primary mobile number is selected over non-primary | |
431 | ||
432 | // Setup | |
6f3a35e0 | 433 | $smartGroupParams = array( |
434 | 'formValues' => array('contact_type' => array('IN' => array('Individual'))), | |
435 | ); | |
436 | $group = $this->smartGroupCreate($smartGroupParams); | |
9f0a25d7 J |
437 | $sms_provider = $this->callAPISuccess('SmsProvider', 'create', array( |
438 | 'sequential' => 1, | |
439 | 'name' => 1, | |
440 | 'title' => "Test", | |
441 | 'username' => "Test", | |
442 | 'password' => "Test", | |
443 | 'api_type' => 1, | |
444 | 'is_active' => 1, | |
445 | )); | |
446 | ||
6f3a35e0 | 447 | // Create Contact 1 and add in group |
448 | $contactID1 = $this->individualCreate(array(), 0); | |
9f0a25d7 J |
449 | $this->callAPISuccess('GroupContact', 'Create', array( |
450 | 'group_id' => $group, | |
6f3a35e0 | 451 | 'contact_id' => $contactID1, |
9f0a25d7 J |
452 | )); |
453 | ||
6f3a35e0 | 454 | // Create contact 2 and add in group |
455 | $contactID2 = $this->individualCreate(array(), 1); | |
9f0a25d7 J |
456 | $this->callAPISuccess('GroupContact', 'Create', array( |
457 | 'group_id' => $group, | |
6f3a35e0 | 458 | 'contact_id' => $contactID2, |
9f0a25d7 J |
459 | )); |
460 | ||
6f3a35e0 | 461 | $contactIDPhoneRecords = array( |
462 | $contactID1 => array( | |
463 | 'primary_phone_id' => CRM_Utils_Array::value('id', $this->callAPISuccess('Phone', 'create', array( | |
464 | 'contact_id' => $contactID1, | |
465 | 'phone' => "01 01", | |
466 | 'location_type_id' => "Home", | |
467 | 'phone_type_id' => "Mobile", | |
468 | 'is_primary' => 1, | |
469 | ))), | |
470 | 'other_phone_id' => CRM_Utils_Array::value('id', $this->callAPISuccess('Phone', 'create', array( | |
471 | 'contact_id' => $contactID1, | |
472 | 'phone' => "01 02", | |
473 | 'location_type_id' => "Work", | |
474 | 'phone_type_id' => "Mobile", | |
475 | 'is_primary' => 0, | |
476 | ))), | |
477 | ), | |
251a8849 | 478 | // Create the non-primary with a lower ID than the primary, to test CRM-21320 |
6f3a35e0 | 479 | $contactID2 => array( |
251a8849 | 480 | 'other_phone_id' => CRM_Utils_Array::value('id', $this->callAPISuccess('Phone', 'create', array( |
6f3a35e0 | 481 | 'contact_id' => $contactID2, |
482 | 'phone' => "02 01", | |
483 | 'location_type_id' => "Home", | |
484 | 'phone_type_id' => "Mobile", | |
251a8849 | 485 | 'is_primary' => 0, |
6f3a35e0 | 486 | ))), |
251a8849 | 487 | 'primary_phone_id' => CRM_Utils_Array::value('id', $this->callAPISuccess('Phone', 'create', array( |
6f3a35e0 | 488 | 'contact_id' => $contactID2, |
489 | 'phone' => "02 02", | |
490 | 'location_type_id' => "Work", | |
491 | 'phone_type_id' => "Mobile", | |
251a8849 | 492 | 'is_primary' => 1, |
6f3a35e0 | 493 | ))), |
494 | ), | |
495 | ); | |
496 | ||
9f0a25d7 | 497 | // Prepare expected results |
6f3a35e0 | 498 | $checkPhoneIDs = array( |
499 | $contactID1 => $contactIDPhoneRecords[$contactID1]['primary_phone_id'], | |
500 | $contactID2 => $contactIDPhoneRecords[$contactID2]['primary_phone_id'], | |
9f0a25d7 J |
501 | ); |
502 | ||
503 | // Create mailing | |
504 | $mailing = $this->callAPISuccess('Mailing', 'create', array('sms_provider_id' => $sms_provider['id'])); | |
6ff6f4f2 | 505 | $mailingInclude = $this->createMailingGroup($mailing['id'], $group); |
9f0a25d7 J |
506 | |
507 | // Get recipients | |
6ff6f4f2 | 508 | CRM_Mailing_BAO_Mailing::getRecipients($mailing['id']); |
9f0a25d7 J |
509 | $recipients = $this->callAPISuccess('MailingRecipients', 'get', array('mailing_id' => $mailing['id'])); |
510 | ||
511 | // Check the count is correct | |
512 | $this->assertEquals(2, $recipients['count'], 'Check recipient count'); | |
513 | ||
514 | // Check we got the 'primary' mobile for both contacts | |
515 | foreach ($recipients['values'] as $value) { | |
6f3a35e0 | 516 | $this->assertEquals($value['phone_id'], $checkPhoneIDs[$value['contact_id']], 'Check correct phone number for contact ' . $value['contact_id']); |
9f0a25d7 J |
517 | } |
518 | ||
519 | // Tidy up | |
520 | $this->deleteMailing($mailing['id']); | |
521 | $this->callAPISuccess('SmsProvider', 'Delete', array('id' => $sms_provider['id'])); | |
522 | $this->groupDelete($group); | |
6f3a35e0 | 523 | $this->contactDelete($contactID1); |
524 | $this->contactDelete($contactID2); | |
9f0a25d7 J |
525 | } |
526 | ||
737f12a7 | 527 | /** |
528 | * Test alterMailingRecipients Hook which is called twice when we create a Mailing, | |
529 | * 1. In the first call we will modify the mailing filter to include only deceased recipients | |
530 | * 2. In the second call we will check if only deceased recipient is populated in MailingRecipient table | |
531 | */ | |
532 | public function testAlterMailingRecipientsHook() { | |
533 | $groupID = $this->groupCreate(); | |
be2c9578 | 534 | $this->tagCreate(array('name' => 'Tagged')); |
737f12a7 | 535 | |
536 | // Create deseased Contact 1 and add in group | |
537 | $contactID1 = $this->individualCreate(array('email' => 'abc@test.com', 'is_deceased' => 1), 0); | |
538 | // Create deseased Contact 2 and add in group | |
539 | $contactID2 = $this->individualCreate(array('email' => 'def@test.com'), 1); | |
be2c9578 | 540 | // Create deseased Contact 3 and add in group |
541 | $contactID3 = $this->individualCreate(array('email' => 'ghi@test.com', 'is_deceased' => 1), 2); | |
542 | ||
737f12a7 | 543 | // Add both the created contacts in group |
544 | $this->callAPISuccess('GroupContact', 'Create', array( | |
545 | 'group_id' => $groupID, | |
546 | 'contact_id' => $contactID1, | |
547 | )); | |
548 | $this->callAPISuccess('GroupContact', 'Create', array( | |
549 | 'group_id' => $groupID, | |
550 | 'contact_id' => $contactID2, | |
551 | )); | |
be2c9578 | 552 | $this->callAPISuccess('GroupContact', 'Create', array( |
553 | 'group_id' => $groupID, | |
554 | 'contact_id' => $contactID3, | |
555 | )); | |
556 | $this->entityTagAdd(array('contact_id' => $contactID3, 'tag_id' => 'Tagged')); | |
557 | ||
737f12a7 | 558 | // trigger the alterMailingRecipients hook |
559 | $this->hookClass->setHook('civicrm_alterMailingRecipients', array($this, 'alterMailingRecipients')); | |
560 | ||
561 | // create mailing that will trigger alterMailingRecipients hook | |
562 | $params = array( | |
563 | 'name' => 'mailing name', | |
564 | 'subject' => 'Test Subject', | |
565 | 'body_html' => '<p>HTML Body</p>', | |
566 | 'text_html' => 'Text Body', | |
567 | 'created_id' => 1, | |
568 | 'groups' => array('include' => array($groupID)), | |
569 | 'scheduled_date' => 'now', | |
570 | ); | |
571 | $this->callAPISuccess('Mailing', 'create', $params); | |
572 | } | |
573 | ||
574 | /** | |
575 | * @implements CRM_Utils_Hook::alterMailingRecipients | |
576 | * | |
577 | * @param object $mailingObject | |
be2c9578 | 578 | * @param array $criteria |
737f12a7 | 579 | * @param string $context |
580 | */ | |
be2c9578 | 581 | public function alterMailingRecipients(&$mailingObject, &$criteria, $context) { |
737f12a7 | 582 | if ($context == 'pre') { |
be2c9578 | 583 | // modify the filter to include only deceased recipient(s) that is Tagged |
584 | $criteria['is_deceased'] = CRM_Utils_SQL_Select::fragment()->where("civicrm_contact.is_deceased = 1"); | |
585 | $criteria['tagged_contact'] = CRM_Utils_SQL_Select::fragment() | |
586 | ->join('civicrm_entity_tag', "INNER JOIN civicrm_entity_tag et ON et.entity_id = civicrm_contact.id AND et.entity_table = 'civicrm_contact'") | |
587 | ->join('civicrm_tag', "INNER JOIN civicrm_tag t ON t.id = et.tag_id") | |
588 | ->where("t.name = 'Tagged'"); | |
737f12a7 | 589 | } |
590 | else { | |
591 | $mailingRecipients = $this->callAPISuccess('MailingRecipients', 'get', array( | |
592 | 'mailing_id' => $mailingObject->id, | |
593 | 'api.Email.getvalue' => array( | |
594 | 'id' => '$value.email_id', | |
595 | 'return' => 'email', | |
596 | ), | |
597 | )); | |
598 | $this->assertEquals(1, $mailingRecipients['count'], 'Check recipient count'); | |
be2c9578 | 599 | $this->assertEquals('ghi@test.com', $mailingRecipients['values'][$mailingRecipients['id']]['api.Email.getvalue'], 'Check if recipient email belong to deceased contact'); |
737f12a7 | 600 | } |
601 | } | |
602 | ||
9f0a25d7 | 603 | } |