Merge pull request #3304 from pratik-joshi/CRM-14704
[civicrm-core.git] / CRM / Member / Import / Parser / Membership.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
06b69b18 4 | CiviCRM version 4.5 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
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
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35
36
37require_once 'api/api.php';
38
39/**
40 * class to parse membership csv files
41 */
42class CRM_Member_Import_Parser_Membership extends CRM_Member_Import_Parser {
43
44 protected $_mapperKeys;
45
46 private $_contactIdIndex;
47 private $_totalAmountIndex;
48 private $_membershipTypeIndex;
49 private $_membershipStatusIndex;
50
51 /**
ceb10dc7 52 * Array of successfully imported membership id's
6a488035
TO
53 *
54 * @array
55 */
56 protected $_newMemberships;
57
58 /**
59 * class constructor
60 */
61 function __construct(&$mapperKeys, $mapperLocType = NULL, $mapperPhoneType = NULL) {
62 parent::__construct();
63 $this->_mapperKeys = &$mapperKeys;
64 }
65
66 /**
67 * the initializer code, called before the processing
68 *
69 * @return void
70 * @access public
71 */
72 function init() {
73 $fields = CRM_Member_BAO_Membership::importableFields($this->_contactType, FALSE);
74
75 foreach ($fields as $name => $field) {
76 $field['type'] = CRM_Utils_Array::value('type', $field, CRM_Utils_Type::T_INT);
77 $field['dataPattern'] = CRM_Utils_Array::value('dataPattern', $field, '//');
78 $field['headerPattern'] = CRM_Utils_Array::value('headerPattern', $field, '//');
79 $this->addField($name, $field['title'], $field['type'], $field['headerPattern'], $field['dataPattern']);
80 }
81
82 $this->_newMemberships = array();
83
84 $this->setActiveFields($this->_mapperKeys);
85
86 // FIXME: we should do this in one place together with Form/MapField.php
87 $this->_contactIdIndex = -1;
88 $this->_membershipTypeIndex = -1;
89 $this->_membershipStatusIndex = -1;
90
91 $index = 0;
92 foreach ($this->_mapperKeys as $key) {
93 switch ($key) {
94 case 'membership_contact_id':
95 $this->_contactIdIndex = $index;
96 break;
97
98 case 'membership_type_id':
99 $this->_membershipTypeIndex = $index;
100 break;
101
102 case 'status_id':
103 $this->_membershipStatusIndex = $index;
104 break;
105 }
106 $index++;
107 }
108 }
109
110 /**
111 * handle the values in mapField mode
112 *
113 * @param array $values the array of values belonging to this line
114 *
115 * @return boolean
116 * @access public
117 */
118 function mapField(&$values) {
a05662ef 119 return CRM_Import_Parser::VALID;
6a488035
TO
120 }
121
122 /**
123 * handle the values in preview mode
124 *
125 * @param array $values the array of values belonging to this line
126 *
127 * @return boolean the result of this processing
128 * @access public
129 */
130 function preview(&$values) {
131 return $this->summary($values);
132 }
133
134 /**
135 * handle the values in summary mode
136 *
137 * @param array $values the array of values belonging to this line
138 *
139 * @return boolean the result of this processing
140 * @access public
141 */
142 function summary(&$values) {
143 $erroneousField = NULL;
144 $response = $this->setActiveFieldValues($values, $erroneousField);
145
146 $errorRequired = FALSE;
147
148 if ($this->_membershipTypeIndex < 0) {
149 $errorRequired = TRUE;
150 }
151 else {
152 $errorRequired = !CRM_Utils_Array::value($this->_membershipTypeIndex, $values);
153 }
154
155 if ($errorRequired) {
156 array_unshift($values, ts('Missing required fields'));
a05662ef 157 return CRM_Import_Parser::ERROR;
6a488035
TO
158 }
159
160 $params = &$this->getActiveFieldParams();
161 $errorMessage = NULL;
162
163 //To check whether start date or join date is provided
8cc574cf 164 if (empty($params['membership_start_date']) && empty($params['join_date'])) {
6a488035 165 $errorMessage = 'Membership Start Date is required to create a memberships.';
719a6fec 166 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Start Date', $errorMessage);
6a488035
TO
167 }
168 //end
169
170 //for date-Formats
171 $session = CRM_Core_Session::singleton();
172 $dateType = $session->get('dateTypes');
173 foreach ($params as $key => $val) {
174
175 if ($val) {
176 switch ($key) {
177 case 'join_date':
178 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
179 if (!CRM_Utils_Rule::date($params[$key])) {
719a6fec 180 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Member Since', $errorMessage);
6a488035
TO
181 }
182 }
183 else {
719a6fec 184 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Member Since', $errorMessage);
6a488035
TO
185 }
186 break;
187
188 case 'membership_start_date':
189 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
190 if (!CRM_Utils_Rule::date($params[$key])) {
719a6fec 191 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Start Date', $errorMessage);
6a488035
TO
192 }
193 }
194 else {
719a6fec 195 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Start Date', $errorMessage);
6a488035
TO
196 }
197 break;
198
199 case 'membership_end_date':
200 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
201 if (!CRM_Utils_Rule::date($params[$key])) {
719a6fec 202 CRM_Contact_Import_Parser_Contact::addToErrorMsg('End date', $errorMessage);
6a488035
TO
203 }
204 }
205 else {
719a6fec 206 CRM_Contact_Import_Parser_Contact::addToErrorMsg('End date', $errorMessage);
6a488035
TO
207 }
208 break;
209
210 case 'membership_type_id':
211 $membershipTypes = CRM_Member_PseudoConstant::membershipType();
212 if (!CRM_Utils_Array::crmInArray($val, $membershipTypes) &&
213 !array_key_exists($val, $membershipTypes)
214 ) {
719a6fec 215 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Membership Type', $errorMessage);
6a488035
TO
216 }
217 break;
218
219 case 'status_id':
220 if (!CRM_Utils_Array::crmInArray($val, CRM_Member_PseudoConstant::membershipStatus())) {
719a6fec 221 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Membership Status', $errorMessage);
6a488035
TO
222 }
223 break;
224
225 case 'email':
226 if (!CRM_Utils_Rule::email($val)) {
719a6fec 227 CRM_Contact_Import_Parser_Contact::addToErrorMsg('Email Address', $errorMessage);
6a488035
TO
228 }
229 }
230 }
231 }
232 //date-Format part ends
233
234 $params['contact_type'] = 'Membership';
235
236 //checking error in custom data
719a6fec 237 CRM_Contact_Import_Parser_Contact::isErrorInCustomData($params, $errorMessage);
6a488035
TO
238
239 if ($errorMessage) {
240 $tempMsg = "Invalid value for field(s) : $errorMessage";
241 array_unshift($values, $tempMsg);
242 $errorMessage = NULL;
a05662ef 243 return CRM_Import_Parser::ERROR;
6a488035
TO
244 }
245
a05662ef 246 return CRM_Import_Parser::VALID;
6a488035
TO
247 }
248
249 /**
250 * handle the values in import mode
251 *
252 * @param int $onDuplicate the code for what action to take on duplicates
253 * @param array $values the array of values belonging to this line
254 *
255 * @return boolean the result of this processing
256 * @access public
257 */
258 function import($onDuplicate, &$values) {
f719e41c 259 try{
4f7b71ab 260 // first make sure this is a valid line
261 $response = $this->summary($values);
262 if ($response != CRM_Import_Parser::VALID) {
263 return $response;
264 }
6a488035 265
4f7b71ab 266 $params = &$this->getActiveFieldParams();
6a488035 267
4f7b71ab 268 //assign join date equal to start date if join date is not provided
8cc574cf 269 if (empty($params['join_date']) && !empty($params['membership_start_date'])) {
4f7b71ab 270 $params['join_date'] = $params['membership_start_date'];
271 }
6a488035 272
4f7b71ab 273 $session = CRM_Core_Session::singleton();
274 $dateType = $session->get('dateTypes');
275 $formatted = array();
276 $customFields = CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $params));
277
278 // don't add to recent items, CRM-4399
279 $formatted['skipRecentView'] = TRUE;
280 $dateLabels = array(
281 'join_date' => ts('Member Since'),
282 'membership_start_date' => ts('Start Date'),
283 'membership_end_date' => ts('End Date'),
284 );
285 foreach ($params as $key => $val) {
286 if ($val) {
287 switch ($key) {
288 case 'join_date':
289 case 'membership_start_date':
290 case 'membership_end_date':
291 if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) {
292 if (!CRM_Utils_Rule::date($params[$key])) {
293 CRM_Contact_Import_Parser_Contact::addToErrorMsg($dateLabels[$key], $errorMessage);
294 }
295 }
296 else {
87bbc876 297 CRM_Contact_Import_Parser_Contact::addToErrorMsg($dateLabels[$key], $errorMessage);
6a488035 298 }
4f7b71ab 299 break;
6a488035 300
4f7b71ab 301 case 'membership_type_id':
302 if (!is_numeric($val)) {
303 unset($params['membership_type_id']);
304 $params['membership_type'] = $val;
305 }
306 break;
6a488035 307
4f7b71ab 308 case 'status_id':
309 if (!is_numeric($val)) {
310 unset($params['status_id']);
311 $params['membership_status'] = $val;
312 }
313 break;
6a488035 314
4f7b71ab 315 case 'is_override':
316 $params[$key] = CRM_Utils_String::strtobool($val);
317 break;
318 }
319 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
320 if ( $customFields[$customFieldID]['data_type'] == 'Date' ) {
321 CRM_Contact_Import_Parser_Contact::formatCustomDate($params, $formatted, $dateType, $key);
322 unset($params[$key]);
323 } else if ( $customFields[$customFieldID]['data_type'] == 'Boolean' ) {
324 $params[$key] = CRM_Utils_String::strtoboolstr($val);
325 }
6a488035
TO
326 }
327 }
328 }
4f7b71ab 329 //date-Format part ends
6a488035 330
4f7b71ab 331 static $indieFields = NULL;
332 if ($indieFields == NULL) {
333 $tempIndieFields = CRM_Member_DAO_Membership::import();
334 $indieFields = $tempIndieFields;
6a488035
TO
335 }
336
4f7b71ab 337 $formatValues = array();
338 foreach ($params as $key => $field) {
339 if ($field == NULL || $field === '') {
340 continue;
341 }
6a488035 342
4f7b71ab 343 $formatValues[$key] = $field;
6a488035
TO
344 }
345
4f7b71ab 346 //format params to meet api v2 requirements.
347 //@todo find a way to test removing this formatting
348 $formatError = $this->membership_format_params($formatValues, $formatted, TRUE);
6a488035 349
4f7b71ab 350 if ($onDuplicate != CRM_Import_Parser::DUPLICATE_UPDATE) {
6a488035
TO
351 $formatted['custom'] = CRM_Core_BAO_CustomField::postProcess($formatted,
352 CRM_Core_DAO::$_nullObject,
4f7b71ab 353 NULL,
6a488035
TO
354 'Membership'
355 );
4f7b71ab 356 }
357 else {
358 //fix for CRM-2219 Update Membership
359 // onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE
8cc574cf 360 if (!empty($formatted['is_override']) && empty($formatted['status_id'])) {
4f7b71ab 361 array_unshift($values, 'Required parameter missing: Status');
362 return CRM_Import_Parser::ERROR;
363 }
6a488035 364
1a9d4317 365 if (!empty($formatValues['membership_id'])) {
4f7b71ab 366 $dao = new CRM_Member_BAO_Membership();
367 $dao->id = $formatValues['membership_id'];
368 $dates = array('join_date', 'start_date', 'end_date');
369 foreach ($dates as $v) {
a7488080 370 if (empty($formatted[$v])) {
4f7b71ab 371 $formatted[$v] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $formatValues['membership_id'], $v);
372 }
373 }
374
375 $formatted['custom'] = CRM_Core_BAO_CustomField::postProcess($formatted,
376 CRM_Core_DAO::$_nullObject,
377 $formatValues['membership_id'],
378 'Membership'
379 );
380 if ($dao->find(TRUE)) {
381 $ids = array(
382 'membership' => $formatValues['membership_id'],
383 'userId' => $session->get('userID'),
384 );
385
386 $newMembership = CRM_Member_BAO_Membership::create($formatted, $ids, TRUE);
387 if (civicrm_error($newMembership)) {
388 array_unshift($values, $newMembership['is_error'] . ' for Membership ID ' . $formatValues['membership_id'] . '. Row was skipped.');
389 return CRM_Import_Parser::ERROR;
390 }
391 else {
392 $this->_newMemberships[] = $newMembership->id;
393 return CRM_Import_Parser::VALID;
394 }
6a488035
TO
395 }
396 else {
4f7b71ab 397 array_unshift($values, 'Matching Membership record not found for Membership ID ' . $formatValues['membership_id'] . '. Row was skipped.');
398 return CRM_Import_Parser::ERROR;
6a488035
TO
399 }
400 }
6a488035 401 }
6a488035 402
4f7b71ab 403 //Format dates
404 $startDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('start_date', $formatted), '%Y-%m-%d');
405 $endDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('end_date', $formatted), '%Y-%m-%d');
406 $joinDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('join_date', $formatted), '%Y-%m-%d');
6a488035 407
4f7b71ab 408 if ($this->_contactIdIndex < 0) {
6a488035 409
4f7b71ab 410 //retrieve contact id using contact dedupe rule
411 $formatValues['contact_type'] = $this->_contactType;
412 $formatValues['version'] = 3;
413 require_once 'CRM/Utils/DeprecatedUtils.php';
414 $error = _civicrm_api3_deprecated_check_contact_dedupe($formatValues);
6a488035 415
4f7b71ab 416 if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) {
417 $matchedIDs = explode(',', $error['error_message']['params'][0]);
418 if (count($matchedIDs) > 1) {
419 array_unshift($values, 'Multiple matching contact records detected for this row. The membership was not imported');
420 return CRM_Import_Parser::ERROR;
421 }
422 else {
423 $cid = $matchedIDs[0];
424 $formatted['contact_id'] = $cid;
425
426 //fix for CRM-1924
427 $calcDates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($formatted['membership_type_id'],
428 $joinDate,
429 $startDate,
430 $endDate
431 );
432 self::formattedDates($calcDates, $formatted);
433
434 //fix for CRM-3570, exclude the statuses those having is_admin = 1
435 //now user can import is_admin if is override is true.
436 $excludeIsAdmin = FALSE;
a7488080 437 if (empty($formatted['is_override'])) {
4f7b71ab 438 $formatted['exclude_is_admin'] = $excludeIsAdmin = TRUE;
439 }
440 $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($startDate,
441 $endDate,
442 $joinDate,
443 'today',
5f11bbcc
EM
444 $excludeIsAdmin,
445 $formatted['membership_type_id'],
446 $formatted
4f7b71ab 447 );
448
a7488080 449 if (empty($formatted['status_id'])) {
4f7b71ab 450 $formatted['status_id'] = $calcStatus['id'];
451 }
a7488080 452 elseif (empty($formatted['is_override'])) {
4f7b71ab 453 if (empty($calcStatus)) {
454 array_unshift($values, 'Status in import row (' . $formatValues['status_id'] . ') does not match calculated status based on your configured Membership Status Rules. Record was not imported.');
455 return CRM_Import_Parser::ERROR;
456 }
457 elseif ($formatted['status_id'] != $calcStatus['id']) {
458 //Status Hold" is either NOT mapped or is FALSE
459 array_unshift($values, 'Status in import row (' . $formatValues['status_id'] . ') does not match calculated status based on your configured Membership Status Rules (' . $calcStatus['name'] . '). Record was not imported.');
460 return CRM_Import_Parser::ERROR;
461 }
462 }
463
464 $newMembership = civicrm_api3('membership', 'create', $formatted);
465
466 $this->_newMemberships[] = $newMembership['id'];
467 return CRM_Import_Parser::VALID;
468 }
6a488035
TO
469 }
470 else {
4f7b71ab 471 // Using new Dedupe rule.
472 $ruleParams = array(
473 'contact_type' => $this->_contactType,
474 'used' => 'Unsupervised',
6a488035 475 );
4f7b71ab 476 $fieldsArray = CRM_Dedupe_BAO_Rule::dedupeRuleFields($ruleParams);
477 $disp = '';
478
479 foreach ($fieldsArray as $value) {
480 if (array_key_exists(trim($value), $params)) {
481 $paramValue = $params[trim($value)];
482 if (is_array($paramValue)) {
483 $disp .= $params[trim($value)][0][trim($value)] . " ";
484 }
485 else {
486 $disp .= $params[trim($value)] . " ";
487 }
488 }
6a488035 489 }
6a488035 490
a7488080 491 if (!empty($params['external_identifier'])) {
4f7b71ab 492 if ($disp) {
493 $disp .= "AND {$params['external_identifier']}";
6a488035 494 }
4f7b71ab 495 else {
496 $disp = $params['external_identifier'];
6a488035
TO
497 }
498 }
499
4f7b71ab 500 array_unshift($values, 'No matching Contact found for (' . $disp . ')');
501 return CRM_Import_Parser::ERROR;
6a488035
TO
502 }
503 }
504 else {
a7488080 505 if (!empty($formatValues['external_identifier'])) {
4f7b71ab 506 $checkCid = new CRM_Contact_DAO_Contact();
507 $checkCid->external_identifier = $formatValues['external_identifier'];
508 $checkCid->find(TRUE);
509 if ($checkCid->id != $formatted['contact_id']) {
510 array_unshift($values, 'Mismatch of External identifier :' . $formatValues['external_identifier'] . ' and Contact Id:' . $formatted['contact_id']);
511 return CRM_Import_Parser::ERROR;
6a488035
TO
512 }
513 }
514
4f7b71ab 515 //to calculate dates
516 $calcDates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($formatted['membership_type_id'],
517 $joinDate,
518 $startDate,
519 $endDate
520 );
521 self::formattedDates($calcDates, $formatted);
522 //end of date calculation part
523
524 //fix for CRM-3570, exclude the statuses those having is_admin = 1
525 //now user can import is_admin if is override is true.
526 $excludeIsAdmin = FALSE;
a7488080 527 if (empty($formatted['is_override'])) {
4f7b71ab 528 $formatted['exclude_is_admin'] = $excludeIsAdmin = TRUE;
529 }
530 $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($startDate,
531 $endDate,
532 $joinDate,
533 'today',
5f11bbcc
EM
534 $excludeIsAdmin,
535 $formatted['membership_type_id'],
536 $formatted
4f7b71ab 537 );
a7488080 538 if (empty($formatted['status_id'])) {
4f7b71ab 539 $formatted['status_id'] = CRM_Utils_Array::value('id', $calcStatus);
540 }
a7488080 541 elseif (empty($formatted['is_override'])) {
4f7b71ab 542 if (empty($calcStatus)) {
543 array_unshift($values, 'Status in import row (' . CRM_Utils_Array::value('status_id', $formatValues) . ') does not match calculated status based on your configured Membership Status Rules. Record was not imported.');
544 return CRM_Import_Parser::ERROR;
6a488035 545 }
4f7b71ab 546 elseif ($formatted['status_id'] != $calcStatus['id']) {
547 //Status Hold" is either NOT mapped or is FALSE
548 array_unshift($values, 'Status in import row (' . CRM_Utils_Array::value('status_id', $formatValues) . ') does not match calculated status based on your configured Membership Status Rules (' . $calcStatus['name'] . '). Record was not imported.');
549 return CRM_Import_Parser::ERROR;
6a488035
TO
550 }
551 }
552
4f7b71ab 553 $newMembership = civicrm_api3('membership', 'create', $formatted);
6a488035 554
4f7b71ab 555 $this->_newMemberships[] = $newMembership['id'];
556 return CRM_Import_Parser::VALID;
6a488035 557 }
f719e41c 558 }
559 catch (Exception $e) {
560 array_unshift($values, $e->getMessage());
561 return CRM_Import_Parser::ERROR;
562 }
6a488035
TO
563 }
564
565 /**
ceb10dc7 566 * Get the array of successfully imported membership id's
6a488035
TO
567 *
568 * @return array
569 * @access public
570 */
571 function &getImportedMemberships() {
572 return $this->_newMemberships;
573 }
574
575 /**
576 * the initializer code, called before the processing
577 *
578 * @return void
579 * @access public
580 */
581 function fini() {}
582
583 /**
584 * to calculate join, start and end dates
585 *
2a6da8d7 586 * @param Array $calcDates array of dates returned by getDatesForMembershipType()
6a488035 587 *
2a6da8d7 588 * @param $formatted
6a488035 589 *
2a6da8d7
EM
590 * @return Array formatted containing date values
591 *
592 * @access public
6a488035
TO
593 */
594 function formattedDates($calcDates, &$formatted) {
595 $dates = array(
596 'join_date',
597 'start_date',
598 'end_date',
599 );
600
601 foreach ($dates as $d) {
602 if (isset($formatted[$d]) &&
603 !CRM_Utils_System::isNull($formatted[$d])
604 ) {
605 $formatted[$d] = CRM_Utils_Date::isoToMysql($formatted[$d]);
606 }
607 elseif (isset($calcDates[$d])) {
608 $formatted[$d] = CRM_Utils_Date::isoToMysql($calcDates[$d]);
609 }
610 }
611 }
77b97be7 612
3c15495c 613 /**
614 * @deprecated - this function formats params according to v2 standards but
615 * need to be sure about the impact of not calling it so retaining on the import class
616 * take the input parameter list as specified in the data model and
617 * convert it into the same format that we use in QF and BAO object
618 *
77b97be7 619 * @param array $params Associative array of property name/value
3c15495c 620 * pairs to insert in new contact.
77b97be7 621 * @param array $values The reformatted properties that we can use internally
3c15495c 622 *
77b97be7 623 * @param array|bool $create Is the formatted Values array going to
3c15495c 624 * be used for CRM_Member_BAO_Membership:create()
625 *
77b97be7 626 * @throws Exception
3c15495c 627 * @return array|error
628 * @access public
629 */
630 function membership_format_params($params, &$values, $create = FALSE) {
631 require_once 'api/v3/utils.php';
632 $fields = CRM_Member_DAO_Membership::fields();
633 _civicrm_api3_store_values($fields, $params, $values);
634
635 $customFields = CRM_Core_BAO_CustomField::getFields( 'Membership');
636
637 foreach ($params as $key => $value) {
638 // ignore empty values or empty arrays etc
639 if (CRM_Utils_System::isNull($value)) {
640 continue;
641 }
642
643 //Handling Custom Data
644 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
645 $values[$key] = $value;
646 $type = $customFields[$customFieldID]['html_type'];
647 if( $type == 'CheckBox' || $type == 'Multi-Select' || $type == 'AdvMulti-Select') {
648 $mulValues = explode( ',' , $value );
649 $customOption = CRM_Core_BAO_CustomOption::getCustomOption($customFieldID, true);
650 $values[$key] = array();
651 foreach( $mulValues as $v1 ) {
652 foreach($customOption as $customValueID => $customLabel) {
653 $customValue = $customLabel['value'];
654 if (( strtolower($customLabel['label']) == strtolower(trim($v1)) ) ||
655 ( strtolower($customValue) == strtolower(trim($v1)) )) {
656 if ( $type == 'CheckBox' ) {
657 $values[$key][$customValue] = 1;
658 } else {
659 $values[$key][] = $customValue;
660 }
661 }
662 }
663 }
664 }
665 }
666
667 switch ($key) {
668 case 'membership_contact_id':
669 if (!CRM_Utils_Rule::integer($value)) {
f719e41c 670 throw new Exception("contact_id not valid: $value");
3c15495c 671 }
672 $dao = new CRM_Core_DAO();
673 $qParams = array();
674 $svq = $dao->singleValueQuery("SELECT id FROM civicrm_contact WHERE id = $value",
675 $qParams
676 );
677 if (!$svq) {
f719e41c 678 throw new Exception("Invalid Contact ID: There is no contact record with contact_id = $value.");
3c15495c 679 }
680 $values['contact_id'] = $values['membership_contact_id'];
681 unset($values['membership_contact_id']);
682 break;
683
684 case 'membership_type_id':
685 if (!CRM_Utils_Array::value($value, CRM_Member_PseudoConstant::membershipType())) {
f719e41c 686 throw new Exception('Invalid Membership Type Id');
3c15495c 687 }
688 $values[$key] = $value;
689 break;
690
691 case 'membership_type':
692 $membershipTypeId = CRM_Utils_Array::key(ucfirst($value),
693 CRM_Member_PseudoConstant::membershipType()
694 );
695 if ($membershipTypeId) {
a7488080 696 if (!empty($values['membership_type_id']) &&
3c15495c 697 $membershipTypeId != $values['membership_type_id']
698 ) {
f719e41c 699 throw new Exception('Mismatched membership Type and Membership Type Id');
3c15495c 700 }
701 }
702 else {
f719e41c 703 throw new Exception('Invalid Membership Type');
3c15495c 704 }
705 $values['membership_type_id'] = $membershipTypeId;
706 break;
707
708 case 'status_id':
709 if (!CRM_Utils_Array::value($value, CRM_Member_PseudoConstant::membershipStatus())) {
f719e41c 710 throw new Exception('Invalid Membership Status Id');
3c15495c 711 }
712 $values[$key] = $value;
713 break;
714
715 case 'membership_status':
716 $membershipStatusId = CRM_Utils_Array::key(ucfirst($value),
717 CRM_Member_PseudoConstant::membershipStatus()
718 );
719 if ($membershipStatusId) {
a7488080 720 if (!empty($values['status_id']) &&
3c15495c 721 $membershipStatusId != $values['status_id']
722 ) {
f719e41c 723 throw new Exception('Mismatched membership Status and Membership Status Id');
3c15495c 724 }
725 }
726 else {
f719e41c 727 throw new Exception('Invalid Membership Status');
3c15495c 728 }
729 $values['status_id'] = $membershipStatusId;
730 break;
731
732 default:
733 break;
734 }
735 }
736
737 _civicrm_api3_custom_format_params($params, $values, 'Membership');
738
739
740 if ($create) {
741 // CRM_Member_BAO_Membership::create() handles membership_start_date,
742 // membership_end_date and membership_source. So, if $values contains
743 // membership_start_date, membership_end_date or membership_source,
744 // convert it to start_date, end_date or source
745 $changes = array(
746 'membership_start_date' => 'start_date',
747 'membership_end_date' => 'end_date',
748 'membership_source' => 'source',
749 );
750
751 foreach ($changes as $orgVal => $changeVal) {
752 if (isset($values[$orgVal])) {
753 $values[$changeVal] = $values[$orgVal];
754 unset($values[$orgVal]);
755 }
756 }
757 }
758
759 return NULL;
760 }
6a488035
TO
761}
762