Merge pull request #18242 from eileenmcnaughton/dep
[civicrm-core.git] / CRM / Dedupe / MergeHandler.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 * This class exists primarily for the purposes of supporting code clean up in the Merger class.
14 *
15 * It is expected to be fast-moving and calling it outside the refactoring work is not advised.
16 *
17 * @package CRM
18 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 */
20 class CRM_Dedupe_MergeHandler {
21
22 /**
23 * ID of contact to be kept.
24 *
25 * @var int
26 */
27 protected $toKeepID;
28
29 /**
30 * ID of contact to be merged and deleted.
31 *
32 * @var int
33 */
34 protected $toRemoveID;
35
36 /**
37 * @return mixed
38 */
39 public function getToKeepID() {
40 return $this->toKeepID;
41 }
42
43 /**
44 * @param mixed $toKeepID
45 */
46 public function setToKeepID($toKeepID) {
47 $this->toKeepID = $toKeepID;
48 }
49
50 /**
51 * @return mixed
52 */
53 public function getToRemoveID() {
54 return $this->toRemoveID;
55 }
56
57 /**
58 * @param mixed $toRemoveID
59 */
60 public function setToRemoveID($toRemoveID) {
61 $this->toRemoveID = $toRemoveID;
62 }
63
64 /**
65 * CRM_Dedupe_MergeHandler constructor.
66 *
67 * @param int $toKeepID
68 * ID of contact to be kept.
69 * @param int $toRemoveID
70 * ID of contact to be removed.
71 */
72 public function __construct(int $toKeepID, int $toRemoveID) {
73 $this->setToKeepID($toKeepID);
74 $this->setToRemoveID($toRemoveID);
75 }
76
77 /**
78 * Get an array of tables that relate to the contact entity and will need consideration in a merge.
79 *
80 * The list of potential tables is filtered by tables which have data for the relevant contacts.
81 */
82 public function getTablesRelatedToTheMergePair() {
83 $relTables = CRM_Dedupe_Merger::relTables();
84 $activeRelTables = CRM_Dedupe_Merger::getActiveRelTables($this->toRemoveID);
85 $activeMainRelTables = CRM_Dedupe_Merger::getActiveRelTables($this->toKeepID);
86 foreach ($relTables as $name => $null) {
87 if (!in_array($name, $activeRelTables, TRUE) &&
88 !(($name === 'rel_table_users') && in_array($name, $activeMainRelTables, TRUE))
89 ) {
90 unset($relTables[$name]);
91 }
92 }
93 return $relTables;
94 }
95
96 /**
97 * Get an array of tables that have a dynamic reference to the contact table.
98 *
99 * This would be the case when the table uses entity_table + entity_id rather than an FK.
100 *
101 * There are a number of tables that 'could' but don't have contact related data so we
102 * do a cached check for this, ensuring the query is only done once per batch run.
103 *
104 * @return array
105 */
106 public function getTablesDynamicallyRelatedToContactTable() {
107 if (!isset(\Civi::$statics[__CLASS__]['dynamic'])) {
108 \Civi::$statics[__CLASS__]['dynamic'] = [];
109 foreach (CRM_Core_DAO::getDynamicReferencesToTable('civicrm_contact') as $tableName => $fields) {
110 if ($tableName === 'civicrm_financial_item') {
111 // It turns out that civicrm_financial_item does not have an index on entity_table (only as the latter
112 // part of a entity_id/entity_table index which probably is not adding any value over & above entity_id
113 // only. This means this is a slow query. The correct fix is probably to add a whitelist to
114 // values for entity_table in the schema.
115 continue;
116 }
117 foreach ($fields as $field) {
118 $sql[] = "(SELECT '$tableName' as civicrm_table, '{$field[0]}' as field_name FROM $tableName WHERE {$field[1]} = 'civicrm_contact' LIMIT 1)";
119 }
120 }
121 $sqlString = implode(' UNION ', $sql);
122 if ($sqlString) {
123 $result = CRM_Core_DAO::executeQuery($sqlString);
124 while ($result->fetch()) {
125 \Civi::$statics[__CLASS__]['dynamic'][$result->civicrm_table] = $result->field_name;
126 }
127 }
128 }
129 return \Civi::$statics[__CLASS__]['dynamic'];
130 }
131
132 }