Commit | Line | Data |
---|---|---|
0622d221 | 1 | <?php |
0622d221 | 2 | |
3 | /** | |
4 | * Class CRM_Dedupe_DedupeMergerTest | |
acb109b7 | 5 | * @group headless |
0622d221 | 6 | */ |
7 | class CRM_Dedupe_MergerTest extends CiviUnitTestCase { | |
8 | ||
9 | protected $_groupId; | |
10 | protected $_contactIds = array(); | |
11 | ||
3308aac0 | 12 | public function tearDown() { |
13 | $this->quickCleanup(array('civicrm_contact', 'civicrm_group_contact', 'civicrm_group')); | |
14 | parent::tearDown(); | |
15 | } | |
16 | ||
0622d221 | 17 | public function createDupeContacts() { |
18 | // create a group to hold contacts, so that dupe checks don't consider any other contacts in the DB | |
19 | $params = array( | |
20 | 'name' => 'Test Dupe Merger Group', | |
21 | 'title' => 'Test Dupe Merger Group', | |
22 | 'domain_id' => 1, | |
23 | 'is_active' => 1, | |
24 | 'visibility' => 'Public Pages', | |
0622d221 | 25 | ); |
87a56b12 | 26 | |
27 | $result = $this->callAPISuccess('group', 'create', $params); | |
0622d221 | 28 | $this->_groupId = $result['id']; |
29 | ||
30 | // contact data set | |
31 | ||
32 | // make dupe checks based on based on following contact sets: | |
33 | // FIRST - LAST - EMAIL | |
34 | // --------------------------------- | |
35 | // robin - hood - robin@example.com | |
36 | // robin - hood - robin@example.com | |
37 | // robin - hood - hood@example.com | |
38 | // robin - dale - robin@example.com | |
39 | // little - dale - dale@example.com | |
40 | // little - dale - dale@example.com | |
41 | // will - dale - dale@example.com | |
42 | // will - dale - will@example.com | |
43 | // will - dale - will@example.com | |
44 | $params = array( | |
45 | array( | |
46 | 'first_name' => 'robin', | |
47 | 'last_name' => 'hood', | |
48 | 'email' => 'robin@example.com', | |
49 | 'contact_type' => 'Individual', | |
50 | ), | |
51 | array( | |
52 | 'first_name' => 'robin', | |
53 | 'last_name' => 'hood', | |
54 | 'email' => 'robin@example.com', | |
55 | 'contact_type' => 'Individual', | |
56 | ), | |
57 | array( | |
58 | 'first_name' => 'robin', | |
59 | 'last_name' => 'hood', | |
60 | 'email' => 'hood@example.com', | |
61 | 'contact_type' => 'Individual', | |
62 | ), | |
63 | array( | |
64 | 'first_name' => 'robin', | |
65 | 'last_name' => 'dale', | |
66 | 'email' => 'robin@example.com', | |
67 | 'contact_type' => 'Individual', | |
68 | ), | |
69 | array( | |
70 | 'first_name' => 'little', | |
71 | 'last_name' => 'dale', | |
72 | 'email' => 'dale@example.com', | |
73 | 'contact_type' => 'Individual', | |
74 | ), | |
75 | array( | |
76 | 'first_name' => 'little', | |
77 | 'last_name' => 'dale', | |
78 | 'email' => 'dale@example.com', | |
79 | 'contact_type' => 'Individual', | |
80 | ), | |
81 | array( | |
82 | 'first_name' => 'will', | |
83 | 'last_name' => 'dale', | |
84 | 'email' => 'dale@example.com', | |
85 | 'contact_type' => 'Individual', | |
86 | ), | |
87 | array( | |
88 | 'first_name' => 'will', | |
89 | 'last_name' => 'dale', | |
90 | 'email' => 'will@example.com', | |
91 | 'contact_type' => 'Individual', | |
92 | ), | |
93 | array( | |
94 | 'first_name' => 'will', | |
95 | 'last_name' => 'dale', | |
96 | 'email' => 'will@example.com', | |
97 | 'contact_type' => 'Individual', | |
98 | ), | |
99 | ); | |
100 | ||
101 | $count = 1; | |
102 | foreach ($params as $param) { | |
103 | $param['version'] = 3; | |
104 | $contact = civicrm_api('contact', 'create', $param); | |
105 | $this->_contactIds[$count++] = $contact['id']; | |
106 | ||
107 | $grpParams = array( | |
108 | 'contact_id' => $contact['id'], | |
109 | 'group_id' => $this->_groupId, | |
110 | 'version' => 3, | |
111 | ); | |
87a56b12 | 112 | $this->callAPISuccess('group_contact', 'create', $grpParams); |
0622d221 | 113 | } |
114 | } | |
115 | ||
93ac19cd | 116 | /** |
117 | * Delete all created contacts. | |
118 | */ | |
0622d221 | 119 | public function deleteDupeContacts() { |
0622d221 | 120 | foreach ($this->_contactIds as $contactId) { |
93ac19cd | 121 | $this->contactDelete($contactId); |
0622d221 | 122 | } |
87a56b12 | 123 | $this->groupDelete($this->_groupId); |
0622d221 | 124 | } |
125 | ||
c8ec0753 | 126 | /** |
a354251e | 127 | * Test the batch merge. |
c8ec0753 | 128 | */ |
0622d221 | 129 | public function testBatchMergeSelectedDuplicates() { |
130 | $this->createDupeContacts(); | |
131 | ||
132 | // verify that all contacts have been created separately | |
133 | $this->assertEquals(count($this->_contactIds), 9, 'Check for number of contacts.'); | |
134 | ||
135 | $dao = new CRM_Dedupe_DAO_RuleGroup(); | |
136 | $dao->contact_type = 'Individual'; | |
137 | $dao->name = 'IndividualSupervised'; | |
138 | $dao->is_default = 1; | |
139 | $dao->find(TRUE); | |
140 | ||
141 | $foundDupes = CRM_Dedupe_Finder::dupesInGroup($dao->id, $this->_groupId); | |
142 | ||
143 | // ------------------------------------------------------------------------- | |
144 | // Name and Email (reserved) Matches ( 3 pairs ) | |
145 | // -------------------------------------------------------------------------- | |
146 | // robin - hood - robin@example.com | |
147 | // robin - hood - robin@example.com | |
148 | // little - dale - dale@example.com | |
149 | // little - dale - dale@example.com | |
150 | // will - dale - will@example.com | |
151 | // will - dale - will@example.com | |
152 | // so 3 pairs for - first + last + mail | |
153 | $this->assertEquals(count($foundDupes), 3, 'Check Individual-Supervised dupe rule for dupesInGroup().'); | |
154 | ||
155 | // Run dedupe finder as the browser would | |
39b959db SL |
156 | //avoid invalid key error |
157 | $_SERVER['REQUEST_METHOD'] = 'GET'; | |
0622d221 | 158 | $object = new CRM_Contact_Page_DedupeFind(); |
159 | $object->set('gid', $this->_groupId); | |
160 | $object->set('rgid', $dao->id); | |
161 | $object->set('action', CRM_Core_Action::UPDATE); | |
64fe2fe0 | 162 | $object->setEmbedded(TRUE); |
0622d221 | 163 | @$object->run(); |
164 | ||
165 | // Retrieve pairs from prev next cache table | |
166 | $select = array('pn.is_selected' => 'is_selected'); | |
b1679439 | 167 | $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($dao->id, $this->_groupId); |
0622d221 | 168 | $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select); |
169 | ||
170 | $this->assertEquals(count($foundDupes), count($pnDupePairs), 'Check number of dupe pairs in prev next cache.'); | |
171 | ||
172 | // mark first two pairs as selected | |
173 | CRM_Core_DAO::singleValueQuery("UPDATE civicrm_prevnext_cache SET is_selected = 1 WHERE id IN ({$pnDupePairs[0]['prevnext_id']}, {$pnDupePairs[1]['prevnext_id']})"); | |
174 | ||
175 | $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select); | |
176 | $this->assertEquals($pnDupePairs[0]['is_selected'], 1, 'Check if first record in dupe pairs is marked as selected.'); | |
177 | $this->assertEquals($pnDupePairs[0]['is_selected'], 1, 'Check if second record in dupe pairs is marked as selected.'); | |
178 | ||
179 | // batch merge selected dupes | |
d13a105a | 180 | $result = CRM_Dedupe_Merger::batchMerge($dao->id, $this->_groupId, 'safe', 5, 1); |
0622d221 | 181 | $this->assertEquals(count($result['merged']), 2, 'Check number of merged pairs.'); |
182 | ||
183 | // retrieve pairs from prev next cache table | |
184 | $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select); | |
185 | $this->assertEquals(count($pnDupePairs), 1, 'Check number of remaining dupe pairs in prev next cache.'); | |
186 | ||
187 | $this->deleteDupeContacts(); | |
188 | } | |
189 | ||
c8ec0753 | 190 | /** |
a354251e | 191 | * Test the batch merge. |
c8ec0753 | 192 | */ |
0622d221 | 193 | public function testBatchMergeAllDuplicates() { |
194 | $this->createDupeContacts(); | |
195 | ||
196 | // verify that all contacts have been created separately | |
197 | $this->assertEquals(count($this->_contactIds), 9, 'Check for number of contacts.'); | |
198 | ||
199 | $dao = new CRM_Dedupe_DAO_RuleGroup(); | |
200 | $dao->contact_type = 'Individual'; | |
201 | $dao->name = 'IndividualSupervised'; | |
202 | $dao->is_default = 1; | |
203 | $dao->find(TRUE); | |
204 | ||
205 | $foundDupes = CRM_Dedupe_Finder::dupesInGroup($dao->id, $this->_groupId); | |
206 | ||
207 | // ------------------------------------------------------------------------- | |
208 | // Name and Email (reserved) Matches ( 3 pairs ) | |
209 | // -------------------------------------------------------------------------- | |
210 | // robin - hood - robin@example.com | |
211 | // robin - hood - robin@example.com | |
212 | // little - dale - dale@example.com | |
213 | // little - dale - dale@example.com | |
214 | // will - dale - will@example.com | |
215 | // will - dale - will@example.com | |
216 | // so 3 pairs for - first + last + mail | |
217 | $this->assertEquals(count($foundDupes), 3, 'Check Individual-Supervised dupe rule for dupesInGroup().'); | |
218 | ||
219 | // Run dedupe finder as the browser would | |
39b959db SL |
220 | //avoid invalid key error |
221 | $_SERVER['REQUEST_METHOD'] = 'GET'; | |
0622d221 | 222 | $object = new CRM_Contact_Page_DedupeFind(); |
223 | $object->set('gid', $this->_groupId); | |
224 | $object->set('rgid', $dao->id); | |
225 | $object->set('action', CRM_Core_Action::UPDATE); | |
64fe2fe0 | 226 | $object->setEmbedded(TRUE); |
0622d221 | 227 | @$object->run(); |
228 | ||
229 | // Retrieve pairs from prev next cache table | |
230 | $select = array('pn.is_selected' => 'is_selected'); | |
b1679439 | 231 | $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($dao->id, $this->_groupId); |
0622d221 | 232 | $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select); |
233 | ||
234 | $this->assertEquals(count($foundDupes), count($pnDupePairs), 'Check number of dupe pairs in prev next cache.'); | |
235 | ||
236 | // batch merge all dupes | |
d13a105a | 237 | $result = CRM_Dedupe_Merger::batchMerge($dao->id, $this->_groupId, 'safe', 5, 2); |
0622d221 | 238 | $this->assertEquals(count($result['merged']), 3, 'Check number of merged pairs.'); |
239 | ||
240 | // retrieve pairs from prev next cache table | |
241 | $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select); | |
242 | $this->assertEquals(count($pnDupePairs), 0, 'Check number of remaining dupe pairs in prev next cache.'); | |
243 | ||
244 | $this->deleteDupeContacts(); | |
245 | } | |
246 | ||
bf17fa88 | 247 | /** |
248 | * The goal of this function is to test that all required tables are returned. | |
249 | */ | |
250 | public function testGetCidRefs() { | |
251 | $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'Contacts'); | |
252 | $this->assertEquals(array_merge($this->getStaticCIDRefs(), $this->getHackedInCIDRef()), CRM_Dedupe_Merger::cidRefs()); | |
253 | $this->assertEquals(array_merge($this->getCalculatedCIDRefs(), $this->getHackedInCIDRef()), CRM_Dedupe_Merger::cidRefs()); | |
254 | } | |
255 | ||
256 | /** | |
257 | * Get the list of not-really-cid-refs that are currently hacked in. | |
258 | * | |
259 | * This is hacked into getCIDs function. | |
260 | * | |
261 | * @return array | |
262 | */ | |
263 | public function getHackedInCIDRef() { | |
264 | return array( | |
265 | 'civicrm_entity_tag' => array( | |
266 | 0 => 'entity_id', | |
267 | ), | |
268 | ); | |
269 | } | |
270 | ||
2988f5c7 | 271 | /** |
272 | * Test function that gets duplicate pairs. | |
273 | * | |
274 | * It turns out there are 2 code paths retrieving this data so my initial focus is on ensuring | |
275 | * they match. | |
276 | */ | |
277 | public function testGetMatches() { | |
278 | $this->setupMatchData(); | |
279 | $pairs = CRM_Dedupe_Merger::getDuplicatePairs( | |
280 | 1, | |
281 | NULL, | |
282 | TRUE, | |
283 | 25, | |
284 | FALSE | |
285 | ); | |
286 | ||
287 | $this->assertEquals(array( | |
288 | 0 => array( | |
08cde01f | 289 | 'srcID' => $this->contacts[1]['id'], |
2988f5c7 | 290 | 'srcName' => 'Mr. Mickey Mouse II', |
08cde01f | 291 | 'dstID' => $this->contacts[0]['id'], |
2988f5c7 | 292 | 'dstName' => 'Mr. Mickey Mouse II', |
293 | 'weight' => 20, | |
294 | 'canMerge' => TRUE, | |
295 | ), | |
3308aac0 | 296 | 1 => array( |
08cde01f | 297 | 'srcID' => $this->contacts[3]['id'], |
3308aac0 | 298 | 'srcName' => 'Mr. Minnie Mouse II', |
08cde01f | 299 | 'dstID' => $this->contacts[2]['id'], |
3308aac0 | 300 | 'dstName' => 'Mr. Minnie Mouse II', |
301 | 'weight' => 20, | |
302 | 'canMerge' => TRUE, | |
303 | ), | |
2988f5c7 | 304 | ), $pairs); |
305 | } | |
306 | ||
bc0f3965 | 307 | /** |
308 | * Test function that gets organization pairs. | |
309 | * | |
310 | * Note the rule will match on organization_name OR email - hence lots of matches. | |
311 | */ | |
312 | public function testGetOrganizationMatches() { | |
313 | $this->setupMatchData(); | |
314 | $ruleGroups = $this->callAPISuccessGetSingle('RuleGroup', array('contact_type' => 'Organization', 'used' => 'Supervised')); | |
315 | ||
316 | $pairs = CRM_Dedupe_Merger::getDuplicatePairs( | |
317 | $ruleGroups['id'], | |
318 | NULL, | |
319 | TRUE, | |
320 | 25, | |
321 | FALSE | |
322 | ); | |
323 | ||
72475b30 | 324 | $expectedPairs = array( |
bc0f3965 | 325 | 0 => array( |
326 | 'srcID' => $this->contacts[5]['id'], | |
327 | 'srcName' => 'Walt Disney Ltd', | |
328 | 'dstID' => $this->contacts[4]['id'], | |
329 | 'dstName' => 'Walt Disney Ltd', | |
330 | 'weight' => 20, | |
331 | 'canMerge' => TRUE, | |
332 | ), | |
333 | 1 => array( | |
334 | 'srcID' => $this->contacts[7]['id'], | |
335 | 'srcName' => 'Walt Disney', | |
336 | 'dstID' => $this->contacts[6]['id'], | |
337 | 'dstName' => 'Walt Disney', | |
338 | 'weight' => 10, | |
339 | 'canMerge' => TRUE, | |
340 | ), | |
341 | 2 => array( | |
342 | 'srcID' => $this->contacts[6]['id'], | |
343 | 'srcName' => 'Walt Disney', | |
344 | 'dstID' => $this->contacts[4]['id'], | |
345 | 'dstName' => 'Walt Disney Ltd', | |
346 | 'weight' => 10, | |
347 | 'canMerge' => TRUE, | |
348 | ), | |
349 | 3 => array( | |
350 | 'srcID' => $this->contacts[6]['id'], | |
351 | 'srcName' => 'Walt Disney', | |
352 | 'dstID' => $this->contacts[5]['id'], | |
353 | 'dstName' => 'Walt Disney Ltd', | |
354 | 'weight' => 10, | |
355 | 'canMerge' => TRUE, | |
356 | ), | |
72475b30 TO |
357 | ); |
358 | usort($pairs, array(__CLASS__, 'compareDupes')); | |
359 | usort($expectedPairs, array(__CLASS__, 'compareDupes')); | |
360 | $this->assertEquals($expectedPairs, $pairs); | |
361 | } | |
362 | ||
363 | /** | |
364 | * Function to sort $duplicate records in a stable way. | |
365 | * | |
366 | * @param array $a | |
367 | * @param array $b | |
368 | * @return int | |
369 | */ | |
370 | public static function compareDupes($a, $b) { | |
371 | foreach (array('srcName', 'dstName', 'srcID', 'dstID') as $field) { | |
372 | if ($a[$field] != $b[$field]) { | |
373 | return ($a[$field] < $b[$field]) ? 1 : -1; | |
374 | } | |
375 | } | |
376 | return 0; | |
bc0f3965 | 377 | } |
378 | ||
379 | /** | |
380 | * Test function that gets organization duplicate pairs. | |
381 | */ | |
382 | public function testGetOrganizationMatchesInGroup() { | |
383 | $this->setupMatchData(); | |
384 | $ruleGroups = $this->callAPISuccessGetSingle('RuleGroup', array('contact_type' => 'Organization', 'used' => 'Supervised')); | |
385 | ||
386 | $groupID = $this->groupCreate(array('title' => 'she-mice')); | |
387 | ||
388 | $this->callAPISuccess('GroupContact', 'create', array('group_id' => $groupID, 'contact_id' => $this->contacts[4]['id'])); | |
389 | ||
390 | $pairs = CRM_Dedupe_Merger::getDuplicatePairs( | |
391 | $ruleGroups['id'], | |
392 | $groupID, | |
393 | TRUE, | |
394 | 25, | |
395 | FALSE | |
396 | ); | |
397 | ||
398 | $this->assertEquals(array( | |
399 | 0 => array( | |
400 | 'srcID' => $this->contacts[5]['id'], | |
401 | 'srcName' => 'Walt Disney Ltd', | |
402 | 'dstID' => $this->contacts[4]['id'], | |
403 | 'dstName' => 'Walt Disney Ltd', | |
404 | 'weight' => 20, | |
405 | 'canMerge' => TRUE, | |
406 | ), | |
407 | 1 => array( | |
408 | 'srcID' => $this->contacts[6]['id'], | |
409 | 'srcName' => 'Walt Disney', | |
410 | 'dstID' => $this->contacts[4]['id'], | |
411 | 'dstName' => 'Walt Disney Ltd', | |
412 | 'weight' => 10, | |
413 | 'canMerge' => TRUE, | |
414 | ), | |
415 | ), $pairs); | |
be61083d | 416 | |
417 | $this->callAPISuccess('GroupContact', 'create', array('group_id' => $groupID, 'contact_id' => $this->contacts[5]['id'])); | |
418 | CRM_Core_DAO::executeQuery("DELETE FROM civicrm_prevnext_cache"); | |
419 | $pairs = CRM_Dedupe_Merger::getDuplicatePairs( | |
420 | $ruleGroups['id'], | |
421 | $groupID, | |
422 | TRUE, | |
423 | 25, | |
424 | FALSE | |
425 | ); | |
426 | ||
427 | $this->assertEquals(array( | |
428 | 0 => array( | |
429 | 'srcID' => $this->contacts[5]['id'], | |
430 | 'srcName' => 'Walt Disney Ltd', | |
431 | 'dstID' => $this->contacts[4]['id'], | |
432 | 'dstName' => 'Walt Disney Ltd', | |
433 | 'weight' => 20, | |
434 | 'canMerge' => TRUE, | |
435 | ), | |
436 | 1 => array( | |
437 | 'srcID' => $this->contacts[6]['id'], | |
438 | 'srcName' => 'Walt Disney', | |
439 | 'dstID' => $this->contacts[4]['id'], | |
440 | 'dstName' => 'Walt Disney Ltd', | |
441 | 'weight' => 10, | |
442 | 'canMerge' => TRUE, | |
443 | ), | |
444 | 2 => array( | |
445 | 'srcID' => $this->contacts[6]['id'], | |
446 | 'srcName' => 'Walt Disney', | |
447 | 'dstID' => $this->contacts[5]['id'], | |
448 | 'dstName' => 'Walt Disney Ltd', | |
449 | 'weight' => 10, | |
450 | 'canMerge' => TRUE, | |
451 | ), | |
452 | ), $pairs); | |
bc0f3965 | 453 | } |
454 | ||
3308aac0 | 455 | /** |
456 | * Test function that gets duplicate pairs. | |
457 | * | |
458 | * It turns out there are 2 code paths retrieving this data so my initial focus is on ensuring | |
459 | * they match. | |
460 | */ | |
461 | public function testGetMatchesInGroup() { | |
462 | $this->setupMatchData(); | |
463 | ||
464 | $groupID = $this->groupCreate(array('title' => 'she-mice')); | |
465 | ||
466 | $this->callAPISuccess('GroupContact', 'create', array('group_id' => $groupID, 'contact_id' => $this->contacts[3]['id'])); | |
467 | ||
468 | $pairs = CRM_Dedupe_Merger::getDuplicatePairs( | |
469 | 1, | |
470 | $groupID, | |
471 | TRUE, | |
472 | 25, | |
473 | FALSE | |
474 | ); | |
475 | ||
476 | $this->assertEquals(array( | |
477 | 0 => array( | |
478 | 'srcID' => $this->contacts[3]['id'], | |
479 | 'srcName' => 'Mr. Minnie Mouse II', | |
480 | 'dstID' => $this->contacts[2]['id'], | |
481 | 'dstName' => 'Mr. Minnie Mouse II', | |
482 | 'weight' => 20, | |
483 | 'canMerge' => TRUE, | |
484 | ), | |
485 | ), $pairs); | |
486 | } | |
487 | ||
0608e1e0 | 488 | /** |
489 | * Test the special info handling is unchanged after cleanup. | |
490 | * | |
491 | * Note the handling is silly - we are testing to lock in over short term changes not to imply any contract on the | |
492 | * function. | |
493 | */ | |
494 | public function testgetRowsElementsAndInfoSpecialInfo() { | |
495 | $contact1 = $this->individualCreate(['preferred_communication_method' => [], 'communication_style_id' => 'Familiar', 'prefix_id' => 'Mrs.', 'suffix_id' => 'III']); | |
496 | $contact2 = $this->individualCreate(['preferred_communication_method' => ['SMS', 'Fax'], 'communication_style_id' => 'Formal', 'gender_id' => 'Female']); | |
497 | $rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($contact1, $contact2); | |
498 | $rows = $rowsElementsAndInfo['rows']; | |
499 | $this->assertEquals(['main' => 'Mrs.', 'other' => 'Mr.', 'title' => 'Individual Prefix'], $rows['move_prefix_id']); | |
500 | $this->assertEquals(['main' => 'III', 'other' => 'II', 'title' => 'Individual Suffix'], $rows['move_suffix_id']); | |
501 | $this->assertEquals(['main' => '', 'other' => 'Female', 'title' => 'Gender'], $rows['move_gender_id']); | |
502 | $this->assertEquals(['main' => 'Familiar', 'other' => 'Formal', 'title' => 'Communication Style'], $rows['move_communication_style_id']); | |
503 | $this->assertEquals(1, $rowsElementsAndInfo['migration_info']['move_communication_style_id']); | |
504 | $this->assertEquals(['main' => '', 'other' => 'SMS, Fax', 'title' => 'Preferred Communication Method'], $rows['move_preferred_communication_method']); | |
505 | $this->assertEquals('\ 14\ 15\ 1', $rowsElementsAndInfo['migration_info']['move_preferred_communication_method']); | |
506 | } | |
507 | ||
c231c0dd JP |
508 | /** |
509 | * Test migration of Membership. | |
510 | */ | |
511 | public function testMergeMembership() { | |
512 | // Contacts setup | |
513 | $this->setupMatchData(); | |
514 | $originalContactID = $this->contacts[0]['id']; | |
515 | $duplicateContactID = $this->contacts[1]['id']; | |
516 | ||
517 | //Add Membership for the duplicate contact. | |
518 | $memTypeId = $this->membershipTypeCreate(); | |
519 | $membership = $this->callAPISuccess('Membership', 'create', [ | |
520 | 'membership_type_id' => $memTypeId, | |
521 | 'contact_id' => $duplicateContactID, | |
522 | ]); | |
523 | //Assert if 'add new' checkbox is enabled on the merge form. | |
524 | $rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($originalContactID, $duplicateContactID); | |
525 | foreach ($rowsElementsAndInfo['elements'] as $element) { | |
526 | if (!empty($element[3]) && $element[3] == 'add new') { | |
527 | $checkedAttr = ['checked' => 'checked']; | |
528 | $this->checkArrayEquals($element[4], $checkedAttr); | |
529 | } | |
530 | } | |
531 | ||
532 | //Merge and move the mem to the main contact. | |
533 | $this->mergeContacts($originalContactID, $duplicateContactID, [ | |
534 | 'move_rel_table_memberships' => 1, | |
39b959db | 535 | 'operation' => ['move_rel_table_memberships' => ['add' => 1]], |
c231c0dd JP |
536 | ]); |
537 | ||
538 | //Check if membership is correctly transferred to original contact. | |
539 | $originalContactMembership = $this->callAPISuccess('Membership', 'get', [ | |
540 | 'membership_type_id' => $memTypeId, | |
541 | 'contact_id' => $originalContactID, | |
542 | ]); | |
543 | $this->assertEquals(1, $originalContactMembership['count']); | |
544 | } | |
545 | ||
0946ab3f | 546 | /** |
547 | * CRM-19653 : Test that custom field data should/shouldn't be overriden on | |
548 | * selecting/not selecting option to migrate data respectively | |
549 | */ | |
550 | public function testCustomDataOverwrite() { | |
dba77ae8 CR |
551 | // Create Custom Field |
552 | $createGroup = $this->setupCustomGroupForIndividual(); | |
553 | $createField = $this->setupCustomField('Graduation', $createGroup); | |
554 | $customFieldName = "custom_" . $createField['id']; | |
555 | ||
556 | // Contacts setup | |
0946ab3f | 557 | $this->setupMatchData(); |
558 | ||
559 | $originalContactID = $this->contacts[0]['id']; | |
39b959db SL |
560 | // used as duplicate contact in 1st use-case |
561 | $duplicateContactID1 = $this->contacts[1]['id']; | |
562 | // used as duplicate contact in 2nd use-case | |
563 | $duplicateContactID2 = $this->contacts[2]['id']; | |
0946ab3f | 564 | |
0946ab3f | 565 | // update the text custom field for original contact with value 'abc' |
566 | $this->callAPISuccess('Contact', 'create', array( | |
567 | 'id' => $originalContactID, | |
dba77ae8 | 568 | "{$customFieldName}" => 'abc', |
0946ab3f | 569 | )); |
dba77ae8 CR |
570 | $this->assertCustomFieldValue($originalContactID, 'abc', $customFieldName); |
571 | ||
0946ab3f | 572 | // update the text custom field for duplicate contact 1 with value 'def' |
573 | $this->callAPISuccess('Contact', 'create', array( | |
574 | 'id' => $duplicateContactID1, | |
dba77ae8 | 575 | "{$customFieldName}" => 'def', |
0946ab3f | 576 | )); |
dba77ae8 CR |
577 | $this->assertCustomFieldValue($duplicateContactID1, 'def', $customFieldName); |
578 | ||
0946ab3f | 579 | // update the text custom field for duplicate contact 2 with value 'ghi' |
580 | $this->callAPISuccess('Contact', 'create', array( | |
581 | 'id' => $duplicateContactID2, | |
dba77ae8 | 582 | "{$customFieldName}" => 'ghi', |
0946ab3f | 583 | )); |
dba77ae8 | 584 | $this->assertCustomFieldValue($duplicateContactID2, 'ghi', $customFieldName); |
0946ab3f | 585 | |
586 | /*** USE-CASE 1: DO NOT OVERWRITE CUSTOM FIELD VALUE **/ | |
dba77ae8 | 587 | $this->mergeContacts($originalContactID, $duplicateContactID1, array( |
39b959db | 588 | "move_{$customFieldName}" => NULL, |
0946ab3f | 589 | )); |
dba77ae8 | 590 | $this->assertCustomFieldValue($originalContactID, 'abc', $customFieldName); |
0946ab3f | 591 | |
592 | /*** USE-CASE 2: OVERWRITE CUSTOM FIELD VALUE **/ | |
dba77ae8 CR |
593 | $this->mergeContacts($originalContactID, $duplicateContactID2, array( |
594 | "move_{$customFieldName}" => 'ghi', | |
595 | )); | |
596 | $this->assertCustomFieldValue($originalContactID, 'ghi', $customFieldName); | |
597 | ||
598 | // cleanup created custom set | |
599 | $this->callAPISuccess('CustomField', 'delete', array('id' => $createField['id'])); | |
600 | $this->callAPISuccess('CustomGroup', 'delete', array('id' => $createGroup['id'])); | |
601 | } | |
602 | ||
603 | /** | |
604 | * Verifies that when a contact with a custom field value is merged into a | |
605 | * contact without a record int its corresponding custom group table, and none | |
606 | * of the custom fields of that custom table are selected, the value is not | |
607 | * merged in. | |
608 | */ | |
609 | public function testMigrationOfUnselectedCustomDataOnEmptyCustomRecord() { | |
610 | // Create Custom Fields | |
611 | $createGroup = $this->setupCustomGroupForIndividual(); | |
612 | $customField1 = $this->setupCustomField('TestField', $createGroup); | |
613 | ||
c1955865 J |
614 | // Create multi-value custom field |
615 | $multiGroup = $this->CustomGroupMultipleCreateByParams(); | |
616 | $multiField = $this->customFieldCreate(array( | |
617 | 'custom_group_id' => $multiGroup['id'], | |
618 | 'label' => 'field_1' . $multiGroup['id'], | |
619 | 'in_selector' => 1, | |
620 | )); | |
621 | ||
dba77ae8 CR |
622 | // Contacts setup |
623 | $this->setupMatchData(); | |
624 | $originalContactID = $this->contacts[0]['id']; | |
625 | $duplicateContactID = $this->contacts[1]['id']; | |
626 | ||
627 | // Update the text custom fields for duplicate contact | |
628 | $this->callAPISuccess('Contact', 'create', array( | |
629 | 'id' => $duplicateContactID, | |
630 | "custom_{$customField1['id']}" => 'abc', | |
c1955865 | 631 | "custom_{$multiField['id']}" => 'def', |
dba77ae8 CR |
632 | )); |
633 | $this->assertCustomFieldValue($duplicateContactID, 'abc', "custom_{$customField1['id']}"); | |
c1955865 | 634 | $this->assertCustomFieldValue($duplicateContactID, 'def', "custom_{$multiField['id']}"); |
dba77ae8 | 635 | |
c1955865 | 636 | // Merge, and ensure that no value was migrated |
dba77ae8 | 637 | $this->mergeContacts($originalContactID, $duplicateContactID, array( |
ee3b1d86 | 638 | "move_custom_{$customField1['id']}" => NULL, |
c1955865 | 639 | "move_rel_table_custom_{$multiGroup['id']}" => NULL, |
dba77ae8 CR |
640 | )); |
641 | $this->assertCustomFieldValue($originalContactID, '', "custom_{$customField1['id']}"); | |
c1955865 | 642 | $this->assertCustomFieldValue($originalContactID, '', "custom_{$multiField['id']}"); |
dba77ae8 CR |
643 | |
644 | // cleanup created custom set | |
645 | $this->callAPISuccess('CustomField', 'delete', array('id' => $customField1['id'])); | |
646 | $this->callAPISuccess('CustomGroup', 'delete', array('id' => $createGroup['id'])); | |
c1955865 J |
647 | $this->callAPISuccess('CustomField', 'delete', array('id' => $multiField['id'])); |
648 | $this->callAPISuccess('CustomGroup', 'delete', array('id' => $multiGroup['id'])); | |
dba77ae8 CR |
649 | } |
650 | ||
651 | /** | |
652 | * Tests that if only part of the custom fields of a custom group are selected | |
653 | * for a merge, only those values are merged, while all other fields of the | |
654 | * custom group retain their original value, specifically for a contact with | |
655 | * no records on the custom group table. | |
656 | */ | |
657 | public function testMigrationOfSomeCustomDataOnEmptyCustomRecord() { | |
658 | // Create Custom Fields | |
659 | $createGroup = $this->setupCustomGroupForIndividual(); | |
660 | $customField1 = $this->setupCustomField('Test1', $createGroup); | |
661 | $customField2 = $this->setupCustomField('Test2', $createGroup); | |
662 | ||
c1955865 J |
663 | // Create multi-value custom field |
664 | $multiGroup = $this->CustomGroupMultipleCreateByParams(); | |
665 | $multiField = $this->customFieldCreate(array( | |
666 | 'custom_group_id' => $multiGroup['id'], | |
667 | 'label' => 'field_1' . $multiGroup['id'], | |
668 | 'in_selector' => 1, | |
669 | )); | |
670 | ||
dba77ae8 CR |
671 | // Contacts setup |
672 | $this->setupMatchData(); | |
673 | $originalContactID = $this->contacts[0]['id']; | |
674 | $duplicateContactID = $this->contacts[1]['id']; | |
675 | ||
676 | // Update the text custom fields for duplicate contact | |
677 | $this->callAPISuccess('Contact', 'create', array( | |
678 | 'id' => $duplicateContactID, | |
679 | "custom_{$customField1['id']}" => 'abc', | |
680 | "custom_{$customField2['id']}" => 'def', | |
c1955865 | 681 | "custom_{$multiField['id']}" => 'ghi', |
dba77ae8 CR |
682 | )); |
683 | $this->assertCustomFieldValue($duplicateContactID, 'abc', "custom_{$customField1['id']}"); | |
684 | $this->assertCustomFieldValue($duplicateContactID, 'def', "custom_{$customField2['id']}"); | |
c1955865 | 685 | $this->assertCustomFieldValue($duplicateContactID, 'ghi', "custom_{$multiField['id']}"); |
dba77ae8 CR |
686 | |
687 | // Perform merge | |
688 | $this->mergeContacts($originalContactID, $duplicateContactID, array( | |
ee3b1d86 | 689 | "move_custom_{$customField1['id']}" => NULL, |
dba77ae8 | 690 | "move_custom_{$customField2['id']}" => 'def', |
c1955865 | 691 | "move_rel_table_custom_{$multiGroup['id']}" => '1', |
dba77ae8 CR |
692 | )); |
693 | $this->assertCustomFieldValue($originalContactID, '', "custom_{$customField1['id']}"); | |
694 | $this->assertCustomFieldValue($originalContactID, 'def', "custom_{$customField2['id']}"); | |
c1955865 | 695 | $this->assertCustomFieldValue($originalContactID, 'ghi', "custom_{$multiField['id']}"); |
dba77ae8 CR |
696 | |
697 | // cleanup created custom set | |
698 | $this->callAPISuccess('CustomField', 'delete', array('id' => $customField1['id'])); | |
699 | $this->callAPISuccess('CustomField', 'delete', array('id' => $customField2['id'])); | |
700 | $this->callAPISuccess('CustomGroup', 'delete', array('id' => $createGroup['id'])); | |
c1955865 J |
701 | $this->callAPISuccess('CustomField', 'delete', array('id' => $multiField['id'])); |
702 | $this->callAPISuccess('CustomGroup', 'delete', array('id' => $multiGroup['id'])); | |
dba77ae8 CR |
703 | } |
704 | ||
705 | /** | |
706 | * Calls merge method on given contacts, with values given in $params array. | |
707 | * | |
708 | * @param $originalContactID | |
709 | * ID of target contact | |
710 | * @param $duplicateContactID | |
711 | * ID of contact to be merged | |
712 | * @param $params | |
713 | * Array of fields to be merged from source into target contact, of the form | |
714 | * ['move_<fieldName>' => <fieldValue>] | |
715 | */ | |
716 | private function mergeContacts($originalContactID, $duplicateContactID, $params) { | |
717 | $rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($originalContactID, $duplicateContactID); | |
718 | ||
0946ab3f | 719 | $migrationData = array( |
720 | 'main_details' => $rowsElementsAndInfo['main_details'], | |
721 | 'other_details' => $rowsElementsAndInfo['other_details'], | |
0946ab3f | 722 | ); |
dba77ae8 CR |
723 | |
724 | // Migrate data of duplicate contact | |
725 | CRM_Dedupe_Merger::moveAllBelongings($originalContactID, $duplicateContactID, array_merge($migrationData, $params)); | |
726 | } | |
727 | ||
728 | /** | |
729 | * Checks if the expected value for the given field corresponds to what is | |
730 | * stored in the database for the given contact ID. | |
731 | * | |
732 | * @param $contactID | |
733 | * @param $expectedValue | |
734 | * @param $customFieldName | |
735 | */ | |
736 | private function assertCustomFieldValue($contactID, $expectedValue, $customFieldName) { | |
0946ab3f | 737 | $data = $this->callAPISuccess('Contact', 'getsingle', array( |
dba77ae8 | 738 | 'id' => $contactID, |
0946ab3f | 739 | 'return' => array($customFieldName), |
740 | )); | |
0946ab3f | 741 | |
dba77ae8 CR |
742 | $this->assertEquals($expectedValue, $data[$customFieldName], "Custom field value was supposed to be '{$expectedValue}', '{$data[$customFieldName]}' found."); |
743 | } | |
744 | ||
745 | /** | |
746 | * Creates a custom group to run tests on contacts that are individuals. | |
747 | * | |
748 | * @return array | |
749 | * Data for the created custom group record | |
750 | */ | |
751 | private function setupCustomGroupForIndividual() { | |
752 | $customGroup = $this->callAPISuccess('custom_group', 'get', array( | |
753 | 'name' => 'test_group', | |
754 | )); | |
755 | ||
756 | if ($customGroup['count'] > 0) { | |
757 | $this->callAPISuccess('CustomGroup', 'delete', array('id' => $customGroup['id'])); | |
758 | } | |
759 | ||
760 | $customGroup = $this->callAPISuccess('custom_group', 'create', array( | |
761 | 'title' => 'Test_Group', | |
762 | 'name' => 'test_group', | |
763 | 'extends' => array('Individual'), | |
764 | 'style' => 'Inline', | |
765 | 'is_multiple' => FALSE, | |
766 | 'is_active' => 1, | |
767 | )); | |
768 | ||
769 | return $customGroup; | |
770 | } | |
771 | ||
772 | /** | |
773 | * Creates a custom field on the provided custom group with the given field | |
774 | * label. | |
775 | * | |
776 | * @param $fieldLabel | |
777 | * @param $createGroup | |
778 | * | |
779 | * @return array | |
780 | * Data for the created custom field record | |
781 | */ | |
782 | private function setupCustomField($fieldLabel, $createGroup) { | |
783 | return $this->callAPISuccess('custom_field', 'create', array( | |
784 | 'label' => $fieldLabel, | |
785 | 'data_type' => 'Alphanumeric', | |
786 | 'html_type' => 'Text', | |
787 | 'custom_group_id' => $createGroup['id'], | |
788 | )); | |
0946ab3f | 789 | } |
790 | ||
3308aac0 | 791 | /** |
792 | * Set up some contacts for our matching. | |
793 | */ | |
2988f5c7 | 794 | public function setupMatchData() { |
795 | $fixtures = array( | |
796 | array( | |
797 | 'first_name' => 'Mickey', | |
798 | 'last_name' => 'Mouse', | |
799 | 'email' => 'mickey@mouse.com', | |
800 | ), | |
801 | array( | |
802 | 'first_name' => 'Mickey', | |
803 | 'last_name' => 'Mouse', | |
804 | 'email' => 'mickey@mouse.com', | |
805 | ), | |
806 | array( | |
807 | 'first_name' => 'Minnie', | |
808 | 'last_name' => 'Mouse', | |
809 | 'email' => 'mickey@mouse.com', | |
810 | ), | |
3308aac0 | 811 | array( |
812 | 'first_name' => 'Minnie', | |
813 | 'last_name' => 'Mouse', | |
814 | 'email' => 'mickey@mouse.com', | |
815 | ), | |
2988f5c7 | 816 | ); |
817 | foreach ($fixtures as $fixture) { | |
818 | $contactID = $this->individualCreate($fixture); | |
819 | $this->contacts[] = array_merge($fixture, array('id' => $contactID)); | |
bc0f3965 | 820 | } |
821 | $organizationFixtures = array( | |
822 | array( | |
823 | 'organization_name' => 'Walt Disney Ltd', | |
824 | 'email' => 'walt@disney.com', | |
825 | ), | |
826 | array( | |
827 | 'organization_name' => 'Walt Disney Ltd', | |
828 | 'email' => 'walt@disney.com', | |
829 | ), | |
830 | array( | |
831 | 'organization_name' => 'Walt Disney', | |
832 | 'email' => 'walt@disney.com', | |
833 | ), | |
834 | array( | |
835 | 'organization_name' => 'Walt Disney', | |
836 | 'email' => 'walter@disney.com', | |
837 | ), | |
838 | ); | |
839 | foreach ($organizationFixtures as $fixture) { | |
840 | $contactID = $this->organizationCreate($fixture); | |
841 | $this->contacts[] = array_merge($fixture, array('id' => $contactID)); | |
2988f5c7 | 842 | } |
843 | } | |
844 | ||
bf17fa88 | 845 | /** |
846 | * Get the list of tables that refer to the CID. | |
847 | * | |
848 | * This is a statically maintained (in this test list). | |
849 | * | |
850 | * There is also a check against an automated list but having both seems to add extra stability to me. They do | |
851 | * not change often. | |
852 | */ | |
853 | public function getStaticCIDRefs() { | |
854 | return array( | |
855 | 'civicrm_acl_cache' => array( | |
856 | 0 => 'contact_id', | |
857 | ), | |
858 | 'civicrm_acl_contact_cache' => array( | |
dbb4e4f9 | 859 | 0 => 'contact_id', |
bf17fa88 | 860 | ), |
861 | 'civicrm_action_log' => array( | |
862 | 0 => 'contact_id', | |
863 | ), | |
864 | 'civicrm_activity_contact' => array( | |
865 | 0 => 'contact_id', | |
866 | ), | |
867 | 'civicrm_address' => array( | |
868 | 0 => 'contact_id', | |
869 | ), | |
870 | 'civicrm_batch' => array( | |
871 | 0 => 'created_id', | |
872 | 1 => 'modified_id', | |
873 | ), | |
874 | 'civicrm_campaign' => array( | |
875 | 0 => 'created_id', | |
876 | 1 => 'last_modified_id', | |
877 | ), | |
878 | 'civicrm_case_contact' => array( | |
879 | 0 => 'contact_id', | |
880 | ), | |
881 | 'civicrm_contact' => array( | |
882 | 0 => 'primary_contact_id', | |
883 | 1 => 'employer_id', | |
884 | ), | |
885 | 'civicrm_contribution' => array( | |
886 | 0 => 'contact_id', | |
887 | ), | |
888 | 'civicrm_contribution_page' => array( | |
889 | 0 => 'created_id', | |
890 | ), | |
891 | 'civicrm_contribution_recur' => array( | |
892 | 0 => 'contact_id', | |
893 | ), | |
894 | 'civicrm_contribution_soft' => array( | |
895 | 0 => 'contact_id', | |
896 | ), | |
897 | 'civicrm_custom_group' => array( | |
898 | 0 => 'created_id', | |
899 | ), | |
900 | 'civicrm_dashboard_contact' => array( | |
901 | 0 => 'contact_id', | |
902 | ), | |
903 | 'civicrm_dedupe_exception' => array( | |
904 | 0 => 'contact_id1', | |
905 | 1 => 'contact_id2', | |
906 | ), | |
907 | 'civicrm_domain' => array( | |
908 | 0 => 'contact_id', | |
909 | ), | |
910 | 'civicrm_email' => array( | |
911 | 0 => 'contact_id', | |
912 | ), | |
913 | 'civicrm_event' => array( | |
914 | 0 => 'created_id', | |
915 | ), | |
916 | 'civicrm_event_carts' => array( | |
917 | 0 => 'user_id', | |
918 | ), | |
919 | 'civicrm_financial_account' => array( | |
920 | 0 => 'contact_id', | |
921 | ), | |
922 | 'civicrm_financial_item' => array( | |
923 | 0 => 'contact_id', | |
924 | ), | |
925 | 'civicrm_grant' => array( | |
926 | 0 => 'contact_id', | |
927 | ), | |
928 | 'civicrm_group' => array( | |
929 | 0 => 'created_id', | |
930 | 1 => 'modified_id', | |
931 | ), | |
932 | 'civicrm_group_contact' => array( | |
933 | 0 => 'contact_id', | |
934 | ), | |
935 | 'civicrm_group_contact_cache' => array( | |
936 | 0 => 'contact_id', | |
937 | ), | |
938 | 'civicrm_group_organization' => array( | |
939 | 0 => 'organization_id', | |
940 | ), | |
941 | 'civicrm_im' => array( | |
942 | 0 => 'contact_id', | |
943 | ), | |
944 | 'civicrm_log' => array( | |
945 | 0 => 'modified_id', | |
946 | ), | |
947 | 'civicrm_mailing' => array( | |
948 | 0 => 'created_id', | |
949 | 1 => 'scheduled_id', | |
950 | 2 => 'approver_id', | |
951 | ), | |
ae2c7e00 | 952 | 'civicrm_file' => array( |
953 | 'created_id', | |
954 | ), | |
bf17fa88 | 955 | 'civicrm_mailing_abtest' => array( |
956 | 0 => 'created_id', | |
957 | ), | |
958 | 'civicrm_mailing_event_queue' => array( | |
959 | 0 => 'contact_id', | |
960 | ), | |
961 | 'civicrm_mailing_event_subscribe' => array( | |
962 | 0 => 'contact_id', | |
963 | ), | |
964 | 'civicrm_mailing_recipients' => array( | |
965 | 0 => 'contact_id', | |
966 | ), | |
967 | 'civicrm_membership' => array( | |
968 | 0 => 'contact_id', | |
969 | ), | |
970 | 'civicrm_membership_log' => array( | |
971 | 0 => 'modified_id', | |
972 | ), | |
973 | 'civicrm_membership_type' => array( | |
974 | 0 => 'member_of_contact_id', | |
975 | ), | |
976 | 'civicrm_note' => array( | |
977 | 0 => 'contact_id', | |
978 | ), | |
979 | 'civicrm_openid' => array( | |
980 | 0 => 'contact_id', | |
981 | ), | |
982 | 'civicrm_participant' => array( | |
983 | 0 => 'contact_id', | |
39b959db SL |
984 | //CRM-16761 |
985 | 1 => 'transferred_to_contact_id', | |
bf17fa88 | 986 | ), |
987 | 'civicrm_payment_token' => array( | |
988 | 0 => 'contact_id', | |
989 | 1 => 'created_id', | |
990 | ), | |
991 | 'civicrm_pcp' => array( | |
992 | 0 => 'contact_id', | |
993 | ), | |
994 | 'civicrm_phone' => array( | |
995 | 0 => 'contact_id', | |
996 | ), | |
997 | 'civicrm_pledge' => array( | |
998 | 0 => 'contact_id', | |
999 | ), | |
1000 | 'civicrm_print_label' => array( | |
1001 | 0 => 'created_id', | |
1002 | ), | |
1003 | 'civicrm_relationship' => array( | |
1004 | 0 => 'contact_id_a', | |
1005 | 1 => 'contact_id_b', | |
1006 | ), | |
1007 | 'civicrm_report_instance' => array( | |
1008 | 0 => 'created_id', | |
1009 | 1 => 'owner_id', | |
1010 | ), | |
1011 | 'civicrm_setting' => array( | |
1012 | 0 => 'contact_id', | |
1013 | 1 => 'created_id', | |
1014 | ), | |
1015 | 'civicrm_subscription_history' => array( | |
1016 | 0 => 'contact_id', | |
1017 | ), | |
1018 | 'civicrm_survey' => array( | |
1019 | 0 => 'created_id', | |
1020 | 1 => 'last_modified_id', | |
1021 | ), | |
1022 | 'civicrm_tag' => array( | |
1023 | 0 => 'created_id', | |
1024 | ), | |
1025 | 'civicrm_uf_group' => array( | |
1026 | 0 => 'created_id', | |
1027 | ), | |
1028 | 'civicrm_uf_match' => array( | |
1029 | 0 => 'contact_id', | |
1030 | ), | |
1031 | 'civicrm_value_testgetcidref_1' => array( | |
1032 | 0 => 'entity_id', | |
1033 | ), | |
1034 | 'civicrm_website' => array( | |
1035 | 0 => 'contact_id', | |
1036 | ), | |
1037 | ); | |
1038 | } | |
1039 | ||
1040 | /** | |
1041 | * Get a list of CIDs that is calculated off the schema. | |
1042 | * | |
1043 | * Note this is an expensive and table locking query. Should be safe in tests though. | |
1044 | */ | |
1045 | public function getCalculatedCIDRefs() { | |
1046 | $cidRefs = array(); | |
1047 | $sql = " | |
1048 | SELECT | |
1049 | table_name, | |
1050 | column_name | |
1051 | FROM information_schema.key_column_usage | |
1052 | WHERE | |
1053 | referenced_table_schema = database() AND | |
1054 | referenced_table_name = 'civicrm_contact' AND | |
1055 | referenced_column_name = 'id'; | |
1056 | "; | |
1057 | $dao = CRM_Core_DAO::executeQuery($sql); | |
1058 | while ($dao->fetch()) { | |
1059 | $cidRefs[$dao->table_name][] = $dao->column_name; | |
1060 | } | |
1061 | // Do specific re-ordering changes to make this the same as the ref validated one. | |
1062 | // The above query orders by FK alphabetically. | |
1063 | // There might be cleverer ways to do this but it shouldn't change much. | |
1064 | $cidRefs['civicrm_contact'][0] = 'primary_contact_id'; | |
1065 | $cidRefs['civicrm_contact'][1] = 'employer_id'; | |
dbb4e4f9 | 1066 | $cidRefs['civicrm_acl_contact_cache'][0] = 'contact_id'; |
bf17fa88 | 1067 | $cidRefs['civicrm_mailing'][0] = 'created_id'; |
1068 | $cidRefs['civicrm_mailing'][1] = 'scheduled_id'; | |
1069 | $cidRefs['civicrm_mailing'][2] = 'approver_id'; | |
1070 | return $cidRefs; | |
1071 | } | |
1072 | ||
0622d221 | 1073 | } |