Commit | Line | Data |
---|---|---|
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 | */ |
22 | class 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' => '  ', |
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' => ' ', | |
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 | } |