[Ref] Separate url path calculation into the relevant classes
[civicrm-core.git] / CRM / Event / Form / Registration / AdditionalParticipant.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
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 |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 *
15 * @package CRM
ca5cec67 16 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
17 */
18
19/**
c039f658 20 * This class generates form components for processing Event.
6a488035
TO
21 */
22class CRM_Event_Form_Registration_AdditionalParticipant extends CRM_Event_Form_Registration {
23
6a488035 24 /**
100fef9d 25 * Pre-registered additional participant id.
90b461f1 26 * @var int
6a488035
TO
27 */
28 public $additionalParticipantId = NULL;
29
30 /**
66f9e52b 31 * Set variables up before form is built.
6a488035
TO
32 *
33 * @return void
6a488035 34 */
00be9182 35 public function preProcess() {
6a488035
TO
36 parent::preProcess();
37
38 $participantNo = substr($this->_name, 12);
39
40 //lets process in-queue participants.
41 if ($this->_participantId && $this->_additionalParticipantIds) {
9c1bc317 42 $this->_additionalParticipantId = $this->_additionalParticipantIds[$participantNo] ?? NULL;
6a488035
TO
43 }
44
45 $participantCnt = $participantNo + 1;
46 $this->assign('formId', $participantNo);
be2fb01f 47 $this->_params = [];
6a488035
TO
48 $this->_params = $this->get('params');
49
50 $participantTot = $this->_params[0]['additional_participants'] + 1;
51 $skipCount = count(array_keys($this->_params, "skip"));
52 if ($skipCount) {
53 $this->assign('skipCount', $skipCount);
54 }
be2fb01f 55 CRM_Utils_System::setTitle(ts('Register Participant %1 of %2', [1 => $participantCnt, 2 => $participantTot]));
6a488035
TO
56
57 //CRM-4320, hack to check last participant.
58 $this->_lastParticipant = FALSE;
59 if ($participantTot == $participantCnt) {
60 $this->_lastParticipant = TRUE;
61 }
62 $this->assign('lastParticipant', $this->_lastParticipant);
63 }
64
65 /**
c490a46a 66 * Set default values for the form. For edit/view mode
6a488035
TO
67 * the default values are retrieved from the database
68 *
6a488035 69 *
355ba699 70 * @return void
6a488035 71 */
00be9182 72 public function setDefaultValues() {
be2fb01f 73 $defaults = $unsetSubmittedOptions = [];
6a488035
TO
74 $discountId = NULL;
75 //fix for CRM-3088, default value for discount set.
76 if (!empty($this->_values['discount'])) {
77 $discountId = CRM_Core_BAO_Discount::findSet($this->_eventId, 'civicrm_event');
8cc574cf 78 if ($discountId && !empty($this->_values['event']['default_discount_fee_id'])) {
0479b4c8 79 $discountKey = CRM_Core_DAO::getFieldValue("CRM_Core_DAO_OptionValue", $this->_values['event']['default_discount_fee_id'], 'weight', 'id'
6a488035
TO
80 );
81 $defaults['amount'] = key(array_slice($this->_values['discount'][$discountId], $discountKey - 1, $discountKey, TRUE));
82 }
83 }
84 if ($this->_priceSetId) {
85 foreach ($this->_feeBlock as $key => $val) {
a7488080 86 if (empty($val['options'])) {
6a488035
TO
87 continue;
88 }
89
be2fb01f 90 $optionsFull = CRM_Utils_Array::value('option_full_ids', $val, []);
6a488035
TO
91 foreach ($val['options'] as $keys => $values) {
92 if ($values['is_default'] && !in_array($keys, $optionsFull)) {
93 if ($val['html_type'] == 'CheckBox') {
94 $defaults["price_{$key}"][$keys] = 1;
95 }
96 else {
97 $defaults["price_{$key}"] = $keys;
98 }
99 }
100 }
101 if (!empty($optionsFull)) {
102 $unsetSubmittedOptions[$val['id']] = $optionsFull;
103 }
104 }
105 }
106
107 //CRM-4320, setdefault additional participant values.
108 if ($this->_allowConfirmation && $this->_additionalParticipantId) {
109 //hack to get set default from eventFees.php
353ffa53
TO
110 $this->_discountId = $discountId;
111 $this->_pId = $this->_additionalParticipantId;
112 $this->_contactId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_additionalParticipantId, 'contact_id');
c7d52684 113
114 CRM_Event_BAO_Participant::formatFieldsAndSetProfileDefaults($this->_contactId, $this);
6a488035
TO
115 $participantDefaults = CRM_Event_Form_EventFees::setDefaultValues($this);
116 $participantDefaults = array_merge($this->_defaults, $participantDefaults);
117 // use primary email address if billing email address is empty
118 if (empty($this->_defaults["email-{$this->_bltID}"]) &&
119 !empty($this->_defaults["email-Primary"])
120 ) {
121 $participantDefaults["email-{$this->_bltID}"] = $this->_defaults["email-Primary"];
122 }
123 $defaults = array_merge($defaults, $participantDefaults);
124 }
125
126 $defaults = array_merge($this->_defaults, $defaults);
127
128 //reset values for all options those are full.
0dc0b759 129 CRM_Event_Form_Registration::resetElementValue($unsetSubmittedOptions, $this);
6a488035
TO
130
131 //load default campaign from page.
132 if (array_key_exists('participant_campaign_id', $this->_fields)) {
9c1bc317 133 $defaults['participant_campaign_id'] = $this->_values['event']['campaign_id'] ?? NULL;
6a488035 134 }
6a488035 135
dde86037
BS
136 //CRM-17865 set custom field defaults
137 if (!empty($this->_fields)) {
138 foreach ($this->_fields as $name => $field) {
139 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($name)) {
140 if (!isset($defaults[$name])) {
141 CRM_Core_BAO_CustomField::setProfileDefaults($customFieldID, $name, $defaults,
142 NULL, CRM_Profile_Form::MODE_REGISTER
143 );
144 }
145 }
146 }
147 }
148
6a488035
TO
149 return $defaults;
150 }
151
152 /**
66f9e52b 153 * Build the form object.
6a488035 154 *
355ba699 155 * @return void
6a488035
TO
156 */
157 public function buildQuickForm() {
5f39c1a6 158
6a488035
TO
159 $button = substr($this->controller->getButtonName(), -4);
160
6a488035
TO
161 if ($this->_values['event']['is_monetary']) {
162 CRM_Event_Form_Registration_Register::buildAmount($this);
163 }
6a488035 164
60b661ac
JP
165 //Add pre and post profiles on the form.
166 foreach (['pre', 'post'] as $keys) {
167 if (isset($this->_values['additional_custom_' . $keys . '_id'])) {
168 $this->buildCustom($this->_values['additional_custom_' . $keys . '_id'], 'additionalCustom' . ucfirst($keys));
169 }
170 }
171
6a488035 172 //add buttons
8cc574cf 173 if ($this->isLastParticipant(TRUE) && empty($this->_values['event']['is_monetary'])) {
423616fa 174 $this->submitOnce = TRUE;
6a488035
TO
175 }
176
177 //handle case where user might sart with waiting by group
178 //registration and skip some people and now group fit to
179 //become registered so need to take payment from user.
180 //this case only occurs at dynamic waiting status, CRM-4320
181 $statusMessage = NULL;
182 $allowToProceed = TRUE;
183 $includeSkipButton = TRUE;
184 $this->_resetAllowWaitlist = FALSE;
185
9da8dc8c 186 $pricesetFieldsCount = CRM_Price_BAO_PriceSet::getPricesetCount($this->_priceSetId);
6a488035
TO
187
188 if ($this->_lastParticipant || $pricesetFieldsCount) {
189 //get the participant total.
190 $processedCnt = self::getParticipantCount($this, $this->_params, TRUE);
191 }
192
8cc574cf 193 if (!$this->_allowConfirmation && !empty($this->_params[0]['bypass_payment']) &&
6a488035
TO
194 $this->_lastParticipant
195 ) {
196
197 //get the event spaces.
198 $spaces = $this->_availableRegistrations;
199
200 $currentPageMaxCount = 1;
201 if ($pricesetFieldsCount) {
202 $currentPageMaxCount = $pricesetFieldsCount;
203 }
204
205 //we might did reset allow waiting in case of dynamic calculation
5f39c1a6 206 // @TODO - does this bypass_payment still exist?
a7488080 207 if (!empty($this->_params[0]['bypass_payment']) &&
6a488035
TO
208 is_numeric($spaces) &&
209 $processedCnt > $spaces
210 ) {
211 $this->_allowWaitlist = TRUE;
212 $this->set('allowWaitlist', TRUE);
213 }
214
215 //lets allow to become a part of runtime waiting list, if primary selected pay later.
216 $realPayLater = FALSE;
8cc574cf 217 if (!empty($this->_values['event']['is_monetary']) && !empty($this->_values['event']['is_pay_later'])) {
9c1bc317 218 $realPayLater = $this->_params[0]['is_pay_later'] ?? NULL;
6a488035
TO
219 }
220
221 //truly spaces are greater than required.
222 if (is_numeric($spaces) && $spaces >= ($processedCnt + $currentPageMaxCount)) {
223 if (CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0 || $this->_requireApproval) {
224 $this->_allowWaitlist = FALSE;
225 $this->set('allowWaitlist', $this->_allowWaitlist);
226 if ($this->_requireApproval) {
be2fb01f 227 $statusMessage = ts("It looks like you are now registering a group of %1 participants. The event has %2 available spaces (you will not be wait listed). Registration for this event requires approval. You will receive an email once your registration has been reviewed.", [
90b461f1
SL
228 1 => ++$processedCnt,
229 2 => $spaces,
230 ]);
6a488035
TO
231 }
232 else {
be2fb01f 233 $statusMessage = ts("It looks like you are now registering a group of %1 participants. The event has %2 available spaces (you will not be wait listed).", [
90b461f1
SL
234 1 => ++$processedCnt,
235 2 => $spaces,
236 ]);
6a488035
TO
237 }
238 }
239 else {
be2fb01f 240 $statusMessage = ts("It looks like you are now registering a group of %1 participants. The event has %2 available spaces (you will not be wait listed). Please go back to the main registration page and reduce the number of additional people. You will also need to complete payment information.", [
90b461f1
SL
241 1 => ++$processedCnt,
242 2 => $spaces,
243 ]);
6a488035
TO
244 $allowToProceed = FALSE;
245 }
246 CRM_Core_Session::setStatus($statusMessage, ts('Registration Error'), 'error');
247 }
248 elseif ($processedCnt == $spaces) {
249 if (CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0
250 || $realPayLater || $this->_requireApproval
251 ) {
252 $this->_resetAllowWaitlist = TRUE;
253 if ($this->_requireApproval) {
254 $statusMessage = ts("If you skip this participant there will be enough spaces in the event for your group (you will not be wait listed). Registration for this event requires approval. You will receive an email once your registration has been reviewed.");
255 }
256 else {
257 $statusMessage = ts("If you skip this participant there will be enough spaces in the event for your group (you will not be wait listed).");
258 }
259 }
260 else {
261 //hey there is enough space and we require payment.
262 $statusMessage = ts("If you skip this participant there will be enough spaces in the event for your group (you will not be wait listed). Please go back to the main registration page and reduce the number of additional people. You will also need to complete payment information.");
263 $includeSkipButton = FALSE;
264 }
265 }
266 }
267
268 // for priceset with count
8cc574cf 269 if ($pricesetFieldsCount && !empty($this->_values['event']['has_waitlist']) &&
6a488035
TO
270 !$this->_allowConfirmation
271 ) {
272
273 if ($this->_isEventFull) {
274 $statusMessage = ts('This event is currently full. You are registering for the waiting list. You will be notified if spaces become available.');
275 }
276 elseif ($this->_allowWaitlist ||
277 (!$this->_allowWaitlist && ($processedCnt + $pricesetFieldsCount) > $this->_availableRegistrations)
278 ) {
279
280 $waitingMsg = ts('It looks like you are registering more participants then there are spaces available. All participants will be added to the waiting list. You will be notified if spaces become available.');
281 $confirmedMsg = ts('It looks like there are enough spaces in this event for your group (you will not be wait listed).');
282 if ($this->_requireApproval) {
283 $waitingMsg = ts('It looks like you are now registering a group of %1 participants. The event has %2 available spaces (you will not be wait listed). Registration for this event requires approval. You will receive an email once your registration has been reviewed.');
284 $confirmedMsg = ts('It looks there are enough spaces in this event for your group (you will not be wait listed). Registration for this event requires approval. You will receive an email once your registration has been reviewed.');
285 }
286
287 $this->assign('waitingMsg', $waitingMsg);
288 $this->assign('confirmedMsg', $confirmedMsg);
289
290 $this->assign('availableRegistrations', $this->_availableRegistrations);
291 $this->assign('currentParticipantCount', $processedCnt);
292 $this->assign('allowGroupOnWaitlist', TRUE);
293
294 $paymentBypassed = NULL;
a7488080 295 if (!empty($this->_params[0]['bypass_payment']) &&
6a488035
TO
296 !$this->_allowWaitlist &&
297 !$realPayLater &&
298 !$this->_requireApproval &&
299 !(CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0)
300 ) {
301 $paymentBypassed = ts('Please go back to the main registration page, to complete payment information.');
302 }
303 $this->assign('paymentBypassed', $paymentBypassed);
304 }
305 }
306
307 $this->assign('statusMessage', $statusMessage);
308
be2fb01f
CW
309 $buttons = [
310 [
f212d37d
CW
311 'type' => 'back',
312 'name' => ts('Go Back'),
6a488035 313 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp',
be2fb01f
CW
314 ],
315 ];
6a488035
TO
316
317 //CRM-4320
318 if ($allowToProceed) {
be2fb01f 319 $buttons = array_merge($buttons, [
90b461f1
SL
320 [
321 'type' => 'upload',
322 'name' => ts('Continue'),
323 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
324 'isDefault' => TRUE,
90b461f1
SL
325 ],
326 ]);
6a488035 327 if ($includeSkipButton) {
be2fb01f 328 $buttons = array_merge($buttons, [
90b461f1
SL
329 [
330 'type' => 'next',
331 'name' => ts('Skip Participant'),
332 'subName' => 'skip',
333 'icon' => 'fa-fast-forward',
334 ],
335 ]);
6a488035
TO
336 }
337 }
338 $this->addButtons($buttons);
be2fb01f 339 $this->addFormRule(['CRM_Event_Form_Registration_AdditionalParticipant', 'formRule'], $this);
86c0d461 340 $this->unsavedChangesWarn = TRUE;
6a488035
TO
341 }
342
343 /**
66f9e52b 344 * Global form rule.
6a488035 345 *
d4dd1e85
TO
346 * @param array $fields
347 * The input form values.
348 * @param array $files
349 * The uploaded files if any.
77b97be7
EM
350 * @param $self
351 *
6a488035 352 *
72b3a70c
CW
353 * @return bool|array
354 * true if no errors, else array of errors
6a488035 355 */
00be9182 356 public static function formRule($fields, $files, $self) {
be2fb01f 357 $errors = [];
6a488035
TO
358 //get the button name.
359 $button = substr($self->controller->getButtonName(), -4);
360
361 $realPayLater = FALSE;
8cc574cf 362 if (!empty($self->_values['event']['is_monetary']) && !empty($self->_values['event']['is_pay_later'])) {
9c1bc317 363 $realPayLater = $self->_params[0]['is_pay_later'] ?? NULL;
6a488035
TO
364 }
365
366 if ($button != 'skip') {
367 //Check that either an email or firstname+lastname is included in the form(CRM-9587)
368 CRM_Event_Form_Registration_Register::checkProfileComplete($fields, $errors, $self->_eventId);
369
370 //Additional Participant can also register for an event only once
371 $isRegistered = CRM_Event_Form_Registration_Register::checkRegistration($fields, $self, TRUE);
372 if ($isRegistered) {
373 if ($self->_values['event']['allow_same_participant_emails']) {
374 $errors['_qf_default'] = ts('A person is already registered for this event.');
375 }
376 else {
377 $errors["email-{$self->_bltID}"] = ts('A person with this email address is already registered for this event.');
378 }
379 }
380
381 //get the complete params.
382 $params = $self->get('params');
383
384 //take the participant instance.
385 $addParticipantNum = substr($self->_name, 12);
386
387 if (is_array($params)) {
388 foreach ($params as $key => $value) {
389 if ($key != $addParticipantNum) {
390 if (!$self->_values['event']['allow_same_participant_emails']) {
391 //collect all email fields
be2fb01f
CW
392 $existingEmails = [];
393 $additionalParticipantEmails = [];
6a488035 394 if (is_array($value)) {
0479b4c8
TO
395 foreach ($value as $key => $val) {
396 if (substr($key, 0, 6) == 'email-' && $val) {
397 $existingEmails[] = $val;
398 }
6a488035
TO
399 }
400 }
6a488035
TO
401 foreach ($fields as $key => $val) {
402 if (substr($key, 0, 6) == 'email-' && $val) {
403 $additionalParticipantEmails[] = $val;
404 $mailKey = $key;
405 }
406 }
407 //check if any emails are common to both arrays
408 if (count(array_intersect($existingEmails, $additionalParticipantEmails))) {
409 $errors[$mailKey] = ts('The email address must be unique for each participant.');
410 break;
411 }
412 }
413 else {
414 // check with first_name and last_name for additional participants
33ab1d69 415 if (!empty($value['first_name']) && ($value['first_name'] == CRM_Utils_Array::value('first_name', $fields)) &&
0479b4c8 416 (CRM_Utils_Array::value('last_name', $value) == CRM_Utils_Array::value('last_name', $fields))
6a488035
TO
417 ) {
418 $errors['first_name'] = ts('The first name and last name must be unique for each participant.');
419 break;
420 }
421 }
422 }
423 }
424 }
425
426 //check for atleast one pricefields should be selected
a7488080 427 if (!empty($fields['priceSetId'])) {
6a488035
TO
428 $allParticipantParams = $params;
429
430 //format current participant params.
431 $allParticipantParams[$addParticipantNum] = self::formatPriceSetParams($self, $fields);
432 $totalParticipants = self::getParticipantCount($self, $allParticipantParams);
433
434 //validate price field params.
435 $priceSetErrors = self::validatePriceSet($self, $allParticipantParams);
be2fb01f 436 $errors = array_merge($errors, CRM_Utils_Array::value($addParticipantNum, $priceSetErrors, []));
6a488035
TO
437
438 if (!$self->_allowConfirmation &&
439 is_numeric($self->_availableRegistrations)
440 ) {
a7488080 441 if (!empty($self->_params[0]['bypass_payment']) &&
6a488035
TO
442 !$self->_allowWaitlist &&
443 !$realPayLater &&
444 !$self->_requireApproval &&
445 !(CRM_Utils_Array::value('amount', $self->_params[0], 0) == 0) &&
446 $totalParticipants < $self->_availableRegistrations
447 ) {
448 $errors['_qf_default'] = ts("Your event registration will be confirmed. Please go back to the main registration page, to complete payment information.");
449 }
450 //check for availability of registrations.
8cc574cf 451 if (!$self->_allowConfirmation && empty($self->_values['event']['has_waitlist']) &&
6a488035
TO
452 $totalParticipants > $self->_availableRegistrations
453 ) {
be2fb01f 454 $errors['_qf_default'] = ts('Sorry, it looks like this event only has %2 spaces available, and you are trying to register %1 participants. Please change your selections accordingly.', [
90b461f1
SL
455 1 => $totalParticipants,
456 2 => $self->_availableRegistrations,
457 ]);
6a488035
TO
458 }
459 }
460 }
461 }
462
8cc574cf 463 if ($button == 'skip' && $self->_lastParticipant && !empty($fields['priceSetId'])) {
9da8dc8c 464 $pricesetFieldsCount = CRM_Price_BAO_PriceSet::getPricesetCount($fields['priceSetId']);
6a488035
TO
465 if (($pricesetFieldsCount < 1) || $self->_allowConfirmation) {
466 return $errors;
467 }
468
8cc574cf 469 if (!empty($self->_values['event']['has_waitlist']) && !empty($self->_params[0]['bypass_payment']) &&
6a488035
TO
470 !$self->_allowWaitlist &&
471 !$realPayLater &&
472 !$self->_requireApproval &&
473 !(CRM_Utils_Array::value('amount', $self->_params[0], 0) == 0)
474 ) {
475 $errors['_qf_default'] = ts("You are going to skip the last participant, your event registration will be confirmed. Please go back to the main registration page, to complete payment information.");
476 }
477 }
478
6a488035
TO
479 if ($button != 'skip' &&
480 $self->_values['event']['is_monetary'] &&
481 !isset($errors['_qf_default']) &&
482 !$self->validatePaymentValues($self, $fields)
483 ) {
484 $errors['_qf_default'] = ts("Your payment information looks incomplete. Please go back to the main registration page, to complete payment information.");
485 $self->set('forcePayement', TRUE);
486 }
487 elseif ($button == 'skip') {
488 $self->set('forcePayement', TRUE);
489 }
490
491 return $errors;
492 }
493
0cf587a7
EM
494 /**
495 * @param $self
496 * @param $fields
497 *
498 * @return bool
499 */
00be9182 500 public function validatePaymentValues($self, $fields) {
6a488035 501
a7488080 502 if (!empty($self->_params[0]['bypass_payment']) ||
6a488035
TO
503 $self->_allowWaitlist ||
504 empty($self->_fields) ||
505 CRM_Utils_Array::value('amount', $self->_params[0]) > 0
506 ) {
507 return TRUE;
508 }
509
510 $validatePayement = FALSE;
a7488080 511 if (!empty($fields['priceSetId'])) {
be2fb01f 512 $lineItem = [];
9da8dc8c 513 CRM_Price_BAO_PriceSet::processAmount($self->_values['fee'], $fields, $lineItem);
6a488035
TO
514 if ($fields['amount'] > 0) {
515 $validatePayement = TRUE;
6a488035
TO
516 // return false;
517 }
518 }
a7488080 519 elseif (!empty($fields['amount']) &&
6a488035
TO
520 (CRM_Utils_Array::value('value', $self->_values['fee'][$fields['amount']]) > 0)
521 ) {
522 $validatePayement = TRUE;
523 }
524
525 if (!$validatePayement) {
6a488035 526 return TRUE;
6a488035
TO
527 }
528
be2fb01f 529 $errors = [];
7cb3d4f0
CW
530
531 CRM_Core_Form::validateMandatoryFields($self->_fields, $fields, $errors);
6a488035 532
5ec4b965 533 if (isset($self->_params[0]['payment_processor'])) {
534 // validate supplied payment instrument values (e.g. credit card number and cvv)
535 $payment_processor_id = $self->_params[0]['payment_processor'];
536 CRM_Core_Payment_Form::validatePaymentInstrument($payment_processor_id, $self->_params[0], $errors, (!$self->_isBillingAddressRequiredForPayLater ? NULL : 'billing'));
537 }
0dc0b759 538 if (!empty($errors)) {
7cb3d4f0 539 return FALSE;
6a488035 540 }
7cb3d4f0 541
6a488035
TO
542 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
543 if ($greetingType = CRM_Utils_Array::value($greeting, $self->_params[0])) {
233319bf 544 $customizedValue = CRM_Core_PseudoConstant::getKey('CRM_Contact_BAO_Contact', $greeting . '_id', 'Customized');
6a488035
TO
545 if ($customizedValue == $greetingType && empty($self->_params[0][$greeting . '_custom'])) {
546 return FALSE;
547 }
548 }
549 }
2ae4d103 550 return TRUE;
6a488035
TO
551 }
552
553 /**
66f9e52b 554 * Process the form submission.
6a488035 555 *
6a488035 556 *
355ba699 557 * @return void
6a488035
TO
558 */
559 public function postProcess() {
560 //get the button name.
561 $button = substr($this->controller->getButtonName(), -4);
562
563 //take the participant instance.
564 $addParticipantNum = substr($this->_name, 12);
565
566 //user submitted params.
567 $params = $this->controller->exportValues($this->_name);
568
569 if (!$this->_allowConfirmation) {
570 // check if the participant is already registered
7dfe13ab 571 $params['contact_id'] = CRM_Event_Form_Registration_Register::getRegistrationContactID($params, $this, TRUE);
6a488035
TO
572 }
573
f5a47ead 574 if (!empty($params['image_URL'])) {
575 CRM_Contact_BAO_Contact::processImageParams($params);
576 }
6a488035
TO
577 //carry campaign to partcipants.
578 if (array_key_exists('participant_campaign_id', $params)) {
579 $params['campaign_id'] = $params['participant_campaign_id'];
580 }
581 else {
9c1bc317 582 $params['campaign_id'] = $this->_values['event']['campaign_id'] ?? NULL;
6a488035
TO
583 }
584
585 // if waiting is enabled
586 if (!$this->_allowConfirmation &&
587 is_numeric($this->_availableRegistrations)
588 ) {
589 $this->_allowWaitlist = FALSE;
590 //get the current page count.
591 $currentCount = self::getParticipantCount($this, $params);
592 if ($button == 'skip') {
593 $currentCount = 'skip';
594 }
595
596 //get the total count.
597 $previousCount = self::getParticipantCount($this, $this->_params, TRUE);
598 $totalParticipants = $previousCount;
599 if (is_numeric($currentCount)) {
600 $totalParticipants += $currentCount;
601 }
a7488080 602 if (!empty($this->_values['event']['has_waitlist']) &&
6a488035
TO
603 $totalParticipants > $this->_availableRegistrations
604 ) {
605 $this->_allowWaitlist = TRUE;
606 }
607 $this->set('allowWaitlist', $this->_allowWaitlist);
608 $this->_lineItemParticipantsCount[$addParticipantNum] = $currentCount;
609 }
610
611 if ($button == 'skip') {
612 //hack for free/zero amount event.
613 if ($this->_resetAllowWaitlist) {
614 $this->_allowWaitlist = FALSE;
615 $this->set('allowWaitlist', FALSE);
616 if ($this->_requireApproval) {
617 $status = ts("You have skipped last participant and which result into event having enough spaces, but your registration require approval, Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.");
618 }
619 else {
620 $status = ts("You have skipped last participant and which result into event having enough spaces, hence your group become as register participants though you selected on wait list.");
621 }
622 CRM_Core_Session::setStatus($status);
623 }
624
625 $this->_params[$addParticipantNum] = 'skip';
626 if (isset($this->_lineItem)) {
627 $this->_lineItem[$addParticipantNum] = 'skip';
628 $this->_lineItemParticipantsCount[$addParticipantNum] = 'skip';
629 }
630 }
631 else {
632
633 $config = CRM_Core_Config::singleton();
634 $params['currencyID'] = $config->defaultCurrency;
635
636 if ($this->_values['event']['is_monetary']) {
637
638 //added for discount
639 $discountId = CRM_Core_BAO_Discount::findSet($this->_eventId, 'civicrm_event');
c039f658 640 $params['amount_level'] = $this->getAmountLevel($params, $discountId);
6a488035
TO
641 if (!empty($this->_values['discount'][$discountId])) {
642 $params['discount_id'] = $discountId;
6a488035
TO
643 $params['amount'] = $this->_values['discount'][$discountId][$params['amount']]['value'];
644 }
645 elseif (empty($params['priceSetId'])) {
6a488035
TO
646 $params['amount'] = $this->_values['fee'][$params['amount']]['value'];
647 }
648 else {
be2fb01f 649 $lineItem = [];
9da8dc8c 650 CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'], $params, $lineItem);
6a488035 651
0dc0b759 652 //build line item array..
653 //if requireApproval/waitlist is enabled we hide fees for primary participant
654 // (and not for additional participant which might be is a bug)
655 //lineItem are not correctly build for primary participant
656 //this results in redundancy since now lineItems for additional participant will be build against primary participantNum
657 //therefore lineItems must always be build against current participant No
658 $this->_lineItem[$addParticipantNum] = $lineItem;
6a488035
TO
659 }
660 }
661
662 if (array_key_exists('participant_role', $params)) {
663 $params['participant_role_id'] = $params['participant_role'];
664 }
665
a7488080 666 if (empty($params['participant_role_id']) && $this->_values['event']['default_role_id']) {
6a488035
TO
667 $params['participant_role_id'] = $this->_values['event']['default_role_id'];
668 }
669
a7488080 670 if (!empty($this->_params[0]['is_pay_later'])) {
6a488035
TO
671 $params['is_pay_later'] = 1;
672 }
673
674 //carry additional participant id, contact id if pre-registered.
675 if ($this->_allowConfirmation && $this->_additionalParticipantId) {
676 $params['contact_id'] = $this->_contactId;
677 $params['participant_id'] = $this->_additionalParticipantId;
678 }
679
680 //build the params array.
0dc0b759 681 $this->_params[$addParticipantNum] = $params;
6a488035
TO
682 }
683
684 //finally set the params.
685 $this->set('params', $this->_params);
686 //set the line item.
687 if ($this->_lineItem) {
688 $this->set('lineItem', $this->_lineItem);
689 $this->set('lineItemParticipantsCount', $this->_lineItemParticipantsCount);
690 }
691
692 $participantNo = count($this->_params);
693 if ($button != 'skip') {
be2fb01f 694 $statusMsg = ts('Registration information for participant %1 has been saved.', [1 => $participantNo]);
6a488035
TO
695 CRM_Core_Session::setStatus($statusMsg, ts('Registration Saved'), 'success');
696 }
697
1909126f 698 // Check whether to process the registration now, calling processRegistration()
699 if (
90b461f1
SL
700 // CRM-11182 - Optional confirmation screen
701 !$this->_values['event']['is_confirm_enabled']
d6121d3e 702 && !$this->_values['event']['is_monetary']
b99f3e96 703 && !empty($this->_params[0]['additional_participants'])
1909126f 704 && $this->isLastParticipant()
6a488035 705 ) {
3033e657 706 $this->processRegistration($this->_params);
6a488035
TO
707 }
708 }
709
0cf587a7
EM
710 /**
711 * @param $additionalParticipant
712 *
713 * @return array
714 */
5dd94759 715 public static function &getPages($additionalParticipant) {
be2fb01f 716 $details = [];
6a488035 717 for ($i = 1; $i <= $additionalParticipant; $i++) {
be2fb01f 718 $details["Participant_{$i}"] = [
6a488035
TO
719 'className' => 'CRM_Event_Form_Registration_AdditionalParticipant',
720 'title' => "Register Additional Participant {$i}",
be2fb01f 721 ];
6a488035
TO
722 }
723 return $details;
724 }
725
726 /**
66f9e52b 727 * Check whether call current participant is last one.
6a488035 728 *
2a6da8d7
EM
729 * @param bool $isButtonJs
730 *
608e6658 731 * @return bool
a6c01b45 732 * ture on success.
6a488035 733 */
00be9182 734 public function isLastParticipant($isButtonJs = FALSE) {
6a488035
TO
735 $participant = $isButtonJs ? $this->_params[0]['additional_participants'] : $this->_params[0]['additional_participants'] + 1;
736 if (count($this->_params) == $participant) {
737 return TRUE;
738 }
739 return FALSE;
740 }
a14eff52 741
6a488035 742}