Merge pull request #12340 from eileenmcnaughton/merge_cleanup
[civicrm-core.git] / CRM / Utils / DeprecatedUtils.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2018 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2018
32 */
33
34 /*
35 * These functions have been deprecated out of API v3 Utils folder as they are not part of the
36 * API. Calling API functions directly is not supported & these functions are not called by any
37 * part of the API so are not really part of the api
38 *
39 */
40
41 require_once 'api/v3/utils.php';
42
43 /**
44 * take the input parameter list as specified in the data model and
45 * convert it into the same format that we use in QF and BAO object
46 *
47 * @param array $params
48 * Associative array of property name/value.
49 * pairs to insert in new contact.
50 * @param array $values
51 * The reformatted properties that we can use internally.
52 * '
53 *
54 * @param bool $create
55 * @param null $onDuplicate
56 *
57 * @return array|CRM_Error
58 */
59 function _civicrm_api3_deprecated_formatted_param($params, &$values, $create = FALSE, $onDuplicate = NULL) {
60 // copy all the contribution fields as is
61
62 $fields = CRM_Contribute_DAO_Contribution::fields();
63
64 _civicrm_api3_store_values($fields, $params, $values);
65
66 require_once 'CRM/Core/OptionGroup.php';
67 $customFields = CRM_Core_BAO_CustomField::getFields('Contribution', FALSE, FALSE, NULL, NULL, FALSE, FALSE, FALSE);
68
69 foreach ($params as $key => $value) {
70 // ignore empty values or empty arrays etc
71 if (CRM_Utils_System::isNull($value)) {
72 continue;
73 }
74
75 // Handling Custom Data
76 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
77 $values[$key] = $value;
78 $type = $customFields[$customFieldID]['html_type'];
79 if ($type == 'CheckBox' || $type == 'Multi-Select') {
80 $mulValues = explode(',', $value);
81 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
82 $values[$key] = array();
83 foreach ($mulValues as $v1) {
84 foreach ($customOption as $customValueID => $customLabel) {
85 $customValue = $customLabel['value'];
86 if ((strtolower($customLabel['label']) == strtolower(trim($v1))) ||
87 (strtolower($customValue) == strtolower(trim($v1)))
88 ) {
89 if ($type == 'CheckBox') {
90 $values[$key][$customValue] = 1;
91 }
92 else {
93 $values[$key][] = $customValue;
94 }
95 }
96 }
97 }
98 }
99 elseif ($type == 'Select' || $type == 'Radio' ||
100 ($type == 'Autocomplete-Select' &&
101 $customFields[$customFieldID]['data_type'] == 'String'
102 )
103 ) {
104 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
105 foreach ($customOption as $customFldID => $customValue) {
106 $val = CRM_Utils_Array::value('value', $customValue);
107 $label = CRM_Utils_Array::value('label', $customValue);
108 $label = strtolower($label);
109 $value = strtolower(trim($value));
110 if (($value == $label) || ($value == strtolower($val))) {
111 $values[$key] = $val;
112 }
113 }
114 }
115 }
116
117 switch ($key) {
118 case 'contribution_contact_id':
119 if (!CRM_Utils_Rule::integer($value)) {
120 return civicrm_api3_create_error("contact_id not valid: $value");
121 }
122 $dao = new CRM_Core_DAO();
123 $qParams = array();
124 $svq = $dao->singleValueQuery("SELECT is_deleted FROM civicrm_contact WHERE id = $value",
125 $qParams
126 );
127 if (!isset($svq)) {
128 return civicrm_api3_create_error("Invalid Contact ID: There is no contact record with contact_id = $value.");
129 }
130 elseif ($svq == 1) {
131 return civicrm_api3_create_error("Invalid Contact ID: contact_id $value is a soft-deleted contact.");
132 }
133
134 $values['contact_id'] = $values['contribution_contact_id'];
135 unset($values['contribution_contact_id']);
136 break;
137
138 case 'contact_type':
139 // import contribution record according to select contact type
140 require_once 'CRM/Contact/DAO/Contact.php';
141 $contactType = new CRM_Contact_DAO_Contact();
142 $contactId = CRM_Utils_Array::value('contribution_contact_id', $params);
143 $externalId = CRM_Utils_Array::value('external_identifier', $params);
144 $email = CRM_Utils_Array::value('email', $params);
145 //when insert mode check contact id or external identifier
146 if ($contactId || $externalId) {
147 $contactType->id = $contactId;
148 $contactType->external_identifier = $externalId;
149 if ($contactType->find(TRUE)) {
150 if ($params['contact_type'] != $contactType->contact_type) {
151 return civicrm_api3_create_error("Contact Type is wrong: $contactType->contact_type");
152 }
153 }
154 }
155 elseif ($email) {
156 if (!CRM_Utils_Rule::email($email)) {
157 return civicrm_api3_create_error("Invalid email address $email provided. Row was skipped");
158 }
159
160 // get the contact id from duplicate contact rule, if more than one contact is returned
161 // we should return error, since current interface allows only one-one mapping
162 $emailParams = array('email' => $email, 'contact_type' => $params['contact_type']);
163 $checkDedupe = _civicrm_api3_deprecated_duplicate_formatted_contact($emailParams);
164 if (!$checkDedupe['is_error']) {
165 return civicrm_api3_create_error("Invalid email address(doesn't exist) $email. Row was skipped");
166 }
167 else {
168 $matchingContactIds = explode(',', $checkDedupe['error_message']['params'][0]);
169 if (count($matchingContactIds) > 1) {
170 return civicrm_api3_create_error("Invalid email address(duplicate) $email. Row was skipped");
171 }
172 elseif (count($matchingContactIds) == 1) {
173 $params['contribution_contact_id'] = $matchingContactIds[0];
174 }
175 }
176 }
177 elseif (!empty($params['contribution_id']) || !empty($params['trxn_id']) || !empty($params['invoice_id'])) {
178 // when update mode check contribution id or trxn id or
179 // invoice id
180 $contactId = new CRM_Contribute_DAO_Contribution();
181 if (!empty($params['contribution_id'])) {
182 $contactId->id = $params['contribution_id'];
183 }
184 elseif (!empty($params['trxn_id'])) {
185 $contactId->trxn_id = $params['trxn_id'];
186 }
187 elseif (!empty($params['invoice_id'])) {
188 $contactId->invoice_id = $params['invoice_id'];
189 }
190 if ($contactId->find(TRUE)) {
191 $contactType->id = $contactId->contact_id;
192 if ($contactType->find(TRUE)) {
193 if ($params['contact_type'] != $contactType->contact_type) {
194 return civicrm_api3_create_error("Contact Type is wrong: $contactType->contact_type");
195 }
196 }
197 }
198 }
199 else {
200 if ($onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE) {
201 return civicrm_api3_create_error("Empty Contribution and Invoice and Transaction ID. Row was skipped.");
202 }
203 }
204 break;
205
206 case 'receive_date':
207 case 'cancel_date':
208 case 'receipt_date':
209 case 'thankyou_date':
210 if (!CRM_Utils_Rule::dateTime($value)) {
211 return civicrm_api3_create_error("$key not a valid date: $value");
212 }
213 break;
214
215 case 'non_deductible_amount':
216 case 'total_amount':
217 case 'fee_amount':
218 case 'net_amount':
219 if (!CRM_Utils_Rule::money($value)) {
220 return civicrm_api3_create_error("$key not a valid amount: $value");
221 }
222 break;
223
224 case 'currency':
225 if (!CRM_Utils_Rule::currencyCode($value)) {
226 return civicrm_api3_create_error("currency not a valid code: $value");
227 }
228 break;
229
230 case 'financial_type':
231 require_once 'CRM/Contribute/PseudoConstant.php';
232 $contriTypes = CRM_Contribute_PseudoConstant::financialType();
233 foreach ($contriTypes as $val => $type) {
234 if (strtolower($value) == strtolower($type)) {
235 $values['financial_type_id'] = $val;
236 break;
237 }
238 }
239 if (empty($values['financial_type_id'])) {
240 return civicrm_api3_create_error("Financial Type is not valid: $value");
241 }
242 break;
243
244 case 'payment_instrument':
245 require_once 'CRM/Core/PseudoConstant.php';
246 $values['payment_instrument_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', $value);
247 if (empty($values['payment_instrument_id'])) {
248 return civicrm_api3_create_error("Payment Instrument is not valid: $value");
249 }
250 break;
251
252 case 'contribution_status_id':
253 require_once 'CRM/Core/PseudoConstant.php';
254 if (!$values['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $value)) {
255 return civicrm_api3_create_error("Contribution Status is not valid: $value");
256 }
257 break;
258
259 case 'soft_credit':
260 // import contribution record according to select contact type
261 // validate contact id and external identifier.
262 $value[$key] = $mismatchContactType = $softCreditContactIds = '';
263 if (isset($params[$key]) && is_array($params[$key])) {
264 foreach ($params[$key] as $softKey => $softParam) {
265 $contactId = CRM_Utils_Array::value('contact_id', $softParam);
266 $externalId = CRM_Utils_Array::value('external_identifier', $softParam);
267 $email = CRM_Utils_Array::value('email', $softParam);
268 if ($contactId || $externalId) {
269 require_once 'CRM/Contact/DAO/Contact.php';
270 $contact = new CRM_Contact_DAO_Contact();
271 $contact->id = $contactId;
272 $contact->external_identifier = $externalId;
273 $errorMsg = NULL;
274 if (!$contact->find(TRUE)) {
275 $field = $contactId ? ts('Contact ID') : ts('External ID');
276 $errorMsg = ts("Soft Credit %1 - %2 doesn't exist. Row was skipped.",
277 array(1 => $field, 2 => $contactId ? $contactId : $externalId));
278 }
279
280 if ($errorMsg) {
281 return civicrm_api3_create_error($errorMsg);
282 }
283
284 // finally get soft credit contact id.
285 $values[$key][$softKey] = $softParam;
286 $values[$key][$softKey]['contact_id'] = $contact->id;
287 }
288 elseif ($email) {
289 if (!CRM_Utils_Rule::email($email)) {
290 return civicrm_api3_create_error("Invalid email address $email provided for Soft Credit. Row was skipped");
291 }
292
293 // get the contact id from duplicate contact rule, if more than one contact is returned
294 // we should return error, since current interface allows only one-one mapping
295 $emailParams = array('email' => $email, 'contact_type' => $params['contact_type']);
296 $checkDedupe = _civicrm_api3_deprecated_duplicate_formatted_contact($emailParams);
297 if (!$checkDedupe['is_error']) {
298 return civicrm_api3_create_error("Invalid email address(doesn't exist) $email for Soft Credit. Row was skipped");
299 }
300 else {
301 $matchingContactIds = explode(',', $checkDedupe['error_message']['params'][0]);
302 if (count($matchingContactIds) > 1) {
303 return civicrm_api3_create_error("Invalid email address(duplicate) $email for Soft Credit. Row was skipped");
304 }
305 elseif (count($matchingContactIds) == 1) {
306 $contactId = $matchingContactIds[0];
307 unset($softParam['email']);
308 $values[$key][$softKey] = $softParam + array('contact_id' => $contactId);
309 }
310 }
311 }
312 }
313 }
314 break;
315
316 case 'pledge_payment':
317 case 'pledge_id':
318
319 // giving respect to pledge_payment flag.
320 if (empty($params['pledge_payment'])) {
321 continue;
322 }
323
324 // get total amount of from import fields
325 $totalAmount = CRM_Utils_Array::value('total_amount', $params);
326
327 $onDuplicate = CRM_Utils_Array::value('onDuplicate', $params);
328
329 // we need to get contact id $contributionContactID to
330 // retrieve pledge details as well as to validate pledge ID
331
332 // first need to check for update mode
333 if ($onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE &&
334 ($params['contribution_id'] || $params['trxn_id'] || $params['invoice_id'])
335 ) {
336 $contribution = new CRM_Contribute_DAO_Contribution();
337 if ($params['contribution_id']) {
338 $contribution->id = $params['contribution_id'];
339 }
340 elseif ($params['trxn_id']) {
341 $contribution->trxn_id = $params['trxn_id'];
342 }
343 elseif ($params['invoice_id']) {
344 $contribution->invoice_id = $params['invoice_id'];
345 }
346
347 if ($contribution->find(TRUE)) {
348 $contributionContactID = $contribution->contact_id;
349 if (!$totalAmount) {
350 $totalAmount = $contribution->total_amount;
351 }
352 }
353 else {
354 return civicrm_api3_create_error('No match found for specified contact in pledge payment data. Row was skipped.');
355 }
356 }
357 else {
358 // first get the contact id for given contribution record.
359 if (!empty($params['contribution_contact_id'])) {
360 $contributionContactID = $params['contribution_contact_id'];
361 }
362 elseif (!empty($params['external_identifier'])) {
363 require_once 'CRM/Contact/DAO/Contact.php';
364 $contact = new CRM_Contact_DAO_Contact();
365 $contact->external_identifier = $params['external_identifier'];
366 if ($contact->find(TRUE)) {
367 $contributionContactID = $params['contribution_contact_id'] = $values['contribution_contact_id'] = $contact->id;
368 }
369 else {
370 return civicrm_api3_create_error('No match found for specified contact in pledge payment data. Row was skipped.');
371 }
372 }
373 else {
374 // we need to get contribution contact using de dupe
375 $error = _civicrm_api3_deprecated_check_contact_dedupe($params);
376
377 if (isset($error['error_message']['params'][0])) {
378 $matchedIDs = explode(',', $error['error_message']['params'][0]);
379
380 // check if only one contact is found
381 if (count($matchedIDs) > 1) {
382 return civicrm_api3_create_error($error['error_message']['message']);
383 }
384 else {
385 $contributionContactID = $params['contribution_contact_id'] = $values['contribution_contact_id'] = $matchedIDs[0];
386 }
387 }
388 else {
389 return civicrm_api3_create_error('No match found for specified contact in contribution data. Row was skipped.');
390 }
391 }
392 }
393
394 if (!empty($params['pledge_id'])) {
395 if (CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', $params['pledge_id'], 'contact_id') != $contributionContactID) {
396 return civicrm_api3_create_error('Invalid Pledge ID provided. Contribution row was skipped.');
397 }
398 $values['pledge_id'] = $params['pledge_id'];
399 }
400 else {
401 // check if there are any pledge related to this contact, with payments pending or in progress
402 require_once 'CRM/Pledge/BAO/Pledge.php';
403 $pledgeDetails = CRM_Pledge_BAO_Pledge::getContactPledges($contributionContactID);
404
405 if (empty($pledgeDetails)) {
406 return civicrm_api3_create_error('No open pledges found for this contact. Contribution row was skipped.');
407 }
408 elseif (count($pledgeDetails) > 1) {
409 return civicrm_api3_create_error('This contact has more than one open pledge. Unable to determine which pledge to apply the contribution to. Contribution row was skipped.');
410 }
411
412 // this mean we have only one pending / in progress pledge
413 $values['pledge_id'] = $pledgeDetails[0];
414 }
415
416 // we need to check if oldest payment amount equal to contribution amount
417 require_once 'CRM/Pledge/BAO/PledgePayment.php';
418 $pledgePaymentDetails = CRM_Pledge_BAO_PledgePayment::getOldestPledgePayment($values['pledge_id']);
419
420 if ($pledgePaymentDetails['amount'] == $totalAmount) {
421 $values['pledge_payment_id'] = $pledgePaymentDetails['id'];
422 }
423 else {
424 return civicrm_api3_create_error('Contribution and Pledge Payment amount mismatch for this record. Contribution row was skipped.');
425 }
426 break;
427
428 default:
429 break;
430 }
431 }
432
433 if (array_key_exists('note', $params)) {
434 $values['note'] = $params['note'];
435 }
436
437 if ($create) {
438 // CRM_Contribute_BAO_Contribution::add() handles contribution_source
439 // So, if $values contains contribution_source, convert it to source
440 $changes = array('contribution_source' => 'source');
441
442 foreach ($changes as $orgVal => $changeVal) {
443 if (isset($values[$orgVal])) {
444 $values[$changeVal] = $values[$orgVal];
445 unset($values[$orgVal]);
446 }
447 }
448 }
449
450 return NULL;
451 }
452
453 /**
454 * Check duplicate contacts based on de-dupe parameters.
455 *
456 * @param array $params
457 *
458 * @return array
459 */
460 function _civicrm_api3_deprecated_check_contact_dedupe($params) {
461 static $cIndieFields = NULL;
462 static $defaultLocationId = NULL;
463
464 $contactType = $params['contact_type'];
465 if ($cIndieFields == NULL) {
466 require_once 'CRM/Contact/BAO/Contact.php';
467 $cTempIndieFields = CRM_Contact_BAO_Contact::importableFields($contactType);
468 $cIndieFields = $cTempIndieFields;
469
470 require_once "CRM/Core/BAO/LocationType.php";
471 $defaultLocation = CRM_Core_BAO_LocationType::getDefault();
472
473 // set the value to default location id else set to 1
474 if (!$defaultLocationId = (int) $defaultLocation->id) {
475 $defaultLocationId = 1;
476 }
477 }
478
479 require_once 'CRM/Contact/BAO/Query.php';
480 $locationFields = CRM_Contact_BAO_Query::$_locationSpecificFields;
481
482 $contactFormatted = array();
483 foreach ($params as $key => $field) {
484 if ($field == NULL || $field === '') {
485 continue;
486 }
487 // CRM-17040, Considering only primary contact when importing contributions. So contribution inserts into primary contact
488 // instead of soft credit contact.
489 if (is_array($field) && $key != "soft_credit") {
490 foreach ($field as $value) {
491 $break = FALSE;
492 if (is_array($value)) {
493 foreach ($value as $name => $testForEmpty) {
494 if ($name !== 'phone_type' &&
495 ($testForEmpty === '' || $testForEmpty == NULL)
496 ) {
497 $break = TRUE;
498 break;
499 }
500 }
501 }
502 else {
503 $break = TRUE;
504 }
505 if (!$break) {
506 _civicrm_api3_deprecated_add_formatted_param($value, $contactFormatted);
507 }
508 }
509 continue;
510 }
511
512 $value = array($key => $field);
513
514 // check if location related field, then we need to add primary location type
515 if (in_array($key, $locationFields)) {
516 $value['location_type_id'] = $defaultLocationId;
517 }
518 elseif (array_key_exists($key, $cIndieFields)) {
519 $value['contact_type'] = $contactType;
520 }
521
522 _civicrm_api3_deprecated_add_formatted_param($value, $contactFormatted);
523 }
524
525 $contactFormatted['contact_type'] = $contactType;
526
527 return _civicrm_api3_deprecated_duplicate_formatted_contact($contactFormatted);
528 }
529
530 /**
531 * take the input parameter list as specified in the data model and
532 * convert it into the same format that we use in QF and BAO object
533 *
534 * @param array $params
535 * Associative array of property name/value.
536 * pairs to insert in new contact.
537 * @param array $values
538 * The reformatted properties that we can use internally.
539 *
540 * @param array|bool $create Is the formatted Values array going to
541 * be used for CRM_Activity_BAO_Activity::create()
542 *
543 * @return array|CRM_Error
544 */
545 function _civicrm_api3_deprecated_activity_formatted_param(&$params, &$values, $create = FALSE) {
546 // copy all the activity fields as is
547 $fields = CRM_Activity_DAO_Activity::fields();
548 _civicrm_api3_store_values($fields, $params, $values);
549
550 require_once 'CRM/Core/OptionGroup.php';
551 $customFields = CRM_Core_BAO_CustomField::getFields('Activity');
552
553 foreach ($params as $key => $value) {
554 // ignore empty values or empty arrays etc
555 if (CRM_Utils_System::isNull($value)) {
556 continue;
557 }
558
559 //Handling Custom Data
560 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
561 $values[$key] = $value;
562 $type = $customFields[$customFieldID]['html_type'];
563 if ($type == 'CheckBox' || $type == 'Multi-Select') {
564 $mulValues = explode(',', $value);
565 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
566 $values[$key] = array();
567 foreach ($mulValues as $v1) {
568 foreach ($customOption as $customValueID => $customLabel) {
569 $customValue = $customLabel['value'];
570 if ((strtolower(trim($customLabel['label'])) == strtolower(trim($v1))) ||
571 (strtolower(trim($customValue)) == strtolower(trim($v1)))
572 ) {
573 if ($type == 'CheckBox') {
574 $values[$key][$customValue] = 1;
575 }
576 else {
577 $values[$key][] = $customValue;
578 }
579 }
580 }
581 }
582 }
583 elseif ($type == 'Select' || $type == 'Radio') {
584 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
585 foreach ($customOption as $customFldID => $customValue) {
586 $val = CRM_Utils_Array::value('value', $customValue);
587 $label = CRM_Utils_Array::value('label', $customValue);
588 $label = strtolower($label);
589 $value = strtolower(trim($value));
590 if (($value == $label) || ($value == strtolower($val))) {
591 $values[$key] = $val;
592 }
593 }
594 }
595 }
596
597 if ($key == 'target_contact_id') {
598 if (!CRM_Utils_Rule::integer($value)) {
599 return civicrm_api3_create_error("contact_id not valid: $value");
600 }
601 $contactID = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_contact WHERE id = $value");
602 if (!$contactID) {
603 return civicrm_api3_create_error("Invalid Contact ID: There is no contact record with contact_id = $value.");
604 }
605 }
606 }
607 return NULL;
608 }
609
610 /**
611 * This function adds the contact variable in $values to the
612 * parameter list $params. For most cases, $values should have length 1. If
613 * the variable being added is a child of Location, a location_type_id must
614 * also be included. If it is a child of phone, a phone_type must be included.
615 *
616 * @param array $values
617 * The variable(s) to be added.
618 * @param array $params
619 * The structured parameter list.
620 *
621 * @return bool|CRM_Utils_Error
622 */
623 function _civicrm_api3_deprecated_add_formatted_param(&$values, &$params) {
624 // Crawl through the possible classes:
625 // Contact
626 // Individual
627 // Household
628 // Organization
629 // Location
630 // Address
631 // Email
632 // Phone
633 // IM
634 // Note
635 // Custom
636
637 // Cache the various object fields
638 static $fields = NULL;
639
640 if ($fields == NULL) {
641 $fields = array();
642 }
643
644 // first add core contact values since for other Civi modules they are not added
645 require_once 'CRM/Contact/BAO/Contact.php';
646 $contactFields = CRM_Contact_DAO_Contact::fields();
647 _civicrm_api3_store_values($contactFields, $values, $params);
648
649 if (isset($values['contact_type'])) {
650 // we're an individual/household/org property
651
652 $fields[$values['contact_type']] = CRM_Contact_DAO_Contact::fields();
653
654 _civicrm_api3_store_values($fields[$values['contact_type']], $values, $params);
655 return TRUE;
656 }
657
658 if (isset($values['individual_prefix'])) {
659 if (!empty($params['prefix_id'])) {
660 $prefixes = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'prefix_id');
661 $params['prefix'] = $prefixes[$params['prefix_id']];
662 }
663 else {
664 $params['prefix'] = $values['individual_prefix'];
665 }
666 return TRUE;
667 }
668
669 if (isset($values['individual_suffix'])) {
670 if (!empty($params['suffix_id'])) {
671 $suffixes = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'suffix_id');
672 $params['suffix'] = $suffixes[$params['suffix_id']];
673 }
674 else {
675 $params['suffix'] = $values['individual_suffix'];
676 }
677 return TRUE;
678 }
679
680 // CRM-4575
681 if (isset($values['email_greeting'])) {
682 if (!empty($params['email_greeting_id'])) {
683 $emailGreetingFilter = array(
684 'contact_type' => CRM_Utils_Array::value('contact_type', $params),
685 'greeting_type' => 'email_greeting',
686 );
687 $emailGreetings = CRM_Core_PseudoConstant::greeting($emailGreetingFilter);
688 $params['email_greeting'] = $emailGreetings[$params['email_greeting_id']];
689 }
690 else {
691 $params['email_greeting'] = $values['email_greeting'];
692 }
693
694 return TRUE;
695 }
696
697 if (isset($values['postal_greeting'])) {
698 if (!empty($params['postal_greeting_id'])) {
699 $postalGreetingFilter = array(
700 'contact_type' => CRM_Utils_Array::value('contact_type', $params),
701 'greeting_type' => 'postal_greeting',
702 );
703 $postalGreetings = CRM_Core_PseudoConstant::greeting($postalGreetingFilter);
704 $params['postal_greeting'] = $postalGreetings[$params['postal_greeting_id']];
705 }
706 else {
707 $params['postal_greeting'] = $values['postal_greeting'];
708 }
709 return TRUE;
710 }
711
712 if (isset($values['addressee'])) {
713 if (!empty($params['addressee_id'])) {
714 $addresseeFilter = array(
715 'contact_type' => CRM_Utils_Array::value('contact_type', $params),
716 'greeting_type' => 'addressee',
717 );
718 $addressee = CRM_Core_PseudoConstant::addressee($addresseeFilter);
719 $params['addressee'] = $addressee[$params['addressee_id']];
720 }
721 else {
722 $params['addressee'] = $values['addressee'];
723 }
724 return TRUE;
725 }
726
727 if (isset($values['gender'])) {
728 if (!empty($params['gender_id'])) {
729 $genders = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
730 $params['gender'] = $genders[$params['gender_id']];
731 }
732 else {
733 $params['gender'] = $values['gender'];
734 }
735 return TRUE;
736 }
737
738 if (!empty($values['preferred_communication_method'])) {
739 $comm = array();
740 $pcm = array_change_key_case(array_flip(CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method')), CASE_LOWER);
741
742 $preffComm = explode(',', $values['preferred_communication_method']);
743 foreach ($preffComm as $v) {
744 $v = strtolower(trim($v));
745 if (array_key_exists($v, $pcm)) {
746 $comm[$pcm[$v]] = 1;
747 }
748 }
749
750 $params['preferred_communication_method'] = $comm;
751 return TRUE;
752 }
753
754 // format the website params.
755 if (!empty($values['url'])) {
756 static $websiteFields;
757 if (!is_array($websiteFields)) {
758 require_once 'CRM/Core/DAO/Website.php';
759 $websiteFields = CRM_Core_DAO_Website::fields();
760 }
761 if (!array_key_exists('website', $params) ||
762 !is_array($params['website'])
763 ) {
764 $params['website'] = array();
765 }
766
767 $websiteCount = count($params['website']);
768 _civicrm_api3_store_values($websiteFields, $values,
769 $params['website'][++$websiteCount]
770 );
771
772 return TRUE;
773 }
774
775 // get the formatted location blocks into params - w/ 3.0 format, CRM-4605
776 if (!empty($values['location_type_id'])) {
777 static $fields = NULL;
778 if ($fields == NULL) {
779 $fields = array();
780 }
781
782 foreach (array(
783 'Phone',
784 'Email',
785 'IM',
786 'OpenID',
787 'Phone_Ext',
788 ) as $block) {
789 $name = strtolower($block);
790 if (!array_key_exists($name, $values)) {
791 continue;
792 }
793
794 if ($name == 'phone_ext') {
795 $block = 'Phone';
796 }
797
798 // block present in value array.
799 if (!array_key_exists($name, $params) || !is_array($params[$name])) {
800 $params[$name] = array();
801 }
802
803 if (!array_key_exists($block, $fields)) {
804 $className = "CRM_Core_DAO_$block";
805 $fields[$block] =& $className::fields();
806 }
807
808 $blockCnt = count($params[$name]);
809
810 // copy value to dao field name.
811 if ($name == 'im') {
812 $values['name'] = $values[$name];
813 }
814
815 _civicrm_api3_store_values($fields[$block], $values,
816 $params[$name][++$blockCnt]
817 );
818
819 if (empty($params['id']) && ($blockCnt == 1)) {
820 $params[$name][$blockCnt]['is_primary'] = TRUE;
821 }
822
823 // we only process single block at a time.
824 return TRUE;
825 }
826
827 // handle address fields.
828 if (!array_key_exists('address', $params) || !is_array($params['address'])) {
829 $params['address'] = array();
830 }
831
832 $addressCnt = 1;
833 foreach ($params['address'] as $cnt => $addressBlock) {
834 if (CRM_Utils_Array::value('location_type_id', $values) ==
835 CRM_Utils_Array::value('location_type_id', $addressBlock)
836 ) {
837 $addressCnt = $cnt;
838 break;
839 }
840 $addressCnt++;
841 }
842
843 if (!array_key_exists('Address', $fields)) {
844 $fields['Address'] = CRM_Core_DAO_Address::fields();
845 }
846
847 // Note: we doing multiple value formatting here for address custom fields, plus putting into right format.
848 // The actual formatting (like date, country ..etc) for address custom fields is taken care of while saving
849 // the address in CRM_Core_BAO_Address::create method
850 if (!empty($values['location_type_id'])) {
851 static $customFields = array();
852 if (empty($customFields)) {
853 $customFields = CRM_Core_BAO_CustomField::getFields('Address');
854 }
855 // make a copy of values, as we going to make changes
856 $newValues = $values;
857 foreach ($values as $key => $val) {
858 $customFieldID = CRM_Core_BAO_CustomField::getKeyID($key);
859 if ($customFieldID && array_key_exists($customFieldID, $customFields)) {
860 // mark an entry in fields array since we want the value of custom field to be copied
861 $fields['Address'][$key] = NULL;
862
863 $htmlType = CRM_Utils_Array::value('html_type', $customFields[$customFieldID]);
864 switch ($htmlType) {
865 case 'CheckBox':
866 case 'Multi-Select':
867 if ($val) {
868 $mulValues = explode(',', $val);
869 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
870 $newValues[$key] = array();
871 foreach ($mulValues as $v1) {
872 foreach ($customOption as $v2) {
873 if ((strtolower($v2['label']) == strtolower(trim($v1))) ||
874 (strtolower($v2['value']) == strtolower(trim($v1)))
875 ) {
876 if ($htmlType == 'CheckBox') {
877 $newValues[$key][$v2['value']] = 1;
878 }
879 else {
880 $newValues[$key][] = $v2['value'];
881 }
882 }
883 }
884 }
885 }
886 break;
887 }
888 }
889 }
890 // consider new values
891 $values = $newValues;
892 }
893
894 _civicrm_api3_store_values($fields['Address'], $values, $params['address'][$addressCnt]);
895
896 $addressFields = array(
897 'county',
898 'country',
899 'state_province',
900 'supplemental_address_1',
901 'supplemental_address_2',
902 'supplemental_address_3',
903 'StateProvince.name',
904 );
905
906 foreach ($addressFields as $field) {
907 if (array_key_exists($field, $values)) {
908 if (!array_key_exists('address', $params)) {
909 $params['address'] = array();
910 }
911 $params['address'][$addressCnt][$field] = $values[$field];
912 }
913 }
914
915 if ($addressCnt == 1) {
916
917 $params['address'][$addressCnt]['is_primary'] = TRUE;
918 }
919 return TRUE;
920 }
921
922 if (isset($values['note'])) {
923 // add a note field
924 if (!isset($params['note'])) {
925 $params['note'] = array();
926 }
927 $noteBlock = count($params['note']) + 1;
928
929 $params['note'][$noteBlock] = array();
930 if (!isset($fields['Note'])) {
931 $fields['Note'] = CRM_Core_DAO_Note::fields();
932 }
933
934 // get the current logged in civicrm user
935 $session = CRM_Core_Session::singleton();
936 $userID = $session->get('userID');
937
938 if ($userID) {
939 $values['contact_id'] = $userID;
940 }
941
942 _civicrm_api3_store_values($fields['Note'], $values, $params['note'][$noteBlock]);
943
944 return TRUE;
945 }
946
947 // Check for custom field values
948
949 if (empty($fields['custom'])) {
950 $fields['custom'] = &CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $values),
951 FALSE, FALSE, NULL, NULL, FALSE, FALSE, FALSE
952 );
953 }
954
955 foreach ($values as $key => $value) {
956 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
957 // check if it's a valid custom field id
958
959 if (!array_key_exists($customFieldID, $fields['custom'])) {
960 return civicrm_api3_create_error('Invalid custom field ID');
961 }
962 else {
963 $params[$key] = $value;
964 }
965 }
966 }
967 }
968
969 /**
970 *
971 * @param array $params
972 *
973 * @return array
974 * <type>
975 */
976 function _civicrm_api3_deprecated_duplicate_formatted_contact($params) {
977 $id = CRM_Utils_Array::value('id', $params);
978 $externalId = CRM_Utils_Array::value('external_identifier', $params);
979 if ($id || $externalId) {
980 $contact = new CRM_Contact_DAO_Contact();
981
982 $contact->id = $id;
983 $contact->external_identifier = $externalId;
984
985 if ($contact->find(TRUE)) {
986 if ($params['contact_type'] != $contact->contact_type) {
987 return civicrm_api3_create_error("Mismatched contact IDs OR Mismatched contact Types");
988 }
989
990 $error = CRM_Core_Error::createError("Found matching contacts: $contact->id",
991 CRM_Core_Error::DUPLICATE_CONTACT,
992 'Fatal', $contact->id
993 );
994 return civicrm_api3_create_error($error->pop());
995 }
996 }
997 else {
998 $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($params, $params['contact_type'], 'Unsupervised');
999
1000 if (!empty($ids)) {
1001 $ids = implode(',', $ids);
1002 $error = CRM_Core_Error::createError("Found matching contacts: $ids",
1003 CRM_Core_Error::DUPLICATE_CONTACT,
1004 'Fatal', $ids
1005 );
1006 return civicrm_api3_create_error($error->pop());
1007 }
1008 }
1009 return civicrm_api3_create_success(TRUE);
1010 }
1011
1012 /**
1013 * Validate a formatted contact parameter list.
1014 *
1015 * @param array $params
1016 * Structured parameter list (as in crm_format_params).
1017 *
1018 * @return bool|CRM_Core_Error
1019 */
1020 function _civicrm_api3_deprecated_validate_formatted_contact(&$params) {
1021 // Look for offending email addresses
1022
1023 if (array_key_exists('email', $params)) {
1024 foreach ($params['email'] as $count => $values) {
1025 if (!is_array($values)) {
1026 continue;
1027 }
1028 if ($email = CRM_Utils_Array::value('email', $values)) {
1029 // validate each email
1030 if (!CRM_Utils_Rule::email($email)) {
1031 return civicrm_api3_create_error('No valid email address');
1032 }
1033
1034 // check for loc type id.
1035 if (empty($values['location_type_id'])) {
1036 return civicrm_api3_create_error('Location Type Id missing.');
1037 }
1038 }
1039 }
1040 }
1041
1042 // Validate custom data fields
1043 if (array_key_exists('custom', $params) && is_array($params['custom'])) {
1044 foreach ($params['custom'] as $key => $custom) {
1045 if (is_array($custom)) {
1046 foreach ($custom as $fieldId => $value) {
1047 $valid = CRM_Core_BAO_CustomValue::typecheck(CRM_Utils_Array::value('type', $value),
1048 CRM_Utils_Array::value('value', $value)
1049 );
1050 if (!$valid && $value['is_required']) {
1051 return civicrm_api3_create_error('Invalid value for custom field \'' .
1052 CRM_Utils_Array::value('name', $custom) . '\''
1053 );
1054 }
1055 if (CRM_Utils_Array::value('type', $custom) == 'Date') {
1056 $params['custom'][$key][$fieldId]['value'] = str_replace('-', '', $params['custom'][$key][$fieldId]['value']);
1057 }
1058 }
1059 }
1060 }
1061 }
1062
1063 return civicrm_api3_create_success(TRUE);
1064 }
1065
1066
1067 /**
1068 * @deprecated - this is part of the import parser not the API & needs to be moved on out
1069 *
1070 * @param array $params
1071 * @param $onDuplicate
1072 *
1073 * @return array|bool
1074 * <type>
1075 */
1076 function _civicrm_api3_deprecated_create_participant_formatted($params, $onDuplicate) {
1077 require_once 'CRM/Event/Import/Parser.php';
1078 if ($onDuplicate != CRM_Import_Parser::DUPLICATE_NOCHECK) {
1079 CRM_Core_Error::reset();
1080 $error = _civicrm_api3_deprecated_participant_check_params($params, TRUE);
1081 if (civicrm_error($error)) {
1082 return $error;
1083 }
1084 }
1085 require_once "api/v3/Participant.php";
1086 return civicrm_api3_participant_create($params);
1087 }
1088
1089 /**
1090 *
1091 * @param array $params
1092 *
1093 * @param bool $checkDuplicate
1094 *
1095 * @return array|bool
1096 * <type>
1097 */
1098 function _civicrm_api3_deprecated_participant_check_params($params, $checkDuplicate = FALSE) {
1099
1100 // check if participant id is valid or not
1101 if (!empty($params['id'])) {
1102 $participant = new CRM_Event_BAO_Participant();
1103 $participant->id = $params['id'];
1104 if (!$participant->find(TRUE)) {
1105 return civicrm_api3_create_error(ts('Participant id is not valid'));
1106 }
1107 }
1108 require_once 'CRM/Contact/BAO/Contact.php';
1109 // check if contact id is valid or not
1110 if (!empty($params['contact_id'])) {
1111 $contact = new CRM_Contact_BAO_Contact();
1112 $contact->id = $params['contact_id'];
1113 if (!$contact->find(TRUE)) {
1114 return civicrm_api3_create_error(ts('Contact id is not valid'));
1115 }
1116 }
1117
1118 // check that event id is not an template
1119 if (!empty($params['event_id'])) {
1120 $isTemplate = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $params['event_id'], 'is_template');
1121 if (!empty($isTemplate)) {
1122 return civicrm_api3_create_error(ts('Event templates are not meant to be registered.'));
1123 }
1124 }
1125
1126 $result = array();
1127 if ($checkDuplicate) {
1128 if (CRM_Event_BAO_Participant::checkDuplicate($params, $result)) {
1129 $participantID = array_pop($result);
1130
1131 $error = CRM_Core_Error::createError("Found matching participant record.",
1132 CRM_Core_Error::DUPLICATE_PARTICIPANT,
1133 'Fatal', $participantID
1134 );
1135
1136 return civicrm_api3_create_error($error->pop(),
1137 array(
1138 'contactID' => $params['contact_id'],
1139 'participantID' => $participantID,
1140 )
1141 );
1142 }
1143 }
1144 return TRUE;
1145 }
1146
1147 /**
1148 * Ensure that we have the right input parameters for custom data
1149 *
1150 * @param array $params
1151 * Associative array of property name/value.
1152 * pairs to insert in new contact.
1153 * @param string $csType
1154 * Contact subtype if exists/passed.
1155 *
1156 * @return null
1157 * on success, error message otherwise
1158 */
1159 function _civicrm_api3_deprecated_contact_check_custom_params($params, $csType = NULL) {
1160 empty($csType) ? $onlyParent = TRUE : $onlyParent = FALSE;
1161
1162 require_once 'CRM/Core/BAO/CustomField.php';
1163 $customFields = CRM_Core_BAO_CustomField::getFields($params['contact_type'],
1164 FALSE,
1165 FALSE,
1166 $csType,
1167 NULL,
1168 $onlyParent,
1169 FALSE,
1170 FALSE
1171 );
1172
1173 foreach ($params as $key => $value) {
1174 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
1175 // check if it's a valid custom field id
1176 if (!array_key_exists($customFieldID, $customFields)) {
1177
1178 $errorMsg = "Invalid Custom Field Contact Type: {$params['contact_type']}";
1179 if (!empty($csType)) {
1180 $errorMsg .= " or Mismatched SubType: " . implode(', ', (array) $csType);
1181 }
1182 return civicrm_api3_create_error($errorMsg);
1183 }
1184 }
1185 }
1186 }
1187
1188 /**
1189 * @param array $params
1190 * @param bool $dupeCheck
1191 * @param int $dedupeRuleGroupID
1192 *
1193 * @return array|null
1194 */
1195 function _civicrm_api3_deprecated_contact_check_params(
1196 &$params,
1197 $dupeCheck = TRUE,
1198 $dedupeRuleGroupID = NULL) {
1199
1200 $requiredCheck = TRUE;
1201
1202 if (isset($params['id']) && is_numeric($params['id'])) {
1203 $requiredCheck = FALSE;
1204 }
1205 if ($requiredCheck) {
1206 if (isset($params['id'])) {
1207 $required = array('Individual', 'Household', 'Organization');
1208 }
1209 $required = array(
1210 'Individual' => array(
1211 array('first_name', 'last_name'),
1212 'email',
1213 ),
1214 'Household' => array(
1215 'household_name',
1216 ),
1217 'Organization' => array(
1218 'organization_name',
1219 ),
1220 );
1221
1222 // contact_type has a limited number of valid values
1223 if (empty($params['contact_type'])) {
1224 return civicrm_api3_create_error("No Contact Type");
1225 }
1226 $fields = CRM_Utils_Array::value($params['contact_type'], $required);
1227 if ($fields == NULL) {
1228 return civicrm_api3_create_error("Invalid Contact Type: {$params['contact_type']}");
1229 }
1230
1231 if ($csType = CRM_Utils_Array::value('contact_sub_type', $params)) {
1232 if (!(CRM_Contact_BAO_ContactType::isExtendsContactType($csType, $params['contact_type']))) {
1233 return civicrm_api3_create_error("Invalid or Mismatched Contact Subtype: " . implode(', ', (array) $csType));
1234 }
1235 }
1236
1237 if (empty($params['contact_id']) && !empty($params['id'])) {
1238 $valid = FALSE;
1239 $error = '';
1240 foreach ($fields as $field) {
1241 if (is_array($field)) {
1242 $valid = TRUE;
1243 foreach ($field as $element) {
1244 if (empty($params[$element])) {
1245 $valid = FALSE;
1246 $error .= $element;
1247 break;
1248 }
1249 }
1250 }
1251 else {
1252 if (!empty($params[$field])) {
1253 $valid = TRUE;
1254 }
1255 }
1256 if ($valid) {
1257 break;
1258 }
1259 }
1260
1261 if (!$valid) {
1262 return civicrm_api3_create_error("Required fields not found for {$params['contact_type']} : $error");
1263 }
1264 }
1265 }
1266
1267 if ($dupeCheck) {
1268 // @todo switch to using api version
1269 // $dupes = civicrm_api3('Contact', 'duplicatecheck', (array('match' => $params, 'dedupe_rule_id' => $dedupeRuleGroupID)));
1270 // $ids = $dupes['count'] ? implode(',', array_keys($dupes['values'])) : NULL;
1271 $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($params, $params['contact_type'], 'Unsupervised', array(), CRM_Utils_Array::value('check_permissions', $params, $dedupeRuleGroupID));
1272 if ($ids != NULL) {
1273 $error = CRM_Core_Error::createError("Found matching contacts: " . implode(',', $ids),
1274 CRM_Core_Error::DUPLICATE_CONTACT,
1275 'Fatal', $ids
1276 );
1277 return civicrm_api3_create_error($error->pop());
1278 }
1279 }
1280
1281 // check for organisations with same name
1282 if (!empty($params['current_employer'])) {
1283 $organizationParams = array('organization_name' => $params['current_employer']);
1284 $dupeIds = CRM_Contact_BAO_Contact::getDuplicateContacts($organizationParams, 'Organization', 'Supervised', array(), FALSE);
1285
1286 // check for mismatch employer name and id
1287 if (!empty($params['employer_id']) && !in_array($params['employer_id'], $dupeIds)
1288 ) {
1289 return civicrm_api3_create_error('Employer name and Employer id Mismatch');
1290 }
1291
1292 // show error if multiple organisation with same name exist
1293 if (empty($params['employer_id']) && (count($dupeIds) > 1)
1294 ) {
1295 return civicrm_api3_create_error('Found more than one Organisation with same Name.');
1296 }
1297 }
1298
1299 return NULL;
1300 }
1301
1302 /**
1303 * @param $result
1304 * @param int $activityTypeID
1305 *
1306 * @return array
1307 * <type> $params
1308 */
1309 function _civicrm_api3_deprecated_activity_buildmailparams($result, $activityTypeID) {
1310 // get ready for collecting data about activity to be created
1311 $params = array();
1312
1313 $params['activity_type_id'] = $activityTypeID;
1314
1315 $params['status_id'] = 'Completed';
1316 if (!empty($result['from']['id'])) {
1317 $params['source_contact_id'] = $params['assignee_contact_id'] = $result['from']['id'];
1318 }
1319 $params['target_contact_id'] = array();
1320 $keys = array('to', 'cc', 'bcc');
1321 foreach ($keys as $key) {
1322 if (is_array($result[$key])) {
1323 foreach ($result[$key] as $key => $keyValue) {
1324 if (!empty($keyValue['id'])) {
1325 $params['target_contact_id'][] = $keyValue['id'];
1326 }
1327 }
1328 }
1329 }
1330 $params['subject'] = $result['subject'];
1331 $params['activity_date_time'] = $result['date'];
1332 $params['details'] = $result['body'];
1333
1334 for ($i = 1; $i <= 5; $i++) {
1335 if (isset($result["attachFile_$i"])) {
1336 $params["attachFile_$i"] = $result["attachFile_$i"];
1337 }
1338 }
1339
1340 return $params;
1341 }