Merge pull request #19268 from seamuslee001/dev_core_2272
[civicrm-core.git] / CRM / Utils / DeprecatedUtils.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 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17
18 /*
19 * These functions have been deprecated out of API v3 Utils folder as they are not part of the
20 * API. Calling API functions directly is not supported & these functions are not called by any
21 * part of the API so are not really part of the api
22 *
23 */
24
25 require_once 'api/v3/utils.php';
26
27 /**
28 * Check duplicate contacts based on de-dupe parameters.
29 *
30 * @param array $params
31 *
32 * @return array
33 */
34 function _civicrm_api3_deprecated_check_contact_dedupe($params) {
35 static $cIndieFields = NULL;
36 static $defaultLocationId = NULL;
37
38 $contactType = $params['contact_type'];
39 if ($cIndieFields == NULL) {
40 require_once 'CRM/Contact/BAO/Contact.php';
41 $cTempIndieFields = CRM_Contact_BAO_Contact::importableFields($contactType);
42 $cIndieFields = $cTempIndieFields;
43
44 require_once "CRM/Core/BAO/LocationType.php";
45 $defaultLocation = CRM_Core_BAO_LocationType::getDefault();
46
47 // set the value to default location id else set to 1
48 if (!$defaultLocationId = (int) $defaultLocation->id) {
49 $defaultLocationId = 1;
50 }
51 }
52
53 require_once 'CRM/Contact/BAO/Query.php';
54 $locationFields = CRM_Contact_BAO_Query::$_locationSpecificFields;
55
56 $contactFormatted = [];
57 foreach ($params as $key => $field) {
58 if ($field == NULL || $field === '') {
59 continue;
60 }
61 // CRM-17040, Considering only primary contact when importing contributions. So contribution inserts into primary contact
62 // instead of soft credit contact.
63 if (is_array($field) && $key != "soft_credit") {
64 foreach ($field as $value) {
65 $break = FALSE;
66 if (is_array($value)) {
67 foreach ($value as $name => $testForEmpty) {
68 if ($name !== 'phone_type' &&
69 ($testForEmpty === '' || $testForEmpty == NULL)
70 ) {
71 $break = TRUE;
72 break;
73 }
74 }
75 }
76 else {
77 $break = TRUE;
78 }
79 if (!$break) {
80 _civicrm_api3_deprecated_add_formatted_param($value, $contactFormatted);
81 }
82 }
83 continue;
84 }
85
86 $value = [$key => $field];
87
88 // check if location related field, then we need to add primary location type
89 if (in_array($key, $locationFields)) {
90 $value['location_type_id'] = $defaultLocationId;
91 }
92 elseif (array_key_exists($key, $cIndieFields)) {
93 $value['contact_type'] = $contactType;
94 }
95
96 _civicrm_api3_deprecated_add_formatted_param($value, $contactFormatted);
97 }
98
99 $contactFormatted['contact_type'] = $contactType;
100
101 return _civicrm_api3_deprecated_duplicate_formatted_contact($contactFormatted);
102 }
103
104 /**
105 * This function adds the contact variable in $values to the
106 * parameter list $params. For most cases, $values should have length 1. If
107 * the variable being added is a child of Location, a location_type_id must
108 * also be included. If it is a child of phone, a phone_type must be included.
109 *
110 * @param array $values
111 * The variable(s) to be added.
112 * @param array $params
113 * The structured parameter list.
114 *
115 * @return bool|CRM_Utils_Error
116 */
117 function _civicrm_api3_deprecated_add_formatted_param(&$values, &$params) {
118 // Crawl through the possible classes:
119 // Contact
120 // Individual
121 // Household
122 // Organization
123 // Location
124 // Address
125 // Email
126 // Phone
127 // IM
128 // Note
129 // Custom
130
131 // Cache the various object fields
132 static $fields = NULL;
133
134 if ($fields == NULL) {
135 $fields = [];
136 }
137
138 // first add core contact values since for other Civi modules they are not added
139 require_once 'CRM/Contact/BAO/Contact.php';
140 $contactFields = CRM_Contact_DAO_Contact::fields();
141 _civicrm_api3_store_values($contactFields, $values, $params);
142
143 if (isset($values['contact_type'])) {
144 // we're an individual/household/org property
145
146 $fields[$values['contact_type']] = CRM_Contact_DAO_Contact::fields();
147
148 _civicrm_api3_store_values($fields[$values['contact_type']], $values, $params);
149 return TRUE;
150 }
151
152 if (isset($values['individual_prefix'])) {
153 if (!empty($params['prefix_id'])) {
154 $prefixes = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'prefix_id');
155 $params['prefix'] = $prefixes[$params['prefix_id']];
156 }
157 else {
158 $params['prefix'] = $values['individual_prefix'];
159 }
160 return TRUE;
161 }
162
163 if (isset($values['individual_suffix'])) {
164 if (!empty($params['suffix_id'])) {
165 $suffixes = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'suffix_id');
166 $params['suffix'] = $suffixes[$params['suffix_id']];
167 }
168 else {
169 $params['suffix'] = $values['individual_suffix'];
170 }
171 return TRUE;
172 }
173
174 // CRM-4575
175 if (isset($values['email_greeting'])) {
176 if (!empty($params['email_greeting_id'])) {
177 $emailGreetingFilter = [
178 'contact_type' => $params['contact_type'] ?? NULL,
179 'greeting_type' => 'email_greeting',
180 ];
181 $emailGreetings = CRM_Core_PseudoConstant::greeting($emailGreetingFilter);
182 $params['email_greeting'] = $emailGreetings[$params['email_greeting_id']];
183 }
184 else {
185 $params['email_greeting'] = $values['email_greeting'];
186 }
187
188 return TRUE;
189 }
190
191 if (isset($values['postal_greeting'])) {
192 if (!empty($params['postal_greeting_id'])) {
193 $postalGreetingFilter = [
194 'contact_type' => $params['contact_type'] ?? NULL,
195 'greeting_type' => 'postal_greeting',
196 ];
197 $postalGreetings = CRM_Core_PseudoConstant::greeting($postalGreetingFilter);
198 $params['postal_greeting'] = $postalGreetings[$params['postal_greeting_id']];
199 }
200 else {
201 $params['postal_greeting'] = $values['postal_greeting'];
202 }
203 return TRUE;
204 }
205
206 if (isset($values['addressee'])) {
207 $params['addressee'] = $values['addressee'];
208 return TRUE;
209 }
210
211 if (isset($values['gender'])) {
212 if (!empty($params['gender_id'])) {
213 $genders = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
214 $params['gender'] = $genders[$params['gender_id']];
215 }
216 else {
217 $params['gender'] = $values['gender'];
218 }
219 return TRUE;
220 }
221
222 if (!empty($values['preferred_communication_method'])) {
223 $comm = [];
224 $pcm = array_change_key_case(array_flip(CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method')), CASE_LOWER);
225
226 $preffComm = explode(',', $values['preferred_communication_method']);
227 foreach ($preffComm as $v) {
228 $v = strtolower(trim($v));
229 if (array_key_exists($v, $pcm)) {
230 $comm[$pcm[$v]] = 1;
231 }
232 }
233
234 $params['preferred_communication_method'] = $comm;
235 return TRUE;
236 }
237
238 // format the website params.
239 if (!empty($values['url'])) {
240 static $websiteFields;
241 if (!is_array($websiteFields)) {
242 require_once 'CRM/Core/DAO/Website.php';
243 $websiteFields = CRM_Core_DAO_Website::fields();
244 }
245 if (!array_key_exists('website', $params) ||
246 !is_array($params['website'])
247 ) {
248 $params['website'] = [];
249 }
250
251 $websiteCount = count($params['website']);
252 _civicrm_api3_store_values($websiteFields, $values,
253 $params['website'][++$websiteCount]
254 );
255
256 return TRUE;
257 }
258
259 // get the formatted location blocks into params - w/ 3.0 format, CRM-4605
260 if (!empty($values['location_type_id'])) {
261 static $fields = NULL;
262 if ($fields == NULL) {
263 $fields = [];
264 }
265
266 foreach ([
267 'Phone',
268 'Email',
269 'IM',
270 'OpenID',
271 'Phone_Ext',
272 ] as $block) {
273 $name = strtolower($block);
274 if (!array_key_exists($name, $values)) {
275 continue;
276 }
277
278 if ($name == 'phone_ext') {
279 $block = 'Phone';
280 }
281
282 // block present in value array.
283 if (!array_key_exists($name, $params) || !is_array($params[$name])) {
284 $params[$name] = [];
285 }
286
287 if (!array_key_exists($block, $fields)) {
288 $className = "CRM_Core_DAO_$block";
289 $fields[$block] =& $className::fields();
290 }
291
292 $blockCnt = count($params[$name]);
293
294 // copy value to dao field name.
295 if ($name == 'im') {
296 $values['name'] = $values[$name];
297 }
298
299 _civicrm_api3_store_values($fields[$block], $values,
300 $params[$name][++$blockCnt]
301 );
302
303 if (empty($params['id']) && ($blockCnt == 1)) {
304 $params[$name][$blockCnt]['is_primary'] = TRUE;
305 }
306
307 // we only process single block at a time.
308 return TRUE;
309 }
310
311 // handle address fields.
312 if (!array_key_exists('address', $params) || !is_array($params['address'])) {
313 $params['address'] = [];
314 }
315
316 $addressCnt = 1;
317 foreach ($params['address'] as $cnt => $addressBlock) {
318 if (CRM_Utils_Array::value('location_type_id', $values) ==
319 CRM_Utils_Array::value('location_type_id', $addressBlock)
320 ) {
321 $addressCnt = $cnt;
322 break;
323 }
324 $addressCnt++;
325 }
326
327 if (!array_key_exists('Address', $fields)) {
328 $fields['Address'] = CRM_Core_DAO_Address::fields();
329 }
330
331 // Note: we doing multiple value formatting here for address custom fields, plus putting into right format.
332 // The actual formatting (like date, country ..etc) for address custom fields is taken care of while saving
333 // the address in CRM_Core_BAO_Address::create method
334 if (!empty($values['location_type_id'])) {
335 static $customFields = [];
336 if (empty($customFields)) {
337 $customFields = CRM_Core_BAO_CustomField::getFields('Address');
338 }
339 // make a copy of values, as we going to make changes
340 $newValues = $values;
341 foreach ($values as $key => $val) {
342 $customFieldID = CRM_Core_BAO_CustomField::getKeyID($key);
343 if ($customFieldID && array_key_exists($customFieldID, $customFields)) {
344 // mark an entry in fields array since we want the value of custom field to be copied
345 $fields['Address'][$key] = NULL;
346
347 $htmlType = $customFields[$customFieldID]['html_type'] ?? NULL;
348 if (CRM_Core_BAO_CustomField::isSerialized($customFields[$customFieldID]) && $val) {
349 $mulValues = explode(',', $val);
350 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
351 $newValues[$key] = [];
352 foreach ($mulValues as $v1) {
353 foreach ($customOption as $v2) {
354 if ((strtolower($v2['label']) == strtolower(trim($v1))) ||
355 (strtolower($v2['value']) == strtolower(trim($v1)))
356 ) {
357 if ($htmlType == 'CheckBox') {
358 $newValues[$key][$v2['value']] = 1;
359 }
360 else {
361 $newValues[$key][] = $v2['value'];
362 }
363 }
364 }
365 }
366 }
367 }
368 }
369 // consider new values
370 $values = $newValues;
371 }
372
373 _civicrm_api3_store_values($fields['Address'], $values, $params['address'][$addressCnt]);
374
375 $addressFields = [
376 'county',
377 'country',
378 'state_province',
379 'supplemental_address_1',
380 'supplemental_address_2',
381 'supplemental_address_3',
382 'StateProvince.name',
383 ];
384
385 foreach ($addressFields as $field) {
386 if (array_key_exists($field, $values)) {
387 if (!array_key_exists('address', $params)) {
388 $params['address'] = [];
389 }
390 $params['address'][$addressCnt][$field] = $values[$field];
391 }
392 }
393
394 if ($addressCnt == 1) {
395
396 $params['address'][$addressCnt]['is_primary'] = TRUE;
397 }
398 return TRUE;
399 }
400
401 if (isset($values['note'])) {
402 // add a note field
403 if (!isset($params['note'])) {
404 $params['note'] = [];
405 }
406 $noteBlock = count($params['note']) + 1;
407
408 $params['note'][$noteBlock] = [];
409 if (!isset($fields['Note'])) {
410 $fields['Note'] = CRM_Core_DAO_Note::fields();
411 }
412
413 // get the current logged in civicrm user
414 $session = CRM_Core_Session::singleton();
415 $userID = $session->get('userID');
416
417 if ($userID) {
418 $values['contact_id'] = $userID;
419 }
420
421 _civicrm_api3_store_values($fields['Note'], $values, $params['note'][$noteBlock]);
422
423 return TRUE;
424 }
425
426 // Check for custom field values
427
428 if (empty($fields['custom'])) {
429 $fields['custom'] = &CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $values),
430 FALSE, FALSE, NULL, NULL, FALSE, FALSE, FALSE
431 );
432 }
433
434 foreach ($values as $key => $value) {
435 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
436 // check if it's a valid custom field id
437
438 if (!array_key_exists($customFieldID, $fields['custom'])) {
439 return civicrm_api3_create_error('Invalid custom field ID');
440 }
441 else {
442 $params[$key] = $value;
443 }
444 }
445 }
446 }
447
448 /**
449 *
450 * @param array $params
451 *
452 * @return array
453 * <type>
454 */
455 function _civicrm_api3_deprecated_duplicate_formatted_contact($params) {
456 $id = $params['id'] ?? NULL;
457 $externalId = $params['external_identifier'] ?? NULL;
458 if ($id || $externalId) {
459 $contact = new CRM_Contact_DAO_Contact();
460
461 $contact->id = $id;
462 $contact->external_identifier = $externalId;
463
464 if ($contact->find(TRUE)) {
465 if ($params['contact_type'] != $contact->contact_type) {
466 return civicrm_api3_create_error("Mismatched contact IDs OR Mismatched contact Types");
467 }
468
469 $error = CRM_Core_Error::createError("Found matching contacts: $contact->id",
470 CRM_Core_Error::DUPLICATE_CONTACT,
471 'Fatal', $contact->id
472 );
473 return civicrm_api3_create_error($error->pop());
474 }
475 }
476 else {
477 $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($params, $params['contact_type'], 'Unsupervised');
478
479 if (!empty($ids)) {
480 $ids = implode(',', $ids);
481 $error = CRM_Core_Error::createError("Found matching contacts: $ids",
482 CRM_Core_Error::DUPLICATE_CONTACT,
483 'Fatal', $ids
484 );
485 return civicrm_api3_create_error($error->pop());
486 }
487 }
488 return civicrm_api3_create_success(TRUE);
489 }
490
491 /**
492 *
493 * @param array $params
494 *
495 * @param bool $checkDuplicate
496 *
497 * @return array|bool
498 * <type>
499 */
500 function _civicrm_api3_deprecated_participant_check_params($params, $checkDuplicate = FALSE) {
501
502 // check if participant id is valid or not
503 if (!empty($params['id'])) {
504 $participant = new CRM_Event_BAO_Participant();
505 $participant->id = $params['id'];
506 if (!$participant->find(TRUE)) {
507 return civicrm_api3_create_error(ts('Participant id is not valid'));
508 }
509 }
510 require_once 'CRM/Contact/BAO/Contact.php';
511 // check if contact id is valid or not
512 if (!empty($params['contact_id'])) {
513 $contact = new CRM_Contact_BAO_Contact();
514 $contact->id = $params['contact_id'];
515 if (!$contact->find(TRUE)) {
516 return civicrm_api3_create_error(ts('Contact id is not valid'));
517 }
518 }
519
520 // check that event id is not an template
521 if (!empty($params['event_id'])) {
522 $isTemplate = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $params['event_id'], 'is_template');
523 if (!empty($isTemplate)) {
524 return civicrm_api3_create_error(ts('Event templates are not meant to be registered.'));
525 }
526 }
527
528 $result = [];
529 if ($checkDuplicate) {
530 if (CRM_Event_BAO_Participant::checkDuplicate($params, $result)) {
531 $participantID = array_pop($result);
532
533 $error = CRM_Core_Error::createError("Found matching participant record.",
534 CRM_Core_Error::DUPLICATE_PARTICIPANT,
535 'Fatal', $participantID
536 );
537
538 return civicrm_api3_create_error($error->pop(),
539 [
540 'contactID' => $params['contact_id'],
541 'participantID' => $participantID,
542 ]
543 );
544 }
545 }
546 return TRUE;
547 }
548
549 /**
550 * @param $result
551 * @param int $activityTypeID
552 *
553 * @return array
554 * <type> $params
555 */
556 function _civicrm_api3_deprecated_activity_buildmailparams($result, $activityTypeID) {
557 // get ready for collecting data about activity to be created
558 $params = [];
559
560 $params['activity_type_id'] = $activityTypeID;
561
562 $params['status_id'] = 'Completed';
563 if (!empty($result['from']['id'])) {
564 $params['source_contact_id'] = $params['assignee_contact_id'] = $result['from']['id'];
565 }
566 $params['target_contact_id'] = [];
567 $keys = ['to', 'cc', 'bcc'];
568 foreach ($keys as $key) {
569 if (is_array($result[$key])) {
570 foreach ($result[$key] as $key => $keyValue) {
571 if (!empty($keyValue['id'])) {
572 $params['target_contact_id'][] = $keyValue['id'];
573 }
574 }
575 }
576 }
577 $params['subject'] = $result['subject'];
578 $params['activity_date_time'] = $result['date'];
579 $params['details'] = $result['body'];
580
581 $numAttachments = Civi::settings()->get('max_attachments_backend') ?? CRM_Core_BAO_File::DEFAULT_MAX_ATTACHMENTS_BACKEND;
582 for ($i = 1; $i <= $numAttachments; $i++) {
583 if (isset($result["attachFile_$i"])) {
584 $params["attachFile_$i"] = $result["attachFile_$i"];
585 }
586 else {
587 // No point looping 100 times if there's only one attachment
588 break;
589 }
590 }
591
592 return $params;
593 }