[REF] Simplify obtuse boolean expressions
[civicrm-core.git] / CRM / Activity / Import / Parser / Activity.php
CommitLineData
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
TO
21 */
22class CRM_Activity_Import_Parser_Activity extends CRM_Activity_Import_Parser {
23
24 protected $_mapperKeys;
25
26 private $_contactIdIndex;
27 private $_activityTypeIndex;
28 private $_activityLabelIndex;
29 private $_activityDateIndex;
30
31 /**
ceb10dc7 32 * Array of successfully imported activity id's
6a488035 33 *
62d3ee27 34 * @var array
6a488035
TO
35 */
36 protected $_newActivity;
37
38 /**
fe482240 39 * Class constructor.
b6c94f42 40 *
41 * @param array $mapperKeys
1ae8fc42 42 * @param int $mapperLocType
43 * @param int $mapperPhoneType
6a488035 44 */
00be9182 45 public function __construct(&$mapperKeys, $mapperLocType = NULL, $mapperPhoneType = NULL) {
6a488035
TO
46 parent::__construct();
47 $this->_mapperKeys = &$mapperKeys;
48 }
49
1ae8fc42 50 /**
51 * Function of undocumented functionality required by the interface.
52 */
53 protected function fini() {}
54
6a488035 55 /**
b6c94f42 56 * The initializer code, called before the processing.
6a488035 57 */
00be9182 58 public function init() {
cc6f3942 59 $activityContact = CRM_Activity_BAO_ActivityContact::import();
60 $activityTarget['target_contact_id'] = $activityContact['contact_id'];
6a488035 61 $fields = array_merge(CRM_Activity_BAO_Activity::importableFields(),
cc6f3942 62 $activityTarget
6a488035
TO
63 );
64
be2fb01f
CW
65 $fields = array_merge($fields, [
66 'source_contact_id' => [
4039effc
JP
67 'title' => ts('Source Contact'),
68 'headerPattern' => '/Source.Contact?/i',
be2fb01f
CW
69 ],
70 'activity_label' => [
cc6f3942 71 'title' => ts('Activity Type Label'),
72 'headerPattern' => '/(activity.)?type label?/i',
be2fb01f
CW
73 ],
74 ]);
6a488035
TO
75
76 foreach ($fields as $name => $field) {
77 $field['type'] = CRM_Utils_Array::value('type', $field, CRM_Utils_Type::T_INT);
78 $field['dataPattern'] = CRM_Utils_Array::value('dataPattern', $field, '//');
79 $field['headerPattern'] = CRM_Utils_Array::value('headerPattern', $field, '//');
80 $this->addField($name, $field['title'], $field['type'], $field['headerPattern'], $field['dataPattern']);
81 }
82
be2fb01f 83 $this->_newActivity = [];
6a488035
TO
84
85 $this->setActiveFields($this->_mapperKeys);
86
87 // FIXME: we should do this in one place together with Form/MapField.php
88 $this->_contactIdIndex = -1;
89 $this->_activityTypeIndex = -1;
90 $this->_activityLabelIndex = -1;
91 $this->_activityDateIndex = -1;
92
93 $index = 0;
94 foreach ($this->_mapperKeys as $key) {
95 switch ($key) {
96 case 'target_contact_id':
97 case 'external_identifier':
98 $this->_contactIdIndex = $index;
99 break;
100
101 case 'activity_label':
102 $this->_activityLabelIndex = $index;
103 break;
104
105 case 'activity_type_id':
106 $this->_activityTypeIndex = $index;
107 break;
108
109 case 'activity_date_time':
110 $this->_activityDateIndex = $index;
111 break;
112 }
113 $index++;
114 }
115 }
116
117 /**
fe482240 118 * Handle the values in mapField mode.
6a488035 119 *
041ab3d1
TO
120 * @param array $values
121 * The array of values belonging to this line.
6a488035 122 *
408b79bf 123 * @return bool
6a488035 124 */
00be9182 125 public function mapField(&$values) {
a05662ef 126 return CRM_Import_Parser::VALID;
6a488035
TO
127 }
128
129 /**
fe482240 130 * Handle the values in preview mode.
6a488035 131 *
041ab3d1
TO
132 * @param array $values
133 * The array of values belonging to this line.
6a488035 134 *
408b79bf 135 * @return bool
a6c01b45 136 * the result of this processing
6a488035 137 */
00be9182 138 public function preview(&$values) {
6a488035
TO
139 return $this->summary($values);
140 }
141
142 /**
fe482240 143 * Handle the values in summary mode.
6a488035 144 *
041ab3d1
TO
145 * @param array $values
146 * The array of values belonging to this line.
6a488035 147 *
408b79bf 148 * @return bool
a6c01b45 149 * the result of this processing
6a488035 150 */
00be9182 151 public function summary(&$values) {
6a488035 152 $erroneousField = NULL;
1ae8fc42 153 $this->setActiveFieldValues($values, $erroneousField);
353ffa53 154 $index = -1;
6a488035
TO
155
156 if ($this->_activityTypeIndex > -1 && $this->_activityLabelIndex > -1) {
157 array_unshift($values, ts('Please select either Activity Type ID OR Activity Type Label.'));
a05662ef 158 return CRM_Import_Parser::ERROR;
6a488035
TO
159 }
160 elseif ($this->_activityLabelIndex > -1) {
161 $index = $this->_activityLabelIndex;
162 }
163 elseif ($this->_activityTypeIndex > -1) {
164 $index = $this->_activityTypeIndex;
165 }
166
167 if ($index < 0 or $this->_activityDateIndex < 0) {
168 $errorRequired = TRUE;
169 }
170 else {
171 $errorRequired = !CRM_Utils_Array::value($index, $values) || !CRM_Utils_Array::value($this->_activityDateIndex, $values);
172 }
173
174 if ($errorRequired) {
175 array_unshift($values, ts('Missing required fields'));
a05662ef 176 return CRM_Import_Parser::ERROR;
6a488035
TO
177 }
178
179 $params = &$this->getActiveFieldParams();
180
181 $errorMessage = NULL;
182
7808aae6 183 // For date-Formats
6a488035
TO
184 $session = CRM_Core_Session::singleton();
185 $dateType = $session->get('dateTypes');
186 if (!isset($params['source_contact_id'])) {
187 $params['source_contact_id'] = $session->get('userID');
188 }
189 foreach ($params as $key => $val) {
190 if ($key == 'activity_date_time') {
191 if ($val) {
192 $dateValue = CRM_Utils_Date::formatDate($val, $dateType);
193 if ($dateValue) {
194 $params[$key] = $dateValue;
195 }
196 else {
719a6fec 197 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Activity date', $errorMessage);
6a488035
TO
198 }
199 }
200 }
201 elseif ($key == 'activity_engagement_level' && $val &&
202 !CRM_Utils_Rule::positiveInteger($val)
203 ) {
719a6fec 204 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Activity Engagement Index', $errorMessage);
6a488035
TO
205 }
206 }
7808aae6 207 // Date-Format part ends.
6a488035 208
7808aae6 209 // Checking error in custom data.
77c21b32 210 $params['contact_type'] = $this->_contactType ?? 'Activity';
6a488035 211
719a6fec 212 CRM_Contact_Import_Parser_Contact::isErrorInCustomData($params, $errorMessage);
6a488035
TO
213
214 if ($errorMessage) {
215 $tempMsg = "Invalid value for field(s) : $errorMessage";
216 array_unshift($values, $tempMsg);
217 $errorMessage = NULL;
a05662ef 218 return CRM_Import_Parser::ERROR;
6a488035
TO
219 }
220
a05662ef 221 return CRM_Import_Parser::VALID;
6a488035
TO
222 }
223
224 /**
fe482240 225 * Handle the values in import mode.
6a488035 226 *
041ab3d1
TO
227 * @param int $onDuplicate
228 * The code for what action to take on duplicates.
229 * @param array $values
230 * The array of values belonging to this line.
6a488035 231 *
408b79bf 232 * @return bool
a6c01b45 233 * the result of this processing
6a488035 234 */
00be9182 235 public function import($onDuplicate, &$values) {
7808aae6 236 // First make sure this is a valid line
6a488035
TO
237 $response = $this->summary($values);
238
a05662ef 239 if ($response != CRM_Import_Parser::VALID) {
6a488035
TO
240 return $response;
241 }
242 $params = &$this->getActiveFieldParams();
243 $activityLabel = array_search('activity_label', $this->_mapperKeys);
244 if ($activityLabel) {
be2fb01f 245 $params = array_merge($params, ['activity_label' => $values[$activityLabel]]);
6a488035 246 }
7808aae6 247 // For date-Formats.
6a488035
TO
248 $session = CRM_Core_Session::singleton();
249 $dateType = $session->get('dateTypes');
250 if (!isset($params['source_contact_id'])) {
251 $params['source_contact_id'] = $session->get('userID');
252 }
1ae8fc42 253
127f50ce 254 $customFields = CRM_Core_BAO_CustomField::getFields('Activity');
6a488035
TO
255
256 foreach ($params as $key => $val) {
257 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
8bc84e3c 258 if ($key == 'activity_date_time' && $val) {
2272a067
BS
259 $params[$key] = CRM_Utils_Date::formatDate($val, $dateType);
260 }
8bc84e3c 261 elseif (!empty($customFields[$customFieldID]) && $customFields[$customFieldID]['data_type'] == 'Date') {
719a6fec 262 CRM_Contact_Import_Parser_Contact::formatCustomDate($params, $params, $dateType, $key);
6a488035 263 }
8bc84e3c 264 elseif (!empty($customFields[$customFieldID]) && $customFields[$customFieldID]['data_type'] == 'Boolean') {
6a488035
TO
265 $params[$key] = CRM_Utils_String::strtoboolstr($val);
266 }
267 }
7cad3e54
C
268 elseif ($key == 'activity_date_time') {
269 $params[$key] = CRM_Utils_Date::formatDate($val, $dateType);
270 }
6a488035
TO
271 elseif ($key == 'activity_subject') {
272 $params['subject'] = $val;
273 }
274 }
7808aae6 275 // Date-Format part ends.
6a488035
TO
276 require_once 'CRM/Utils/DeprecatedUtils.php';
277 $formatError = _civicrm_api3_deprecated_activity_formatted_param($params, $params, TRUE);
278
279 if ($formatError) {
280 array_unshift($values, $formatError['error_message']);
a05662ef 281 return CRM_Import_Parser::ERROR;
6a488035
TO
282 }
283
284 $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
6a488035
TO
285 NULL,
286 'Activity'
287 );
288
289 if ($this->_contactIdIndex < 0) {
290
7808aae6
SB
291 // Retrieve contact id using contact dedupe rule.
292 // Since we are supporting only individual's activity import.
6a488035
TO
293 $params['contact_type'] = 'Individual';
294 $params['version'] = 3;
295 $error = _civicrm_api3_deprecated_duplicate_formatted_contact($params);
296
297 if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) {
298 $matchedIDs = explode(',', $error['error_message']['params'][0]);
299 if (count($matchedIDs) > 1) {
300 array_unshift($values, 'Multiple matching contact records detected for this row. The activity was not imported');
a05662ef 301 return CRM_Import_Parser::ERROR;
6a488035
TO
302 }
303 else {
304 $cid = $matchedIDs[0];
305 $params['target_contact_id'] = $cid;
306 $params['version'] = 3;
307 $newActivity = civicrm_api('activity', 'create', $params);
a7488080 308 if (!empty($newActivity['is_error'])) {
6a488035 309 array_unshift($values, $newActivity['error_message']);
a05662ef 310 return CRM_Import_Parser::ERROR;
6a488035
TO
311 }
312
313 $this->_newActivity[] = $newActivity['id'];
a05662ef 314 return CRM_Import_Parser::VALID;
6a488035
TO
315 }
316 }
317 else {
318 // Using new Dedupe rule.
be2fb01f 319 $ruleParams = [
6a488035 320 'contact_type' => 'Individual',
353ffa53 321 'used' => 'Unsupervised',
be2fb01f 322 ];
6a488035
TO
323 $fieldsArray = CRM_Dedupe_BAO_Rule::dedupeRuleFields($ruleParams);
324
325 $disp = NULL;
326 foreach ($fieldsArray as $value) {
327 if (array_key_exists(trim($value), $params)) {
328 $paramValue = $params[trim($value)];
329 if (is_array($paramValue)) {
330 $disp .= $params[trim($value)][0][trim($value)] . " ";
331 }
332 else {
333 $disp .= $params[trim($value)] . " ";
334 }
335 }
336 }
337
a7488080 338 if (!empty($params['external_identifier'])) {
6a488035
TO
339 if ($disp) {
340 $disp .= "AND {$params['external_identifier']}";
341 }
342 else {
343 $disp = $params['external_identifier'];
344 }
345 }
346
347 array_unshift($values, 'No matching Contact found for (' . $disp . ')');
a05662ef 348 return CRM_Import_Parser::ERROR;
6a488035
TO
349 }
350 }
351 else {
a7488080 352 if (!empty($params['external_identifier'])) {
6a488035
TO
353 $targetContactId = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
354 $params['external_identifier'], 'id', 'external_identifier'
355 );
356
a7488080 357 if (!empty($params['target_contact_id']) &&
6a488035
TO
358 $params['target_contact_id'] != $targetContactId
359 ) {
d79be26c 360 array_unshift($values, 'Mismatch of External ID:' . $params['external_identifier'] . ' and Contact Id:' . $params['target_contact_id']);
a05662ef 361 return CRM_Import_Parser::ERROR;
6a488035
TO
362 }
363 elseif ($targetContactId) {
364 $params['target_contact_id'] = $targetContactId;
365 }
366 else {
d79be26c 367 array_unshift($values, 'No Matching Contact for External ID:' . $params['external_identifier']);
a05662ef 368 return CRM_Import_Parser::ERROR;
6a488035
TO
369 }
370 }
371
372 $params['version'] = 3;
373 $newActivity = civicrm_api('activity', 'create', $params);
a7488080 374 if (!empty($newActivity['is_error'])) {
6a488035 375 array_unshift($values, $newActivity['error_message']);
a05662ef 376 return CRM_Import_Parser::ERROR;
6a488035
TO
377 }
378
379 $this->_newActivity[] = $newActivity['id'];
a05662ef 380 return CRM_Import_Parser::VALID;
6a488035
TO
381 }
382 }
383
6a488035 384}