Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 5 | | | |
bc77d7c0 TO |
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 | | |
6a488035 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 TO |
16 | */ |
17 | ||
6a488035 TO |
18 | |
19 | /** | |
b6c94f42 | 20 | * Class to parse activity csv files. |
6a488035 | 21 | */ |
8addbaf3 | 22 | class CRM_Activity_Import_Parser_Activity extends CRM_Import_Parser { |
6a488035 | 23 | |
3764aead EM |
24 | /** |
25 | * Get information about the provided job. | |
26 | * - name | |
27 | * - id (generally the same as name) | |
28 | * - label | |
29 | * | |
30 | * e.g. ['activity_import' => ['id' => 'activity_import', 'label' => ts('Activity Import'), 'name' => 'activity_import']] | |
31 | * | |
32 | * @return array | |
33 | */ | |
34 | public static function getUserJobInfo(): array { | |
35 | return [ | |
36 | 'activity_import' => [ | |
37 | 'id' => 'activity_import', | |
38 | 'name' => 'activity_import', | |
39 | 'label' => ts('Activity Import'), | |
40 | ], | |
41 | ]; | |
42 | } | |
43 | ||
6a488035 | 44 | /** |
b6c94f42 | 45 | * The initializer code, called before the processing. |
6a488035 | 46 | */ |
00be9182 | 47 | public function init() { |
7eebbdaa EM |
48 | $this->setFieldMetadata(); |
49 | ||
50 | foreach ($this->importableFieldsMetadata as $name => $field) { | |
6a488035 TO |
51 | $field['type'] = CRM_Utils_Array::value('type', $field, CRM_Utils_Type::T_INT); |
52 | $field['dataPattern'] = CRM_Utils_Array::value('dataPattern', $field, '//'); | |
53 | $field['headerPattern'] = CRM_Utils_Array::value('headerPattern', $field, '//'); | |
4245bf70 MM |
54 | if (!empty($field['custom_group_id'])) { |
55 | $field['title'] = $field["groupTitle"] . ' :: ' . $field["title"]; | |
56 | } | |
6a488035 TO |
57 | $this->addField($name, $field['title'], $field['type'], $field['headerPattern'], $field['dataPattern']); |
58 | } | |
6a488035 TO |
59 | } |
60 | ||
61 | /** | |
fe482240 | 62 | * Handle the values in import mode. |
6a488035 | 63 | * |
041ab3d1 TO |
64 | * @param array $values |
65 | * The array of values belonging to this line. | |
6a488035 | 66 | */ |
7eebbdaa EM |
67 | public function import($values) { |
68 | $rowNumber = (int) ($values[array_key_last($values)]); | |
7808aae6 | 69 | // First make sure this is a valid line |
3ac87609 | 70 | try { |
7eebbdaa | 71 | $params = $this->getMappedRow($values); |
6a488035 | 72 | |
945b79bf | 73 | if (empty($params['external_identifier']) && empty($params['target_contact_id'])) { |
6a488035 | 74 | |
945b79bf EM |
75 | // Retrieve contact id using contact dedupe rule. |
76 | // Since we are supporting only individual's activity import. | |
77 | $params['contact_type'] = 'Individual'; | |
78 | $params['version'] = 3; | |
79 | $matchedIDs = CRM_Contact_BAO_Contact::getDuplicateContacts($params, 'Individual'); | |
80 | ||
81 | if (!empty($matchedIDs)) { | |
82 | if (count($matchedIDs) > 1) { | |
7eebbdaa | 83 | throw new CRM_Core_Exception('Multiple matching contact records detected for this row. The activity was not imported'); |
945b79bf EM |
84 | } |
85 | $cid = $matchedIDs[0]; | |
86 | $params['target_contact_id'] = $cid; | |
87 | $params['version'] = 3; | |
88 | $newActivity = civicrm_api('activity', 'create', $params); | |
89 | if (!empty($newActivity['is_error'])) { | |
7eebbdaa | 90 | throw new CRM_Core_Exception($newActivity['error_message']); |
945b79bf EM |
91 | } |
92 | ||
93 | $this->_newActivity[] = $newActivity['id']; | |
7eebbdaa EM |
94 | $this->setImportStatus($rowNumber, 'IMPORTED', '', $newActivity['id']); |
95 | return; | |
6a488035 | 96 | |
6a488035 | 97 | } |
945b79bf EM |
98 | // Using new Dedupe rule. |
99 | $ruleParams = [ | |
100 | 'contact_type' => 'Individual', | |
101 | 'used' => 'Unsupervised', | |
102 | ]; | |
103 | $fieldsArray = CRM_Dedupe_BAO_DedupeRule::dedupeRuleFields($ruleParams); | |
104 | ||
105 | $disp = NULL; | |
106 | foreach ($fieldsArray as $value) { | |
107 | if (array_key_exists(trim($value), $params)) { | |
108 | $paramValue = $params[trim($value)]; | |
109 | if (is_array($paramValue)) { | |
110 | $disp .= $params[trim($value)][0][trim($value)] . " "; | |
111 | } | |
112 | else { | |
113 | $disp .= $params[trim($value)] . " "; | |
114 | } | |
115 | } | |
6a488035 TO |
116 | } |
117 | ||
945b79bf EM |
118 | if (!empty($params['external_identifier'])) { |
119 | if ($disp) { | |
120 | $disp .= "AND {$params['external_identifier']}"; | |
6a488035 TO |
121 | } |
122 | else { | |
945b79bf | 123 | $disp = $params['external_identifier']; |
6a488035 TO |
124 | } |
125 | } | |
81882fd1 EM |
126 | if (empty($params['id'])) { |
127 | throw new CRM_Core_Exception('No matching Contact found for (' . $disp . ')'); | |
128 | } | |
945b79bf | 129 | } |
a7488080 | 130 | if (!empty($params['external_identifier'])) { |
945b79bf EM |
131 | $targetContactId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', |
132 | $params['external_identifier'], 'id', 'external_identifier' | |
133 | ); | |
134 | ||
135 | if (!empty($params['target_contact_id']) && | |
136 | $params['target_contact_id'] != $targetContactId | |
137 | ) { | |
7eebbdaa | 138 | throw new CRM_Core_Exception('Mismatch of External ID:' . $params['external_identifier'] . ' and Contact Id:' . $params['target_contact_id']); |
945b79bf EM |
139 | } |
140 | if ($targetContactId) { | |
141 | $params['target_contact_id'] = $targetContactId; | |
6a488035 TO |
142 | } |
143 | else { | |
7eebbdaa | 144 | throw new CRM_Core_Exception('No Matching Contact for External ID:' . $params['external_identifier']); |
6a488035 TO |
145 | } |
146 | } | |
147 | ||
945b79bf EM |
148 | $params['version'] = 3; |
149 | $newActivity = civicrm_api('activity', 'create', $params); | |
150 | if (!empty($newActivity['is_error'])) { | |
7eebbdaa | 151 | throw new CRM_Core_Exception($newActivity['error_message']); |
cb8bc3b6 | 152 | } |
153 | } | |
945b79bf | 154 | catch (CRM_Core_Exception $e) { |
7eebbdaa EM |
155 | $this->setImportStatus($rowNumber, 'ERROR', $e->getMessage()); |
156 | return; | |
6a488035 | 157 | } |
cb8bc3b6 | 158 | $this->_newActivity[] = $newActivity['id']; |
7eebbdaa EM |
159 | $this->setImportStatus($rowNumber, 'IMPORTED', '', $newActivity['id']); |
160 | } | |
161 | ||
162 | /** | |
163 | * Get the row from the csv mapped to our parameters. | |
164 | * | |
165 | * @param array $values | |
166 | * | |
167 | * @return array | |
168 | * @throws \API_Exception | |
169 | */ | |
170 | public function getMappedRow(array $values): array { | |
171 | $params = []; | |
172 | foreach ($this->getFieldMappings() as $i => $mappedField) { | |
173 | if ($mappedField['name'] === 'do_not_import') { | |
174 | continue; | |
175 | } | |
176 | if ($mappedField['name']) { | |
177 | $fieldName = $this->getFieldMetadata($mappedField['name'])['name']; | |
178 | if (in_array($mappedField['name'], ['target_contact_id', 'source_contact_id'])) { | |
179 | $fieldName = $mappedField['name']; | |
180 | } | |
181 | $params[$fieldName] = $this->getTransformedFieldValue($mappedField['name'], $values[$i]); | |
182 | } | |
183 | } | |
184 | return $params; | |
6a488035 TO |
185 | } |
186 | ||
7eebbdaa EM |
187 | /** |
188 | * @return array | |
189 | */ | |
190 | protected function getRequiredFields(): array { | |
191 | return [['activity_type_id' => ts('Activity Type'), 'activity_date_time' => ts('Activity Date')]]; | |
192 | } | |
193 | ||
c5a8afa5 | 194 | /** |
37fe444e | 195 | * @deprecated - these are just used in a couple of parent class functions now. |
8addbaf3 EM |
196 | * @param string $name |
197 | * @param $title | |
198 | * @param int $type | |
199 | * @param string $headerPattern | |
200 | * @param string $dataPattern | |
201 | */ | |
202 | public function addField($name, $title, $type = CRM_Utils_Type::T_INT, $headerPattern = '//', $dataPattern = '//') { | |
203 | if (empty($name)) { | |
204 | $this->_fields['doNotImport'] = new CRM_Activity_Import_Field($name, $title, $type, $headerPattern, $dataPattern); | |
205 | } | |
206 | else { | |
207 | ||
208 | $tempField = CRM_Contact_BAO_Contact::importableFields('Individual', NULL); | |
209 | if (!array_key_exists($name, $tempField)) { | |
210 | $this->_fields[$name] = new CRM_Activity_Import_Field($name, $title, $type, $headerPattern, $dataPattern); | |
211 | } | |
212 | else { | |
213 | $this->_fields[$name] = new CRM_Contact_Import_Field($name, $title, $type, $headerPattern, $dataPattern, CRM_Utils_Array::value('hasLocationType', $tempField[$name])); | |
214 | } | |
215 | } | |
216 | } | |
217 | ||
7eebbdaa EM |
218 | /** |
219 | * Ensure metadata is loaded. | |
220 | */ | |
221 | protected function setFieldMetadata(): void { | |
222 | if (empty($this->importableFieldsMetadata)) { | |
223 | $activityContact = CRM_Activity_BAO_ActivityContact::import(); | |
37fe444e EM |
224 | $fields = ['' => ['title' => ts('- do not import -')]]; |
225 | ||
226 | $tmpFields = CRM_Activity_DAO_Activity::import(); | |
227 | $contactFields = CRM_Contact_BAO_Contact::importableFields('Individual', NULL); | |
228 | ||
229 | // Using new Dedupe rule. | |
230 | $ruleParams = [ | |
231 | 'contact_type' => 'Individual', | |
232 | 'used' => 'Unsupervised', | |
233 | ]; | |
234 | $fieldsArray = CRM_Dedupe_BAO_DedupeRule::dedupeRuleFields($ruleParams); | |
235 | ||
236 | $tmpConatctField = []; | |
237 | if (is_array($fieldsArray)) { | |
238 | foreach ($fieldsArray as $value) { | |
239 | $customFieldId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField', | |
240 | $value, | |
241 | 'id', | |
242 | 'column_name' | |
243 | ); | |
97b5d1ab EM |
244 | $value = trim($customFieldId ? 'custom_' . $customFieldId : $value); |
245 | $tmpConatctField[$value] = $contactFields[$value]; | |
246 | $tmpConatctField[$value]['title'] = $tmpConatctField[$value]['title'] . " (match to contact)"; | |
37fe444e EM |
247 | } |
248 | } | |
249 | $tmpConatctField['external_identifier'] = $contactFields['external_identifier']; | |
97b5d1ab | 250 | $tmpConatctField['external_identifier']['title'] = $contactFields['external_identifier']['title'] . ' (match to contact)'; |
37fe444e EM |
251 | $fields = array_merge($fields, $tmpConatctField); |
252 | $fields = array_merge($fields, $tmpFields); | |
253 | $fields = array_merge($fields, CRM_Core_BAO_CustomField::getFieldsForImport('Activity')); | |
7eebbdaa EM |
254 | |
255 | $fields = array_merge($fields, [ | |
256 | 'source_contact_id' => [ | |
257 | 'title' => ts('Source Contact'), | |
258 | 'headerPattern' => '/Source.Contact?/i', | |
37fe444e EM |
259 | 'name' => 'source_type_id', |
260 | 'options' => FALSE, | |
261 | 'type' => CRM_Utils_Type::T_INT, | |
7eebbdaa | 262 | ], |
97b5d1ab EM |
263 | 'target_contact_id' => [ |
264 | 'title' => ts('Target Contact'), | |
265 | 'headerPattern' => '/Target.Contact?/i', | |
266 | 'name' => 'target_type_id', | |
267 | 'options' => FALSE, | |
268 | 'type' => CRM_Utils_Type::T_INT, | |
269 | ], | |
7eebbdaa EM |
270 | ]); |
271 | $this->importableFieldsMetadata = $fields; | |
272 | } | |
273 | } | |
274 | ||
6a488035 | 275 | } |