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