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