Cleanup references to old dedupe class names
[civicrm-core.git] / CRM / Import / Form / MapField.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 * @package CRM
14 * @copyright CiviCRM LLC https://civicrm.org/licensing
15 */
16
17 /**
18 * This class gets the name of the file to upload.
19 *
20 * TODO: CRM-11254 - There's still a lot of duplicate code in the 5 child classes that should be moved here
21 */
22 abstract class CRM_Import_Form_MapField extends CRM_Core_Form {
23
24 /**
25 * Cache of preview data values
26 *
27 * @var array
28 */
29 protected $_dataValues;
30
31 /**
32 * Mapper fields
33 *
34 * @var array
35 */
36 protected $_mapperFields;
37
38 /**
39 * Loaded mapping ID
40 *
41 * @var int
42 */
43 protected $_loadedMappingId;
44
45 /**
46 * Number of columns in import file
47 *
48 * @var int
49 */
50 protected $_columnCount;
51
52 /**
53 * Column headers, if we have them
54 *
55 * @var array
56 */
57 protected $_columnHeaders;
58
59 /**
60 * An array of booleans to keep track of whether a field has been used in
61 * form building already.
62 *
63 * @var array
64 */
65 protected $_fieldUsed;
66
67 /**
68 * Return a descriptive name for the page, used in wizard header.
69 *
70 * @return string
71 */
72 public function getTitle() {
73 return ts('Match Fields');
74 }
75
76 /**
77 * Attempt to match header labels with our mapper fields.
78 *
79 * @param string $header
80 * @param array $patterns
81 *
82 * @return string
83 */
84 public function defaultFromHeader($header, &$patterns) {
85 foreach ($patterns as $key => $re) {
86 // Skip empty key/patterns
87 if (!$key || !$re || strlen("$re") < 5) {
88 continue;
89 }
90
91 // Scan through the headerPatterns defined in the schema for a match
92 if (preg_match($re, $header)) {
93 $this->_fieldUsed[$key] = TRUE;
94 return $key;
95 }
96 }
97 return '';
98 }
99
100 /**
101 * Guess at the field names given the data and patterns from the schema.
102 *
103 * @param array $patterns
104 * @param string $index
105 *
106 * @return string
107 */
108 public function defaultFromData($patterns, $index) {
109 $best = '';
110 $bestHits = 0;
111 $n = count($this->_dataValues);
112
113 foreach ($patterns as $key => $re) {
114 // Skip empty key/patterns
115 if (!$key || !$re || strlen("$re") < 5) {
116 continue;
117 }
118
119 /* Take a vote over the preview data set */
120 $hits = 0;
121 for ($i = 0; $i < $n; $i++) {
122 if (isset($this->_dataValues[$i][$index])) {
123 if (preg_match($re, $this->_dataValues[$i][$index])) {
124 $hits++;
125 }
126 }
127 }
128 if ($hits > $bestHits) {
129 $bestHits = $hits;
130 $best = $key;
131 }
132 }
133
134 if ($best != '') {
135 $this->_fieldUsed[$best] = TRUE;
136 }
137 return $best;
138 }
139
140 /**
141 * Add the saved mapping fields to the form.
142 *
143 * @param int|null $savedMappingID
144 *
145 * @throws \CiviCRM_API3_Exception
146 */
147 protected function buildSavedMappingFields($savedMappingID) {
148 //to save the current mappings
149 if (!$savedMappingID) {
150 $saveDetailsName = ts('Save this field mapping');
151 $this->applyFilter('saveMappingName', 'trim');
152 $this->add('text', 'saveMappingName', ts('Name'));
153 $this->add('text', 'saveMappingDesc', ts('Description'));
154 }
155 else {
156 $savedMapping = $this->get('savedMapping');
157
158 $mappingName = (string) civicrm_api3('Mapping', 'getvalue', ['id' => $savedMappingID, 'return' => 'name']);
159 $this->set('loadedMapping', $savedMapping);
160 $this->assign('loadedMapping', $mappingName);
161 $this->assign('savedName', $mappingName);
162 $this->add('hidden', 'mappingId', $savedMappingID);
163
164 $this->addElement('checkbox', 'updateMapping', ts('Update this field mapping'), NULL);
165 $saveDetailsName = ts('Save as a new field mapping');
166 $this->add('text', 'saveMappingName', ts('Name'));
167 $this->add('text', 'saveMappingDesc', ts('Description'));
168 }
169
170 $this->addElement('checkbox', 'saveMapping', $saveDetailsName, NULL, ['onclick' => "showSaveDetails(this)"]);
171 }
172
173 /**
174 * Validate that sufficient fields have been supplied to match to a contact.
175 *
176 * @param string $contactType
177 * @param array $importKeys
178 *
179 * @return string
180 * Message if insufficient fields are present. Empty string otherwise.
181 */
182 protected static function validateRequiredContactMatchFields(string $contactType, array $importKeys): string {
183 [$ruleFields, $threshold] = CRM_Dedupe_BAO_DedupeRuleGroup::dedupeRuleFieldsWeight([
184 'used' => 'Unsupervised',
185 'contact_type' => $contactType,
186 ]);
187 $weightSum = 0;
188 foreach ($importKeys as $key => $val) {
189 if (array_key_exists($val, $ruleFields)) {
190 $weightSum += $ruleFields[$val];
191 }
192 }
193 $fieldMessage = '';
194 foreach ($ruleFields as $field => $weight) {
195 $fieldMessage .= ' ' . $field . '(weight ' . $weight . ')';
196 }
197 if ($weightSum < $threshold) {
198 return $fieldMessage . ' ' . ts('(Sum of all weights should be greater than or equal to threshold: %1).', array(
199 1 => $threshold,
200 ));
201 }
202 return '';
203 }
204
205 }