Merge pull request #10763 from JMAConsulting/CRM-20967
[civicrm-core.git] / CRM / Utils / DeprecatedUtils.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
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-2017
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/OptionGroup.php';
246 $values['payment_instrument_id'] = CRM_Core_OptionGroup::getValue('payment_instrument', $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/OptionGroup.php';
254 if (!$values['contribution_status_id'] = CRM_Core_OptionGroup::getValue('contribution_status', $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 if (is_array($field)) {
488 foreach ($field as $value) {
489 $break = FALSE;
490 if (is_array($value)) {
491 foreach ($value as $name => $testForEmpty) {
492 if ($name !== 'phone_type' &&
493 ($testForEmpty === '' || $testForEmpty == NULL)
494 ) {
495 $break = TRUE;
496 break;
497 }
498 }
499 }
500 else {
501 $break = TRUE;
502 }
503 if (!$break) {
504 _civicrm_api3_deprecated_add_formatted_param($value, $contactFormatted);
505 }
506 }
507 continue;
508 }
509
510 $value = array($key => $field);
511
512 // check if location related field, then we need to add primary location type
513 if (in_array($key, $locationFields)) {
514 $value['location_type_id'] = $defaultLocationId;
515 }
516 elseif (array_key_exists($key, $cIndieFields)) {
517 $value['contact_type'] = $contactType;
518 }
519
520 _civicrm_api3_deprecated_add_formatted_param($value, $contactFormatted);
521 }
522
523 $contactFormatted['contact_type'] = $contactType;
524
525 return _civicrm_api3_deprecated_duplicate_formatted_contact($contactFormatted);
526 }
527
528 /**
529 * take the input parameter list as specified in the data model and
530 * convert it into the same format that we use in QF and BAO object
531 *
532 * @param array $params
533 * Associative array of property name/value.
534 * pairs to insert in new contact.
535 * @param array $values
536 * The reformatted properties that we can use internally.
537 *
538 * @param array|bool $create Is the formatted Values array going to
539 * be used for CRM_Activity_BAO_Activity::create()
540 *
541 * @return array|CRM_Error
542 */
543 function _civicrm_api3_deprecated_activity_formatted_param(&$params, &$values, $create = FALSE) {
544 // copy all the activity fields as is
545 $fields = CRM_Activity_DAO_Activity::fields();
546 _civicrm_api3_store_values($fields, $params, $values);
547
548 require_once 'CRM/Core/OptionGroup.php';
549 $customFields = CRM_Core_BAO_CustomField::getFields('Activity');
550
551 foreach ($params as $key => $value) {
552 // ignore empty values or empty arrays etc
553 if (CRM_Utils_System::isNull($value)) {
554 continue;
555 }
556
557 //Handling Custom Data
558 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
559 $values[$key] = $value;
560 $type = $customFields[$customFieldID]['html_type'];
561 if ($type == 'CheckBox' || $type == 'Multi-Select') {
562 $mulValues = explode(',', $value);
563 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
564 $values[$key] = array();
565 foreach ($mulValues as $v1) {
566 foreach ($customOption as $customValueID => $customLabel) {
567 $customValue = $customLabel['value'];
568 if ((strtolower(trim($customLabel['label'])) == strtolower(trim($v1))) ||
569 (strtolower(trim($customValue)) == strtolower(trim($v1)))
570 ) {
571 if ($type == 'CheckBox') {
572 $values[$key][$customValue] = 1;
573 }
574 else {
575 $values[$key][] = $customValue;
576 }
577 }
578 }
579 }
580 }
581 elseif ($type == 'Select' || $type == 'Radio') {
582 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
583 foreach ($customOption as $customFldID => $customValue) {
584 $val = CRM_Utils_Array::value('value', $customValue);
585 $label = CRM_Utils_Array::value('label', $customValue);
586 $label = strtolower($label);
587 $value = strtolower(trim($value));
588 if (($value == $label) || ($value == strtolower($val))) {
589 $values[$key] = $val;
590 }
591 }
592 }
593 }
594
595 if ($key == 'target_contact_id') {
596 if (!CRM_Utils_Rule::integer($value)) {
597 return civicrm_api3_create_error("contact_id not valid: $value");
598 }
599 $contactID = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_contact WHERE id = $value");
600 if (!$contactID) {
601 return civicrm_api3_create_error("Invalid Contact ID: There is no contact record with contact_id = $value.");
602 }
603 }
604 }
605 return NULL;
606 }
607
608 /**
609 * This function adds the contact variable in $values to the
610 * parameter list $params. For most cases, $values should have length 1. If
611 * the variable being added is a child of Location, a location_type_id must
612 * also be included. If it is a child of phone, a phone_type must be included.
613 *
614 * @param array $values
615 * The variable(s) to be added.
616 * @param array $params
617 * The structured parameter list.
618 *
619 * @return bool|CRM_Utils_Error
620 */
621 function _civicrm_api3_deprecated_add_formatted_param(&$values, &$params) {
622 // Crawl through the possible classes:
623 // Contact
624 // Individual
625 // Household
626 // Organization
627 // Location
628 // Address
629 // Email
630 // Phone
631 // IM
632 // Note
633 // Custom
634
635 // Cache the various object fields
636 static $fields = NULL;
637
638 if ($fields == NULL) {
639 $fields = array();
640 }
641
642 // first add core contact values since for other Civi modules they are not added
643 require_once 'CRM/Contact/BAO/Contact.php';
644 $contactFields = CRM_Contact_DAO_Contact::fields();
645 _civicrm_api3_store_values($contactFields, $values, $params);
646
647 if (isset($values['contact_type'])) {
648 // we're an individual/household/org property
649
650 $fields[$values['contact_type']] = CRM_Contact_DAO_Contact::fields();
651
652 _civicrm_api3_store_values($fields[$values['contact_type']], $values, $params);
653 return TRUE;
654 }
655
656 if (isset($values['individual_prefix'])) {
657 if (!empty($params['prefix_id'])) {
658 $prefixes = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'prefix_id');
659 $params['prefix'] = $prefixes[$params['prefix_id']];
660 }
661 else {
662 $params['prefix'] = $values['individual_prefix'];
663 }
664 return TRUE;
665 }
666
667 if (isset($values['individual_suffix'])) {
668 if (!empty($params['suffix_id'])) {
669 $suffixes = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'suffix_id');
670 $params['suffix'] = $suffixes[$params['suffix_id']];
671 }
672 else {
673 $params['suffix'] = $values['individual_suffix'];
674 }
675 return TRUE;
676 }
677
678 // CRM-4575
679 if (isset($values['email_greeting'])) {
680 if (!empty($params['email_greeting_id'])) {
681 $emailGreetingFilter = array(
682 'contact_type' => CRM_Utils_Array::value('contact_type', $params),
683 'greeting_type' => 'email_greeting',
684 );
685 $emailGreetings = CRM_Core_PseudoConstant::greeting($emailGreetingFilter);
686 $params['email_greeting'] = $emailGreetings[$params['email_greeting_id']];
687 }
688 else {
689 $params['email_greeting'] = $values['email_greeting'];
690 }
691
692 return TRUE;
693 }
694
695 if (isset($values['postal_greeting'])) {
696 if (!empty($params['postal_greeting_id'])) {
697 $postalGreetingFilter = array(
698 'contact_type' => CRM_Utils_Array::value('contact_type', $params),
699 'greeting_type' => 'postal_greeting',
700 );
701 $postalGreetings = CRM_Core_PseudoConstant::greeting($postalGreetingFilter);
702 $params['postal_greeting'] = $postalGreetings[$params['postal_greeting_id']];
703 }
704 else {
705 $params['postal_greeting'] = $values['postal_greeting'];
706 }
707 return TRUE;
708 }
709
710 if (isset($values['addressee'])) {
711 if (!empty($params['addressee_id'])) {
712 $addresseeFilter = array(
713 'contact_type' => CRM_Utils_Array::value('contact_type', $params),
714 'greeting_type' => 'addressee',
715 );
716 $addressee = CRM_Core_PseudoConstant::addressee($addresseeFilter);
717 $params['addressee'] = $addressee[$params['addressee_id']];
718 }
719 else {
720 $params['addressee'] = $values['addressee'];
721 }
722 return TRUE;
723 }
724
725 if (isset($values['gender'])) {
726 if (!empty($params['gender_id'])) {
727 $genders = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
728 $params['gender'] = $genders[$params['gender_id']];
729 }
730 else {
731 $params['gender'] = $values['gender'];
732 }
733 return TRUE;
734 }
735
736 if (!empty($values['preferred_communication_method'])) {
737 $comm = array();
738 $pcm = array_change_key_case(array_flip(CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method')), CASE_LOWER);
739
740 $preffComm = explode(',', $values['preferred_communication_method']);
741 foreach ($preffComm as $v) {
742 $v = strtolower(trim($v));
743 if (array_key_exists($v, $pcm)) {
744 $comm[$pcm[$v]] = 1;
745 }
746 }
747
748 $params['preferred_communication_method'] = $comm;
749 return TRUE;
750 }
751
752 // format the website params.
753 if (!empty($values['url'])) {
754 static $websiteFields;
755 if (!is_array($websiteFields)) {
756 require_once 'CRM/Core/DAO/Website.php';
757 $websiteFields = CRM_Core_DAO_Website::fields();
758 }
759 if (!array_key_exists('website', $params) ||
760 !is_array($params['website'])
761 ) {
762 $params['website'] = array();
763 }
764
765 $websiteCount = count($params['website']);
766 _civicrm_api3_store_values($websiteFields, $values,
767 $params['website'][++$websiteCount]
768 );
769
770 return TRUE;
771 }
772
773 // get the formatted location blocks into params - w/ 3.0 format, CRM-4605
774 if (!empty($values['location_type_id'])) {
775 static $fields = NULL;
776 if ($fields == NULL) {
777 $fields = array();
778 }
779
780 foreach (array(
781 'Phone',
782 'Email',
783 'IM',
784 'OpenID',
785 'Phone_Ext',
786 ) as $block) {
787 $name = strtolower($block);
788 if (!array_key_exists($name, $values)) {
789 continue;
790 }
791
792 if ($name == 'phone_ext') {
793 $block = 'Phone';
794 }
795
796 // block present in value array.
797 if (!array_key_exists($name, $params) || !is_array($params[$name])) {
798 $params[$name] = array();
799 }
800
801 if (!array_key_exists($block, $fields)) {
802 $className = "CRM_Core_DAO_$block";
803 $fields[$block] =& $className::fields();
804 }
805
806 $blockCnt = count($params[$name]);
807
808 // copy value to dao field name.
809 if ($name == 'im') {
810 $values['name'] = $values[$name];
811 }
812
813 _civicrm_api3_store_values($fields[$block], $values,
814 $params[$name][++$blockCnt]
815 );
816
817 if (empty($params['id']) && ($blockCnt == 1)) {
818 $params[$name][$blockCnt]['is_primary'] = TRUE;
819 }
820
821 // we only process single block at a time.
822 return TRUE;
823 }
824
825 // handle address fields.
826 if (!array_key_exists('address', $params) || !is_array($params['address'])) {
827 $params['address'] = array();
828 }
829
830 $addressCnt = 1;
831 foreach ($params['address'] as $cnt => $addressBlock) {
832 if (CRM_Utils_Array::value('location_type_id', $values) ==
833 CRM_Utils_Array::value('location_type_id', $addressBlock)
834 ) {
835 $addressCnt = $cnt;
836 break;
837 }
838 $addressCnt++;
839 }
840
841 if (!array_key_exists('Address', $fields)) {
842 $fields['Address'] = CRM_Core_DAO_Address::fields();
843 }
844
845 // Note: we doing multiple value formatting here for address custom fields, plus putting into right format.
846 // The actual formatting (like date, country ..etc) for address custom fields is taken care of while saving
847 // the address in CRM_Core_BAO_Address::create method
848 if (!empty($values['location_type_id'])) {
849 static $customFields = array();
850 if (empty($customFields)) {
851 $customFields = CRM_Core_BAO_CustomField::getFields('Address');
852 }
853 // make a copy of values, as we going to make changes
854 $newValues = $values;
855 foreach ($values as $key => $val) {
856 $customFieldID = CRM_Core_BAO_CustomField::getKeyID($key);
857 if ($customFieldID && array_key_exists($customFieldID, $customFields)) {
858 // mark an entry in fields array since we want the value of custom field to be copied
859 $fields['Address'][$key] = NULL;
860
861 $htmlType = CRM_Utils_Array::value('html_type', $customFields[$customFieldID]);
862 switch ($htmlType) {
863 case 'CheckBox':
864 case 'AdvMulti-Select':
865 case 'Multi-Select':
866 if ($val) {
867 $mulValues = explode(',', $val);
868 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, TRUE);
869 $newValues[$key] = array();
870 foreach ($mulValues as $v1) {
871 foreach ($customOption as $v2) {
872 if ((strtolower($v2['label']) == strtolower(trim($v1))) ||
873 (strtolower($v2['value']) == strtolower(trim($v1)))
874 ) {
875 if ($htmlType == 'CheckBox') {
876 $newValues[$key][$v2['value']] = 1;
877 }
878 else {
879 $newValues[$key][] = $v2['value'];
880 }
881 }
882 }
883 }
884 }
885 break;
886 }
887 }
888 }
889 // consider new values
890 $values = $newValues;
891 }
892
893 _civicrm_api3_store_values($fields['Address'], $values, $params['address'][$addressCnt]);
894
895 $addressFields = array(
896 'county',
897 'country',
898 'state_province',
899 'supplemental_address_1',
900 'supplemental_address_2',
901 'supplemental_address_3',
902 'StateProvince.name',
903 );
904
905 foreach ($addressFields as $field) {
906 if (array_key_exists($field, $values)) {
907 if (!array_key_exists('address', $params)) {
908 $params['address'] = array();
909 }
910 $params['address'][$addressCnt][$field] = $values[$field];
911 }
912 }
913
914 if ($addressCnt == 1) {
915
916 $params['address'][$addressCnt]['is_primary'] = TRUE;
917 }
918 return TRUE;
919 }
920
921 if (isset($values['note'])) {
922 // add a note field
923 if (!isset($params['note'])) {
924 $params['note'] = array();
925 }
926 $noteBlock = count($params['note']) + 1;
927
928 $params['note'][$noteBlock] = array();
929 if (!isset($fields['Note'])) {
930 $fields['Note'] = CRM_Core_DAO_Note::fields();
931 }
932
933 // get the current logged in civicrm user
934 $session = CRM_Core_Session::singleton();
935 $userID = $session->get('userID');
936
937 if ($userID) {
938 $values['contact_id'] = $userID;
939 }
940
941 _civicrm_api3_store_values($fields['Note'], $values, $params['note'][$noteBlock]);
942
943 return TRUE;
944 }
945
946 // Check for custom field values
947
948 if (empty($fields['custom'])) {
949 $fields['custom'] = &CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $values),
950 FALSE, FALSE, NULL, NULL, FALSE, FALSE, FALSE
951 );
952 }
953
954 foreach ($values as $key => $value) {
955 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
956 // check if it's a valid custom field id
957
958 if (!array_key_exists($customFieldID, $fields['custom'])) {
959 return civicrm_api3_create_error('Invalid custom field ID');
960 }
961 else {
962 $params[$key] = $value;
963 }
964 }
965 }
966 }
967
968 /**
969 *
970 * @param array $params
971 *
972 * @return array
973 * <type>
974 */
975 function _civicrm_api3_deprecated_duplicate_formatted_contact($params) {
976 $id = CRM_Utils_Array::value('id', $params);
977 $externalId = CRM_Utils_Array::value('external_identifier', $params);
978 if ($id || $externalId) {
979 $contact = new CRM_Contact_DAO_Contact();
980
981 $contact->id = $id;
982 $contact->external_identifier = $externalId;
983
984 if ($contact->find(TRUE)) {
985 if ($params['contact_type'] != $contact->contact_type) {
986 return civicrm_api3_create_error("Mismatched contact IDs OR Mismatched contact Types");
987 }
988
989 $error = CRM_Core_Error::createError("Found matching contacts: $contact->id",
990 CRM_Core_Error::DUPLICATE_CONTACT,
991 'Fatal', $contact->id
992 );
993 return civicrm_api3_create_error($error->pop());
994 }
995 }
996 else {
997 $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($params, $params['contact_type'], 'Unsupervised');
998
999 if (!empty($ids)) {
1000 $ids = implode(',', $ids);
1001 $error = CRM_Core_Error::createError("Found matching contacts: $ids",
1002 CRM_Core_Error::DUPLICATE_CONTACT,
1003 'Fatal', $ids
1004 );
1005 return civicrm_api3_create_error($error->pop());
1006 }
1007 }
1008 return civicrm_api3_create_success(TRUE);
1009 }
1010
1011 /**
1012 * Validate a formatted contact parameter list.
1013 *
1014 * @param array $params
1015 * Structured parameter list (as in crm_format_params).
1016 *
1017 * @return bool|CRM_Core_Error
1018 */
1019 function _civicrm_api3_deprecated_validate_formatted_contact(&$params) {
1020 // Look for offending email addresses
1021
1022 if (array_key_exists('email', $params)) {
1023 foreach ($params['email'] as $count => $values) {
1024 if (!is_array($values)) {
1025 continue;
1026 }
1027 if ($email = CRM_Utils_Array::value('email', $values)) {
1028 // validate each email
1029 if (!CRM_Utils_Rule::email($email)) {
1030 return civicrm_api3_create_error('No valid email address');
1031 }
1032
1033 // check for loc type id.
1034 if (empty($values['location_type_id'])) {
1035 return civicrm_api3_create_error('Location Type Id missing.');
1036 }
1037 }
1038 }
1039 }
1040
1041 // Validate custom data fields
1042 if (array_key_exists('custom', $params) && is_array($params['custom'])) {
1043 foreach ($params['custom'] as $key => $custom) {
1044 if (is_array($custom)) {
1045 foreach ($custom as $fieldId => $value) {
1046 $valid = CRM_Core_BAO_CustomValue::typecheck(CRM_Utils_Array::value('type', $value),
1047 CRM_Utils_Array::value('value', $value)
1048 );
1049 if (!$valid && $value['is_required']) {
1050 return civicrm_api3_create_error('Invalid value for custom field \'' .
1051 CRM_Utils_Array::value('name', $custom) . '\''
1052 );
1053 }
1054 if (CRM_Utils_Array::value('type', $custom) == 'Date') {
1055 $params['custom'][$key][$fieldId]['value'] = str_replace('-', '', $params['custom'][$key][$fieldId]['value']);
1056 }
1057 }
1058 }
1059 }
1060 }
1061
1062 return civicrm_api3_create_success(TRUE);
1063 }
1064
1065
1066 /**
1067 * @deprecated - this is part of the import parser not the API & needs to be moved on out
1068 *
1069 * @param array $params
1070 * @param $onDuplicate
1071 *
1072 * @return array|bool
1073 * <type>
1074 */
1075 function _civicrm_api3_deprecated_create_participant_formatted($params, $onDuplicate) {
1076 require_once 'CRM/Event/Import/Parser.php';
1077 if ($onDuplicate != CRM_Import_Parser::DUPLICATE_NOCHECK) {
1078 CRM_Core_Error::reset();
1079 $error = _civicrm_api3_deprecated_participant_check_params($params, TRUE);
1080 if (civicrm_error($error)) {
1081 return $error;
1082 }
1083 }
1084 require_once "api/v3/Participant.php";
1085 return civicrm_api3_participant_create($params);
1086 }
1087
1088 /**
1089 *
1090 * @param array $params
1091 *
1092 * @param bool $checkDuplicate
1093 *
1094 * @return array|bool
1095 * <type>
1096 */
1097 function _civicrm_api3_deprecated_participant_check_params($params, $checkDuplicate = FALSE) {
1098
1099 // check if participant id is valid or not
1100 if (!empty($params['id'])) {
1101 $participant = new CRM_Event_BAO_Participant();
1102 $participant->id = $params['id'];
1103 if (!$participant->find(TRUE)) {
1104 return civicrm_api3_create_error(ts('Participant id is not valid'));
1105 }
1106 }
1107 require_once 'CRM/Contact/BAO/Contact.php';
1108 // check if contact id is valid or not
1109 if (!empty($params['contact_id'])) {
1110 $contact = new CRM_Contact_BAO_Contact();
1111 $contact->id = $params['contact_id'];
1112 if (!$contact->find(TRUE)) {
1113 return civicrm_api3_create_error(ts('Contact id is not valid'));
1114 }
1115 }
1116
1117 // check that event id is not an template
1118 if (!empty($params['event_id'])) {
1119 $isTemplate = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $params['event_id'], 'is_template');
1120 if (!empty($isTemplate)) {
1121 return civicrm_api3_create_error(ts('Event templates are not meant to be registered.'));
1122 }
1123 }
1124
1125 $result = array();
1126 if ($checkDuplicate) {
1127 if (CRM_Event_BAO_Participant::checkDuplicate($params, $result)) {
1128 $participantID = array_pop($result);
1129
1130 $error = CRM_Core_Error::createError("Found matching participant record.",
1131 CRM_Core_Error::DUPLICATE_PARTICIPANT,
1132 'Fatal', $participantID
1133 );
1134
1135 return civicrm_api3_create_error($error->pop(),
1136 array(
1137 'contactID' => $params['contact_id'],
1138 'participantID' => $participantID,
1139 )
1140 );
1141 }
1142 }
1143 return TRUE;
1144 }
1145
1146 /**
1147 * Ensure that we have the right input parameters for custom data
1148 *
1149 * @param array $params
1150 * Associative array of property name/value.
1151 * pairs to insert in new contact.
1152 * @param string $csType
1153 * Contact subtype if exists/passed.
1154 *
1155 * @return null
1156 * on success, error message otherwise
1157 */
1158 function _civicrm_api3_deprecated_contact_check_custom_params($params, $csType = NULL) {
1159 empty($csType) ? $onlyParent = TRUE : $onlyParent = FALSE;
1160
1161 require_once 'CRM/Core/BAO/CustomField.php';
1162 $customFields = CRM_Core_BAO_CustomField::getFields($params['contact_type'],
1163 FALSE,
1164 FALSE,
1165 $csType,
1166 NULL,
1167 $onlyParent,
1168 FALSE,
1169 FALSE
1170 );
1171
1172 foreach ($params as $key => $value) {
1173 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
1174 // check if it's a valid custom field id
1175 if (!array_key_exists($customFieldID, $customFields)) {
1176
1177 $errorMsg = "Invalid Custom Field Contact Type: {$params['contact_type']}";
1178 if (!empty($csType)) {
1179 $errorMsg .= " or Mismatched SubType: " . implode(', ', (array) $csType);
1180 }
1181 return civicrm_api3_create_error($errorMsg);
1182 }
1183 }
1184 }
1185 }
1186
1187 /**
1188 * @param array $params
1189 * @param bool $dupeCheck
1190 * @param int $dedupeRuleGroupID
1191 *
1192 * @return array|null
1193 */
1194 function _civicrm_api3_deprecated_contact_check_params(
1195 &$params,
1196 $dupeCheck = TRUE,
1197 $dedupeRuleGroupID = NULL) {
1198
1199 $requiredCheck = TRUE;
1200
1201 if (isset($params['id']) && is_numeric($params['id'])) {
1202 $requiredCheck = FALSE;
1203 }
1204 if ($requiredCheck) {
1205 if (isset($params['id'])) {
1206 $required = array('Individual', 'Household', 'Organization');
1207 }
1208 $required = array(
1209 'Individual' => array(
1210 array('first_name', 'last_name'),
1211 'email',
1212 ),
1213 'Household' => array(
1214 'household_name',
1215 ),
1216 'Organization' => array(
1217 'organization_name',
1218 ),
1219 );
1220
1221 // contact_type has a limited number of valid values
1222 if (empty($params['contact_type'])) {
1223 return civicrm_api3_create_error("No Contact Type");
1224 }
1225 $fields = CRM_Utils_Array::value($params['contact_type'], $required);
1226 if ($fields == NULL) {
1227 return civicrm_api3_create_error("Invalid Contact Type: {$params['contact_type']}");
1228 }
1229
1230 if ($csType = CRM_Utils_Array::value('contact_sub_type', $params)) {
1231 if (!(CRM_Contact_BAO_ContactType::isExtendsContactType($csType, $params['contact_type']))) {
1232 return civicrm_api3_create_error("Invalid or Mismatched Contact Subtype: " . implode(', ', (array) $csType));
1233 }
1234 }
1235
1236 if (empty($params['contact_id']) && !empty($params['id'])) {
1237 $valid = FALSE;
1238 $error = '';
1239 foreach ($fields as $field) {
1240 if (is_array($field)) {
1241 $valid = TRUE;
1242 foreach ($field as $element) {
1243 if (empty($params[$element])) {
1244 $valid = FALSE;
1245 $error .= $element;
1246 break;
1247 }
1248 }
1249 }
1250 else {
1251 if (!empty($params[$field])) {
1252 $valid = TRUE;
1253 }
1254 }
1255 if ($valid) {
1256 break;
1257 }
1258 }
1259
1260 if (!$valid) {
1261 return civicrm_api3_create_error("Required fields not found for {$params['contact_type']} : $error");
1262 }
1263 }
1264 }
1265
1266 if ($dupeCheck) {
1267 // @todo switch to using api version
1268 // $dupes = civicrm_api3('Contact', 'duplicatecheck', (array('match' => $params, 'dedupe_rule_id' => $dedupeRuleGroupID)));
1269 // $ids = $dupes['count'] ? implode(',', array_keys($dupes['values'])) : NULL;
1270 $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($params, $params['contact_type'], 'Unsupervised', array(), CRM_Utils_Array::value('check_permissions', $params, $dedupeRuleGroupID));
1271 if ($ids != NULL) {
1272 $error = CRM_Core_Error::createError("Found matching contacts: " . implode(',', $ids),
1273 CRM_Core_Error::DUPLICATE_CONTACT,
1274 'Fatal', $ids
1275 );
1276 return civicrm_api3_create_error($error->pop());
1277 }
1278 }
1279
1280 // check for organisations with same name
1281 if (!empty($params['current_employer'])) {
1282 $organizationParams = array('organization_name' => $params['current_employer']);
1283 $dupeIds = CRM_Contact_BAO_Contact::getDuplicateContacts($organizationParams, 'Organization', 'Supervised', array(), FALSE);
1284
1285 // check for mismatch employer name and id
1286 if (!empty($params['employer_id']) && !in_array($params['employer_id'], $dupeIds)
1287 ) {
1288 return civicrm_api3_create_error('Employer name and Employer id Mismatch');
1289 }
1290
1291 // show error if multiple organisation with same name exist
1292 if (empty($params['employer_id']) && (count($dupeIds) > 1)
1293 ) {
1294 return civicrm_api3_create_error('Found more than one Organisation with same Name.');
1295 }
1296 }
1297
1298 return NULL;
1299 }
1300
1301 /**
1302 * @param $result
1303 * @param int $activityTypeID
1304 *
1305 * @return array
1306 * <type> $params
1307 */
1308 function _civicrm_api3_deprecated_activity_buildmailparams($result, $activityTypeID) {
1309 // get ready for collecting data about activity to be created
1310 $params = array();
1311
1312 $params['activity_type_id'] = $activityTypeID;
1313
1314 $params['status_id'] = 'Completed';
1315 if (!empty($result['from']['id'])) {
1316 $params['source_contact_id'] = $params['assignee_contact_id'] = $result['from']['id'];
1317 }
1318 $params['target_contact_id'] = array();
1319 $keys = array('to', 'cc', 'bcc');
1320 foreach ($keys as $key) {
1321 if (is_array($result[$key])) {
1322 foreach ($result[$key] as $key => $keyValue) {
1323 if (!empty($keyValue['id'])) {
1324 $params['target_contact_id'][] = $keyValue['id'];
1325 }
1326 }
1327 }
1328 }
1329 $params['subject'] = $result['subject'];
1330 $params['activity_date_time'] = $result['date'];
1331 $params['details'] = $result['body'];
1332
1333 for ($i = 1; $i <= 5; $i++) {
1334 if (isset($result["attachFile_$i"])) {
1335 $params["attachFile_$i"] = $result["attachFile_$i"];
1336 }
1337 }
1338
1339 return $params;
1340 }