Merge pull request #336 from kurund/memcache-fixes
[civicrm-core.git] / CRM / Event / Form / Registration / Confirm.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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 *
31 * @package CRM
32 * @copyright CiviCRM LLC (c) 2004-2013
33 * $Id$
34 *
35 */
36
37 /**
38 * This class generates form components for processing Event
39 *
40 */
41 class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration {
42
43 /**
44 * the values for the contribution db object
45 *
46 * @var array
47 * @protected
48 */
49 public $_values;
50
51 /**
52 * the total amount
53 *
54 * @var float
55 * @public
56 */
57 public $_totalAmount;
58
59 /**
60 * Function to set variables up before form is built
61 *
62 * @return void
63 * @access public
64 */
65 function preProcess() {
66 parent::preProcess();
67
68 // lineItem isn't set until Register postProcess
69 $this->_lineItem = $this->get('lineItem');
70
71 $this->_params = $this->get('params');
72
73 $this->_params[0]['is_pay_later'] = $this->get('is_pay_later');
74 $this->assign('is_pay_later', $this->_params[0]['is_pay_later']);
75 if ($this->_params[0]['is_pay_later']) {
76 $this->assign('pay_later_receipt', $this->_values['event']['pay_later_receipt']);
77 }
78
79 CRM_Utils_Hook::eventDiscount($this, $this->_params);
80
81 if (CRM_Utils_Array::value('discount', $this->_params[0]) &&
82 CRM_Utils_Array::value('applied', $this->_params[0]['discount'])
83 ) {
84 $this->set('hookDiscount', $this->_params[0]['discount']);
85 $this->assign('hookDiscount', $this->_params[0]['discount']);
86 }
87
88 $config = CRM_Core_Config::singleton();
89 if ($this->_contributeMode == 'express') {
90 $params = array();
91 // rfp == redirect from paypal
92 $rfp = CRM_Utils_Request::retrieve('rfp', 'Boolean',
93 CRM_Core_DAO::$_nullObject, FALSE, NULL, 'GET'
94 );
95
96 //we lost rfp in case of additional participant. So set it explicitly.
97 if ($rfp || CRM_Utils_Array::value('additional_participants', $this->_params[0], FALSE)) {
98 $payment = CRM_Core_Payment::singleton($this->_mode, $this->_paymentProcessor, $this);
99 $paymentObjError = ts('The system did not record payment details for this payment and so could not process the transaction. Please report this error to the site administrator.');
100 if (is_object($payment))
101 $expressParams = $payment->getExpressCheckoutDetails($this->get('token'));
102 else
103 CRM_Core_Error::fatal($paymentObjError);
104
105 $params['payer'] = $expressParams['payer'];
106 $params['payer_id'] = $expressParams['payer_id'];
107 $params['payer_status'] = $expressParams['payer_status'];
108
109 CRM_Core_Payment_Form::mapParams($this->_bltID, $expressParams, $params, FALSE);
110
111 // fix state and country id if present
112 if (isset($params["billing_state_province_id-{$this->_bltID}"])) {
113 $params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($params["billing_state_province_id-{$this->_bltID}"]);
114 }
115 if (isset($params['billing_country_id'])) {
116 $params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($params["billing_country_id-{$this->_bltID}"]);
117 }
118
119 // set a few other parameters for PayPal
120 $params['token'] = $this->get('token');
121 $params['amount'] = $this->_params[0]['amount'];
122 if (CRM_Utils_Array::value('discount', $this->_params[0])) {
123 $params['discount'] = $this->_params[0]['discount'];
124 $params['discountAmount'] = $this->_params[0]['discountAmount'];
125 $params['discountMessage'] = $this->_params[0]['discountMessage'];
126 }
127 $params['amount_level'] = $this->_params[0]['amount_level'];
128 $params['currencyID'] = $this->_params[0]['currencyID'];
129 $params['payment_action'] = 'Sale';
130
131 // also merge all the other values from the profile fields
132 $values = $this->controller->exportValues('Register');
133 $skipFields = array(
134 'amount',
135 "street_address-{$this->_bltID}",
136 "city-{$this->_bltID}",
137 "state_province_id-{$this->_bltID}",
138 "postal_code-{$this->_bltID}",
139 "country_id-{$this->_bltID}",
140 );
141
142 foreach ($values as $name => $value) {
143 // skip amount field
144 if (!in_array($name, $skipFields)) {
145 $params[$name] = $value;
146 }
147 }
148 $this->set('getExpressCheckoutDetails', $params);
149 }
150 else {
151 $params = $this->get('getExpressCheckoutDetails');
152 }
153 $this->_params[0] = $params;
154 $this->_params[0]['is_primary'] = 1;
155 }
156 else {
157 //process only primary participant params.
158 $registerParams = $this->_params[0];
159 if (isset($registerParams["billing_state_province_id-{$this->_bltID}"])
160 && $registerParams["billing_state_province_id-{$this->_bltID}"]
161 ) {
162 $registerParams["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($registerParams["billing_state_province_id-{$this->_bltID}"]);
163 }
164
165 if (isset($registerParams["billing_country_id-{$this->_bltID}"]) && $registerParams["billing_country_id-{$this->_bltID}"]) {
166 $registerParams["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($registerParams["billing_country_id-{$this->_bltID}"]);
167 }
168 if (isset($registerParams['credit_card_exp_date'])) {
169 $registerParams['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($registerParams);
170 $registerParams['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($registerParams);
171 }
172 if ($this->_values['event']['is_monetary']) {
173 $registerParams['ip_address'] = CRM_Utils_System::ipAddress();
174 $registerParams['currencyID'] = $this->_params[0]['currencyID'];
175 $registerParams['payment_action'] = 'Sale';
176 }
177 //assign back primary participant params.
178 $this->_params[0] = $registerParams;
179 }
180
181 if ($this->_values['event']['is_monetary']) {
182 $this->_params[0]['invoiceID'] = $this->get('invoiceID');
183 }
184 $this->assign('defaultRole', FALSE);
185 if (CRM_Utils_Array::value('defaultRole', $this->_params[0]) == 1) {
186 $this->assign('defaultRole', TRUE);
187 }
188
189 if (!CRM_Utils_Array::value('participant_role_id', $this->_params[0]) &&
190 $this->_values['event']['default_role_id']
191 ) {
192 $this->_params[0]['participant_role_id'] = $this->_values['event']['default_role_id'];
193 }
194
195 if (isset($this->_values['event']['confirm_title'])) {
196 CRM_Utils_System::setTitle($this->_values['event']['confirm_title']);
197 }
198
199 if ($this->_pcpId) {
200 $params = CRM_Contribute_Form_Contribution_Confirm::processPcp($this, $this->_params[0]);
201 $this->_params[0] = $params;
202 }
203
204 $this->set('params', $this->_params);
205 }
206
207 /**
208 * overwrite action, since we are only showing elements in frozen mode
209 * no help display needed
210 *
211 * @return int
212 * @access public
213 */
214 function getAction() {
215 if ($this->_action & CRM_Core_Action::PREVIEW) {
216 return CRM_Core_Action::VIEW | CRM_Core_Action::PREVIEW;
217 }
218 else {
219 return CRM_Core_Action::VIEW;
220 }
221 }
222
223 /**
224 * Function to build the form
225 *
226 * @return None
227 * @access public
228 */
229 public function buildQuickForm() {
230 $this->assignToTemplate();
231 if ($this->_params[0]['amount'] || $this->_params[0]['amount'] == 0) {
232 $this->_amount = array();
233
234 foreach ($this->_params as $k => $v) {
235 if (is_array($v)) {
236 foreach (array(
237 'first_name', 'last_name') as $name) {
238 if (isset($v['billing_' . $name]) &&
239 !isset($v[$name])
240 ) {
241 $v[$name] = $v['billing_' . $name];
242 }
243 }
244
245 if (CRM_Utils_Array::value('first_name', $v) && CRM_Utils_Array::value('last_name', $v)) {
246 $append = $v['first_name'] . ' ' . $v['last_name'];
247 }
248 else {
249 //use an email if we have one
250 foreach ($v as $v_key => $v_val) {
251 if (substr($v_key, 0, 6) == 'email-') {
252 $append = $v[$v_key];
253 }
254 }
255 }
256
257 $this->_amount[$k]['amount'] = $v['amount'];
258 if (CRM_Utils_Array::value('discountAmount', $v)) {
259 $this->_amount[$k]['amount'] -= $v['discountAmount'];
260 }
261
262 $this->_amount[$k]['label'] = preg_replace('/\ 1/', '', $v['amount_level']) . ' - ' . $append;
263 $this->_part[$k]['info'] = CRM_Utils_Array::value('first_name', $v) . ' ' . CRM_Utils_Array::value('last_name', $v);
264 if (!CRM_Utils_Array::value('first_name', $v)) {
265 $this->_part[$k]['info'] = $append;
266 }
267 $this->_totalAmount = $this->_totalAmount + $this->_amount[$k]['amount'];
268 if (CRM_Utils_Array::value('is_primary', $v)) {
269 $this->set('primaryParticipantAmount', $this->_amount[$k]['amount']);
270 }
271 }
272 }
273
274 $this->assign('part', $this->_part);
275 $this->set('part', $this->_part);
276 $this->assign('amounts', $this->_amount);
277 $this->assign('totalAmount', $this->_totalAmount);
278 $this->set('totalAmount', $this->_totalAmount);
279 }
280
281 $config = CRM_Core_Config::singleton();
282
283 //$this->buildCustom($this->_values['custom_pre_id'], 'customPre', TRUE);
284 //$this->buildCustom($this->_values['custom_post_id'], 'customPost', TRUE);
285
286 if ($this->_priceSetId && !CRM_Core_DAO::getFieldValue('CRM_Price_DAO_Set', $this->_priceSetId, 'is_quick_config')) {
287 $lineItemForTemplate = array();
288 foreach ($this->_lineItem as $key => $value) {
289 if (!empty($value)) {
290 $lineItemForTemplate[$key] = $value;
291 }
292 }
293 if (!empty($lineItemForTemplate)) {
294 $this->assign('lineItem', $lineItemForTemplate);
295 }
296 }
297
298 //display additional participants profile.
299 $participantParams = $this->_params;
300 $formattedValues = $profileFields = array();
301 $count = 1;
302 foreach ($participantParams as $participantNum => $participantValue) {
303 if ($participantNum) {
304 $prefix1 = 'additional';
305 $prefix2 = 'additional_';
306 } else {
307 $prefix1 = '';
308 $prefix2 = '';
309 }
310 if ($participantValue != 'skip') {
311 //get the customPre profile info
312 if (CRM_Utils_Array::value( $prefix2 . 'custom_pre_id', $this->_values)) {
313 $values = $groupName = array();
314 CRM_Event_BAO_Event::displayProfile($participantValue,
315 $this->_values[ $prefix2 . 'custom_pre_id'],
316 $groupName,
317 $values,
318 $profileFields
319 );
320
321 if (count($values)) {
322 $formattedValues[$count][$prefix1 . 'CustomPre'] = $values;
323 }
324 $formattedValues[$count][$prefix1 . 'CustomPreGroupTitle'] = CRM_Utils_Array::value('groupTitle', $groupName);
325 }
326 //get the customPost profile info
327 if (CRM_Utils_Array::value( $prefix2 . 'custom_post_id', $this->_values)) {
328 $values = $groupName = array();
329 foreach ($this->_values[$prefix2 . 'custom_post_id'] as $gids) {
330 $val = array();
331 CRM_Event_BAO_Event::displayProfile($participantValue,
332 $gids,
333 $group,
334 $val,
335 $profileFields
336 );
337 $values[$gids] = $val;
338 $groupName[$gids] = $group;
339 }
340
341 if (count($values)) {
342 $formattedValues[$count][$prefix1 . 'CustomPost'] = $values;
343 }
344
345 if (isset($formattedValues[$count][$prefix1 . 'CustomPre'])) {
346 $formattedValues[$count][$prefix1 . 'CustomPost'] = array_diff_assoc($formattedValues[$count][$prefix1 . 'CustomPost'],
347 $formattedValues[$count][$prefix1 . 'CustomPre']
348 );
349 }
350
351 $formattedValues[$count][$prefix1 . 'CustomPostGroupTitle'] = $groupName;
352 }
353 $count++;
354 }
355 $this->_fields = $profileFields;
356 }
357 if (!empty($formattedValues) ) {
358 $this->assign('primaryParticipantProfile', $formattedValues[1]);
359 $this->set('primaryParticipantProfile', $formattedValues[1]);
360 if ($count > 2) {
361 unset($formattedValues[1]);
362 $this->assign('addParticipantProfile', $formattedValues);
363 $this->set('addParticipantProfile', $formattedValues);
364 }
365 }
366
367 //consider total amount.
368 $this->assign('isAmountzero', ($this->_totalAmount <= 0) ? TRUE : FALSE);
369
370 if ($this->_paymentProcessor['payment_processor_type'] == 'Google_Checkout' &&
371 !CRM_Utils_Array::value('is_pay_later', $this->_params[0]) && !($this->_params[0]['amount'] == 0) &&
372 !$this->_allowWaitlist && !$this->_requireApproval
373 ) {
374 $this->_checkoutButtonName = $this->getButtonName('next', 'checkout');
375 $this->add('image',
376 $this->_checkoutButtonName,
377 $this->_paymentProcessor['url_button'],
378 array('class' => 'form-submit')
379 );
380
381 $this->addButtons(array(
382 array(
383 'type' => 'back',
384 'name' => ts('<< Go Back'),
385 ),
386 )
387 );
388 }
389 else {
390 $contribButton = ts('Continue');
391 $this->addButtons(array(
392 array(
393 'type' => 'next',
394 'name' => $contribButton,
395 'isDefault' => TRUE,
396 'js' => array('onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"),
397 ),
398 array(
399 'type' => 'back',
400 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
401 'name' => ts('Go Back'),
402 ),
403 )
404 );
405 }
406
407 $defaults = array();
408 $fields = array();
409 if (!empty($this->_fields)) {
410 foreach ($this->_fields as $name => $dontCare) {
411 $fields[$name] = 1;
412 }
413 }
414 $fields["billing_state_province-{$this->_bltID}"] = $fields["billing_country-{$this->_bltID}"] = $fields["email-{$this->_bltID}"] = 1;
415 foreach ($fields as $name => $dontCare) {
416 if (isset($this->_params[0][$name])) {
417 $defaults[$name] = $this->_params[0][$name];
418 if (substr($name, 0, 7) == 'custom_') {
419 $timeField = "{$name}_time";
420 if (isset($this->_params[0][$timeField])) {
421 $defaults[$timeField] = $this->_params[0][$timeField];
422 }
423 if (isset($this->_params[0]["{$name}_id"])) {
424 $defaults["{$name}_id"] = $this->_params[0]["{$name}_id"];
425 }
426 }
427 elseif (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)
428 && !empty($this->_params[0][$name . '_custom'])
429 ) {
430 $defaults[$name . '_custom'] = $this->_params[0][$name . '_custom'];
431 }
432 }
433 }
434
435 // now fix all state country selectors
436 CRM_Core_BAO_Address::fixAllStateSelects($this, $defaults);
437
438 $this->setDefaults($defaults);
439 $this->freeze();
440
441 //lets give meaningful status message, CRM-4320.
442 $this->assign('isOnWaitlist', $this->_allowWaitlist);
443 $this->assign('isRequireApproval', $this->_requireApproval);
444
445 // Assign Participant Count to Lineitem Table
446 $this->assign('pricesetFieldsCount', CRM_Price_BAO_Set::getPricesetCount($this->_priceSetId));
447 }
448
449 /**
450 * Function to process the form
451 *
452 * @access public
453 *
454 * @return None
455 */
456 public function postProcess() {
457 $now = date('YmdHis');
458 $config = CRM_Core_Config::singleton();
459 $session = CRM_Core_Session::singleton();
460 $this->_params = $this->get('params');
461 if (CRM_Utils_Array::value('contact_id', $this->_params[0])) {
462 $contactID = $this->_params[0]['contact_id'];
463 }
464 else {
465 $contactID = parent::getContactID();
466 }
467
468 // if a discount has been applied, lets now deduct it from the amount
469 // and fix the fee level
470 if (CRM_Utils_Array::value('discount', $this->_params[0]) &&
471 CRM_Utils_Array::value('applied', $this->_params[0]['discount'])
472 ) {
473 foreach ($this->_params as $k => $v) {
474 if (CRM_Utils_Array::value('amount', $this->_params[$k]) > 0 &&
475 CRM_Utils_Array::value('discountAmount', $this->_params[$k])
476 ) {
477 $this->_params[$k]['amount'] -= $this->_params[$k]['discountAmount'];
478 $this->_params[$k]['amount_level'] .= CRM_Utils_Array::value('discountMessage', $this->_params[$k]);
479 }
480 }
481 $this->set('params', $this->_params);
482 }
483
484 // CRM-4320, lets build array of cancelled additional participant ids
485 // those are drop or skip by primary at the time of confirmation.
486 // get all in and then unset those we want to process.
487 $cancelledIds = $this->_additionalParticipantIds;
488
489 $params = $this->_params;
490 $this->set('finalAmount', $this->_amount);
491 $participantCount = array();
492
493 //unset the skip participant from params.
494 //build the $participantCount array.
495 //maintain record for all participants.
496 foreach ($params as $participantNum => $record) {
497 if ($record == 'skip') {
498 unset($params[$participantNum]);
499 $participantCount[$participantNum] = 'skip';
500 }
501 elseif ($participantNum) {
502 $participantCount[$participantNum] = 'participant';
503 }
504
505 //lets get additional participant id to cancel.
506 if ($this->_allowConfirmation && is_array($cancelledIds)) {
507 $additonalId = CRM_Utils_Array::value('participant_id', $record);
508 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
509 unset($cancelledIds[$key]);
510 }
511 }
512 }
513
514 $payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
515 $paymentObjError = ts('The system did not record payment details for this payment and so could not process the transaction. Please report this error to the site administrator.');
516
517 $this->participantIDS = array();
518 $fields = array();
519 foreach ($params as $key => $value) {
520 $this->fixLocationFields($value, $fields);
521 //unset the billing parameters if it is pay later mode
522 //to avoid creation of billing location
523 if ($this->_allowWaitlist || $this->_requireApproval ||
524 CRM_Utils_Array::value('is_pay_later', $value) || !CRM_Utils_Array::value('is_primary', $value)
525 ) {
526 $billingFields = array(
527 "email-{$this->_bltID}",
528 'billing_first_name',
529 'billing_middle_name',
530 'billing_last_name',
531 "billing_street_address-{$this->_bltID}",
532 "billing_city-{$this->_bltID}",
533 "billing_state_province-{$this->_bltID}",
534 "billing_state_province_id-{$this->_bltID}",
535 "billing_postal_code-{$this->_bltID}",
536 "billing_country-{$this->_bltID}",
537 "billing_country_id-{$this->_bltID}",
538 "address_name-{$this->_bltID}",
539 );
540 foreach ($billingFields as $field) {
541 unset($value[$field]);
542 }
543 if (CRM_Utils_Array::value('is_pay_later', $value)) {
544 $this->_values['params']['is_pay_later'] = TRUE;
545 }
546 }
547
548 //Unset ContactID for additional participants and set RegisterBy Id.
549 if (!CRM_Utils_Array::value('is_primary', $value)) {
550 $contactID = CRM_Utils_Array::value('contact_id', $value);
551 $registerByID = $this->get('registerByID');
552 if ($registerByID) {
553 $value['registered_by_id'] = $registerByID;
554 }
555 }
556 else {
557 $value['amount'] = $this->_totalAmount;
558 }
559
560 $contactID = $this->updateContactFields($contactID, $value, $fields);
561
562 // lets store the contactID in the session
563 // we dont store in userID in case the user is doing multiple
564 // transactions etc
565 // for things like tell a friend
566 if (!parent::getContactID() && CRM_Utils_Array::value('is_primary', $value)) {
567 $session->set('transaction.userID', $contactID);
568 }
569
570 $value['description'] = ts('Online Event Registration') . ': ' . $this->_values['event']['title'];
571 $value['accountingCode'] = CRM_Utils_Array::value('accountingCode',
572 $this->_values['event']
573 );
574
575 // required only if paid event
576 if ($this->_values['event']['is_monetary']) {
577 if (is_array($this->_paymentProcessor)) {
578 $payment = CRM_Core_Payment::singleton($this->_mode, $this->_paymentProcessor, $this);
579 }
580 $pending = FALSE;
581 $result = NULL;
582
583 if ($this->_allowWaitlist || $this->_requireApproval) {
584 //get the participant statuses.
585 $waitingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Waiting'");
586 if ($this->_allowWaitlist) {
587 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
588 }
589 else {
590 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
591 }
592
593 //there might be case user seleted pay later and
594 //now becomes part of run time waiting list.
595 $value['is_pay_later'] = FALSE;
596 }
597 elseif (CRM_Utils_Array::value('is_pay_later', $value) ||
598 $value['amount'] == 0 ||
599 $this->_contributeMode == 'checkout' ||
600 $this->_contributeMode == 'notify'
601 ) {
602 if ($value['amount'] != 0) {
603 $pending = TRUE;
604 //get the participant statuses.
605 $pendingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Pending'");
606 $status = CRM_Utils_Array::value('is_pay_later', $value) ? 'Pending from pay later' : 'Pending from incomplete transaction';
607 $value['participant_status_id'] = $value['participant_status'] = array_search($status, $pendingStatuses);
608 }
609 }
610 elseif ($this->_contributeMode == 'express' && CRM_Utils_Array::value('is_primary', $value)) {
611 if (is_object($payment))
612 $result = $payment->doExpressCheckout($value);
613 else
614 CRM_Core_Error::fatal($paymentObjError);
615 }
616 elseif (CRM_Utils_Array::value('is_primary', $value)) {
617 CRM_Core_Payment_Form::mapParams($this->_bltID, $value, $value, TRUE);
618 if (is_object($payment)) {
619 $result = $payment->doDirectPayment($value);
620 }
621 else {
622 CRM_Core_Error::fatal($paymentObjError);
623 }
624 }
625
626 if (is_a($result, 'CRM_Core_Error')) {
627 CRM_Core_Error::displaySessionError($result);
628 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/event/register', "id={$this->_eventId}"));
629 }
630
631 if ($result) {
632 $value = array_merge($value, $result);
633 }
634
635 $value['receive_date'] = $now;
636 if ($this->_allowConfirmation) {
637 $value['participant_register_date'] = $this->_values['participant']['register_date'];
638 }
639
640 $createContrib = ($value['amount'] != 0) ? TRUE : FALSE;
641 // force to create zero amount contribution, CRM-5095
642 if (!$createContrib && ($value['amount'] == 0)
643 && $this->_priceSetId && $this->_lineItem
644 ) {
645 $createContrib = TRUE;
646 }
647
648 if ($createContrib && CRM_Utils_Array::value('is_primary', $value) &&
649 !$this->_allowWaitlist && !$this->_requireApproval
650 ) {
651 // if paid event add a contribution record
652 //if primary participant contributing additional amount
653 //append (multiple participants) to its fee level. CRM-4196.
654 $isAdditionalAmount = FALSE;
655 if (count($params) > 1) {
656 $isAdditionalAmount = TRUE;
657 }
658
659 //passing contribution id is already registered.
660 $contribution =
661 self::processContribution($this, $value, $result, $contactID, $pending, $isAdditionalAmount);
662 $value['contributionID'] = $contribution->id;
663 $value['contributionTypeID'] = $contribution->financial_type_id;
664 $value['receive_date'] = $contribution->receive_date;
665 $value['trxn_id'] = $contribution->trxn_id;
666 $value['contributionID'] = $contribution->id;
667 $value['contributionTypeID'] = $contribution->financial_type_id;
668 }
669 $value['contactID'] = $contactID;
670 $value['eventID'] = $this->_eventId;
671 $value['item_name'] = $value['description'];
672 }
673
674 //CRM-4453.
675 if (CRM_Utils_Array::value('is_primary', $value)) {
676 $primaryCurrencyID = CRM_Utils_Array::value('currencyID', $value);
677 }
678 if (!CRM_Utils_Array::value('currencyID', $value)) {
679 $value['currencyID'] = $primaryCurrencyID;
680 }
681
682 if (!$pending && CRM_Utils_Array::value('is_primary', $value) &&
683 !$this->_allowWaitlist && !$this->_requireApproval
684 ) {
685 // transactionID & receive date required while building email template
686 $this->assign('trxn_id', $value['trxn_id']);
687 $this->assign('receive_date', CRM_Utils_Date::mysqlToIso($value['receive_date']));
688 $this->set('receiveDate', CRM_Utils_Date::mysqlToIso($value['receive_date']));
689 $this->set('trxnId', CRM_Utils_Array::value('trxn_id', $value));
690 }
691
692 $this->set('value', $value);
693
694 // handle register date CRM-4320
695 if ($this->_allowConfirmation) {
696 $registerDate = CRM_Utils_Array::value( 'participant_register_date', $params );
697 }
698 elseif (CRM_Utils_Array::value('participant_register_date', $params) &&
699 is_array($params['participant_register_date']) &&
700 !empty($params['participant_register_date'])
701 ) {
702 $registerDate = CRM_Utils_Date::format($params['participant_register_date']);
703 }
704 else {
705 $registerDate = date('YmdHis');
706 }
707 $this->assign('register_date', $registerDate);
708
709 $this->confirmPostProcess($contactID, $contribution, $payment);
710 }
711
712 //handle if no additional participant.
713 if (!$registerByID) {
714 $registerByID = $this->get('registerByID');
715 }
716
717 $this->set('participantIDs', $this->_participantIDS);
718
719 // create line items, CRM-5313
720 if ($this->_priceSetId &&
721 !empty($this->_lineItem)
722 ) {
723 // take all processed participant ids.
724 $allParticipantIds = $this->_participantIDS;
725
726 // when participant re-walk wizard.
727 if ($this->_allowConfirmation &&
728 !empty($this->_additionalParticipantIds)
729 ) {
730 $allParticipantIds = array_merge(array($registerByID), $this->_additionalParticipantIds);
731 }
732
733 $entityTable = 'civicrm_participant';
734 foreach ($this->_lineItem as $key => $value) {
735 if (($value != 'skip') &&
736 ($entityId = CRM_Utils_Array::value($key, $allParticipantIds))
737 ) {
738
739 // do cleanup line items if participant re-walking wizard.
740 if ($this->_allowConfirmation) {
741 CRM_Price_BAO_LineItem::deleteLineItems($entityId, $entityTable);
742 }
743 $lineItem[$this->_priceSetId] = $value;
744 CRM_Price_BAO_LineItem::processPriceSet($entityId, $lineItem, $contribution, $entityTable);
745 }
746 }
747 }
748
749 //update status and send mail to cancelled additonal participants, CRM-4320
750 if ($this->_allowConfirmation && is_array($cancelledIds) && !empty($cancelledIds)) {
751 $cancelledId = array_search('Cancelled',
752 CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Negative'")
753 );
754 CRM_Event_BAO_Participant::transitionParticipants($cancelledIds, $cancelledId);
755 }
756
757 $isTest = FALSE;
758 if ($this->_action & CRM_Core_Action::PREVIEW) {
759 $isTest = TRUE;
760 }
761
762 // for Transfer checkout.
763 if (($this->_contributeMode == 'checkout' ||
764 $this->_contributeMode == 'notify'
765 ) &&
766 !CRM_Utils_Array::value('is_pay_later', $params[0]) &&
767 !$this->_allowWaitlist && !$this->_requireApproval &&
768 $this->_totalAmount > 0
769 ) {
770
771 $primaryParticipant = $this->get('primaryParticipant');
772
773 if (!CRM_Utils_Array::value('participantID', $primaryParticipant)) {
774 $primaryParticipant['participantID'] = $registerByID;
775 }
776
777 //build an array of custom profile and assigning it to template
778 $customProfile = CRM_Event_BAO_Event::buildCustomProfile($registerByID, $this->_values, NULL, $isTest);
779 if (count($customProfile)) {
780 $this->assign('customProfile', $customProfile);
781 $this->set('customProfile', $customProfile);
782 }
783
784 // do a transfer only if a monetary payment greater than 0
785 if ($this->_values['event']['is_monetary'] && $primaryParticipant) {
786 if ($payment && is_object($payment)) {
787 // call postprocess hook before leaving
788 $this->postProcessHook();
789 // this does not return
790 $payment->doTransferCheckout($primaryParticipant, 'event');
791 }
792 else {
793 CRM_Core_Error::fatal($paymentObjError);
794 }
795 }
796 }
797 else {
798 //otherwise send mail Confirmation/Receipt
799 $primaryContactId = $this->get('primaryContactId');
800
801 //build an array of cId/pId of participants
802 $additionalIDs = CRM_Event_BAO_Event::buildCustomProfile($registerByID,
803 NULL, $primaryContactId, $isTest,
804 TRUE
805 );
806 //lets send mails to all with meaningful text, CRM-4320.
807 $this->assign('isOnWaitlist', $this->_allowWaitlist);
808 $this->assign('isRequireApproval', $this->_requireApproval);
809
810 //need to copy, since we are unsetting on the way.
811 $copyParticipantCount = $participantCount;
812
813 //lets carry all paticipant params w/ values.
814 foreach ($additionalIDs as $participantID => $contactId) {
815 $participantNum = NULL;
816 if ($participantID == $registerByID) {
817 $participantNum = 0;
818 }
819 else {
820 if ($participantNum = array_search('participant', $copyParticipantCount)) {
821 unset($copyParticipantCount[$participantNum]);
822 }
823 }
824 if ($participantNum === NULL)
825 break;
826
827 //carry the participant submitted values.
828 $this->_values['params'][$participantID] = $params[$participantNum];
829 }
830
831 foreach ($additionalIDs as $participantID => $contactId) {
832 $participantNum = 0;
833 if ($participantID == $registerByID) {
834 //set as Primary Participant
835 $this->assign('isPrimary', 1);
836 //build an array of custom profile and assigning it to template.
837 $customProfile = CRM_Event_BAO_Event::buildCustomProfile($participantID, $this->_values, NULL, $isTest);
838
839 if (count($customProfile)) {
840 $this->assign('customProfile', $customProfile);
841 $this->set('customProfile', $customProfile);
842 }
843 $this->_values['params']['additionalParticipant'] = FALSE;
844 }
845 else {
846 //take the Additional participant number.
847 if ($participantNum = array_search('participant', $participantCount)) {
848 unset($participantCount[$participantNum]);
849 }
850 $this->assign('isPrimary', 0);
851 $this->assign('customProfile', NULL);
852 //Additional Participant should get only it's payment information
853 if ($this->_amount) {
854 $amount = array();
855 $params = $this->get('params');
856 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
857 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
858 $this->assign('amounts', $amount);
859 }
860 if ($this->_lineItem) {
861 $lineItems = $this->_lineItem;
862 $lineItem = array();
863 if ($lineItemValue = CRM_Utils_Array::value($participantNum, $lineItems)) {
864 $lineItem[] = $lineItemValue;
865 }
866 $this->assign('lineItem', $lineItem);
867 }
868 $this->_values['params']['additionalParticipant'] = TRUE;
869 }
870
871 //pass these variables since these are run time calculated.
872 $this->_values['params']['isOnWaitlist'] = $this->_allowWaitlist;
873 $this->_values['params']['isRequireApproval'] = $this->_requireApproval;
874
875 //send mail to primary as well as additional participants.
876 $this->assign('contactID', $contactId);
877 $this->assign('participantID', $participantID);
878 CRM_Event_BAO_Event::sendMail($contactId, $this->_values, $participantID, $isTest);
879 }
880 }
881 }
882 //end of function
883
884 /**
885 * Process the contribution
886 *
887 * @return void
888 * @access public
889 */
890 static function processContribution(&$form, $params, $result, $contactID,
891 $pending = FALSE, $isAdditionalAmount = FALSE
892 ) {
893 $transaction = new CRM_Core_Transaction();
894
895 $config = CRM_Core_Config::singleton();
896 $now = date('YmdHis');
897 $receiptDate = NULL;
898
899 if ($form->_values['event']['is_email_confirm']) {
900 $receiptDate = $now;
901 }
902 //CRM-4196
903 if ($isAdditionalAmount) {
904 $params['amount_level'] = $params['amount_level'] . ts(' (multiple participants)') . CRM_Core_DAO::VALUE_SEPARATOR;
905 }
906
907 $contribParams = array(
908 'contact_id' => $contactID,
909 'financial_type_id' => $form->_values['event']['financial_type_id'] ?
910 $form->_values['event']['financial_type_id'] : $params['financial_type_id'],
911 'receive_date' => $now,
912 'total_amount' => $params['amount'],
913 'amount_level' => $params['amount_level'],
914 'invoice_id' => $params['invoiceID'],
915 'currency' => $params['currencyID'],
916 'source' => $params['description'],
917 'is_pay_later' => CRM_Utils_Array::value('is_pay_later', $params, 0),
918 'campaign_id' => CRM_Utils_Array::value('campaign_id', $params),
919 );
920
921 if (!CRM_Utils_Array::value('is_pay_later', $params)) {
922 $contribParams['payment_instrument_id'] = 1;
923 }
924
925 if (!$pending && $result) {
926 $contribParams += array(
927 'fee_amount' => CRM_Utils_Array::value('fee_amount', $result),
928 'net_amount' => CRM_Utils_Array::value('net_amount', $result, $params['amount']),
929 'trxn_id' => $result['trxn_id'],
930 'receipt_date' => $receiptDate,
931 );
932 }
933
934 $allStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
935 $contribParams['contribution_status_id'] = array_search('Completed', $allStatuses);
936 if ($pending) {
937 $contribParams['contribution_status_id'] = array_search('Pending', $allStatuses);
938 }
939
940 $contribParams['is_test'] = 0;
941 if ($form->_action & CRM_Core_Action::PREVIEW || CRM_Utils_Array::value('mode', $params) == 'test') {
942 $contribParams['is_test'] = 1;
943 }
944
945 $contribID = NULL;
946 if (CRM_Utils_Array::value('invoice_id', $contribParams)) {
947 $contribID = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution',
948 $contribParams['invoice_id'],
949 'id',
950 'invoice_id'
951 );
952 }
953
954 $ids = array();
955 if ($contribID) {
956 $ids['contribution'] = $contribID;
957 $contribParams['id'] = $contribID;
958 }
959
960 //create an contribution address
961 if ($form->_contributeMode != 'notify' && !CRM_Utils_Array::value('is_pay_later', $params)) {
962 $contribParams['address_id'] = CRM_Contribute_BAO_Contribution::createAddress($params, $form->_bltID);
963 }
964
965 // Prepare soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin.
966 if (CRM_Utils_Array::value('pcp_made_through_id', $params) ||
967 CRM_Utils_Array::value('soft_credit_to', $params)
968 ) {
969
970 // if its due to pcp
971 if (CRM_Utils_Array::value('pcp_made_through_id', $params)) {
972 $contribSoftContactId = CRM_Core_DAO::getFieldValue('CRM_PCP_DAO_PCP',
973 $params['pcp_made_through_id'],
974 'contact_id'
975 );
976 }
977 else {
978 $contribSoftContactId = CRM_Utils_Array::value('soft_credit_to', $params);
979 }
980
981 // Pass these details onto with the contribution to make them
982 // available at hook_post_process, CRM-8908
983 $contribParams['soft_credit_to'] = $params['soft_credit_to'] = $contribSoftContactId;
984 }
985 $contribParams['payment_processor'] = CRM_Utils_Array::value('payment_processor', $params);
986 $contribParams['skipLineItem'] = 1;
987 // create contribution record
988 $contribution = CRM_Contribute_BAO_Contribution::add($contribParams, $ids);
989 // CRM-11124
990 CRM_Event_BAO_Participant::createDiscountTrxn($form->_eventId, $contribParams, $params['amount_priceset_level_radio']);
991
992 // process soft credit / pcp pages
993 CRM_Contribute_Form_Contribution_Confirm::processPcpSoft($params, $contribution);
994
995 $transaction->commit();
996
997 return $contribution;
998 }
999
1000 /**
1001 * Fix the Location Fields
1002 *
1003 * @return void
1004 * @access public
1005 */
1006 public function fixLocationFields(&$params, &$fields) {
1007 if (!empty($this->_fields)) {
1008 foreach ($this->_fields as $name => $dontCare) {
1009 $fields[$name] = 1;
1010 }
1011 }
1012
1013 if (is_array($fields)) {
1014 if (!array_key_exists('first_name', $fields)) {
1015 $nameFields = array('first_name', 'middle_name', 'last_name');
1016 foreach ($nameFields as $name) {
1017 $fields[$name] = 1;
1018 if (array_key_exists("billing_$name", $params)) {
1019 $params[$name] = $params["billing_{$name}"];
1020 $params['preserveDBName'] = TRUE;
1021 }
1022 }
1023 }
1024 }
1025
1026 // also add location name to the array
1027 if ($this->_values['event']['is_monetary']) {
1028 $params["address_name-{$this->_bltID}"] = CRM_Utils_Array::value('billing_first_name', $params) . ' ' . CRM_Utils_Array::value('billing_middle_name', $params) . ' ' . CRM_Utils_Array::value('billing_last_name', $params);
1029 $fields["address_name-{$this->_bltID}"] = 1;
1030 }
1031 $fields["email-{$this->_bltID}"] = 1;
1032 $fields['email-Primary'] = 1;
1033
1034 //if its pay later or additional participant set email address as primary.
1035 if ((CRM_Utils_Array::value('is_pay_later', $params) ||
1036 !CRM_Utils_Array::value('is_primary', $params) ||
1037 !$this->_values['event']['is_monetary'] ||
1038 $this->_allowWaitlist ||
1039 $this->_requireApproval
1040 ) &&
1041 CRM_Utils_Array::value("email-{$this->_bltID}", $params)
1042 ) {
1043 $params['email-Primary'] = $params["email-{$this->_bltID}"];
1044 }
1045 }
1046
1047 /**
1048 * function to update contact fields
1049 *
1050 * @return void
1051 * @access public
1052 */
1053 public function updateContactFields($contactID, $params, $fields) {
1054 //add the contact to group, if add to group is selected for a
1055 //particular uf group
1056
1057 // get the add to groups
1058 $addToGroups = array();
1059
1060 if (!empty($this->_fields)) {
1061 foreach ($this->_fields as $key => $value) {
1062 if (CRM_Utils_Array::value('add_to_group_id', $value)) {
1063 $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
1064 }
1065 }
1066 }
1067
1068 // check for profile double opt-in and get groups to be subscribed
1069 $subscribeGroupIds = CRM_Core_BAO_UFGroup::getDoubleOptInGroupIds($params, $contactID);
1070
1071 foreach ($addToGroups as $k) {
1072 if (array_key_exists($k, $subscribeGroupIds)) {
1073 unset($addToGroups[$k]);
1074 }
1075 }
1076
1077 // since we are directly adding contact to group lets unset it from mailing
1078 if (!empty($addToGroups)) {
1079 foreach ($addToGroups as $groupId) {
1080 if (isset($subscribeGroupIds[$groupId])) {
1081 unset($subscribeGroupIds[$groupId]);
1082 }
1083 }
1084 }
1085 if ($contactID) {
1086 $ctype = CRM_Core_DAO::getFieldValue(
1087 'CRM_Contact_DAO_Contact',
1088 $contactID,
1089 'contact_type'
1090 );
1091 $contactID = CRM_Contact_BAO_Contact::createProfileContact(
1092 $params,
1093 $fields,
1094 $contactID,
1095 $addToGroups,
1096 NULL,
1097 $ctype,
1098 TRUE
1099 );
1100 }
1101 else {
1102
1103 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
1104 if (!isset($params[$greeting . '_id'])) {
1105 $params[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils::defaultGreeting('Individual', $greeting);
1106 }
1107 }
1108
1109 $contactID = CRM_Contact_BAO_Contact::createProfileContact($params,
1110 $fields,
1111 NULL,
1112 $addToGroups,
1113 NULL,
1114 NULL,
1115 TRUE
1116 );
1117 $this->set('contactID', $contactID);
1118 }
1119
1120 //get email primary first if exist
1121 $subscribtionEmail = array('email' => CRM_Utils_Array::value('email-Primary', $params));
1122 if (!$subscribtionEmail['email']) {
1123 $subscribtionEmail['email'] = CRM_Utils_Array::value("email-{$this->_bltID}", $params);
1124 }
1125 // subscribing contact to groups
1126 if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
1127 CRM_Mailing_Event_BAO_Subscribe::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
1128 }
1129
1130 return $contactID;
1131 }
1132 }