Ignore location_type_id for dedupe on import also
[civicrm-core.git] / CRM / Dedupe / MergeHandler.php
index b28c00630049248b75b74d845d1a355dba2d24c3..db454c0e70fc1a31aa2ad0e8a02f952b0dea5619 100644 (file)
@@ -110,4 +110,38 @@ class CRM_Dedupe_MergeHandler {
     return $relTables;
   }
 
+  /**
+   * Get an array of tables that have a dynamic reference to the contact table.
+   *
+   * This would be the case when the table uses entity_table + entity_id rather than an FK.
+   *
+   * There are a number of tables that 'could' but don't have contact related data so we
+   * do a cached check for this, ensuring the query is only done once per batch run.
+   *
+   * @return array
+   */
+  public function getTablesDynamicallyRelatedToContactTable() {
+    if (!isset(\Civi::$statics[__CLASS__]['dynamic'])) {
+      \Civi::$statics[__CLASS__]['dynamic'] = [];
+      foreach (CRM_Core_DAO::getDynamicReferencesToTable('civicrm_contact') as $tableName => $field) {
+        if ($tableName === 'civicrm_financial_item') {
+          // It turns out that civicrm_financial_item does not have an index on entity_table (only as the latter
+          // part of a entity_id/entity_table index which probably is not adding any value over & above entity_id
+          // only. This means this is a slow query. The correct fix is probably to add a whitelist to
+          // values for entity_table in the schema.
+          continue;
+        }
+        $sql[] = "(SELECT '$tableName' as civicrm_table, '{$field[0]}' as field_name FROM $tableName WHERE entity_table = 'civicrm_contact' LIMIT 1)";
+      }
+      $sqlString = implode(' UNION ', $sql);
+      if ($sqlString) {
+        $result = CRM_Core_DAO::executeQuery($sqlString);
+        while ($result->fetch()) {
+          \Civi::$statics[__CLASS__]['dynamic'][$result->civicrm_table] = $result->field_name;
+        }
+      }
+    }
+    return \Civi::$statics[__CLASS__]['dynamic'];
+  }
+
 }