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