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