Minor code cleanup - remove unnecessary ids declaration
[civicrm-core.git] / CRM / Event / Form / Registration / Confirm.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
6a488035 29 * @package CRM
6b83d5bd 30 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
31 */
32
33/**
3bdf1f3a 34 * This class generates form components for processing Event.
6a488035
TO
35 */
36class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration {
37
38 /**
66f9e52b 39 * The values for the contribution db object.
6a488035
TO
40 *
41 * @var array
6a488035
TO
42 */
43 public $_values;
44
45 /**
66f9e52b 46 * The total amount.
6a488035
TO
47 *
48 * @var float
6a488035
TO
49 */
50 public $_totalAmount;
51
3ae1b2f4 52 /**
53 * Monetary fields that may be submitted.
54 *
55 * These should get a standardised format in the beginPostProcess function.
56 *
57 * These fields are common to many forms. Some may override this.
58 */
59 protected $submittableMoneyFields = ['total_amount', 'net_amount', 'non_deductible_amount', 'fee_amount', 'tax_amount', 'amount'];
60
6a488035 61 /**
66f9e52b 62 * Set variables up before form is built.
6a488035 63 */
00be9182 64 public function preProcess() {
6a488035
TO
65 parent::preProcess();
66
67 // lineItem isn't set until Register postProcess
68 $this->_lineItem = $this->get('lineItem');
69
70 $this->_params = $this->get('params');
d91b8b33 71 $this->_params[0]['tax_amount'] = $this->get('tax_amount');
6a488035
TO
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
8cc574cf 81 if (!empty($this->_params[0]['discount']) && !empty($this->_params[0]['discount']['applied'])) {
6a488035
TO
82 $this->set('hookDiscount', $this->_params[0]['discount']);
83 $this->assign('hookDiscount', $this->_params[0]['discount']);
84 }
85
0f2b049e 86 // The concept of contributeMode is deprecated.
6a488035
TO
87 if ($this->_contributeMode == 'express') {
88 $params = array();
89 // rfp == redirect from paypal
9a1b1b8e 90 // rfp is probably not required - the getPreApprovalDetails should deal with any payment-processor specific 'stuff'
6a488035
TO
91 $rfp = CRM_Utils_Request::retrieve('rfp', 'Boolean',
92 CRM_Core_DAO::$_nullObject, FALSE, NULL, 'GET'
93 );
94
95 //we lost rfp in case of additional participant. So set it explicitly.
96 if ($rfp || CRM_Utils_Array::value('additional_participants', $this->_params[0], FALSE)) {
9a1b1b8e 97 if (!empty($this->_paymentProcessor) && $this->_paymentProcessor['object']->supports('preApproval')) {
98 $preApprovalParams = $this->_paymentProcessor['object']->getPreApprovalDetails($this->get('pre_approval_parameters'));
99 $params = array_merge($this->_params, $preApprovalParams);
0479b4c8 100 }
9a1b1b8e 101 CRM_Core_Payment_Form::mapParams($this->_bltID, $params, $params, FALSE);
6a488035 102
9a1b1b8e 103 // set a few other parameters that are not really specific to this method because we don't know what
104 // will break if we change this.
6a488035 105 $params['amount'] = $this->_params[0]['amount'];
a7488080 106 if (!empty($this->_params[0]['discount'])) {
6a488035
TO
107 $params['discount'] = $this->_params[0]['discount'];
108 $params['discountAmount'] = $this->_params[0]['discountAmount'];
109 $params['discountMessage'] = $this->_params[0]['discountMessage'];
110 }
362bd1b7 111
6a488035
TO
112 $params['amount_level'] = $this->_params[0]['amount_level'];
113 $params['currencyID'] = $this->_params[0]['currencyID'];
6a488035
TO
114
115 // also merge all the other values from the profile fields
116 $values = $this->controller->exportValues('Register');
117 $skipFields = array(
118 'amount',
119 "street_address-{$this->_bltID}",
120 "city-{$this->_bltID}",
121 "state_province_id-{$this->_bltID}",
122 "postal_code-{$this->_bltID}",
123 "country_id-{$this->_bltID}",
124 );
125
126 foreach ($values as $name => $value) {
127 // skip amount field
128 if (!in_array($name, $skipFields)) {
129 $params[$name] = $value;
130 }
bb2240a2 131 if (substr($name, 0, 6) == 'price_') {
b5b712c1 132 $params[$name] = $this->_params[0][$name];
bb2240a2 133 }
6a488035
TO
134 }
135 $this->set('getExpressCheckoutDetails', $params);
136 }
9a1b1b8e 137 $this->_params[0] = array_merge($this->_params[0], $params);
6a488035
TO
138 $this->_params[0]['is_primary'] = 1;
139 }
140 else {
141 //process only primary participant params.
142 $registerParams = $this->_params[0];
143 if (isset($registerParams["billing_state_province_id-{$this->_bltID}"])
144 && $registerParams["billing_state_province_id-{$this->_bltID}"]
145 ) {
146 $registerParams["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($registerParams["billing_state_province_id-{$this->_bltID}"]);
147 }
148
149 if (isset($registerParams["billing_country_id-{$this->_bltID}"]) && $registerParams["billing_country_id-{$this->_bltID}"]) {
150 $registerParams["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($registerParams["billing_country_id-{$this->_bltID}"]);
151 }
152 if (isset($registerParams['credit_card_exp_date'])) {
353ffa53 153 $registerParams['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($registerParams);
6a488035
TO
154 $registerParams['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($registerParams);
155 }
156 if ($this->_values['event']['is_monetary']) {
157 $registerParams['ip_address'] = CRM_Utils_System::ipAddress();
158 $registerParams['currencyID'] = $this->_params[0]['currencyID'];
6a488035
TO
159 }
160 //assign back primary participant params.
161 $this->_params[0] = $registerParams;
162 }
163
164 if ($this->_values['event']['is_monetary']) {
165 $this->_params[0]['invoiceID'] = $this->get('invoiceID');
166 }
167 $this->assign('defaultRole', FALSE);
168 if (CRM_Utils_Array::value('defaultRole', $this->_params[0]) == 1) {
169 $this->assign('defaultRole', TRUE);
170 }
171
a7488080 172 if (empty($this->_params[0]['participant_role_id']) &&
6a488035
TO
173 $this->_values['event']['default_role_id']
174 ) {
175 $this->_params[0]['participant_role_id'] = $this->_values['event']['default_role_id'];
176 }
177
178 if (isset($this->_values['event']['confirm_title'])) {
179 CRM_Utils_System::setTitle($this->_values['event']['confirm_title']);
180 }
181
182 if ($this->_pcpId) {
183 $params = CRM_Contribute_Form_Contribution_Confirm::processPcp($this, $this->_params[0]);
184 $this->_params[0] = $params;
185 }
186
187 $this->set('params', $this->_params);
188 }
189
190 /**
3bdf1f3a 191 * Overwrite action, since we are only showing elements in frozen mode no help display needed.
6a488035
TO
192 *
193 * @return int
6a488035 194 */
00be9182 195 public function getAction() {
6a488035
TO
196 if ($this->_action & CRM_Core_Action::PREVIEW) {
197 return CRM_Core_Action::VIEW | CRM_Core_Action::PREVIEW;
198 }
199 else {
200 return CRM_Core_Action::VIEW;
201 }
202 }
203
204 /**
66f9e52b 205 * Build the form object.
6a488035
TO
206 */
207 public function buildQuickForm() {
208 $this->assignToTemplate();
1909126f 209
210 if ($this->_values['event']['is_monetary'] &&
ef27a9b6
AS
211 ($this->_params[0]['amount'] || $this->_params[0]['amount'] == 0) &&
212 !$this->_requireApproval
1909126f 213 ) {
6a488035
TO
214 $this->_amount = array();
215
79d001a2 216 $taxAmount = 0;
6a488035 217 foreach ($this->_params as $k => $v) {
3ae1b2f4 218 $this->cleanMoneyFields($v);
7bde3600 219 if ($v == 'skip') {
220 continue;
221 }
75b065ce 222 $individualTaxAmount = 0;
79d001a2
PB
223 //display tax amount on confirmation page
224 $taxAmount += $v['tax_amount'];
6a488035
TO
225 if (is_array($v)) {
226 foreach (array(
353ffa53 227 'first_name',
317fceb4 228 'last_name',
353ffa53 229 ) as $name) {
6a488035
TO
230 if (isset($v['billing_' . $name]) &&
231 !isset($v[$name])
232 ) {
233 $v[$name] = $v['billing_' . $name];
234 }
235 }
236
8cc574cf 237 if (!empty($v['first_name']) && !empty($v['last_name'])) {
6a488035
TO
238 $append = $v['first_name'] . ' ' . $v['last_name'];
239 }
240 else {
241 //use an email if we have one
242 foreach ($v as $v_key => $v_val) {
243 if (substr($v_key, 0, 6) == 'email-') {
244 $append = $v[$v_key];
245 }
246 }
247 }
248
249 $this->_amount[$k]['amount'] = $v['amount'];
a7488080 250 if (!empty($v['discountAmount'])) {
6a488035
TO
251 $this->_amount[$k]['amount'] -= $v['discountAmount'];
252 }
253
254 $this->_amount[$k]['label'] = preg_replace('/\ 1/', '', $v['amount_level']) . ' - ' . $append;
255 $this->_part[$k]['info'] = CRM_Utils_Array::value('first_name', $v) . ' ' . CRM_Utils_Array::value('last_name', $v);
a7488080 256 if (empty($v['first_name'])) {
6a488035
TO
257 $this->_part[$k]['info'] = $append;
258 }
75b065ce 259
260 /*CRM-16320 */
261 $individual[$k]['totalAmtWithTax'] = $this->_amount[$k]['amount'];
262 $individual[$k]['totalTaxAmt'] = $individualTaxAmount + $v['tax_amount'];
6a488035 263 $this->_totalAmount = $this->_totalAmount + $this->_amount[$k]['amount'];
a7488080 264 if (!empty($v['is_primary'])) {
6a488035
TO
265 $this->set('primaryParticipantAmount', $this->_amount[$k]['amount']);
266 }
267 }
268 }
269
aaffa79f 270 $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
03b412ae
PB
271 $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
272 $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
03b412ae
PB
273 if ($invoicing) {
274 $this->assign('totalTaxAmount', $taxAmount);
d9e4ebe7 275 $this->assign('taxTerm', $taxTerm);
75b065ce 276 $this->assign('individual', $individual);
277 $this->set('individual', $individual);
03b412ae 278 }
75b065ce 279
6a488035
TO
280 $this->assign('part', $this->_part);
281 $this->set('part', $this->_part);
282 $this->assign('amounts', $this->_amount);
283 $this->assign('totalAmount', $this->_totalAmount);
284 $this->set('totalAmount', $this->_totalAmount);
285 }
286
9da8dc8c 287 if ($this->_priceSetId && !CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
6a488035 288 $lineItemForTemplate = array();
03b412ae 289 $getTaxDetails = FALSE;
26fe6f4c 290 if (!empty($this->_lineItem) && is_array($this->_lineItem)) {
291 foreach ($this->_lineItem as $key => $value) {
292 if (!empty($value)) {
293 $lineItemForTemplate[$key] = $value;
294 }
295 if ($invoicing) {
296 foreach ($value as $v) {
297 if (isset($v['tax_rate'])) {
298 $getTaxDetails = TRUE;
299 }
03b412ae
PB
300 }
301 }
302 }
6a488035
TO
303 }
304 if (!empty($lineItemForTemplate)) {
305 $this->assign('lineItem', $lineItemForTemplate);
306 }
d9e4ebe7 307 $this->assign('getTaxDetails', $getTaxDetails);
6a488035
TO
308 }
309
310 //display additional participants profile.
5bdcb00b 311 self::assignProfiles($this);
6a488035
TO
312
313 //consider total amount.
314 $this->assign('isAmountzero', ($this->_totalAmount <= 0) ? TRUE : FALSE);
315
229159bf
CW
316 $contribButton = ts('Continue');
317 $this->addButtons(array(
318 array(
319 'type' => 'back',
320 'name' => ts('Go Back'),
321 ),
322 array(
323 'type' => 'next',
324 'name' => $contribButton,
325 'isDefault' => TRUE,
326 'js' => array('onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"),
327 ),
328 )
329 );
6a488035
TO
330
331 $defaults = array();
332 $fields = array();
333 if (!empty($this->_fields)) {
334 foreach ($this->_fields as $name => $dontCare) {
335 $fields[$name] = 1;
336 }
337 }
338 $fields["billing_state_province-{$this->_bltID}"] = $fields["billing_country-{$this->_bltID}"] = $fields["email-{$this->_bltID}"] = 1;
339 foreach ($fields as $name => $dontCare) {
340 if (isset($this->_params[0][$name])) {
341 $defaults[$name] = $this->_params[0][$name];
342 if (substr($name, 0, 7) == 'custom_') {
343 $timeField = "{$name}_time";
344 if (isset($this->_params[0][$timeField])) {
345 $defaults[$timeField] = $this->_params[0][$timeField];
346 }
347 if (isset($this->_params[0]["{$name}_id"])) {
348 $defaults["{$name}_id"] = $this->_params[0]["{$name}_id"];
349 }
350 }
351 elseif (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)
352 && !empty($this->_params[0][$name . '_custom'])
353 ) {
354 $defaults[$name . '_custom'] = $this->_params[0][$name . '_custom'];
355 }
356 }
357 }
358
6a488035
TO
359 $this->setDefaults($defaults);
360 $this->freeze();
361
362 //lets give meaningful status message, CRM-4320.
363 $this->assign('isOnWaitlist', $this->_allowWaitlist);
364 $this->assign('isRequireApproval', $this->_requireApproval);
365
366 // Assign Participant Count to Lineitem Table
9da8dc8c 367 $this->assign('pricesetFieldsCount', CRM_Price_BAO_PriceSet::getPricesetCount($this->_priceSetId));
79b152ac 368 $this->addFormRule(array('CRM_Event_Form_Registration_Confirm', 'formRule'), $this);
6a488035
TO
369 }
370
ca87146b 371 /**
3bdf1f3a 372 * Apply form rule.
373 *
374 * @param array $fields
375 * @param array $files
376 * @param CRM_Core_Form $self
ca87146b
EM
377 *
378 * @return array|bool
379 */
00be9182 380 public static function formRule($fields, $files, $self) {
79b152ac 381 $errors = array();
382 $eventFull = CRM_Event_BAO_Participant::eventFull($self->_eventId, FALSE, CRM_Utils_Array::value('has_waitlist', $self->_values['event']));
383 if ($eventFull && empty($self->_allowConfirmation)) {
384 if (empty($self->_allowWaitlist)) {
0479b4c8 385 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/event/register', "reset=1&id={$self->_eventId}", FALSE, NULL, FALSE, TRUE));
79b152ac 386 }
387 }
388 $self->_feeBlock = $self->_values['fee'];
389 CRM_Event_Form_Registration_Register::formatFieldsForOptionFull($self);
390
0dc0b759 391 if (!empty($self->_priceSetId) &&
392 !$self->_requireApproval && !$self->_allowWaitlist
393 ) {
79b152ac 394 $priceSetErrors = self::validatePriceSet($self, $self->_params);
0dc0b759 395 if (!empty($priceSetErrors)) {
2ae4d103 396 CRM_Core_Session::setStatus(ts('You have been returned to the start of the registration process and any sold out events have been removed from your selections. You will not be able to continue until you review your booking and select different events if you wish.'), ts('Unfortunately some of your options have now sold out for one or more participants.'), 'error');
0dc0b759 397 CRM_Core_Session::setStatus(ts('Please note that the options which are marked or selected are sold out for participant being viewed.'), ts('Sold out:'), 'error');
398 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/event/register', "_qf_Register_display=true&qfKey={$fields['qfKey']}"));
399 }
79b152ac 400 }
401
0dc0b759 402 return empty($priceSetErrors) ? TRUE : $priceSetErrors;
79b152ac 403 }
353ffa53 404
6a488035 405 /**
66f9e52b 406 * Process the form submission.
6a488035
TO
407 */
408 public function postProcess() {
353ffa53 409 $now = date('YmdHis');
af72b8c7 410
6a488035 411 $this->_params = $this->get('params');
3ae1b2f4 412 $this->cleanMoneyFields($this->_params);
413
a7488080 414 if (!empty($this->_params[0]['contact_id'])) {
e1ce628e 415 // unclear when this would be set & whether it could be checked in getContactID.
416 // perhaps it relates to when cid is in the url
417 //@todo someone who knows add comments on the various contactIDs in this form
6a488035
TO
418 $contactID = $this->_params[0]['contact_id'];
419 }
420 else {
5c280496 421 $contactID = $this->getContactID();
6a488035
TO
422 }
423
424 // if a discount has been applied, lets now deduct it from the amount
425 // and fix the fee level
8cc574cf 426 if (!empty($this->_params[0]['discount']) && !empty($this->_params[0]['discount']['applied'])) {
6a488035 427 foreach ($this->_params as $k => $v) {
8cc574cf 428 if (CRM_Utils_Array::value('amount', $this->_params[$k]) > 0 && !empty($this->_params[$k]['discountAmount'])) {
6a488035
TO
429 $this->_params[$k]['amount'] -= $this->_params[$k]['discountAmount'];
430 $this->_params[$k]['amount_level'] .= CRM_Utils_Array::value('discountMessage', $this->_params[$k]);
431 }
432 }
433 $this->set('params', $this->_params);
434 }
435
436 // CRM-4320, lets build array of cancelled additional participant ids
437 // those are drop or skip by primary at the time of confirmation.
438 // get all in and then unset those we want to process.
439 $cancelledIds = $this->_additionalParticipantIds;
440
441 $params = $this->_params;
1909126f 442 if ($this->_values['event']['is_monetary']) {
443 $this->set('finalAmount', $this->_amount);
444 }
6a488035 445 $participantCount = array();
b6c8057d 446 $taxAmount = $totalTaxAmount = 0;
6a488035
TO
447
448 //unset the skip participant from params.
449 //build the $participantCount array.
450 //maintain record for all participants.
451 foreach ($params as $participantNum => $record) {
452 if ($record == 'skip') {
453 unset($params[$participantNum]);
454 $participantCount[$participantNum] = 'skip';
455 }
456 elseif ($participantNum) {
457 $participantCount[$participantNum] = 'participant';
458 }
b6c8057d
PN
459 $totalTaxAmount += CRM_Utils_Array::value('tax_amount', $record, 0);
460 if (CRM_Utils_Array::value('is_primary', $record)) {
461 $taxAmount = &$params[$participantNum]['tax_amount'];
462 }
6a488035
TO
463 //lets get additional participant id to cancel.
464 if ($this->_allowConfirmation && is_array($cancelledIds)) {
465 $additonalId = CRM_Utils_Array::value('participant_id', $record);
466 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
467 unset($cancelledIds[$key]);
468 }
469 }
470 }
b6c8057d 471 $taxAmount = $totalTaxAmount;
6a488035
TO
472 $payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
473 $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.');
474
475 $this->participantIDS = array();
476 $fields = array();
477 foreach ($params as $key => $value) {
a9f7d48b 478 CRM_Event_Form_Registration_Confirm::fixLocationFields($value, $fields, $this);
6a488035
TO
479 //unset the billing parameters if it is pay later mode
480 //to avoid creation of billing location
0b05b9a9 481 // @todo - the reasoning for this is unclear - elsewhere we check what fields are provided by
482 // the form & if billing fields exist we create the address, relying on the form to collect
483 // only information we intend to store.
8ae4d0d3 484 if ($this->_allowWaitlist
485 || $this->_requireApproval
486 || (!empty($value['is_pay_later']) && !$this->_isBillingAddressRequiredForPayLater)
487 || empty($value['is_primary'])
488 ) {
6a488035
TO
489 $billingFields = array(
490 "email-{$this->_bltID}",
491 'billing_first_name',
492 'billing_middle_name',
493 'billing_last_name',
494 "billing_street_address-{$this->_bltID}",
495 "billing_city-{$this->_bltID}",
496 "billing_state_province-{$this->_bltID}",
497 "billing_state_province_id-{$this->_bltID}",
498 "billing_postal_code-{$this->_bltID}",
499 "billing_country-{$this->_bltID}",
500 "billing_country_id-{$this->_bltID}",
501 "address_name-{$this->_bltID}",
502 );
503 foreach ($billingFields as $field) {
504 unset($value[$field]);
505 }
a7488080 506 if (!empty($value['is_pay_later'])) {
6a488035
TO
507 $this->_values['params']['is_pay_later'] = TRUE;
508 }
509 }
510
511 //Unset ContactID for additional participants and set RegisterBy Id.
a7488080 512 if (empty($value['is_primary'])) {
6a488035
TO
513 $contactID = CRM_Utils_Array::value('contact_id', $value);
514 $registerByID = $this->get('registerByID');
515 if ($registerByID) {
516 $value['registered_by_id'] = $registerByID;
517 }
518 }
519 else {
520 $value['amount'] = $this->_totalAmount;
521 }
522
a9f7d48b 523 $contactID = CRM_Event_Form_Registration_Confirm::updateContactFields($contactID, $value, $fields, $this);
6a488035
TO
524
525 // lets store the contactID in the session
526 // we dont store in userID in case the user is doing multiple
527 // transactions etc
528 // for things like tell a friend
8cc574cf 529 if (!$this->getContactID() && !empty($value['is_primary'])) {
af72b8c7 530 $session = CRM_Core_Session::singleton();
6a488035
TO
531 $session->set('transaction.userID', $contactID);
532 }
533
534 $value['description'] = ts('Online Event Registration') . ': ' . $this->_values['event']['title'];
535 $value['accountingCode'] = CRM_Utils_Array::value('accountingCode',
536 $this->_values['event']
537 );
538
752f450d 539 $pending = FALSE;
67c8322d
J
540 if ($this->_allowWaitlist || $this->_requireApproval) {
541 //get the participant statuses.
542 $waitingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Waiting'");
543 if ($this->_allowWaitlist) {
544 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
545 }
546 else {
547 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
548 }
549
6acc9d56 550 //there might be case user selected pay later and
67c8322d
J
551 //now becomes part of run time waiting list.
552 $value['is_pay_later'] = FALSE;
553 }
6acc9d56
MWMC
554 elseif ($this->_values['event']['is_monetary']) {
555 // required only if paid event
6a488035 556 if (is_array($this->_paymentProcessor)) {
077017db 557 $payment = $this->_paymentProcessor['object'];
6a488035 558 }
ec022878 559 if (!empty($this->_paymentProcessor) && $this->_paymentProcessor['object']->supports('preApproval')) {
560 $preApprovalParams = $this->_paymentProcessor['object']->getPreApprovalDetails($this->get('pre_approval_parameters'));
561 $value = array_merge($value, $preApprovalParams);
562 }
6a488035
TO
563 $result = NULL;
564
67c8322d 565 if (!empty($value['is_pay_later']) ||
6a488035 566 $value['amount'] == 0 ||
0f2b049e 567 // The concept of contributeMode is deprecated.
6a488035
TO
568 $this->_contributeMode == 'checkout' ||
569 $this->_contributeMode == 'notify'
570 ) {
571 if ($value['amount'] != 0) {
572 $pending = TRUE;
573 //get the participant statuses.
574 $pendingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Pending'");
0d8afee2 575 $status = !empty($value['is_pay_later']) ? 'Pending from pay later' : 'Pending from incomplete transaction';
6a488035
TO
576 $value['participant_status_id'] = $value['participant_status'] = array_search($status, $pendingStatuses);
577 }
578 }
a7488080 579 elseif (!empty($value['is_primary'])) {
6a488035 580 CRM_Core_Payment_Form::mapParams($this->_bltID, $value, $value, TRUE);
bd7b39e7
PJ
581 // payment email param can be empty for _bltID mapping
582 // thus provide mapping for it with a different email value
583 if (empty($value['email'])) {
584 $value['email'] = CRM_Utils_Array::valueByRegexKey('/^email-/', $value);
585 }
586
6a488035 587 if (is_object($payment)) {
55f9f634 588 // Not quite sure why we don't just user $value since it contains the data
589 // from result
590 // @todo ditch $result & retest.
591 list($result, $value) = $this->processPayment($payment, $value);
6a488035
TO
592 }
593 else {
594 CRM_Core_Error::fatal($paymentObjError);
595 }
596 }
597
6a488035
TO
598 $value['receive_date'] = $now;
599 if ($this->_allowConfirmation) {
600 $value['participant_register_date'] = $this->_values['participant']['register_date'];
601 }
602
603 $createContrib = ($value['amount'] != 0) ? TRUE : FALSE;
604 // force to create zero amount contribution, CRM-5095
605 if (!$createContrib && ($value['amount'] == 0)
606 && $this->_priceSetId && $this->_lineItem
607 ) {
608 $createContrib = TRUE;
609 }
610
8cc574cf 611 if ($createContrib && !empty($value['is_primary']) &&
6a488035
TO
612 !$this->_allowWaitlist && !$this->_requireApproval
613 ) {
614 // if paid event add a contribution record
615 //if primary participant contributing additional amount
616 //append (multiple participants) to its fee level. CRM-4196.
617 $isAdditionalAmount = FALSE;
618 if (count($params) > 1) {
619 $isAdditionalAmount = TRUE;
620 }
621
622 //passing contribution id is already registered.
632196ea 623 $contribution = self::processContribution($this, $value, $result, $contactID, $pending, $isAdditionalAmount, $this->_paymentProcessor);
6a488035
TO
624 $value['contributionID'] = $contribution->id;
625 $value['contributionTypeID'] = $contribution->financial_type_id;
626 $value['receive_date'] = $contribution->receive_date;
627 $value['trxn_id'] = $contribution->trxn_id;
628 $value['contributionID'] = $contribution->id;
629 $value['contributionTypeID'] = $contribution->financial_type_id;
630 }
631 $value['contactID'] = $contactID;
353ffa53 632 $value['eventID'] = $this->_eventId;
6a488035
TO
633 $value['item_name'] = $value['description'];
634 }
9a32a8fc
GC
635
636 if (!empty($value['contributionID'])) {
637 $this->_values['contributionId'] = $value['contributionID'];
638 }
6a488035
TO
639
640 //CRM-4453.
a7488080 641 if (!empty($value['is_primary'])) {
6a488035
TO
642 $primaryCurrencyID = CRM_Utils_Array::value('currencyID', $value);
643 }
a7488080 644 if (empty($value['currencyID'])) {
6a488035
TO
645 $value['currencyID'] = $primaryCurrencyID;
646 }
647
1909126f 648 // CRM-11182 - Confirmation page might not be monetary
649 if ($this->_values['event']['is_monetary']) {
650 if (!$pending && !empty($value['is_primary']) &&
651 !$this->_allowWaitlist && !$this->_requireApproval
652 ) {
653 // transactionID & receive date required while building email template
bcdf9664
PN
654 $this->assign('trxn_id', CRM_Utils_Array::value('trxn_id', $value));
655 $this->assign('receive_date', CRM_Utils_Date::mysqlToIso(CRM_Utils_Array::value('receive_date', $value)));
656 $this->set('receiveDate', CRM_Utils_Date::mysqlToIso(CRM_Utils_Array::value('receive_date', $value)));
1909126f 657 $this->set('trxnId', CRM_Utils_Array::value('trxn_id', $value));
658 }
6a488035 659 }
f55dc004 660
ffcec972 661 $value['fee_amount'] = CRM_Utils_Array::value('amount', $value);
6a488035
TO
662 $this->set('value', $value);
663
664 // handle register date CRM-4320
665 if ($this->_allowConfirmation) {
481a74f4 666 $registerDate = CRM_Utils_Array::value('participant_register_date', $params);
6a488035 667 }
a7488080 668 elseif (!empty($params['participant_register_date']) &&
6a488035
TO
669 is_array($params['participant_register_date']) &&
670 !empty($params['participant_register_date'])
671 ) {
672 $registerDate = CRM_Utils_Date::format($params['participant_register_date']);
673 }
674 else {
675 $registerDate = date('YmdHis');
676 }
677 $this->assign('register_date', $registerDate);
678
679 $this->confirmPostProcess($contactID, $contribution, $payment);
680 }
681
682 //handle if no additional participant.
683 if (!$registerByID) {
684 $registerByID = $this->get('registerByID');
685 }
686
687 $this->set('participantIDs', $this->_participantIDS);
688
689 // create line items, CRM-5313
690 if ($this->_priceSetId &&
691 !empty($this->_lineItem)
692 ) {
693 // take all processed participant ids.
694 $allParticipantIds = $this->_participantIDS;
695
696 // when participant re-walk wizard.
697 if ($this->_allowConfirmation &&
698 !empty($this->_additionalParticipantIds)
699 ) {
700 $allParticipantIds = array_merge(array($registerByID), $this->_additionalParticipantIds);
701 }
702
703 $entityTable = 'civicrm_participant';
aaffa79f 704 $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
03b412ae 705 $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
79d001a2
PB
706 $totalTaxAmount = 0;
707 $dataArray = array();
6a488035 708 foreach ($this->_lineItem as $key => $value) {
e189cf22 709 if ($value == 'skip') {
710 continue;
711 }
712 if ($entityId = CRM_Utils_Array::value($key, $allParticipantIds)) {
6a488035
TO
713 // do cleanup line items if participant re-walking wizard.
714 if ($this->_allowConfirmation) {
715 CRM_Price_BAO_LineItem::deleteLineItems($entityId, $entityTable);
716 }
717 $lineItem[$this->_priceSetId] = $value;
718 CRM_Price_BAO_LineItem::processPriceSet($entityId, $lineItem, $contribution, $entityTable);
719 }
03b412ae
PB
720 if ($invoicing) {
721 foreach ($value as $line) {
722 if (isset($line['tax_amount']) && isset($line['tax_rate'])) {
723 $totalTaxAmount = $line['tax_amount'] + $totalTaxAmount;
724 if (isset($dataArray[$line['tax_rate']])) {
725 $dataArray[$line['tax_rate']] = $dataArray[$line['tax_rate']] + CRM_Utils_Array::value('tax_amount', $line);
726 }
727 else {
728 $dataArray[$line['tax_rate']] = CRM_Utils_Array::value('tax_amount', $line);
729 }
79d001a2
PB
730 }
731 }
732 }
6a488035 733 }
03b412ae
PB
734 if ($invoicing) {
735 $this->assign('dataArray', $dataArray);
736 $this->assign('totalTaxAmount', $totalTaxAmount);
737 }
6a488035
TO
738 }
739
b44e3f84 740 //update status and send mail to cancelled additional participants, CRM-4320
6a488035
TO
741 if ($this->_allowConfirmation && is_array($cancelledIds) && !empty($cancelledIds)) {
742 $cancelledId = array_search('Cancelled',
743 CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Negative'")
744 );
745 CRM_Event_BAO_Participant::transitionParticipants($cancelledIds, $cancelledId);
746 }
747
748 $isTest = FALSE;
749 if ($this->_action & CRM_Core_Action::PREVIEW) {
750 $isTest = TRUE;
751 }
752
753 // for Transfer checkout.
0f2b049e 754 // The concept of contributeMode is deprecated.
6a488035
TO
755 if (($this->_contributeMode == 'checkout' ||
756 $this->_contributeMode == 'notify'
8cc574cf 757 ) && empty($params[0]['is_pay_later']) &&
6a488035
TO
758 !$this->_allowWaitlist && !$this->_requireApproval &&
759 $this->_totalAmount > 0
760 ) {
761
762 $primaryParticipant = $this->get('primaryParticipant');
763
a7488080 764 if (empty($primaryParticipant['participantID'])) {
6a488035
TO
765 $primaryParticipant['participantID'] = $registerByID;
766 }
767
768 //build an array of custom profile and assigning it to template
769 $customProfile = CRM_Event_BAO_Event::buildCustomProfile($registerByID, $this->_values, NULL, $isTest);
770 if (count($customProfile)) {
771 $this->assign('customProfile', $customProfile);
772 $this->set('customProfile', $customProfile);
773 }
774
775 // do a transfer only if a monetary payment greater than 0
776 if ($this->_values['event']['is_monetary'] && $primaryParticipant) {
777 if ($payment && is_object($payment)) {
03665663 778 //CRM 14512 provide line items of all participants to payment gateway
779 $primaryContactId = $this->get('primaryContactId');
fb3b1f9a 780
03665663 781 //build an array of cId/pId of participants
782 $additionalIDs = CRM_Event_BAO_Event::buildCustomProfile($registerByID, NULL, $primaryContactId, $isTest, TRUE);
783
784 //need to copy, since we are unsetting on the way.
785 $copyParticipantCountLines = $participantCount;
786
787 //lets carry all participant params w/ values.
788 foreach ($additionalIDs as $participantID => $contactId) {
789 $participantNum = NULL;
790 $participantNum = $participantID;
791 if ($participantID == $registerByID) {
3bdf1f3a 792 // This is the is primary participant.
793 $participantNum = 0;
03665663 794 }
795 else {
796 if ($participantNum = array_search('participant', $copyParticipantCountLines)) {
797 //if no participant found break.
798 if ($participantNum === NULL) {
799 break;
800 }
6acc9d56 801 //unset current participant so we don't check them again
03665663 802 unset($copyParticipantCountLines[$participantNum]);
803 }
804 }
805 // get values of line items
806 if ($this->_amount) {
807 $amount = array();
808 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
809 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
810 $params[$participantNum]['amounts'] = $amount;
811 }
812
813 if (!empty($this->_lineItem)) {
353ffa53
TO
814 $lineItems = $this->_lineItem;
815 $lineItem = array();
03665663 816 if ($lineItemValue = CRM_Utils_Array::value($participantNum, $lineItems)) {
817 $lineItem[] = $lineItemValue;
818 }
819 $params[$participantNum]['lineItem'] = $lineItem;
820 }
821
822 //only add additional particpants and not the primary particpant as we already have that
823 //added to $primaryParticipant so that this change doesn't break or require changes to
824 //existing gateway implementations
825 $primaryParticipant['participants_info'][$participantID] = $params[$participantNum];
826 }
827
828 //get event custom field information
0b330e6d 829 $groupTree = CRM_Core_BAO_CustomGroup::getTree('Event', NULL, $this->_eventId, 0, $this->_values['event']['event_type_id']);
03665663 830 $primaryParticipant['eventCustomFields'] = $groupTree;
fb3b1f9a 831
6a488035
TO
832 // call postprocess hook before leaving
833 $this->postProcessHook();
55f9f634 834
835 $this->processPayment($payment, $primaryParticipant);
6a488035
TO
836 }
837 else {
838 CRM_Core_Error::fatal($paymentObjError);
839 }
840 }
841 }
842 else {
843 //otherwise send mail Confirmation/Receipt
844 $primaryContactId = $this->get('primaryContactId');
845
846 //build an array of cId/pId of participants
847 $additionalIDs = CRM_Event_BAO_Event::buildCustomProfile($registerByID,
848 NULL, $primaryContactId, $isTest,
849 TRUE
850 );
6acc9d56 851 //let's send mails to all with meaningful text, CRM-4320.
6a488035
TO
852 $this->assign('isOnWaitlist', $this->_allowWaitlist);
853 $this->assign('isRequireApproval', $this->_requireApproval);
854
855 //need to copy, since we are unsetting on the way.
856 $copyParticipantCount = $participantCount;
857
6acc9d56 858 //let's carry all participant params w/ values.
6a488035
TO
859 foreach ($additionalIDs as $participantID => $contactId) {
860 $participantNum = NULL;
861 if ($participantID == $registerByID) {
862 $participantNum = 0;
863 }
864 else {
865 if ($participantNum = array_search('participant', $copyParticipantCount)) {
866 unset($copyParticipantCount[$participantNum]);
867 }
868 }
0479b4c8
TO
869 if ($participantNum === NULL) {
870 break;
871 }
6a488035
TO
872
873 //carry the participant submitted values.
874 $this->_values['params'][$participantID] = $params[$participantNum];
875 }
876
877 foreach ($additionalIDs as $participantID => $contactId) {
878 $participantNum = 0;
879 if ($participantID == $registerByID) {
880 //set as Primary Participant
881 $this->assign('isPrimary', 1);
882 //build an array of custom profile and assigning it to template.
883 $customProfile = CRM_Event_BAO_Event::buildCustomProfile($participantID, $this->_values, NULL, $isTest);
884
885 if (count($customProfile)) {
886 $this->assign('customProfile', $customProfile);
887 $this->set('customProfile', $customProfile);
888 }
889 $this->_values['params']['additionalParticipant'] = FALSE;
890 }
891 else {
892 //take the Additional participant number.
893 if ($participantNum = array_search('participant', $participantCount)) {
894 unset($participantCount[$participantNum]);
895 }
4abc4ee1 896 // Change $this->_values['participant'] to include additional participant values
897 $ids = $participantValues = array();
898 $participantParams = array('id' => $participantID);
899 CRM_Event_BAO_Participant::getValues($participantParams, $participantValues, $ids);
900 $this->_values['participant'] = $participantValues[$participantID];
901
6a488035
TO
902 $this->assign('isPrimary', 0);
903 $this->assign('customProfile', NULL);
904 //Additional Participant should get only it's payment information
1909126f 905 if (!empty($this->_amount)) {
6a488035
TO
906 $amount = array();
907 $params = $this->get('params');
908 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
909 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
910 $this->assign('amounts', $amount);
911 }
912 if ($this->_lineItem) {
353ffa53
TO
913 $lineItems = $this->_lineItem;
914 $lineItem = array();
6a488035
TO
915 if ($lineItemValue = CRM_Utils_Array::value($participantNum, $lineItems)) {
916 $lineItem[] = $lineItemValue;
917 }
75b065ce 918 if ($invoicing) {
919 $individual = $this->get('individual');
920 $dataArray[key($dataArray)] = $individual[$participantNum]['totalTaxAmt'];
921 $this->assign('dataArray', $dataArray);
922 $this->assign('totalAmount', $individual[$participantNum]['totalAmtWithTax']);
923 $this->assign('totalTaxAmount', $individual[$participantNum]['totalTaxAmt']);
924 $this->assign('individual', array($individual[$participantNum]));
925 }
6a488035
TO
926 $this->assign('lineItem', $lineItem);
927 }
928 $this->_values['params']['additionalParticipant'] = TRUE;
7d92d486 929 $this->assign('isAdditionalParticipant', $this->_values['params']['additionalParticipant']);
6a488035
TO
930 }
931
932 //pass these variables since these are run time calculated.
933 $this->_values['params']['isOnWaitlist'] = $this->_allowWaitlist;
934 $this->_values['params']['isRequireApproval'] = $this->_requireApproval;
935
936 //send mail to primary as well as additional participants.
937 $this->assign('contactID', $contactId);
938 $this->assign('participantID', $participantID);
939 CRM_Event_BAO_Event::sendMail($contactId, $this->_values, $participantID, $isTest);
940 }
941 }
942 }
6a488035
TO
943
944 /**
66f9e52b 945 * Process the contribution.
6a488035 946 *
c490a46a
CW
947 * @param CRM_Core_Form $form
948 * @param array $params
3bdf1f3a 949 * @param array $result
100fef9d 950 * @param int $contactID
dd244018
EM
951 * @param bool $pending
952 * @param bool $isAdditionalAmount
6acc9d56 953 * @param array $paymentProcessor
dd244018 954 *
3bdf1f3a 955 * @return \CRM_Contribute_BAO_Contribution
6acc9d56 956 * @throws \CRM_Core_Exception
6a488035 957 */
317fceb4 958 public static function processContribution(
ddca8f33 959 &$form, $params, $result, $contactID,
632196ea 960 $pending = FALSE, $isAdditionalAmount = FALSE,
961 $paymentProcessor = NULL
6a488035
TO
962 ) {
963 $transaction = new CRM_Core_Transaction();
964
353ffa53 965 $now = date('YmdHis');
6a488035
TO
966 $receiptDate = NULL;
967
bf2c70af 968 if (!empty($form->_values['event']['is_email_confirm'])) {
6a488035
TO
969 $receiptDate = $now;
970 }
971 //CRM-4196
972 if ($isAdditionalAmount) {
973 $params['amount_level'] = $params['amount_level'] . ts(' (multiple participants)') . CRM_Core_DAO::VALUE_SEPARATOR;
974 }
975
a7f2d5fd 976 // CRM-20264: fetch CC type ID and number (last 4 digit) and assign it back to $params
977 CRM_Contribute_Form_AbstractEditPayment::formatCreditCardDetails($params);
978
6a488035
TO
979 $contribParams = array(
980 'contact_id' => $contactID,
353ffa53 981 'financial_type_id' => !empty($form->_values['event']['financial_type_id']) ? $form->_values['event']['financial_type_id'] : $params['financial_type_id'],
6a488035
TO
982 'receive_date' => $now,
983 'total_amount' => $params['amount'],
d91b8b33 984 'tax_amount' => $params['tax_amount'],
6a488035
TO
985 'amount_level' => $params['amount_level'],
986 'invoice_id' => $params['invoiceID'],
987 'currency' => $params['currencyID'],
13bb29e4 988 'source' => !empty($params['participant_source']) ? $params['participant_source'] : $params['description'],
6a488035
TO
989 'is_pay_later' => CRM_Utils_Array::value('is_pay_later', $params, 0),
990 'campaign_id' => CRM_Utils_Array::value('campaign_id', $params),
5d3a2b9f 991 'card_type_id' => CRM_Utils_Array::value('card_type_id', $params),
992 'pan_truncation' => CRM_Utils_Array::value('pan_truncation', $params),
6a488035
TO
993 );
994
632196ea 995 if ($paymentProcessor) {
996 $contribParams['payment_instrument_id'] = $paymentProcessor['payment_instrument_id'];
dcc0e041 997 $contribParams['payment_processor'] = $paymentProcessor['id'];
6a488035
TO
998 }
999
1000 if (!$pending && $result) {
1001 $contribParams += array(
1002 'fee_amount' => CRM_Utils_Array::value('fee_amount', $result),
1003 'net_amount' => CRM_Utils_Array::value('net_amount', $result, $params['amount']),
1004 'trxn_id' => $result['trxn_id'],
1005 'receipt_date' => $receiptDate,
1006 );
1007 }
1008
1009 $allStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
1010 $contribParams['contribution_status_id'] = array_search('Completed', $allStatuses);
1011 if ($pending) {
1012 $contribParams['contribution_status_id'] = array_search('Pending', $allStatuses);
1013 }
1014
1015 $contribParams['is_test'] = 0;
1016 if ($form->_action & CRM_Core_Action::PREVIEW || CRM_Utils_Array::value('mode', $params) == 'test') {
1017 $contribParams['is_test'] = 1;
1018 }
1019
a7488080 1020 if (!empty($contribParams['invoice_id'])) {
3c884887 1021 $contribParams['id'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution',
6a488035
TO
1022 $contribParams['invoice_id'],
1023 'id',
1024 'invoice_id'
1025 );
1026 }
1027
8cf6bd83
PN
1028 if (CRM_Contribute_BAO_Contribution::checkContributeSettings('deferred_revenue_enabled')) {
1029 $eventStartDate = CRM_Utils_Array::value(
1030 'start_date',
1031 CRM_Utils_Array::value(
1032 'event',
1033 $form->_values
1034 )
1035 );
a493ffb6 1036 if (strtotime($eventStartDate) > strtotime(date('Ymt'))) {
8cf6bd83
PN
1037 $contribParams['revenue_recognition_date'] = date('Ymd', strtotime($eventStartDate));
1038 }
1039 }
6a488035 1040 //create an contribution address
0f2b049e 1041 // The concept of contributeMode is deprecated. Elsewhere we use the function processBillingAddress() - although
1042 // currently that is only inherited by back-office forms.
8cc574cf 1043 if ($form->_contributeMode != 'notify' && empty($params['is_pay_later'])) {
6a488035
TO
1044 $contribParams['address_id'] = CRM_Contribute_BAO_Contribution::createAddress($params, $form->_bltID);
1045 }
1046
6a488035 1047 $contribParams['skipLineItem'] = 1;
3ae1b2f4 1048 $contribParams['skipCleanMoney'] = 1;
6a488035 1049 // create contribution record
66ea9833 1050 $contribution = CRM_Contribute_BAO_Contribution::add($contribParams);
6a488035 1051 // CRM-11124
362bd1b7 1052 CRM_Event_BAO_Participant::createDiscountTrxn($form->_eventId, $contribParams, NULL, CRM_Price_BAO_PriceSet::parseFirstPriceSetValueIDFromParams($params));
6a488035
TO
1053
1054 // process soft credit / pcp pages
7a13735b 1055 if (!empty($params['pcp_made_through_id'])) {
03b0e225 1056 CRM_Contribute_BAO_ContributionSoft::formatSoftCreditParams($params, $form);
7a13735b 1057 CRM_Contribute_BAO_ContributionSoft::processSoftContribution($params, $contribution);
1058 }
6a488035
TO
1059
1060 $transaction->commit();
1061
1062 return $contribution;
1063 }
1064
1065 /**
66f9e52b 1066 * Fix the Location Fields.
6a488035 1067 *
b7a83c2c
J
1068 * @todo Reconcile with the contribution method formatParamsForPaymentProcessor
1069 * rather than adding different logic to check when to keep the billing
1070 * fields. There might be a difference in handling guest/multiple
1071 * participants though.
1072 *
c490a46a 1073 * @param array $params
3bdf1f3a 1074 * @param array $fields
c490a46a 1075 * @param CRM_Core_Form $form
6a488035 1076 */
4fb756af 1077 public static function fixLocationFields(&$params, &$fields, &$form) {
a9f7d48b
AS
1078 if (!empty($form->_fields)) {
1079 foreach ($form->_fields as $name => $dontCare) {
6a488035
TO
1080 $fields[$name] = 1;
1081 }
1082 }
1083
08318d90
J
1084 // If there's no 'first_name' in the profile then overwrite the names from
1085 // the billing fields (if they are set)
6a488035
TO
1086 if (is_array($fields)) {
1087 if (!array_key_exists('first_name', $fields)) {
1088 $nameFields = array('first_name', 'middle_name', 'last_name');
1089 foreach ($nameFields as $name) {
1090 $fields[$name] = 1;
1091 if (array_key_exists("billing_$name", $params)) {
1092 $params[$name] = $params["billing_{$name}"];
1093 $params['preserveDBName'] = TRUE;
1094 }
1095 }
1096 }
1097 }
1098
08318d90 1099 // Add the billing names to the billing address, if a billing name is set
5329bf02 1100 if (!empty($params['billing_first_name'])) {
a9f7d48b
AS
1101 $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);
1102 $fields["address_name-{$form->_bltID}"] = 1;
6a488035 1103 }
08318d90 1104
a9f7d48b 1105 $fields["email-{$form->_bltID}"] = 1;
6a488035
TO
1106 $fields['email-Primary'] = 1;
1107
1108 //if its pay later or additional participant set email address as primary.
8cc574cf 1109 if ((!empty($params['is_pay_later']) || empty($params['is_primary']) ||
a9f7d48b
AS
1110 !$form->_values['event']['is_monetary'] ||
1111 $form->_allowWaitlist ||
1112 $form->_requireApproval
353ffa53
TO
1113 ) && !empty($params["email-{$form->_bltID}"])
1114 ) {
a9f7d48b 1115 $params['email-Primary'] = $params["email-{$form->_bltID}"];
6a488035
TO
1116 }
1117 }
1118
1119 /**
66f9e52b 1120 * Update contact fields.
6a488035 1121 *
100fef9d 1122 * @param int $contactID
c490a46a 1123 * @param array $params
3bdf1f3a 1124 * @param array $fields
c490a46a 1125 * @param CRM_Core_Form $form
dd244018 1126 *
3bdf1f3a 1127 * @return int
6a488035 1128 */
4fb756af 1129 public static function updateContactFields($contactID, $params, $fields, &$form) {
6a488035
TO
1130 //add the contact to group, if add to group is selected for a
1131 //particular uf group
1132
1133 // get the add to groups
1134 $addToGroups = array();
1135
a9f7d48b
AS
1136 if (!empty($form->_fields)) {
1137 foreach ($form->_fields as $key => $value) {
a7488080 1138 if (!empty($value['add_to_group_id'])) {
6a488035
TO
1139 $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
1140 }
1141 }
1142 }
1143
1144 // check for profile double opt-in and get groups to be subscribed
1145 $subscribeGroupIds = CRM_Core_BAO_UFGroup::getDoubleOptInGroupIds($params, $contactID);
1146
1147 foreach ($addToGroups as $k) {
1148 if (array_key_exists($k, $subscribeGroupIds)) {
1149 unset($addToGroups[$k]);
1150 }
1151 }
1152
1153 // since we are directly adding contact to group lets unset it from mailing
1154 if (!empty($addToGroups)) {
1155 foreach ($addToGroups as $groupId) {
1156 if (isset($subscribeGroupIds[$groupId])) {
1157 unset($subscribeGroupIds[$groupId]);
1158 }
1159 }
1160 }
1161 if ($contactID) {
1162 $ctype = CRM_Core_DAO::getFieldValue(
1163 'CRM_Contact_DAO_Contact',
1164 $contactID,
1165 'contact_type'
1166 );
e1ce628e 1167
22e263ad 1168 if (array_key_exists('contact_id', $params) && empty($params['contact_id'])) {
e1ce628e 1169 // we unset this here because the downstream function ignores the contactID we give it
1170 // if it is set & it is difficult to understand the implications of 'fixing' this downstream
1171 // but if we are passing a contact id into this function it's reasonable to assume we don't
1172 // want it ignored
1173 unset($params['contact_id']);
1174 }
1175
6a488035
TO
1176 $contactID = CRM_Contact_BAO_Contact::createProfileContact(
1177 $params,
1178 $fields,
1179 $contactID,
1180 $addToGroups,
1181 NULL,
1182 $ctype,
1183 TRUE
1184 );
1185 }
1186 else {
1187
1188 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
1189 if (!isset($params[$greeting . '_id'])) {
1190 $params[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils::defaultGreeting('Individual', $greeting);
1191 }
1192 }
1193
1194 $contactID = CRM_Contact_BAO_Contact::createProfileContact($params,
1195 $fields,
1196 NULL,
1197 $addToGroups,
1198 NULL,
1199 NULL,
1200 TRUE
1201 );
a9f7d48b 1202 $form->set('contactID', $contactID);
6a488035
TO
1203 }
1204
1205 //get email primary first if exist
1206 $subscribtionEmail = array('email' => CRM_Utils_Array::value('email-Primary', $params));
1207 if (!$subscribtionEmail['email']) {
a9f7d48b 1208 $subscribtionEmail['email'] = CRM_Utils_Array::value("email-{$form->_bltID}", $params);
6a488035
TO
1209 }
1210 // subscribing contact to groups
1211 if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
1212 CRM_Mailing_Event_BAO_Subscribe::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
1213 }
1214
1215 return $contactID;
1216 }
5bdcb00b 1217
0cf587a7 1218 /**
3bdf1f3a 1219 * Assign Profiles.
1220 *
1221 * @param CRM_Core_Form $form
0cf587a7 1222 */
5bdcb00b 1223 public static function assignProfiles(&$form) {
5bdcb00b
PJ
1224 $participantParams = $form->_params;
1225 $formattedValues = $profileFields = array();
353ffa53 1226 $count = 1;
5bdcb00b
PJ
1227 foreach ($participantParams as $participantNum => $participantValue) {
1228 if ($participantNum) {
0479b4c8
TO
1229 $prefix1 = 'additional';
1230 $prefix2 = 'additional_';
0db6c3e1
TO
1231 }
1232 else {
0479b4c8
TO
1233 $prefix1 = '';
1234 $prefix2 = '';
5bdcb00b
PJ
1235 }
1236 if ($participantValue != 'skip') {
1237 //get the customPre profile info
1238 if (!empty($form->_values[$prefix2 . 'custom_pre_id'])) {
1239 $values = $groupName = array();
1240 CRM_Event_BAO_Event::displayProfile($participantValue,
0479b4c8 1241 $form->_values[$prefix2 . 'custom_pre_id'],
5bdcb00b
PJ
1242 $groupName,
1243 $values,
1244 $profileFields
1245 );
1246
1247 if (count($values)) {
1248 $formattedValues[$count][$prefix1 . 'CustomPre'] = $values;
1249 }
1250 $formattedValues[$count][$prefix1 . 'CustomPreGroupTitle'] = CRM_Utils_Array::value('groupTitle', $groupName);
1251 }
1252 //get the customPost profile info
1253 if (!empty($form->_values[$prefix2 . 'custom_post_id'])) {
1254 $values = $groupName = array();
1255 foreach ($form->_values[$prefix2 . 'custom_post_id'] as $gids) {
1256 $val = array();
1257 CRM_Event_BAO_Event::displayProfile($participantValue,
1258 $gids,
1259 $group,
1260 $val,
1261 $profileFields
1262 );
1263 $values[$gids] = $val;
1264 $groupName[$gids] = $group;
1265 }
1266
1267 if (count($values)) {
1268 $formattedValues[$count][$prefix1 . 'CustomPost'] = $values;
1269 }
1270
1271 if (isset($formattedValues[$count][$prefix1 . 'CustomPre'])) {
1272 $formattedValues[$count][$prefix1 . 'CustomPost'] = array_diff_assoc($formattedValues[$count][$prefix1 . 'CustomPost'],
1273 $formattedValues[$count][$prefix1 . 'CustomPre']
1274 );
1275 }
1276
1277 $formattedValues[$count][$prefix1 . 'CustomPostGroupTitle'] = $groupName;
1278 }
1279 $count++;
1280 }
1281 $form->_fields = $profileFields;
1282 }
481a74f4 1283 if (!empty($formattedValues)) {
5bdcb00b 1284 $form->assign('primaryParticipantProfile', $formattedValues[1]);
0479b4c8 1285 $form->set('primaryParticipantProfile', $formattedValues[1]);
5bdcb00b
PJ
1286 if ($count > 2) {
1287 unset($formattedValues[1]);
1288 $form->assign('addParticipantProfile', $formattedValues);
0479b4c8 1289 $form->set('addParticipantProfile', $formattedValues);
5bdcb00b
PJ
1290 }
1291 }
1292 }
96025800 1293
632196ea 1294 /**
1295 * Submit in test mode.
1296 *
1297 * @param $params
1298 */
1299 public static function testSubmit($params) {
1300 $form = new CRM_Event_Form_Registration_Confirm();
1301 // This way the mocked up controller ignores the session stuff.
1302 $_SERVER['REQUEST_METHOD'] = 'GET';
1303 $_REQUEST['id'] = $form->_eventId = $params['id'];
1304 $form->controller = new CRM_Event_Controller_Registration();
1305 $form->_params = $params['params'];
3ae1b2f4 1306 // This happens in buildQuickForm so emulate here.
1307 $form->_amount = $form->_totalAmount = CRM_Utils_Rule::cleanMoney(CRM_Utils_Array::value('totalAmount', $params));
632196ea 1308 $form->set('params', $params['params']);
1309 $form->_values['custom_pre_id'] = array();
1310 $form->_values['custom_post_id'] = array();
6704d983 1311 $form->_values['event'] = CRM_Utils_Array::value('event', $params);
632196ea 1312 $form->_contributeMode = $params['contributeMode'];
1313 $eventParams = array('id' => $params['id']);
1314 CRM_Event_BAO_Event::retrieve($eventParams, $form->_values['event']);
1315 $form->set('registerByID', $params['registerByID']);
5e40de84 1316 if (!empty($params['paymentProcessorObj'])) {
1317 $form->_paymentProcessor = $params['paymentProcessorObj'];
1318 }
632196ea 1319 $form->postProcess();
1320 }
1321
55f9f634 1322 /**
1323 * Process the payment, redirecting back to the page on error.
1324 *
1325 * @param $payment
1326 * @param $value
1327 *
1328 * @return array
1329 */
1330 private function processPayment($payment, $value) {
1331 try {
1332 $result = $payment->doPayment($value, 'event');
1333 return array($result, $value);
1334 }
1335 catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
22f9da80 1336 Civi::log()->error('Payment processor exception: ' . $e->getMessage());
55f9f634 1337 CRM_Core_Session::singleton()->setStatus($e->getMessage());
1338 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/event/register', "id={$this->_eventId}"));
1339 }
1340 return array();
1341 }
1342
3ae1b2f4 1343 /**
1344 * Clean money fields from the form.
1345 *
1346 * @param array $params
1347 */
1348 protected function cleanMoneyFields(&$params) {
1349 foreach ($this->submittableMoneyFields as $moneyField) {
1350 foreach ($params as $index => $paramField) {
1351 if (isset($paramField[$moneyField])) {
1352 $params[$index][$moneyField] = CRM_Utils_Rule::cleanMoney($paramField[$moneyField]);
1353 }
1354 }
1355 }
1356 }
1357
6a488035 1358}