From c507b8ff001768acdc37b1e77e73b7643cd5fc96 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Wed, 7 Sep 2022 11:25:13 +1200 Subject: [PATCH] [REF] Extract rule-loading function This makes it possible to load multiple dedupe rules at once --- CRM/Import/Parser.php | 123 ++++++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/CRM/Import/Parser.php b/CRM/Import/Parser.php index 63127ac0739c..cadaae9102ea 100644 --- a/CRM/Import/Parser.php +++ b/CRM/Import/Parser.php @@ -998,55 +998,24 @@ public function getDedupeRule(string $contactType, ?string $name = NULL): array $name = $this->getDefaultRuleForContactType($contactType); } if (empty($this->dedupeRules[$name])) { - $this->dedupeRules[$name] = (array) DedupeRuleGroup::get(FALSE) - ->addWhere('name', '=', $name) - ->addSelect('threshold', 'name', 'id', 'title', 'contact_type') - ->execute()->first(); - $fields = []; - $this->dedupeRules[$name]['rule_message'] = $fieldMessage = ''; - // Now we add the fields in a format like ['first_name' => 6, 'custom_8' => 9] - // The number is the weight and we add both api three & four style fields so the - // array can be used for converted & unconverted. - $ruleFields = DedupeRule::get(FALSE) - ->addWhere('dedupe_rule_group_id', '=', $this->dedupeRules[$name]['id']) - ->addSelect('id', 'rule_table', 'rule_field', 'rule_weight')->execute(); - foreach ($ruleFields as $ruleField) { - $fieldMessage .= ' ' . $ruleField['rule_field'] . '(weight ' . $ruleField['rule_weight'] . ')'; - if ($ruleField['rule_table'] === 'civicrm_contact') { - $fields[$ruleField['rule_field']] = $ruleField['rule_weight']; - } - // If not a contact field we add both api variants of fields. - elseif ($ruleField['rule_table'] === 'civicrm_phone') { - // Actually the dedupe rule for phone should always be phone_numeric. so checking 'phone' is probably unncessary - if (in_array($ruleField['rule_field'], ['phone', 'phone_numeric'], TRUE)) { - $fields['phone'] = $ruleField['rule_weight']; - $fields['phone_primary.phone'] = $ruleField['rule_weight']; - } - } - elseif ($ruleField['rule_field'] === 'email') { - $fields['email'] = $ruleField['rule_weight']; - $fields['email_primary.email'] = $ruleField['rule_weight']; - } - elseif ($ruleField['rule_table'] === 'civicrm_address') { - $fields[$ruleField['rule_field']] = $ruleField['rule_weight']; - $fields['address_primary' . $ruleField['rule_field']] = $ruleField['rule_weight']; - } - else { - // At this point it must be a custom field. - $customField = CustomField::get(FALSE)->addWhere('custom_group_id.table_name', '=', $ruleField['rule_table']) - ->addWhere('column_name', '=', $ruleField['rule_field']) - ->addSelect('id', 'name', 'custom_group_id.name')->execute()->first(); - $fields['custom_' . $customField['id']] = $ruleField['rule_weight']; - $fields[$customField['custom_group_id.name'] . '.' . $customField['name']] = $ruleField['rule_weight']; - } - } - $this->dedupeRules[$name]['rule_message'] = ts('Missing required contact matching fields.') . " $fieldMessage " . ts('(Sum of all weights should be greater than or equal to threshold: %1).', [1 => $this->dedupeRules[$name]['threshold']]) . '
'; - - $this->dedupeRules[$name]['fields'] = $fields; + $where = [['name', '=', $name]]; + $this->loadRules($where); } return $this->dedupeRules[$name]; } + /** + * Get all dedupe rules. + * + * @return array + * + * @throws \CRM_Core_Exception + */ + public function getAllDedupeRules(): array { + $this->loadRules(); + return $this->dedupeRules; + } + /** * This function adds the contact variable in $values to the * parameter list $params. For most cases, $values should have length 1. If @@ -2467,4 +2436,68 @@ protected function getAllContactFields(string $prefix = 'Contact.'): array { return $prefixedFields; } + /** + * @param array $where + * @param $name + * + * @return mixed + * @throws \API_Exception + * @throws \Civi\API\Exception\UnauthorizedException + */ + protected function loadRules(array $where = []) { + $rules = DedupeRuleGroup::get(FALSE) + ->setWhere($where) + ->addSelect('threshold', 'name', 'id', 'title', 'contact_type') + ->execute(); + foreach ($rules as $dedupeRule) { + $fields = []; + $name = $dedupeRule['name']; + $this->dedupeRules[$name] = $dedupeRule; + $this->dedupeRules[$name]['rule_message'] = $fieldMessage = ''; + // Now we add the fields in a format like ['first_name' => 6, 'custom_8' => 9] + // The number is the weight and we add both api three & four style fields so the + // array can be used for converted & unconverted. + $ruleFields = DedupeRule::get(FALSE) + ->addWhere('dedupe_rule_group_id', '=', $this->dedupeRules[$name]['id']) + ->addSelect('id', 'rule_table', 'rule_field', 'rule_weight') + ->execute(); + foreach ($ruleFields as $ruleField) { + $fieldMessage .= ' ' . $ruleField['rule_field'] . '(weight ' . $ruleField['rule_weight'] . ')'; + if ($ruleField['rule_table'] === 'civicrm_contact') { + $fields[$ruleField['rule_field']] = $ruleField['rule_weight']; + } + // If not a contact field we add both api variants of fields. + elseif ($ruleField['rule_table'] === 'civicrm_phone') { + // Actually the dedupe rule for phone should always be phone_numeric. so checking 'phone' is probably unncessary + if (in_array($ruleField['rule_field'], ['phone', 'phone_numeric'], TRUE)) { + $fields['phone'] = $ruleField['rule_weight']; + $fields['phone_primary.phone'] = $ruleField['rule_weight']; + } + } + elseif ($ruleField['rule_field'] === 'email') { + $fields['email'] = $ruleField['rule_weight']; + $fields['email_primary.email'] = $ruleField['rule_weight']; + } + elseif ($ruleField['rule_table'] === 'civicrm_address') { + $fields[$ruleField['rule_field']] = $ruleField['rule_weight']; + $fields['address_primary' . $ruleField['rule_field']] = $ruleField['rule_weight']; + } + else { + // At this point it must be a custom field. + $customField = CustomField::get(FALSE) + ->addWhere('custom_group_id.table_name', '=', $ruleField['rule_table']) + ->addWhere('column_name', '=', $ruleField['rule_field']) + ->addSelect('id', 'name', 'custom_group_id.name') + ->execute() + ->first(); + $fields['custom_' . $customField['id']] = $ruleField['rule_weight']; + $fields[$customField['custom_group_id.name'] . '.' . $customField['name']] = $ruleField['rule_weight']; + } + } + $this->dedupeRules[$name]['rule_message'] = ts('Missing required contact matching fields.') . " $fieldMessage " . ts('(Sum of all weights should be greater than or equal to threshold: %1).', [1 => $this->dedupeRules[$name]['threshold']]) . '
'; + + $this->dedupeRules[$name]['fields'] = $fields; + } + } + }