Merge remote-tracking branch 'upstream/4.5' into 4.5-master-2015-02-09-11-44-07
[civicrm-core.git] / CRM / Event / Form / Registration / AdditionalParticipant.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 *
31 * @package CRM
32 * @copyright CiviCRM LLC (c) 2004-2014
33 * $Id$
34 *
35 */
36
37 /**
38 * This class generates form components for processing Event
39 *
40 */
41 class CRM_Event_Form_Registration_AdditionalParticipant extends CRM_Event_Form_Registration {
42
43 /**
44 * The defaults involved in this page.
45 */
46 public $_defaults = array();
47
48 /**
49 * Pre-registered additional participant id.
50 */
51 public $additionalParticipantId = NULL;
52
53 /**
54 * Set variables up before form is built.
55 *
56 * @return void
57 */
58 public function preProcess() {
59 parent::preProcess();
60
61 $participantNo = substr($this->_name, 12);
62
63 //lets process in-queue participants.
64 if ($this->_participantId && $this->_additionalParticipantIds) {
65 $this->_additionalParticipantId = CRM_Utils_Array::value($participantNo, $this->_additionalParticipantIds);
66 }
67
68 $participantCnt = $participantNo + 1;
69 $this->assign('formId', $participantNo);
70 $this->_params = array();
71 $this->_params = $this->get('params');
72
73 $participantTot = $this->_params[0]['additional_participants'] + 1;
74 $skipCount = count(array_keys($this->_params, "skip"));
75 if ($skipCount) {
76 $this->assign('skipCount', $skipCount);
77 }
78 CRM_Utils_System::setTitle(ts('Register Participant %1 of %2', array(1 => $participantCnt, 2 => $participantTot)));
79
80 //CRM-4320, hack to check last participant.
81 $this->_lastParticipant = FALSE;
82 if ($participantTot == $participantCnt) {
83 $this->_lastParticipant = TRUE;
84 }
85 $this->assign('lastParticipant', $this->_lastParticipant);
86 }
87
88 /**
89 * Set default values for the form. For edit/view mode
90 * the default values are retrieved from the database
91 *
92 *
93 * @return void
94 */
95 public function setDefaultValues() {
96 $defaults = $unsetSubmittedOptions = array();
97 $discountId = NULL;
98 //fix for CRM-3088, default value for discount set.
99 if (!empty($this->_values['discount'])) {
100 $discountId = CRM_Core_BAO_Discount::findSet($this->_eventId, 'civicrm_event');
101 if ($discountId && !empty($this->_values['event']['default_discount_fee_id'])) {
102 $discountKey = CRM_Core_DAO::getFieldValue("CRM_Core_DAO_OptionValue", $this->_values['event']['default_discount_fee_id'], 'weight', 'id'
103 );
104 $defaults['amount'] = key(array_slice($this->_values['discount'][$discountId], $discountKey - 1, $discountKey, TRUE));
105 }
106 }
107 if ($this->_priceSetId) {
108 foreach ($this->_feeBlock as $key => $val) {
109 if (empty($val['options'])) {
110 continue;
111 }
112
113 $optionsFull = CRM_Utils_Array::value('option_full_ids', $val, array());
114 foreach ($val['options'] as $keys => $values) {
115 if ($values['is_default'] && !in_array($keys, $optionsFull)) {
116 if ($val['html_type'] == 'CheckBox') {
117 $defaults["price_{$key}"][$keys] = 1;
118 }
119 else {
120 $defaults["price_{$key}"] = $keys;
121 }
122 }
123 }
124 if (!empty($optionsFull)) {
125 $unsetSubmittedOptions[$val['id']] = $optionsFull;
126 }
127 }
128 }
129
130 //CRM-4320, setdefault additional participant values.
131 if ($this->_allowConfirmation && $this->_additionalParticipantId) {
132 //hack to get set default from eventFees.php
133 $this->_discountId = $discountId;
134 $this->_pId = $this->_additionalParticipantId;
135 $this->_contactId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_additionalParticipantId, 'contact_id');
136 $participantDefaults = CRM_Event_Form_EventFees::setDefaultValues($this);
137 $participantDefaults = array_merge($this->_defaults, $participantDefaults);
138 // use primary email address if billing email address is empty
139 if (empty($this->_defaults["email-{$this->_bltID}"]) &&
140 !empty($this->_defaults["email-Primary"])
141 ) {
142 $participantDefaults["email-{$this->_bltID}"] = $this->_defaults["email-Primary"];
143 }
144 $defaults = array_merge($defaults, $participantDefaults);
145 }
146
147 $defaults = array_merge($this->_defaults, $defaults);
148
149 //reset values for all options those are full.
150 if (!empty($unsetSubmittedOptions) && empty($_POST)) {
151 $this->resetElementValue($unsetSubmittedOptions);
152 }
153
154 //load default campaign from page.
155 if (array_key_exists('participant_campaign_id', $this->_fields)) {
156 $defaults['participant_campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values['event']);
157 }
158
159 return $defaults;
160 }
161
162 /**
163 * Build the form object.
164 *
165 * @return void
166 */
167 public function buildQuickForm() {
168 $config = CRM_Core_Config::singleton();
169 $button = substr($this->controller->getButtonName(), -4);
170
171 $this->add('hidden', 'scriptFee', NULL);
172 $this->add('hidden', 'scriptArray', NULL);
173
174 if ($this->_values['event']['is_monetary']) {
175 CRM_Event_Form_Registration_Register::buildAmount($this);
176 }
177 $first_name = $last_name = NULL;
178 $pre = $post = array();
179 foreach (array(
180 'pre',
181 'post',
182 ) as $keys) {
183 if (isset($this->_values['additional_custom_' . $keys . '_id'])) {
184 $this->buildCustom($this->_values['additional_custom_' . $keys . '_id'], 'additionalCustom' . ucfirst($keys), TRUE);
185 $$keys = CRM_Core_BAO_UFGroup::getFields($this->_values['additional_custom_' . $keys . '_id']);
186 }
187 foreach (array(
188 'first_name',
189 'last_name',
190 ) as $name) {
191 if (array_key_exists($name, $$keys) &&
192 CRM_Utils_Array::value('is_required', CRM_Utils_Array::value($name, $$keys))
193 ) {
194 $$name = 1;
195 }
196 }
197 }
198
199 $required = ($button == 'skip' ||
200 $this->_values['event']['allow_same_participant_emails'] == 1 &&
201 ($first_name && $last_name)
202 ) ? FALSE : TRUE;
203
204 //add buttons
205 $js = NULL;
206 if ($this->isLastParticipant(TRUE) && empty($this->_values['event']['is_monetary'])) {
207 $js = array('onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');");
208 }
209
210 //handle case where user might sart with waiting by group
211 //registration and skip some people and now group fit to
212 //become registered so need to take payment from user.
213 //this case only occurs at dynamic waiting status, CRM-4320
214 $statusMessage = NULL;
215 $allowToProceed = TRUE;
216 $includeSkipButton = TRUE;
217 $this->_resetAllowWaitlist = FALSE;
218
219 $pricesetFieldsCount = CRM_Price_BAO_PriceSet::getPricesetCount($this->_priceSetId);
220
221 if ($this->_lastParticipant || $pricesetFieldsCount) {
222 //get the participant total.
223 $processedCnt = self::getParticipantCount($this, $this->_params, TRUE);
224 }
225
226 if (!$this->_allowConfirmation && !empty($this->_params[0]['bypass_payment']) &&
227 $this->_lastParticipant
228 ) {
229
230 //get the event spaces.
231 $spaces = $this->_availableRegistrations;
232
233 $currentPageMaxCount = 1;
234 if ($pricesetFieldsCount) {
235 $currentPageMaxCount = $pricesetFieldsCount;
236 }
237
238 //we might did reset allow waiting in case of dynamic calculation
239 if (!empty($this->_params[0]['bypass_payment']) &&
240 is_numeric($spaces) &&
241 $processedCnt > $spaces
242 ) {
243 $this->_allowWaitlist = TRUE;
244 $this->set('allowWaitlist', TRUE);
245 }
246
247 //lets allow to become a part of runtime waiting list, if primary selected pay later.
248 $realPayLater = FALSE;
249 if (!empty($this->_values['event']['is_monetary']) && !empty($this->_values['event']['is_pay_later'])) {
250 $realPayLater = CRM_Utils_Array::value('is_pay_later', $this->_params[0]);
251 }
252
253 //truly spaces are greater than required.
254 if (is_numeric($spaces) && $spaces >= ($processedCnt + $currentPageMaxCount)) {
255 if (CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0 || $this->_requireApproval) {
256 $this->_allowWaitlist = FALSE;
257 $this->set('allowWaitlist', $this->_allowWaitlist);
258 if ($this->_requireApproval) {
259 $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.", array(
260 1 => ++$processedCnt,
261 2 => $spaces,
262 ));
263 }
264 else {
265 $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).", array(
266 1 => ++$processedCnt,
267 2 => $spaces,
268 ));
269 }
270 }
271 else {
272 $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.", array(
273 1 => ++$processedCnt,
274 2 => $spaces,
275 ));
276 $allowToProceed = FALSE;
277 }
278 CRM_Core_Session::setStatus($statusMessage, ts('Registration Error'), 'error');
279 }
280 elseif ($processedCnt == $spaces) {
281 if (CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0
282 || $realPayLater || $this->_requireApproval
283 ) {
284 $this->_resetAllowWaitlist = TRUE;
285 if ($this->_requireApproval) {
286 $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.");
287 }
288 else {
289 $statusMessage = ts("If you skip this participant there will be enough spaces in the event for your group (you will not be wait listed).");
290 }
291 }
292 else {
293 //hey there is enough space and we require payment.
294 $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.");
295 $includeSkipButton = FALSE;
296 }
297 }
298 }
299
300 // for priceset with count
301 if ($pricesetFieldsCount && !empty($this->_values['event']['has_waitlist']) &&
302 !$this->_allowConfirmation
303 ) {
304
305 if ($this->_isEventFull) {
306 $statusMessage = ts('This event is currently full. You are registering for the waiting list. You will be notified if spaces become available.');
307 }
308 elseif ($this->_allowWaitlist ||
309 (!$this->_allowWaitlist && ($processedCnt + $pricesetFieldsCount) > $this->_availableRegistrations)
310 ) {
311
312 $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.');
313 $confirmedMsg = ts('It looks like there are enough spaces in this event for your group (you will not be wait listed).');
314 if ($this->_requireApproval) {
315 $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.');
316 $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.');
317 }
318
319 $this->assign('waitingMsg', $waitingMsg);
320 $this->assign('confirmedMsg', $confirmedMsg);
321
322 $this->assign('availableRegistrations', $this->_availableRegistrations);
323 $this->assign('currentParticipantCount', $processedCnt);
324 $this->assign('allowGroupOnWaitlist', TRUE);
325
326 $paymentBypassed = NULL;
327 if (!empty($this->_params[0]['bypass_payment']) &&
328 !$this->_allowWaitlist &&
329 !$realPayLater &&
330 !$this->_requireApproval &&
331 !(CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0)
332 ) {
333 $paymentBypassed = ts('Please go back to the main registration page, to complete payment information.');
334 }
335 $this->assign('paymentBypassed', $paymentBypassed);
336 }
337 }
338
339 $this->assign('statusMessage', $statusMessage);
340
341 $buttons = array(
342 array(
343 'type' => 'back',
344 'name' => ts('Go Back'),
345 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp',
346 ),
347 );
348
349 //CRM-4320
350 if ($allowToProceed) {
351 $buttons = array_merge($buttons, array(
352 array(
353 'type' => 'next',
354 'name' => ts('Continue'),
355 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
356 'isDefault' => TRUE,
357 'js' => $js,
358 ),
359 )
360 );
361 if ($includeSkipButton) {
362 $buttons = array_merge($buttons, array(
363 array(
364 'type' => 'next',
365 'name' => ts('Skip Participant'),
366 'subName' => 'skip',
367 'icon' => 'seek-next',
368 ),
369 )
370 );
371 }
372 }
373 $this->addButtons($buttons);
374 $this->addFormRule(array('CRM_Event_Form_Registration_AdditionalParticipant', 'formRule'), $this);
375 }
376
377 /**
378 * Global form rule.
379 *
380 * @param array $fields
381 * The input form values.
382 * @param array $files
383 * The uploaded files if any.
384 * @param $self
385 *
386 *
387 * @return bool|array
388 * true if no errors, else array of errors
389 */
390 public static function formRule($fields, $files, $self) {
391 $errors = array();
392 //get the button name.
393 $button = substr($self->controller->getButtonName(), -4);
394
395 $realPayLater = FALSE;
396 if (!empty($self->_values['event']['is_monetary']) && !empty($self->_values['event']['is_pay_later'])) {
397 $realPayLater = CRM_Utils_Array::value('is_pay_later', $self->_params[0]);
398 }
399
400 if ($button != 'skip') {
401 //Check that either an email or firstname+lastname is included in the form(CRM-9587)
402 CRM_Event_Form_Registration_Register::checkProfileComplete($fields, $errors, $self->_eventId);
403
404 //Additional Participant can also register for an event only once
405 $isRegistered = CRM_Event_Form_Registration_Register::checkRegistration($fields, $self, TRUE);
406 if ($isRegistered) {
407 if ($self->_values['event']['allow_same_participant_emails']) {
408 $errors['_qf_default'] = ts('A person is already registered for this event.');
409 }
410 else {
411 $errors["email-{$self->_bltID}"] = ts('A person with this email address is already registered for this event.');
412 }
413 }
414
415 //get the complete params.
416 $params = $self->get('params');
417
418 //take the participant instance.
419 $addParticipantNum = substr($self->_name, 12);
420
421 if (is_array($params)) {
422 foreach ($params as $key => $value) {
423 if ($key != $addParticipantNum) {
424 if (!$self->_values['event']['allow_same_participant_emails']) {
425 //collect all email fields
426 $existingEmails = array();
427 $additionalParticipantEmails = array();
428 if (is_array($value)) {
429 foreach ($value as $key => $val) {
430 if (substr($key, 0, 6) == 'email-' && $val) {
431 $existingEmails[] = $val;
432 }
433 }
434 }
435 foreach ($fields as $key => $val) {
436 if (substr($key, 0, 6) == 'email-' && $val) {
437 $additionalParticipantEmails[] = $val;
438 $mailKey = $key;
439 }
440 }
441 //check if any emails are common to both arrays
442 if (count(array_intersect($existingEmails, $additionalParticipantEmails))) {
443 $errors[$mailKey] = ts('The email address must be unique for each participant.');
444 break;
445 }
446 }
447 else {
448 // check with first_name and last_name for additional participants
449 if (!empty($value['first_name']) && ($value['first_name'] == CRM_Utils_Array::value('first_name', $fields)) &&
450 (CRM_Utils_Array::value('last_name', $value) == CRM_Utils_Array::value('last_name', $fields))
451 ) {
452 $errors['first_name'] = ts('The first name and last name must be unique for each participant.');
453 break;
454 }
455 }
456 }
457 }
458 }
459
460 //check for atleast one pricefields should be selected
461 if (!empty($fields['priceSetId'])) {
462 $allParticipantParams = $params;
463
464 //format current participant params.
465 $allParticipantParams[$addParticipantNum] = self::formatPriceSetParams($self, $fields);
466 $totalParticipants = self::getParticipantCount($self, $allParticipantParams);
467
468 //validate price field params.
469 $priceSetErrors = self::validatePriceSet($self, $allParticipantParams);
470 $errors = array_merge($errors, CRM_Utils_Array::value($addParticipantNum, $priceSetErrors, array()));
471
472 if (!$self->_allowConfirmation &&
473 is_numeric($self->_availableRegistrations)
474 ) {
475 if (!empty($self->_params[0]['bypass_payment']) &&
476 !$self->_allowWaitlist &&
477 !$realPayLater &&
478 !$self->_requireApproval &&
479 !(CRM_Utils_Array::value('amount', $self->_params[0], 0) == 0) &&
480 $totalParticipants < $self->_availableRegistrations
481 ) {
482 $errors['_qf_default'] = ts("Your event registration will be confirmed. Please go back to the main registration page, to complete payment information.");
483 }
484 //check for availability of registrations.
485 if (!$self->_allowConfirmation && empty($self->_values['event']['has_waitlist']) &&
486 $totalParticipants > $self->_availableRegistrations
487 ) {
488 $errors['_qf_default'] = ts('It looks like event has only %2 seats available and you are trying to register %1 participants, so could you please select price options accordingly.', array(
489 1 => $totalParticipants,
490 2 => $self->_availableRegistrations,
491 ));
492 }
493 }
494 }
495 }
496
497 if ($button == 'skip' && $self->_lastParticipant && !empty($fields['priceSetId'])) {
498 $pricesetFieldsCount = CRM_Price_BAO_PriceSet::getPricesetCount($fields['priceSetId']);
499 if (($pricesetFieldsCount < 1) || $self->_allowConfirmation) {
500 return $errors;
501 }
502
503 if (!empty($self->_values['event']['has_waitlist']) && !empty($self->_params[0]['bypass_payment']) &&
504 !$self->_allowWaitlist &&
505 !$realPayLater &&
506 !$self->_requireApproval &&
507 !(CRM_Utils_Array::value('amount', $self->_params[0], 0) == 0)
508 ) {
509 $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.");
510 }
511 }
512
513 if ($button != 'skip' &&
514 $self->_values['event']['is_monetary'] &&
515 !isset($errors['_qf_default']) &&
516 !$self->validatePaymentValues($self, $fields)
517 ) {
518 $errors['_qf_default'] = ts("Your payment information looks incomplete. Please go back to the main registration page, to complete payment information.");
519 $self->set('forcePayement', TRUE);
520 }
521 elseif ($button == 'skip') {
522 $self->set('forcePayement', TRUE);
523 }
524
525 return $errors;
526 }
527
528 /**
529 * @param $self
530 * @param $fields
531 *
532 * @return bool
533 */
534 public function validatePaymentValues($self, $fields) {
535
536 if (!empty($self->_params[0]['bypass_payment']) ||
537 $self->_allowWaitlist ||
538 empty($self->_fields) ||
539 CRM_Utils_Array::value('amount', $self->_params[0]) > 0
540 ) {
541 return TRUE;
542 }
543
544 $validatePayement = FALSE;
545 if (!empty($fields['priceSetId'])) {
546 $lineItem = array();
547 CRM_Price_BAO_PriceSet::processAmount($self->_values['fee'], $fields, $lineItem);
548 if ($fields['amount'] > 0) {
549 $validatePayement = TRUE;
550 // $self->_forcePayement = true;
551 // return false;
552 }
553 }
554 elseif (!empty($fields['amount']) &&
555 (CRM_Utils_Array::value('value', $self->_values['fee'][$fields['amount']]) > 0)
556 ) {
557 $validatePayement = TRUE;
558 }
559
560 if (!$validatePayement) {
561 return TRUE;
562 }
563
564 $errors = array();
565
566 CRM_Core_Form::validateMandatoryFields($self->_fields, $fields, $errors);
567
568 // validate supplied payment instrument values (e.g. credit card number and cvv)
569 $payment_processor_id = $self->params[0]['payment_processor_id'];
570 CRM_Core_Payment_Form::validatePaymentInstrument($payment_processor_id, $self->_params[0], $errors, $self);
571
572 if ($errors) {
573 return FALSE;
574 }
575
576 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
577 if ($greetingType = CRM_Utils_Array::value($greeting, $self->_params[0])) {
578 $customizedValue = CRM_Core_OptionGroup::getValue($greeting, 'Customized', 'name');
579 if ($customizedValue == $greetingType && empty($self->_params[0][$greeting . '_custom'])) {
580 return FALSE;
581 }
582 }
583 }
584 }
585
586 /**
587 * Process the form submission.
588 *
589 *
590 * @return void
591 */
592 public function postProcess() {
593 //get the button name.
594 $button = substr($this->controller->getButtonName(), -4);
595
596 //take the participant instance.
597 $addParticipantNum = substr($this->_name, 12);
598
599 //user submitted params.
600 $params = $this->controller->exportValues($this->_name);
601
602 if (!$this->_allowConfirmation) {
603 // check if the participant is already registered
604 $params['contact_id'] = CRM_Event_Form_Registration_Register::checkRegistration($params, $this, TRUE, TRUE);
605 }
606
607 //carry campaign to partcipants.
608 if (array_key_exists('participant_campaign_id', $params)) {
609 $params['campaign_id'] = $params['participant_campaign_id'];
610 }
611 else {
612 $params['campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values['event']);
613 }
614
615 // if waiting is enabled
616 if (!$this->_allowConfirmation &&
617 is_numeric($this->_availableRegistrations)
618 ) {
619 $this->_allowWaitlist = FALSE;
620 //get the current page count.
621 $currentCount = self::getParticipantCount($this, $params);
622 if ($button == 'skip') {
623 $currentCount = 'skip';
624 }
625
626 //get the total count.
627 $previousCount = self::getParticipantCount($this, $this->_params, TRUE);
628 $totalParticipants = $previousCount;
629 if (is_numeric($currentCount)) {
630 $totalParticipants += $currentCount;
631 }
632 if (!empty($this->_values['event']['has_waitlist']) &&
633 $totalParticipants > $this->_availableRegistrations
634 ) {
635 $this->_allowWaitlist = TRUE;
636 }
637 $this->set('allowWaitlist', $this->_allowWaitlist);
638 $this->_lineItemParticipantsCount[$addParticipantNum] = $currentCount;
639 }
640
641 if ($button == 'skip') {
642 //hack for free/zero amount event.
643 if ($this->_resetAllowWaitlist) {
644 $this->_allowWaitlist = FALSE;
645 $this->set('allowWaitlist', FALSE);
646 if ($this->_requireApproval) {
647 $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.");
648 }
649 else {
650 $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.");
651 }
652 CRM_Core_Session::setStatus($status);
653 }
654
655 $this->_params[$addParticipantNum] = 'skip';
656 if (isset($this->_lineItem)) {
657 $this->_lineItem[$addParticipantNum] = 'skip';
658 $this->_lineItemParticipantsCount[$addParticipantNum] = 'skip';
659 }
660 }
661 else {
662
663 $config = CRM_Core_Config::singleton();
664 $params['currencyID'] = $config->defaultCurrency;
665
666 if ($this->_values['event']['is_monetary']) {
667
668 //added for discount
669 $discountId = CRM_Core_BAO_Discount::findSet($this->_eventId, 'civicrm_event');
670
671 if (!empty($this->_values['discount'][$discountId])) {
672 $params['discount_id'] = $discountId;
673 $params['amount_level'] = $this->_values['discount'][$discountId][$params['amount']]['label'];
674 $params['amount'] = $this->_values['discount'][$discountId][$params['amount']]['value'];
675 }
676 elseif (empty($params['priceSetId'])) {
677 $params['amount_level'] = $this->_values['fee'][$params['amount']]['label'];
678 $params['amount'] = $this->_values['fee'][$params['amount']]['value'];
679 }
680 else {
681 $lineItem = array();
682 CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'], $params, $lineItem);
683
684 //build the line item..
685 if (array_key_exists($addParticipantNum, $this->_lineItem)) {
686 $this->_lineItem[$addParticipantNum] = $lineItem;
687 }
688 else {
689 $this->_lineItem[] = $lineItem;
690 }
691 }
692 }
693
694 if (array_key_exists('participant_role', $params)) {
695 $params['participant_role_id'] = $params['participant_role'];
696 }
697
698 if (empty($params['participant_role_id']) && $this->_values['event']['default_role_id']) {
699 $params['participant_role_id'] = $this->_values['event']['default_role_id'];
700 }
701
702 if (!empty($this->_params[0]['is_pay_later'])) {
703 $params['is_pay_later'] = 1;
704 }
705
706 //carry additional participant id, contact id if pre-registered.
707 if ($this->_allowConfirmation && $this->_additionalParticipantId) {
708 $params['contact_id'] = $this->_contactId;
709 $params['participant_id'] = $this->_additionalParticipantId;
710 }
711
712 //build the params array.
713 if (array_key_exists($addParticipantNum, $this->_params)) {
714 $this->_params[$addParticipantNum] = $params;
715 }
716 else {
717 $this->_params[] = $params;
718 }
719 }
720
721 //finally set the params.
722 $this->set('params', $this->_params);
723 //set the line item.
724 if ($this->_lineItem) {
725 $this->set('lineItem', $this->_lineItem);
726 $this->set('lineItemParticipantsCount', $this->_lineItemParticipantsCount);
727 }
728
729 $participantNo = count($this->_params);
730 if ($button != 'skip') {
731 $statusMsg = ts('Registration information for participant %1 has been saved.', array(1 => $participantNo));
732 CRM_Core_Session::setStatus($statusMsg, ts('Registration Saved'), 'success');
733 }
734
735 // Check whether to process the registration now, calling processRegistration()
736 if (
737 !$this->_values['event']['is_confirm_enabled'] // CRM-11182 - Optional confirmation screen
738 && !$this->_values['event']['is_monetary']
739 && CRM_Utils_Array::value('additional_participants', $this->_params[0])
740 && $this->isLastParticipant()
741 ) {
742 CRM_Event_Form_Registration_Register::processRegistration($this->_params, NULL);
743 }
744 }
745
746 /**
747 * @param $additionalParticipant
748 *
749 * @return array
750 */
751 public static function &getPages($additionalParticipant) {
752 $details = array();
753 for ($i = 1; $i <= $additionalParticipant; $i++) {
754 $details["Participant_{$i}"] = array(
755 'className' => 'CRM_Event_Form_Registration_AdditionalParticipant',
756 'title' => "Register Additional Participant {$i}",
757 );
758 }
759 return $details;
760 }
761
762 /**
763 * Check whether call current participant is last one.
764 *
765 * @param bool $isButtonJs
766 *
767 * @return bool
768 * ture on success.
769 */
770 public function isLastParticipant($isButtonJs = FALSE) {
771 $participant = $isButtonJs ? $this->_params[0]['additional_participants'] : $this->_params[0]['additional_participants'] + 1;
772 if (count($this->_params) == $participant) {
773 return TRUE;
774 }
775 return FALSE;
776 }
777
778 /**
779 * Reset values for all options those are full.
780 *
781 */
782 public function resetElementValue($optionFullIds = array()) {
783 if (!is_array($optionFullIds) ||
784 empty($optionFullIds) ||
785 !$this->isSubmitted()
786 ) {
787 return;
788 }
789
790 foreach ($optionFullIds as $fldId => $optIds) {
791 $name = "price_$fldId";
792 if (!$this->elementExists($name)) {
793 continue;
794 }
795
796 $element = $this->getElement($name);
797 $eleType = $element->getType();
798
799 $resetSubmitted = FALSE;
800 switch ($eleType) {
801 case 'text':
802 if ($element->isFrozen()) {
803 $element->setValue('');
804 $resetSubmitted = TRUE;
805 }
806 break;
807
808 case 'group':
809 if (is_array($element->_elements)) {
810 foreach ($element->_elements as $child) {
811 $childType = $child->getType();
812 $methodName = 'getName';
813 if ($childType) {
814 $methodName = 'getValue';
815 }
816 if (in_array($child->{$methodName}(), $optIds) && $child->isFrozen()) {
817 $resetSubmitted = TRUE;
818 $child->updateAttributes(array('checked' => NULL));
819 }
820 }
821 }
822 break;
823
824 case 'select':
825 $resetSubmitted = TRUE;
826 $element->_values = array();
827 break;
828 }
829
830 //finally unset values from submitted.
831 if ($resetSubmitted) {
832 $this->resetSubmittedValue($name, $optIds);
833 }
834 }
835 }
836
837 /**
838 * @param string $elementName
839 * @param array $optionIds
840 */
841 public function resetSubmittedValue($elementName, $optionIds = array()) {
842 if (empty($elementName) ||
843 !$this->elementExists($elementName) ||
844 !$this->getSubmitValue($elementName)
845 ) {
846 return;
847 }
848 foreach (array(
849 'constantValues',
850 'submitValues',
851 'defaultValues',
852 ) as $val) {
853 $values = &$this->{"_$val"};
854 if (!is_array($values) || empty($values)) {
855 continue;
856 }
857 $eleVal = CRM_Utils_Array::value($elementName, $values);
858 if (empty($eleVal)) {
859 continue;
860 }
861 if (is_array($eleVal)) {
862 $found = FALSE;
863 foreach ($eleVal as $keyId => $ignore) {
864 if (in_array($keyId, $optionIds)) {
865 $found = TRUE;
866 unset($values[$elementName][$keyId]);
867 }
868 }
869 if ($found && empty($values[$elementName][$keyId])) {
870 $values[$elementName][$keyId] = NULL;
871 }
872 }
873 else {
874 $values[$elementName][$keyId] = NULL;
875 }
876 }
877 }
878
879 }