Merge pull request #13158 from elisseck/dev/core/544
[civicrm-core.git] / CRM / Event / Form / Registration / Register.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
6a488035 29 * @package CRM
6b83d5bd 30 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
31 */
32
33/**
3bdf1f3a 34 * This class generates form components for processing Event.
6a488035
TO
35 */
36class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration {
37
38 /**
66f9e52b 39 * The fields involved in this page.
6a488035
TO
40 */
41 public $_fields;
42
6a488035
TO
43 /**
44 * The status message that user view.
6a488035
TO
45 */
46 protected $_waitlistMsg = NULL;
47 protected $_requireApprovalMsg = NULL;
48
3bdf1f3a 49 /**
50 * Deprecated parameter that we hope to remove.
51 *
52 * @var bool
53 */
6a488035
TO
54 public $_quickConfig = NULL;
55
56 /**
3bdf1f3a 57 * Skip duplicate check.
58 *
59 * This can be set using hook_civicrm_buildForm() to override the registration dupe check.
6a488035
TO
60 * CRM-7604
61 */
62 public $_skipDupeRegistrationCheck = FALSE;
63
cc789d46 64 public $_paymentProcessorID;
6a488035 65
16d1c8e2 66 /**
3bdf1f3a 67 * Show fee block or not.
68 *
16d1c8e2 69 * @var boolean determines if fee block should be shown or hidden
70 */
71 public $_noFees;
72
0b36bfd7
MWMC
73 /**
74 * @var array Fee Block
75 */
76 public $_feeBlock;
77
cc789d46 78 /**
3bdf1f3a 79 * Array of payment related fields to potentially display on this form (generally credit card or debit card fields).
80 *
81 * This is rendered via billingBlock.tpl.
82 *
cc789d46
EM
83 * @var array
84 */
85 public $_paymentFields = array();
86
7b64dc81 87 /**
88 * Get the contact id for the registration.
89 *
90 * @param array $fields
0b36bfd7 91 * @param CRM_Event_Form_Registration $form
7b64dc81 92 * @param bool $isAdditional
93 *
94 * @return int|null
95 */
0b36bfd7 96 public static function getRegistrationContactID($fields, $form, $isAdditional) {
7b64dc81 97 $contactID = NULL;
98 if (!$isAdditional) {
0b36bfd7 99 $contactID = $form->getContactID();
7b64dc81 100 }
101 if (!$contactID && is_array($fields) && $fields) {
b8cb7e46 102 $contactID = CRM_Contact_BAO_Contact::getFirstDuplicateContact($fields, 'Individual', 'Unsupervised', [], FALSE, CRM_Utils_Array::value('dedupe_rule_group_id', $form->_values['event']), ['event_id' => CRM_Utils_Array::value('id', $form->_values['event'])]);
7b64dc81 103 }
104 return $contactID;
105 }
106
6a488035 107 /**
66f9e52b 108 * Set variables up before form is built.
6a488035 109 */
00be9182 110 public function preProcess() {
6a488035 111 parent::preProcess();
7bf9cde2 112
6a488035
TO
113 //CRM-4320.
114 //here we can't use parent $this->_allowWaitlist as user might
cc789d46 115 //walk back and we might set this value in this postProcess.
6a488035 116 //(we set when spaces < group count and want to allow become part of waiting )
6a488035
TO
117 $eventFull = CRM_Event_BAO_Participant::eventFull($this->_eventId, FALSE, CRM_Utils_Array::value('has_waitlist', $this->_values['event']));
118
b6a469c5
CW
119 // Get payment processors if appropriate for this event
120 // We hide the payment fields if the event is full or requires approval,
121 // and the current user has not yet been approved CRM-12279
16d1c8e2 122 $this->_noFees = (($eventFull || $this->_requireApproval) && !$this->_allowConfirmation);
42e3a033
EM
123 $this->_paymentProcessors = $this->_noFees ? array() : $this->get('paymentProcessors');
124 $this->preProcessPaymentOptions();
b6a469c5 125
6a488035 126 $this->_allowWaitlist = FALSE;
8cc574cf 127 if ($eventFull && !$this->_allowConfirmation && !empty($this->_values['event']['has_waitlist'])) {
6a488035
TO
128 $this->_allowWaitlist = TRUE;
129 $this->_waitlistMsg = CRM_Utils_Array::value('waitlist_text', $this->_values['event']);
130 if (!$this->_waitlistMsg) {
131 $this->_waitlistMsg = ts('This event is currently full. However you can register now and get added to a waiting list. You will be notified if spaces become available.');
132 }
133 }
134 $this->set('allowWaitlist', $this->_allowWaitlist);
135
136 //To check if the user is already registered for the event(CRM-2426)
137 if (!$this->_skipDupeRegistrationCheck) {
138 self::checkRegistration(NULL, $this);
139 }
140
141 $this->assign('availableRegistrations', $this->_availableRegistrations);
142
143 // get the participant values from EventFees.php, CRM-4320
144 if ($this->_allowConfirmation) {
145 CRM_Event_Form_EventFees::preProcess($this);
146 }
6a488035
TO
147 }
148
149 /**
70d1766d 150 * Set default values for the form.
6a488035 151 */
00be9182 152 public function setDefaultValues() {
2ab5ff1d 153 $this->_defaults = array();
5ec4b965 154 if (!$this->_allowConfirmation && $this->_requireApproval) {
155 $this->_defaults['bypass_payment'] = 1;
156 }
5c280496 157 $contactID = $this->getContactID();
70d1766d 158 CRM_Core_Payment_Form::setDefaultValues($this, $contactID);
a28e436f 159
c7d52684 160 CRM_Event_BAO_Participant::formatFieldsAndSetProfileDefaults($contactID, $this);
3feb567a 161
13ac605f
DG
162 // Set default payment processor as default payment_processor radio button value
163 if (!empty($this->_paymentProcessors)) {
164 foreach ($this->_paymentProcessors as $pid => $value) {
a7488080 165 if (!empty($value['is_default'])) {
e02d7e96 166 $this->_defaults['payment_processor_id'] = $pid;
13ac605f
DG
167 }
168 }
169 }
170
6a488035
TO
171 //if event is monetary and pay later is enabled and payment
172 //processor is not available then freeze the pay later checkbox with
173 //default check
a7488080 174 if (!empty($this->_values['event']['is_pay_later']) &&
6a488035
TO
175 !is_array($this->_paymentProcessor)
176 ) {
177 $this->_defaults['is_pay_later'] = 1;
178 }
179
180 //set custom field defaults
181 if (!empty($this->_fields)) {
182 //load default campaign from page.
183 if (array_key_exists('participant_campaign_id', $this->_fields)) {
184 $this->_defaults['participant_campaign_id'] = CRM_Utils_Array::value('campaign_id',
185 $this->_values['event']
186 );
187 }
188
189 foreach ($this->_fields as $name => $field) {
190 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($name)) {
191 // fix for CRM-1743
192 if (!isset($this->_defaults[$name])) {
193 CRM_Core_BAO_CustomField::setProfileDefaults($customFieldID, $name, $this->_defaults,
194 NULL, CRM_Profile_Form::MODE_REGISTER
195 );
196 }
197 }
198 }
199 }
200
201 //fix for CRM-3088, default value for discount set.
202 $discountId = NULL;
203 if (!empty($this->_values['discount'])) {
204 $discountId = CRM_Core_BAO_Discount::findSet($this->_eventId, 'civicrm_event');
205 if ($discountId) {
206 if (isset($this->_values['event']['default_discount_fee_id'])) {
207 $discountKey = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue',
208 $this->_values['event']['default_discount_fee_id'],
209 'weight', 'id'
210 );
211
212 $this->_defaults['amount'] = key(array_slice($this->_values['discount'][$discountId],
353ffa53
TO
213 $discountKey - 1, $discountKey, TRUE
214 ));
6a488035
TO
215 }
216 }
217 }
218
219 // add this event's default participant role to defaults array
220 // (for cases where participant_role field is included in form via profile)
221 if ($this->_values['event']['default_role_id']) {
608e6658 222 $this->_defaults['participant_role']
223 = $this->_defaults['participant_role_id'] = $this->_values['event']['default_role_id'];
6a488035
TO
224 }
225 if ($this->_priceSetId && !empty($this->_feeBlock)) {
226 foreach ($this->_feeBlock as $key => $val) {
0dc0b759 227 if (empty($val['options'])) {
228 continue;
229 }
230 $optionFullIds = CRM_Utils_Array::value('option_full_ids', $val, array());
6a488035 231 foreach ($val['options'] as $keys => $values) {
8cc574cf 232 if ($values['is_default'] && empty($values['is_full'])) {
6a488035
TO
233
234 if ($val['html_type'] == 'CheckBox') {
235 $this->_defaults["price_{$key}"][$keys] = 1;
236 }
237 else {
238 $this->_defaults["price_{$key}"] = $keys;
239 }
240 }
241 }
0dc0b759 242 $unsetSubmittedOptions[$val['id']] = $optionFullIds;
6a488035 243 }
0dc0b759 244 //reset values for all options those are full.
245 CRM_Event_Form_Registration::resetElementValue($unsetSubmittedOptions, $this);
6a488035
TO
246 }
247
248 //set default participant fields, CRM-4320.
249 $hasAdditionalParticipants = FALSE;
250 if ($this->_allowConfirmation) {
251 $this->_contactId = $contactID;
252 $this->_discountId = $discountId;
253 $forcePayLater = CRM_Utils_Array::value('is_pay_later', $this->_defaults, FALSE);
254 $this->_defaults = array_merge($this->_defaults, CRM_Event_Form_EventFees::setDefaultValues($this));
255 $this->_defaults['is_pay_later'] = $forcePayLater;
256
257 if ($this->_additionalParticipantIds) {
258 $hasAdditionalParticipants = TRUE;
259 $this->_defaults['additional_participants'] = count($this->_additionalParticipantIds);
260 }
261 }
262 $this->assign('hasAdditionalParticipants', $hasAdditionalParticipants);
263
264 // //hack to simplify credit card entry for testing
265 // $this->_defaults['credit_card_type'] = 'Visa';
266 // $this->_defaults['credit_card_number'] = '4807731747657838';
267 // $this->_defaults['cvv2'] = '000';
268 // $this->_defaults['credit_card_exp_date'] = array( 'Y' => '2010', 'M' => '05' );
269
270 // to process Custom data that are appended to URL
271 $getDefaults = CRM_Core_BAO_CustomGroup::extractGetParams($this, "'Contact', 'Individual', 'Contribution', 'Participant'");
272 if (!empty($getDefaults)) {
273 $this->_defaults = array_merge($this->_defaults, $getDefaults);
274 }
275
276 return $this->_defaults;
277 }
278
279 /**
66f9e52b 280 * Build the form object.
6a488035
TO
281 */
282 public function buildQuickForm() {
4839c695
KJ
283 // build profiles first so that we can determine address fields etc
284 // and then show copy address checkbox
285 $this->buildCustom($this->_values['custom_pre_id'], 'customPre');
286 $this->buildCustom($this->_values['custom_post_id'], 'customPost');
287
d38c288e 288 // CRM-18399: used by template to pass pre profile id as a url arg
289 $this->assign('custom_pre_id', $this->_values['custom_pre_id']);
4839c695 290
cc789d46 291 CRM_Core_Payment_ProcessorForm::buildQuickForm($this);
6a488035 292
5c280496 293 $contactID = $this->getContactID();
37326fa1
DG
294 if ($contactID) {
295 $this->assign('contact_id', $contactID);
f498a273 296 $this->assign('display_name', CRM_Contact_BAO_Contact::displayName($contactID));
37326fa1 297 }
6a488035 298
6a488035
TO
299 $this->add('hidden', 'scriptFee', NULL);
300 $this->add('hidden', 'scriptArray', NULL);
301
302 $bypassPayment = $allowGroupOnWaitlist = $isAdditionalParticipants = FALSE;
303 if ($this->_values['event']['is_multiple_registrations']) {
304 // don't allow to add additional during confirmation if not preregistered.
305 if (!$this->_allowConfirmation || $this->_additionalParticipantIds) {
f1bc01e0 306 // CRM-17745: Make maximum additional participants configurable
6a488035 307 // Label is value + 1, since the code sees this is ADDITIONAL participants (in addition to "self")
f1bc01e0
J
308 $additionalOptions = array();
309 $additionalOptions[''] = 1;
30ddbdcb 310 for ($i = 1; $i <= $this->_values['event']['max_additional_participants']; $i++) {
f1bc01e0
J
311 $additionalOptions[$i] = $i + 1;
312 }
5f39c1a6 313 $this->add('select', 'additional_participants',
6a488035
TO
314 ts('How many people are you registering?'),
315 $additionalOptions,
316 NULL,
317 array('onChange' => "allowParticipant()")
318 );
319 $isAdditionalParticipants = TRUE;
320 }
321 }
322
5ec4b965 323 if (!$this->_allowConfirmation) {
324 $bypassPayment = TRUE;
325 }
326
6a488035 327 //hack to allow group to register w/ waiting
8cc574cf 328 if ((!empty($this->_values['event']['is_multiple_registrations']) ||
6a488035
TO
329 $this->_priceSetId
330 ) &&
331 !$this->_allowConfirmation &&
353ffa53
TO
332 is_numeric($this->_availableRegistrations) && !empty($this->_values['event']['has_waitlist'])
333 ) {
6a488035
TO
334 $bypassPayment = TRUE;
335 //case might be group become as a part of waitlist.
336 //If not waitlist then they require admin approve.
337 $allowGroupOnWaitlist = TRUE;
338 $this->_waitlistMsg = ts("This event has only %1 space(s) left. If you continue and register more than %1 people (including yourself ), the whole group will be wait listed. Or, you can reduce the number of people you are registering to %1 to avoid being put on the waiting list.", array(1 => $this->_availableRegistrations));
339
340 if ($this->_requireApproval) {
341 $this->_requireApprovalMsg = CRM_Utils_Array::value('approval_req_text', $this->_values['event'],
342 ts('Registration for this event requires approval. Once your registration(s) have been reviewed, you will receive an email with a link to a web page where you can complete the registration process.')
343 );
344 }
345 }
346
347 //case where only approval needed - no waitlist.
348 if ($this->_requireApproval &&
349 !$this->_allowWaitlist && !$bypassPayment
350 ) {
351 $this->_requireApprovalMsg = CRM_Utils_Array::value('approval_req_text', $this->_values['event'],
352 ts('Registration for this event requires 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.')
353 );
354 }
355
356 //lets display status to primary page only.
357 $this->assign('waitlistMsg', $this->_waitlistMsg);
358 $this->assign('requireApprovalMsg', $this->_requireApprovalMsg);
359 $this->assign('allowGroupOnWaitlist', $allowGroupOnWaitlist);
360 $this->assign('isAdditionalParticipants', $isAdditionalParticipants);
361
6a488035
TO
362 if ($this->_values['event']['is_monetary']) {
363 self::buildAmount($this);
364 }
365
596bff78 366 $pps = array();
367 //@todo this processor adding fn is another one duplicated on contribute - a shared
368 // common class would make this sort of thing extractable
cf6a124f 369 $onlinePaymentProcessorEnabled = FALSE;
6a488035 370 if (!empty($this->_paymentProcessors)) {
596bff78 371 foreach ($this->_paymentProcessors as $key => $name) {
22e263ad 372 if ($name['billing_mode'] == 1) {
596bff78 373 $onlinePaymentProcessorEnabled = TRUE;
374 }
6a488035
TO
375 $pps[$key] = $name['name'];
376 }
377 }
aa288d3f 378 if ($this->getContactID() === 0 && !$this->_values['event']['is_multiple_registrations']) {
e1ce628e 379 //@todo we are blocking for multiple registrations because we haven't tested
596bff78 380 $this->addCidZeroOptions($onlinePaymentProcessorEnabled);
381 }
a7488080 382 if (!empty($this->_values['event']['is_pay_later']) &&
6a488035
TO
383 ($this->_allowConfirmation || (!$this->_requireApproval && !$this->_allowWaitlist))
384 ) {
385 $pps[0] = $this->_values['event']['pay_later_text'];
386 }
387
388 if ($this->_values['event']['is_monetary']) {
389 if (count($pps) > 1) {
e02d7e96 390 $this->addRadio('payment_processor_id', ts('Payment Method'), $pps,
fdf1844b 391 NULL, "&nbsp;"
6a488035
TO
392 );
393 }
394 elseif (!empty($pps)) {
395 $ppKeys = array_keys($pps);
396 $currentPP = array_pop($ppKeys);
e02d7e96 397 $this->addElement('hidden', 'payment_processor_id', $currentPP);
6a488035
TO
398 }
399 }
400
5ec4b965 401 $this->addElement('hidden', 'bypass_payment', NULL, array('id' => 'bypass_payment'));
402
6a488035 403 $this->assign('bypassPayment', $bypassPayment);
6a488035 404
5c280496 405 $userID = $this->getContactID();
6a488035
TO
406
407 if (!$userID) {
408 $createCMSUser = FALSE;
409
410 if ($this->_values['custom_pre_id']) {
411 $profileID = $this->_values['custom_pre_id'];
412 $createCMSUser = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'is_cms_user');
413 }
414
415 if (!$createCMSUser &&
416 $this->_values['custom_post_id']
417 ) {
418 if (!is_array($this->_values['custom_post_id'])) {
419 $profileIDs = array($this->_values['custom_post_id']);
420 }
421 else {
422 $profileIDs = $this->_values['custom_post_id'];
423 }
424 foreach ($profileIDs as $pid) {
425 if (CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $pid, 'is_cms_user')) {
426 $profileID = $pid;
427 $createCMSUser = TRUE;
428 break;
429 }
430 }
431 }
432
433 if ($createCMSUser) {
434 CRM_Core_BAO_CMSUser::buildForm($this, $profileID, TRUE);
435 }
436 }
437
438 //we have to load confirm contribution button in template
439 //when multiple payment processor as the user
440 //can toggle with payment processor selection
441 $billingModePaymentProcessors = 0;
442 if (!CRM_Utils_System::isNull($this->_paymentProcessors)) {
443 foreach ($this->_paymentProcessors as $key => $values) {
444 if ($values['billing_mode'] == CRM_Core_Payment::BILLING_MODE_BUTTON) {
445 $billingModePaymentProcessors++;
446 }
447 }
448 }
449
450 if ($billingModePaymentProcessors && count($this->_paymentProcessors) == $billingModePaymentProcessors) {
451 $allAreBillingModeProcessors = TRUE;
0db6c3e1
TO
452 }
453 else {
6a488035
TO
454 $allAreBillingModeProcessors = FALSE;
455 }
456
8cc574cf 457 if (!$allAreBillingModeProcessors || !empty($this->_values['event']['is_pay_later']) || $bypassPayment
6a488035
TO
458 ) {
459
460 //freeze button to avoid multiple calls.
461 $js = NULL;
462
a7488080 463 if (empty($this->_values['event']['is_monetary'])) {
6a488035
TO
464 $js = array('onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');");
465 }
2a6da8d7 466
1909126f 467 // CRM-11182 - Optional confirmation screen
468 // Change button label depending on whether the next action is confirm or register
469 if (
470 !$this->_values['event']['is_multiple_registrations']
d6121d3e 471 && !$this->_values['event']['is_monetary']
1909126f 472 && !$this->_values['event']['is_confirm_enabled']
473 ) {
f212d37d 474 $buttonLabel = ts('Register');
0db6c3e1
TO
475 }
476 else {
f212d37d 477 $buttonLabel = ts('Continue');
1909126f 478 }
2a6da8d7 479
6a488035
TO
480 $this->addButtons(array(
481 array(
482 'type' => 'upload',
1909126f 483 'name' => $buttonLabel,
6a488035
TO
484 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
485 'isDefault' => TRUE,
486 'js' => $js,
487 ),
488 )
489 );
490 }
491
492 $this->addFormRule(array('CRM_Event_Form_Registration_Register', 'formRule'), $this);
86c0d461 493 $this->unsavedChangesWarn = TRUE;
6a488035
TO
494
495 // add pcp fields
496 if ($this->_pcpId) {
497 CRM_PCP_BAO_PCP::buildPcp($this->_pcpId, $this);
498 }
499 }
500
501 /**
100fef9d 502 * Build the radio/text form elements for the amount field
6a488035 503 *
0b36bfd7 504 * @param CRM_Event_Form_Registration_Register $form
d4dd1e85
TO
505 * Form object.
506 * @param bool $required
507 * True if you want to add formRule.
508 * @param int $discountId
509 * Discount id for the event.
6a488035
TO
510 */
511 static public function buildAmount(&$form, $required = TRUE, $discountId = NULL) {
16d1c8e2 512 // build amount only when needed, skip incase of event full and waitlisting is enabled
513 // and few other conditions check preProcess()
a2a1e950 514 if (property_exists($form, '_noFees') && $form->_noFees) {
16d1c8e2 515 return;
516 }
517
6a488035 518 //if payment done, no need to build the fee block.
7bf9cde2 519 if (!empty($form->_paymentId)) {
b6e641a4 520 //fix to display line item in update mode.
6a488035
TO
521 $form->assign('priceSet', isset($form->_priceSet) ? $form->_priceSet : NULL);
522 return;
523 }
524
525 $feeFields = CRM_Utils_Array::value('fee', $form->_values);
526
527 if (is_array($feeFields)) {
528 $form->_feeBlock = &$form->_values['fee'];
529 }
530
531 //check for discount.
532 $discountedFee = CRM_Utils_Array::value('discount', $form->_values);
533 if (is_array($discountedFee) && !empty($discountedFee)) {
534 if (!$discountId) {
535 $form->_discountId = $discountId = CRM_Core_BAO_Discount::findSet($form->_eventId, 'civicrm_event');
536 }
537 if ($discountId) {
538 $form->_feeBlock = &$form->_values['discount'][$discountId];
539 }
540 }
541 if (!is_array($form->_feeBlock)) {
542 $form->_feeBlock = array();
543 }
544
545 //its time to call the hook.
546 CRM_Utils_Hook::buildAmount('event', $form, $form->_feeBlock);
547
548 //reset required if participant is skipped.
549 $button = substr($form->controller->getButtonName(), -4);
550 if ($required && $button == 'skip') {
551 $required = FALSE;
552 }
553
554 $className = CRM_Utils_System::getClassName($form);
555
556 //build the priceset fields.
557 if (isset($form->_priceSetId) && $form->_priceSetId) {
558
559 //format price set fields across option full.
560 self::formatFieldsForOptionFull($form);
561
a7488080 562 if (!empty($form->_priceSet['is_quick_config'])) {
6a488035
TO
563 $form->_quickConfig = $form->_priceSet['is_quick_config'];
564 }
565 $form->add('hidden', 'priceSetId', $form->_priceSetId);
566
c7b3d063 567 // CRM-14492 Admin price fields should show up on event registration if user has 'administer CiviCRM' permissions
ab8a593e 568 $adminFieldVisible = FALSE;
c7b3d063 569 if (CRM_Core_Permission::check('administer CiviCRM')) {
4eeb9a5b 570 $adminFieldVisible = TRUE;
c7b3d063
DG
571 }
572
a13c171d
CR
573 $hideAdminValues = TRUE;
574 if (CRM_Core_Permission::check('edit event participants')) {
575 $hideAdminValues = FALSE;
576 }
577
6a488035 578 foreach ($form->_feeBlock as $field) {
d06f3157 579 // public AND admin visibility fields are included for back-office registration and back-office change selections
6a488035 580 if (CRM_Utils_Array::value('visibility', $field) == 'public' ||
4eeb9a5b 581 (CRM_Utils_Array::value('visibility', $field) == 'admin' && $adminFieldVisible == TRUE) ||
d06f3157
DG
582 $className == 'CRM_Event_Form_Participant' ||
583 $className == 'CRM_Event_Form_ParticipantFeeSelection'
6a488035
TO
584 ) {
585 $fieldId = $field['id'];
586 $elementName = 'price_' . $fieldId;
587
588 $isRequire = CRM_Utils_Array::value('is_required', $field);
589 if ($button == 'skip') {
590 $isRequire = FALSE;
591 }
592
593 //user might modified w/ hook.
594 $options = CRM_Utils_Array::value('options', $field);
a13c171d
CR
595 $formClasses = array('CRM_Event_Form_Participant', 'CRM_Event_Form_ParticipantFeeSelection');
596
6a488035
TO
597 if (!is_array($options)) {
598 continue;
599 }
a13c171d 600 elseif ($hideAdminValues && !in_array($className, $formClasses)) {
ad2785a2
CR
601 $publicVisibilityID = CRM_Price_BAO_PriceField::getVisibilityOptionID('public');
602 $adminVisibilityID = CRM_Price_BAO_PriceField::getVisibilityOptionID('admin');
603
a13c171d 604 foreach ($options as $key => $currentOption) {
ad2785a2
CR
605 $optionVisibility = CRM_Utils_Array::value('visibility_id', $currentOption, $publicVisibilityID);
606 if ($optionVisibility == $adminVisibilityID) {
a13c171d
CR
607 unset($options[$key]);
608 }
609 }
610 }
6a488035
TO
611
612 $optionFullIds = CRM_Utils_Array::value('option_full_ids', $field, array());
613
614 //soft suppress required rule when option is full.
615 if (!empty($optionFullIds) && (count($options) == count($optionFullIds))) {
616 $isRequire = FALSE;
617 }
1019b2fe
SL
618 if (!empty($options)) {
619 //build the element.
620 CRM_Price_BAO_PriceField::addQuickFormElement($form,
621 $elementName,
622 $fieldId,
623 FALSE,
624 $isRequire,
625 NULL,
626 $options,
627 $optionFullIds
628 );
629 }
6a488035
TO
630 }
631 }
632 $form->assign('priceSet', $form->_priceSet);
633 }
634 else {
635 $eventFeeBlockValues = array();
636 foreach ($form->_feeBlock as $fee) {
637 if (is_array($fee)) {
638
639 //CRM-7632, CRM-6201
640 $totalAmountJs = NULL;
641 if ($className == 'CRM_Event_Form_Participant') {
642 $totalAmountJs = array('onClick' => "fillTotalAmount(" . $fee['value'] . ")");
643 }
644
645 $eventFeeBlockValues['amount_id_' . $fee['amount_id']] = $fee['value'];
646 $elements[] = &$form->createElement('radio', NULL, '',
647 CRM_Utils_Money::format($fee['value']) . ' ' .
648 $fee['label'],
649 $fee['amount_id'],
650 $totalAmountJs
651 );
652 }
653 }
654 $form->assign('eventFeeBlockValues', json_encode($eventFeeBlockValues));
655
656 $form->_defaults['amount'] = CRM_Utils_Array::value('default_fee_id', $form->_values['event']);
657 $element = &$form->addGroup($elements, 'amount', ts('Event Fee(s)'), '<br />');
658 if (isset($form->_online) && $form->_online) {
659 $element->freeze();
660 }
661 if ($required) {
662 $form->addRule('amount', ts('Fee Level is a required field.'), 'required');
663 }
664 }
665 }
666
0cf587a7 667 /**
0b36bfd7 668 * @param CRM_Event_Form_Registration $form
0cf587a7 669 */
6a488035
TO
670 public static function formatFieldsForOptionFull(&$form) {
671 $priceSet = $form->get('priceSet');
672 $priceSetId = $form->get('priceSetId');
e9bb507e 673 $defaultPricefieldIds = array();
674 if (!empty($form->_values['line_items'])) {
675 foreach ($form->_values['line_items'] as $lineItem) {
676 $defaultPricefieldIds[] = $lineItem['price_field_value_id'];
677 }
678 }
6a488035
TO
679 if (!$priceSetId ||
680 !is_array($priceSet) ||
353ffa53
TO
681 empty($priceSet) || empty($priceSet['optionsMaxValueTotal'])
682 ) {
6a488035
TO
683 return;
684 }
685
686 $skipParticipants = $formattedPriceSetDefaults = array();
e03317f1 687 if (!empty($form->_allowConfirmation) && (isset($form->_pId) || isset($form->_additionalParticipantId))) {
6a488035
TO
688 $participantId = isset($form->_pId) ? $form->_pId : $form->_additionalParticipantId;
689 $pricesetDefaults = CRM_Event_Form_EventFees::setDefaultPriceSet($participantId,
690 $form->_eventId
691 );
692 // modify options full to respect the selected fields
693 // options on confirmation.
217d80ab 694 $formattedPriceSetDefaults = self::formatPriceSetParams($form, $pricesetDefaults);
6a488035
TO
695
696 // to skip current registered participants fields option count on confirmation.
697 $skipParticipants[] = $form->_participantId;
698 if (!empty($form->_additionalParticipantIds)) {
699 $skipParticipants = array_merge($skipParticipants, $form->_additionalParticipantIds);
700 }
701 }
702
703 $className = CRM_Utils_System::getClassName($form);
704
705 //get the current price event price set options count.
706 $currentOptionsCount = self::getPriceSetOptionCount($form);
707 $recordedOptionsCount = CRM_Event_BAO_Participant::priceSetOptionsCount($form->_eventId, $skipParticipants);
e9bb507e 708 $optionFullTotalAmount = 0;
0dc0b759 709 $currentParticipantNo = (int) substr($form->_name, 12);
6a488035
TO
710 foreach ($form->_feeBlock as & $field) {
711 $optionFullIds = array();
712 $fieldId = $field['id'];
713 if (!is_array($field['options'])) {
714 continue;
715 }
716 foreach ($field['options'] as & $option) {
353ffa53
TO
717 $optId = $option['id'];
718 $count = CRM_Utils_Array::value('count', $option, 0);
719 $maxValue = CRM_Utils_Array::value('max_value', $option, 0);
720 $dbTotalCount = CRM_Utils_Array::value($optId, $recordedOptionsCount, 0);
6a488035
TO
721 $currentTotalCount = CRM_Utils_Array::value($optId, $currentOptionsCount, 0);
722
79b152ac 723 $totalCount = $currentTotalCount + $dbTotalCount;
6a488035
TO
724 $isFull = FALSE;
725 if ($maxValue &&
0dc0b759 726 (($totalCount >= $maxValue) &&
727 (empty($form->_lineItem[$currentParticipantNo][$optId]['price_field_id']) || $dbTotalCount >= $maxValue))
6a488035
TO
728 ) {
729 $isFull = TRUE;
730 $optionFullIds[$optId] = $optId;
e9bb507e 731 if ($field['html_type'] != 'Select') {
732 if (in_array($optId, $defaultPricefieldIds)) {
733 $optionFullTotalAmount += CRM_Utils_Array::value('amount', $option);
734 }
735 }
736 else {
737 if (!empty($defaultPricefieldIds) && in_array($optId, $defaultPricefieldIds)) {
738 unset($optionFullIds[$optId]);
739 }
740 }
6a488035 741 }
6a488035
TO
742 //here option is not full,
743 //but we don't want to allow participant to increase
744 //seats at the time of re-walking registration.
745 if ($count &&
8dfe9fe3 746 !empty($form->_allowConfirmation) &&
6a488035
TO
747 !empty($formattedPriceSetDefaults)
748 ) {
217d80ab 749 if (empty($formattedPriceSetDefaults["price_{$field}"]) || empty($formattedPriceSetDefaults["price_{$fieldId}"][$optId])) {
6a488035
TO
750 $optionFullIds[$optId] = $optId;
751 $isFull = TRUE;
752 }
753 }
754 $option['is_full'] = $isFull;
755 $option['db_total_count'] = $dbTotalCount;
756 $option['total_option_count'] = $dbTotalCount + $currentTotalCount;
757 }
758
759 //ignore option full for offline registration.
760 if ($className == 'CRM_Event_Form_Participant') {
761 $optionFullIds = array();
762 }
763
764 //finally get option ids in.
765 $field['option_full_ids'] = $optionFullIds;
766 }
e9bb507e 767 $form->assign('optionFullTotalAmount', $optionFullTotalAmount);
6a488035
TO
768 }
769
770 /**
66f9e52b 771 * Global form rule.
6a488035 772 *
d4dd1e85
TO
773 * @param array $fields
774 * The input form values.
775 * @param array $files
776 * The uploaded files if any.
0b36bfd7 777 * @param CRM_Event_Form_Registration $form
2a6da8d7 778 *
6a488035 779 *
72b3a70c
CW
780 * @return bool|array
781 * true if no errors, else array of errors
6a488035 782 */
0b36bfd7 783 public static function formRule($fields, $files, $form) {
6a488035
TO
784 $errors = array();
785 //check that either an email or firstname+lastname is included in the form(CRM-9587)
0b36bfd7 786 self::checkProfileComplete($fields, $errors, $form->_eventId);
6a488035 787 //To check if the user is already registered for the event(CRM-2426)
0b36bfd7
MWMC
788 if (!$form->_skipDupeRegistrationCheck) {
789 self::checkRegistration($fields, $form);
6a488035
TO
790 }
791 //check for availability of registrations.
0b36bfd7
MWMC
792 if (!$form->_allowConfirmation && empty($fields['bypass_payment']) &&
793 is_numeric($form->_availableRegistrations) &&
794 CRM_Utils_Array::value('additional_participants', $fields) >= $form->_availableRegistrations
6a488035 795 ) {
0b36bfd7 796 $errors['additional_participants'] = ts("There is only enough space left on this event for %1 participant(s).", array(1 => $form->_availableRegistrations));
6a488035
TO
797 }
798
799 // during confirmation don't allow to increase additional participants, CRM-4320
0b36bfd7
MWMC
800 if ($form->_allowConfirmation && !empty($fields['additional_participants']) &&
801 is_array($form->_additionalParticipantIds) &&
802 $fields['additional_participants'] > count($form->_additionalParticipantIds)
6a488035 803 ) {
0b36bfd7 804 $errors['additional_participants'] = ts("Oops. It looks like you are trying to increase the number of additional people you are registering for. You can confirm registration for a maximum of %1 additional people.", array(1 => count($form->_additionalParticipantIds)));
6a488035
TO
805 }
806
807 //don't allow to register w/ waiting if enough spaces available.
0b36bfd7
MWMC
808 if (!empty($fields['bypass_payment']) && $form->_allowConfirmation) {
809 if (!is_numeric($form->_availableRegistrations) ||
810 (empty($fields['priceSetId']) && CRM_Utils_Array::value('additional_participants', $fields) < $form->_availableRegistrations)
6a488035
TO
811 ) {
812 $errors['bypass_payment'] = ts("Oops. There are enough available spaces in this event. You can not add yourself to the waiting list.");
813 }
814 }
815
a7488080 816 if (!empty($fields['additional_participants']) &&
6a488035
TO
817 !CRM_Utils_Rule::positiveInteger($fields['additional_participants'])
818 ) {
819 $errors['additional_participants'] = ts('Please enter a whole number for Number of additional people.');
820 }
821
822 // priceset validations
0dc0b759 823 if (!empty($fields['priceSetId']) &&
0b36bfd7 824 !$form->_requireApproval && !$form->_allowWaitlist
0dc0b759 825 ) {
6a488035 826 //format params.
0b36bfd7 827 $formatted = self::formatPriceSetParams($form, $fields);
6a488035 828 $ppParams = array($formatted);
0b36bfd7
MWMC
829 $priceSetErrors = self::validatePriceSet($form, $ppParams);
830 $primaryParticipantCount = self::getParticipantCount($form, $ppParams);
6a488035
TO
831
832 //get price set fields errors in.
833 $errors = array_merge($errors, CRM_Utils_Array::value(0, $priceSetErrors, array()));
834
835 $totalParticipants = $primaryParticipantCount;
a7488080 836 if (!empty($fields['additional_participants'])) {
6a488035
TO
837 $totalParticipants += $fields['additional_participants'];
838 }
839
a7488080 840 if (empty($fields['bypass_payment']) &&
0b36bfd7
MWMC
841 !$form->_allowConfirmation &&
842 is_numeric($form->_availableRegistrations) &&
843 $form->_availableRegistrations < $totalParticipants
6a488035 844 ) {
0b36bfd7 845 $errors['_qf_default'] = ts("Only %1 Registrations available.", array(1 => $form->_availableRegistrations));
6a488035
TO
846 }
847
848 $lineItem = array();
0b36bfd7 849 CRM_Price_BAO_PriceSet::processAmount($form->_values['fee'], $fields, $lineItem);
601c7a24 850
851 $minAmt = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $fields['priceSetId'], 'min_amount');
6a488035
TO
852 if ($fields['amount'] < 0) {
853 $errors['_qf_default'] = ts('Event Fee(s) can not be less than zero. Please select the options accordingly');
854 }
601c7a24 855 elseif (!empty($minAmt) && $fields['amount'] < $minAmt) {
856 $errors['_qf_default'] = ts('A minimum amount of %1 should be selected from Event Fee(s).', array(
857 1 => CRM_Utils_Money::format($minAmt),
858 ));
859 }
6a488035
TO
860 }
861
f48e6cf7 862 // @todo - can we remove the 'is_monetary' concept?
0b36bfd7
MWMC
863 if ($form->_values['event']['is_monetary']) {
864 if (empty($form->_requireApproval) && !empty($fields['amount']) && $fields['amount'] > 0 &&
1019b2fe 865 !isset($fields['payment_processor_id'])) {
e02d7e96 866 $errors['payment_processor_id'] = ts('Please select a Payment Method');
0d588131 867 }
6a488035 868
0d588131 869 $isZeroAmount = $skipPaymentValidation = FALSE;
a7488080 870 if (!empty($fields['priceSetId'])) {
6a488035
TO
871 if (CRM_Utils_Array::value('amount', $fields) == 0) {
872 $isZeroAmount = TRUE;
873 }
874 }
a7488080 875 elseif (!empty($fields['amount']) &&
0b36bfd7
MWMC
876 (isset($form->_values['discount'][$fields['amount']])
877 && CRM_Utils_Array::value('value', $form->_values['discount'][$fields['amount']]) == 0
6a488035
TO
878 )
879 ) {
880 $isZeroAmount = TRUE;
881 }
a7488080 882 elseif (!empty($fields['amount']) &&
0b36bfd7
MWMC
883 (isset($form->_values['fee'][$fields['amount']])
884 && CRM_Utils_Array::value('value', $form->_values['fee'][$fields['amount']]) == 0
6a488035
TO
885 )
886 ) {
887 $isZeroAmount = TRUE;
888 }
889
0b36bfd7 890 if ($isZeroAmount && !($form->_forcePayement && !empty($fields['additional_participants']))) {
0d588131 891 $skipPaymentValidation = TRUE;
6a488035
TO
892 }
893
f48e6cf7 894 // also return if zero fees for valid members
895 if (!empty($fields['bypass_payment']) ||
0d588131 896 $skipPaymentValidation ||
0b36bfd7 897 (!$form->_allowConfirmation && ($form->_requireApproval || $form->_allowWaitlist))
6a488035
TO
898 ) {
899 return empty($errors) ? TRUE : $errors;
900 }
f48e6cf7 901 CRM_Core_Payment_Form::validatePaymentInstrument(
902 $fields['payment_processor_id'],
903 $fields,
904 $errors,
0b36bfd7 905 (!$form->_isBillingAddressRequiredForPayLater ? NULL : 'billing')
f48e6cf7 906 );
6a488035 907 }
6a488035 908
6a488035
TO
909 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
910 if ($greetingType = CRM_Utils_Array::value($greeting, $fields)) {
233319bf 911 $customizedValue = CRM_Core_PseudoConstant::getKey('CRM_Contact_BAO_Contact', $greeting . '_id', 'Customized');
6a488035 912 if ($customizedValue == $greetingType && empty($fields[$greeting . '_custom'])) {
217d80ab 913 $errors[$greeting . '_custom'] = ts('Custom %1 is a required field if %1 is of type Customized.',
6a488035
TO
914 array(1 => ucwords(str_replace('_', ' ', $greeting)))
915 );
916 }
917 }
918 }
919 return empty($errors) ? TRUE : $errors;
920 }
921
922 /**
ec022878 923 * Check if profiles are complete when event registration occurs(CRM-9587).
924 *
925 * @param array $fields
926 * @param array $errors
927 * @param int $eventId
6a488035 928 */
00be9182 929 public static function checkProfileComplete($fields, &$errors, $eventId) {
6a488035
TO
930 $email = '';
931 foreach ($fields as $fieldname => $fieldvalue) {
932 if (substr($fieldname, 0, 6) == 'email-' && $fieldvalue) {
933 $email = $fieldvalue;
934 }
935 }
936
8cc574cf 937 if (!$email && !(!empty($fields['first_name']) && !empty($fields['last_name']))) {
6a488035
TO
938 $defaults = $params = array('id' => $eventId);
939 CRM_Event_BAO_Event::retrieve($params, $defaults);
940 $message = ts("Mandatory fields (first name and last name, OR email address) are missing from this form.");
941 $errors['_qf_default'] = $message;
942 }
943 }
944
945 /**
66f9e52b 946 * Process the form submission.
6a488035
TO
947 */
948 public function postProcess() {
949 // get the submitted form values.
950 $params = $this->controller->exportValues($this->_name);
951
952 //set as Primary participant
953 $params['is_primary'] = 1;
954
8ae4d0d3 955 if ($this->_values['event']['is_pay_later']
e02d7e96 956 && (!array_key_exists('hidden_processor', $params) || $params['payment_processor_id'] == 0)
353ffa53 957 ) {
6a488035
TO
958 $params['is_pay_later'] = 1;
959 }
960 else {
961 $params['is_pay_later'] = 0;
962 }
963
964 $this->set('is_pay_later', $params['is_pay_later']);
965
966 // assign pay later stuff
967 $this->_params['is_pay_later'] = CRM_Utils_Array::value('is_pay_later', $params, FALSE);
968 $this->assign('is_pay_later', $params['is_pay_later']);
969 if ($params['is_pay_later']) {
970 $this->assign('pay_later_text', $this->_values['event']['pay_later_text']);
971 $this->assign('pay_later_receipt', $this->_values['event']['pay_later_receipt']);
972 }
6a488035 973
168e792f
DL
974 if (!$this->_allowConfirmation) {
975 // check if the participant is already registered
976 if (!$this->_skipDupeRegistrationCheck) {
7dfe13ab 977 $params['contact_id'] = self::getRegistrationContactID($params, $this, FALSE);
168e792f
DL
978 }
979 }
980
a7488080 981 if (!empty($params['image_URL'])) {
6a488035
TO
982 CRM_Contact_BAO_Contact::processImageParams($params);
983 }
984
985 //carry campaign to partcipants.
986 if (array_key_exists('participant_campaign_id', $params)) {
987 $params['campaign_id'] = $params['participant_campaign_id'];
988 }
989 else {
990 $params['campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values['event']);
991 }
992
993 //hack to allow group to register w/ waiting
994 $primaryParticipantCount = self::getParticipantCount($this, $params);
995
996 $totalParticipants = $primaryParticipantCount;
a7488080 997 if (!empty($params['additional_participants'])) {
6a488035
TO
998 $totalParticipants += $params['additional_participants'];
999 }
8cc574cf 1000 if (!$this->_allowConfirmation && !empty($params['bypass_payment']) &&
6a488035
TO
1001 is_numeric($this->_availableRegistrations) &&
1002 $totalParticipants > $this->_availableRegistrations
1003 ) {
1004 $this->_allowWaitlist = TRUE;
1005 $this->set('allowWaitlist', TRUE);
1006 }
1007
1008 //carry participant id if pre-registered.
1009 if ($this->_allowConfirmation && $this->_participantId) {
1010 $params['participant_id'] = $this->_participantId;
1011 }
1012
1013 $params['defaultRole'] = 1;
1014 if (array_key_exists('participant_role', $params)) {
1015 $params['participant_role_id'] = $params['participant_role'];
1016 }
1017
1018 if (array_key_exists('participant_role_id', $params)) {
1019 $params['defaultRole'] = 0;
1020 }
a7488080 1021 if (empty($params['participant_role_id']) &&
6a488035
TO
1022 $this->_values['event']['default_role_id']
1023 ) {
1024 $params['participant_role_id'] = $this->_values['event']['default_role_id'];
1025 }
1026
1027 $config = CRM_Core_Config::singleton();
1028 $params['currencyID'] = $config->defaultCurrency;
1029
1030 if ($this->_values['event']['is_monetary']) {
1031 // we first reset the confirm page so it accepts new values
1032 $this->controller->resetPage('Confirm');
1033
1034 //added for discount
1035 $discountId = CRM_Core_BAO_Discount::findSet($this->_eventId, 'civicrm_event');
c039f658 1036 $params['amount_level'] = $this->getAmountLevel($params, $discountId);
6a488035
TO
1037 if (!empty($this->_values['discount'][$discountId])) {
1038 $params['discount_id'] = $discountId;
6a488035
TO
1039 $params['amount'] = $this->_values['discount'][$discountId][$params['amount']]['value'];
1040 }
1041 elseif (empty($params['priceSetId'])) {
16d1c8e2 1042 if (!empty($params['amount'])) {
16d1c8e2 1043 $params['amount'] = $this->_values['fee'][$params['amount']]['value'];
1044 }
1045 else {
c039f658 1046 $params['amount'] = '';
16d1c8e2 1047 }
6a488035
TO
1048 }
1049 else {
1050 $lineItem = array();
9da8dc8c 1051 CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'], $params, $lineItem);
d91b8b33 1052 if ($params['tax_amount']) {
1053 $this->set('tax_amount', $params['tax_amount']);
1054 }
9d8d8fd0 1055 $submittedLineItems = $this->get('lineItem');
1056 if (!empty($submittedLineItems) && is_array($submittedLineItems)) {
0dc0b759 1057 $submittedLineItems[0] = $lineItem;
1058 }
1059 else {
1060 $submittedLineItems = array($lineItem);
1061 }
dba6436f 1062 $submittedLineItems = array_filter($submittedLineItems);
0dc0b759 1063 $this->set('lineItem', $submittedLineItems);
6a488035
TO
1064 $this->set('lineItemParticipantsCount', array($primaryParticipantCount));
1065 }
1066
1067 $this->set('amount', $params['amount']);
1068 $this->set('amount_level', $params['amount_level']);
1069
1070 // generate and set an invoiceID for this transaction
1071 $invoiceID = md5(uniqid(rand(), TRUE));
1072 $this->set('invoiceID', $invoiceID);
1073
b0c462ac 1074 if ($this->_paymentProcessor) {
077017db 1075 $payment = $this->_paymentProcessor['object'];
ec022878 1076 $payment->setBaseReturnUrl('civicrm/event/register');
6a488035 1077 }
0eb1f7ff 1078
1079 // ContributeMode is a deprecated concept. It is short-hand for a bunch of
1080 // assumptions we are working to remove.
6a488035
TO
1081 $this->set('contributeMode', 'direct');
1082
0eb1f7ff 1083 // This code is duplicated multiple places and should be consolidated.
6a488035
TO
1084 if (isset($params["state_province_id-{$this->_bltID}"]) &&
1085 $params["state_province_id-{$this->_bltID}"]
1086 ) {
1087 $params["state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($params["state_province_id-{$this->_bltID}"]);
1088 }
1089
1090 if (isset($params["country_id-{$this->_bltID}"]) &&
1091 $params["country_id-{$this->_bltID}"]
1092 ) {
1093 $params["country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($params["country_id-{$this->_bltID}"]);
1094 }
1095 if (isset($params['credit_card_exp_date'])) {
1096 $params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($params);
1097 $params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($params);
1098 }
1099 if ($this->_values['event']['is_monetary']) {
1100 $params['ip_address'] = CRM_Utils_System::ipAddress();
1101 $params['currencyID'] = $config->defaultCurrency;
6a488035
TO
1102 $params['invoiceID'] = $invoiceID;
1103 }
d0ebccea 1104 $this->_params = $this->get('params');
ec022878 1105 // Set the button so we know what
1106 $params['button'] = $this->controller->getButtonName();
d0ebccea 1107 if (!empty($this->_params) && is_array($this->_params)) {
0dc0b759 1108 $this->_params[0] = $params;
1109 }
1110 else {
1111 $this->_params = array();
1112 $this->_params[] = $params;
1113 }
6a488035 1114 $this->set('params', $this->_params);
f92fc7eb 1115 if ($this->_paymentProcessor &&
223190c8 1116 // Actually we don't really need to check if it supports pre-approval - we could just call
1117 // it regardless as the function we call re-acts tot the rests of the preApproval call.
ec022878 1118 $this->_paymentProcessor['object']->supports('preApproval')
1119 && !$this->_allowWaitlist &&
1120 !$this->_requireApproval
f92fc7eb 1121 ) {
6a488035 1122
0f2b049e 1123 // The concept of contributeMode is deprecated - but still needs removal from the message templates.
ec022878 1124 $this->set('contributeMode', 'express');
6a488035 1125
ec022878 1126 // Send Event Name & Id in Params
1127 $params['eventName'] = $this->_values['event']['title'];
1128 $params['eventId'] = $this->_values['event']['id'];
6a488035 1129
ec022878 1130 $params['cancelURL'] = CRM_Utils_System::url('civicrm/event/register',
1131 "_qf_Register_display=1&qfKey={$this->controller->_key}",
1132 TRUE, NULL, FALSE
1133 );
1134 if (CRM_Utils_Array::value('additional_participants', $params, FALSE)) {
1135 $urlArgs = "_qf_Participant_1_display=1&rfp=1&qfKey={$this->controller->_key}";
1136 }
1137 else {
1138 $urlArgs = "_qf_Confirm_display=1&rfp=1&qfKey={$this->controller->_key}";
1139 }
1140 $params['returnURL'] = CRM_Utils_System::url('civicrm/event/register',
1141 $urlArgs,
1142 TRUE, NULL, FALSE
1143 );
1144 $params['invoiceID'] = $invoiceID;
6a488035 1145
ec022878 1146 $params['component'] = 'event';
223190c8 1147 $this->handlePreApproval($params);
6a488035 1148 }
f92fc7eb 1149 elseif ($this->_paymentProcessor &&
5e3148f4 1150 (int) $this->_paymentProcessor['billing_mode'] & CRM_Core_Payment::BILLING_MODE_NOTIFY
f92fc7eb 1151 ) {
0f2b049e 1152 // The concept of contributeMode is deprecated - but still needs removal from the message templates.
6a488035
TO
1153 $this->set('contributeMode', 'notify');
1154 }
13f230bc 1155 }
1156 else {
1157 $params['description'] = ts('Online Event Registration') . ' ' . $this->_values['event']['title'];
6a488035 1158
13f230bc 1159 $this->_params = array();
1160 $this->_params[] = $params;
1161 $this->set('params', $this->_params);
6a488035 1162
13f230bc 1163 if (
1164 empty($params['additional_participants'])
1165 && !$this->_values['event']['is_confirm_enabled'] // CRM-11182 - Optional confirmation screen
1166 ) {
3033e657 1167 $this->processRegistration($this->_params);
6a488035
TO
1168 }
1169 }
1170
1171 // If registering > 1 participant, give status message
1172 if (CRM_Utils_Array::value('additional_participants', $params, FALSE)) {
1173 $statusMsg = ts('Registration information for participant 1 has been saved.');
1174 CRM_Core_Session::setStatus($statusMsg, ts('Saved'), 'success');
1175 }
1176 }
6a488035 1177
6a488035 1178 /**
66f9e52b 1179 * Method to check if the user is already registered for the event.
6a488035
TO
1180 * and if result found redirect to the event info page
1181 *
d4dd1e85
TO
1182 * @param array $fields
1183 * The input form values(anonymous user).
0b36bfd7 1184 * @param CRM_Event_Form_Registration_Register $form
d4dd1e85
TO
1185 * Event data.
1186 * @param bool $isAdditional
1187 * Treat isAdditional participants a bit differently.
6a488035 1188 *
54957108 1189 * @return int
6a488035 1190 */
0b36bfd7 1191 public static function checkRegistration($fields, $form, $isAdditional = FALSE) {
6a488035
TO
1192 // CRM-3907, skip check for preview registrations
1193 // CRM-4320 participant need to walk wizard
7dfe13ab 1194 if (
0b36bfd7 1195 ($form->_mode == 'test' || $form->_allowConfirmation)
6a488035
TO
1196 ) {
1197 return FALSE;
1198 }
1199
0b36bfd7 1200 $contactID = self::getRegistrationContactID($fields, $form, $isAdditional);
6a488035 1201
6a488035
TO
1202 if ($contactID) {
1203 $participant = new CRM_Event_BAO_Participant();
1204 $participant->contact_id = $contactID;
0b36bfd7 1205 $participant->event_id = $form->_values['event']['id'];
6a488035
TO
1206 if (!empty($fields['participant_role']) && is_numeric($fields['participant_role'])) {
1207 $participant->role_id = $fields['participant_role'];
1208 }
1209 else {
0b36bfd7 1210 $participant->role_id = $form->_values['event']['default_role_id'];
6a488035
TO
1211 }
1212 $participant->is_test = 0;
1213 $participant->find();
1214 $statusTypes = CRM_Event_PseudoConstant::participantStatus(NULL, 'is_counted = 1');
1215 while ($participant->fetch()) {
1216 if (array_key_exists($participant->status_id, $statusTypes)) {
0b36bfd7 1217 if (!$isAdditional && !$form->_values['event']['allow_same_participant_emails']) {
6a488035 1218 $registerUrl = CRM_Utils_System::url('civicrm/event/register',
0b36bfd7 1219 "reset=1&id={$form->_values['event']['id']}&cid=0"
6a488035 1220 );
0b36bfd7
MWMC
1221 if ($form->_pcpId) {
1222 $registerUrl .= '&pcpId=' . $form->_pcpId;
6a488035
TO
1223 }
1224
06141953 1225 $status = ts("It looks like you are already registered for this event. If you want to change your registration, or you feel that you've received this message in error, please contact the site administrator.") . ' ' . ts('You can also <a href="%1">register another participant</a>.', array(1 => $registerUrl));
7dfe13ab 1226 CRM_Core_Session::singleton()->setStatus($status, ts('Oops.'), 'alert');
6a488035 1227 $url = CRM_Utils_System::url('civicrm/event/info',
0b36bfd7 1228 "reset=1&id={$form->_values['event']['id']}&noFullMsg=true"
6a488035 1229 );
0b36bfd7 1230 if ($form->_action & CRM_Core_Action::PREVIEW) {
6a488035
TO
1231 $url .= '&action=preview';
1232 }
1233
0b36bfd7
MWMC
1234 if ($form->_pcpId) {
1235 $url .= '&pcpId=' . $form->_pcpId;
6a488035
TO
1236 }
1237
1238 CRM_Utils_System::redirect($url);
1239 }
1240
1241 if ($isAdditional) {
06141953 1242 $status = ts("It looks like this participant is already registered for this event. If you want to change your registration, or you feel that you've received this message in error, please contact the site administrator.");
7dfe13ab 1243 CRM_Core_Session::singleton()->setStatus($status, ts('Oops.'), 'alert');
6a488035
TO
1244 return $participant->id;
1245 }
1246 }
1247 }
1248 }
1249 }
96025800 1250
6a488035 1251}