3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
30 * @copyright CiviCRM LLC (c) 2004-2015
34 * This class generates form components for processing Event.
36 class CRM_Event_Form_Registration_Register
extends CRM_Event_Form_Registration
{
39 * The fields involved in this page.
44 * The status message that user view.
46 protected $_waitlistMsg = NULL;
47 protected $_requireApprovalMsg = NULL;
50 * Deprecated parameter that we hope to remove.
54 public $_quickConfig = NULL;
57 * Skip duplicate check.
59 * This can be set using hook_civicrm_buildForm() to override the registration dupe check.
62 public $_skipDupeRegistrationCheck = FALSE;
64 public $_paymentProcessorID;
67 * Show fee block or not.
69 * @var boolean determines if fee block should be shown or hidden
74 * Array of payment related fields to potentially display on this form (generally credit card or debit card fields).
76 * This is rendered via billingBlock.tpl.
80 public $_paymentFields = array();
83 * Set variables up before form is built.
85 public function preProcess() {
89 //here we can't use parent $this->_allowWaitlist as user might
90 //walk back and we might set this value in this postProcess.
91 //(we set when spaces < group count and want to allow become part of waiting )
92 $eventFull = CRM_Event_BAO_Participant
::eventFull($this->_eventId
, FALSE, CRM_Utils_Array
::value('has_waitlist', $this->_values
['event']));
94 // Get payment processors if appropriate for this event
95 // We hide the payment fields if the event is full or requires approval,
96 // and the current user has not yet been approved CRM-12279
97 $this->_noFees
= (($eventFull ||
$this->_requireApproval
) && !$this->_allowConfirmation
);
98 $this->_paymentProcessors
= $this->_noFees ?
array() : $this->get('paymentProcessors');
99 $this->preProcessPaymentOptions();
101 $this->_allowWaitlist
= FALSE;
102 if ($eventFull && !$this->_allowConfirmation
&& !empty($this->_values
['event']['has_waitlist'])) {
103 $this->_allowWaitlist
= TRUE;
104 $this->_waitlistMsg
= CRM_Utils_Array
::value('waitlist_text', $this->_values
['event']);
105 if (!$this->_waitlistMsg
) {
106 $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.');
109 $this->set('allowWaitlist', $this->_allowWaitlist
);
111 //To check if the user is already registered for the event(CRM-2426)
112 if (!$this->_skipDupeRegistrationCheck
) {
113 self
::checkRegistration(NULL, $this);
116 $this->assign('availableRegistrations', $this->_availableRegistrations
);
118 // get the participant values from EventFees.php, CRM-4320
119 if ($this->_allowConfirmation
) {
120 CRM_Event_Form_EventFees
::preProcess($this);
125 * Set default values for the form.
127 public function setDefaultValues() {
128 $this->_defaults
= array();
129 $contactID = $this->getContactID();
130 CRM_Core_Payment_Form
::setDefaultValues($this, $contactID);
135 if (!empty($this->_fields
)) {
136 $removeCustomFieldTypes = array('Participant');
137 foreach ($this->_fields
as $name => $dontCare) {
138 if (substr($name, 0, 7) == 'custom_') {
139 $id = substr($name, 7);
140 if (!$this->_allowConfirmation
&&
141 !CRM_Core_BAO_CustomGroup
::checkCustomField($id, $removeCustomFieldTypes)
145 // ignore component fields
147 elseif ((substr($name, 0, 12) == 'participant_')) {
155 if (!empty($fields)) {
156 CRM_Core_BAO_UFGroup
::setProfileDefaults($contactID, $fields, $this->_defaults
);
159 // Set default payment processor as default payment_processor radio button value
160 if (!empty($this->_paymentProcessors
)) {
161 foreach ($this->_paymentProcessors
as $pid => $value) {
162 if (!empty($value['is_default'])) {
163 $this->_defaults
['payment_processor_id'] = $pid;
168 //if event is monetary and pay later is enabled and payment
169 //processor is not available then freeze the pay later checkbox with
171 if (!empty($this->_values
['event']['is_pay_later']) &&
172 !is_array($this->_paymentProcessor
)
174 $this->_defaults
['is_pay_later'] = 1;
177 //set custom field defaults
178 if (!empty($this->_fields
)) {
179 //load default campaign from page.
180 if (array_key_exists('participant_campaign_id', $this->_fields
)) {
181 $this->_defaults
['participant_campaign_id'] = CRM_Utils_Array
::value('campaign_id',
182 $this->_values
['event']
186 foreach ($this->_fields
as $name => $field) {
187 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
189 if (!isset($this->_defaults
[$name])) {
190 CRM_Core_BAO_CustomField
::setProfileDefaults($customFieldID, $name, $this->_defaults
,
191 NULL, CRM_Profile_Form
::MODE_REGISTER
198 //fix for CRM-3088, default value for discount set.
200 if (!empty($this->_values
['discount'])) {
201 $discountId = CRM_Core_BAO_Discount
::findSet($this->_eventId
, 'civicrm_event');
203 if (isset($this->_values
['event']['default_discount_fee_id'])) {
204 $discountKey = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_OptionValue',
205 $this->_values
['event']['default_discount_fee_id'],
209 $this->_defaults
['amount'] = key(array_slice($this->_values
['discount'][$discountId],
210 $discountKey - 1, $discountKey, TRUE
216 // add this event's default participant role to defaults array
217 // (for cases where participant_role field is included in form via profile)
218 if ($this->_values
['event']['default_role_id']) {
219 $this->_defaults
['participant_role']
220 = $this->_defaults
['participant_role_id'] = $this->_values
['event']['default_role_id'];
222 if ($this->_priceSetId
&& !empty($this->_feeBlock
)) {
223 foreach ($this->_feeBlock
as $key => $val) {
224 if (empty($val['options'])) {
227 $optionFullIds = CRM_Utils_Array
::value('option_full_ids', $val, array());
228 foreach ($val['options'] as $keys => $values) {
229 if ($values['is_default'] && empty($values['is_full'])) {
231 if ($val['html_type'] == 'CheckBox') {
232 $this->_defaults
["price_{$key}"][$keys] = 1;
235 $this->_defaults
["price_{$key}"] = $keys;
239 $unsetSubmittedOptions[$val['id']] = $optionFullIds;
241 //reset values for all options those are full.
242 CRM_Event_Form_Registration
::resetElementValue($unsetSubmittedOptions, $this);
245 //set default participant fields, CRM-4320.
246 $hasAdditionalParticipants = FALSE;
247 if ($this->_allowConfirmation
) {
248 $this->_contactId
= $contactID;
249 $this->_discountId
= $discountId;
250 $forcePayLater = CRM_Utils_Array
::value('is_pay_later', $this->_defaults
, FALSE);
251 $this->_defaults
= array_merge($this->_defaults
, CRM_Event_Form_EventFees
::setDefaultValues($this));
252 $this->_defaults
['is_pay_later'] = $forcePayLater;
254 if ($this->_additionalParticipantIds
) {
255 $hasAdditionalParticipants = TRUE;
256 $this->_defaults
['additional_participants'] = count($this->_additionalParticipantIds
);
259 $this->assign('hasAdditionalParticipants', $hasAdditionalParticipants);
261 // //hack to simplify credit card entry for testing
262 // $this->_defaults['credit_card_type'] = 'Visa';
263 // $this->_defaults['credit_card_number'] = '4807731747657838';
264 // $this->_defaults['cvv2'] = '000';
265 // $this->_defaults['credit_card_exp_date'] = array( 'Y' => '2010', 'M' => '05' );
267 // to process Custom data that are appended to URL
268 $getDefaults = CRM_Core_BAO_CustomGroup
::extractGetParams($this, "'Contact', 'Individual', 'Contribution', 'Participant'");
269 if (!empty($getDefaults)) {
270 $this->_defaults
= array_merge($this->_defaults
, $getDefaults);
273 return $this->_defaults
;
277 * Build the form object.
281 public function buildQuickForm() {
282 // build profiles first so that we can determine address fields etc
283 // and then show copy address checkbox
284 $this->buildCustom($this->_values
['custom_pre_id'], 'customPre');
285 $this->buildCustom($this->_values
['custom_post_id'], 'customPost');
287 if (!empty($this->_fields
) && !empty($this->_values
['custom_pre_id'])) {
288 $profileAddressFields = array();
289 foreach ($this->_fields
as $key => $value) {
290 CRM_Core_BAO_UFField
::assignAddressField($key, $profileAddressFields, array(
291 'uf_group_id' => $this->_values
['custom_pre_id'],
294 $this->set('profileAddressFields', $profileAddressFields);
297 CRM_Core_Payment_ProcessorForm
::buildQuickForm($this);
299 $contactID = $this->getContactID();
301 $this->assign('contact_id', $contactID);
302 $this->assign('display_name', CRM_Contact_BAO_Contact
::displayName($contactID));
305 $this->add('hidden', 'scriptFee', NULL);
306 $this->add('hidden', 'scriptArray', NULL);
308 $bypassPayment = $allowGroupOnWaitlist = $isAdditionalParticipants = FALSE;
309 if ($this->_values
['event']['is_multiple_registrations']) {
310 // don't allow to add additional during confirmation if not preregistered.
311 if (!$this->_allowConfirmation ||
$this->_additionalParticipantIds
) {
312 // Hardcode maximum number of additional participants here for now. May need to make this configurable per event.
313 // Label is value + 1, since the code sees this is ADDITIONAL participants (in addition to "self")
314 $additionalOptions = array(
326 $element = $this->add('select', 'additional_participants',
327 ts('How many people are you registering?'),
330 array('onChange' => "allowParticipant()")
332 $isAdditionalParticipants = TRUE;
336 //hack to allow group to register w/ waiting
337 if ((!empty($this->_values
['event']['is_multiple_registrations']) ||
340 !$this->_allowConfirmation
&&
341 is_numeric($this->_availableRegistrations
) && !empty($this->_values
['event']['has_waitlist'])
343 $bypassPayment = TRUE;
344 //case might be group become as a part of waitlist.
345 //If not waitlist then they require admin approve.
346 $allowGroupOnWaitlist = TRUE;
347 $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
));
349 if ($this->_requireApproval
) {
350 $this->_requireApprovalMsg
= CRM_Utils_Array
::value('approval_req_text', $this->_values
['event'],
351 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.')
356 //case where only approval needed - no waitlist.
357 if ($this->_requireApproval
&&
358 !$this->_allowWaitlist
&& !$bypassPayment
360 $this->_requireApprovalMsg
= CRM_Utils_Array
::value('approval_req_text', $this->_values
['event'],
361 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.')
365 //lets display status to primary page only.
366 $this->assign('waitlistMsg', $this->_waitlistMsg
);
367 $this->assign('requireApprovalMsg', $this->_requireApprovalMsg
);
368 $this->assign('allowGroupOnWaitlist', $allowGroupOnWaitlist);
369 $this->assign('isAdditionalParticipants', $isAdditionalParticipants);
371 //lets get js on two different qf elements.
372 $showHidePayfieldName = NULL;
373 $showHidePaymentInformation = FALSE;
374 if ($this->_values
['event']['is_monetary']) {
375 self
::buildAmount($this);
379 //@todo this processor adding fn is another one duplicated on contribute - a shared
380 // common class would make this sort of thing extractable
381 $onlinePaymentProcessorEnabled = FALSE;
382 if (!empty($this->_paymentProcessors
)) {
383 foreach ($this->_paymentProcessors
as $key => $name) {
384 if ($name['billing_mode'] == 1) {
385 $onlinePaymentProcessorEnabled = TRUE;
387 $pps[$key] = $name['name'];
390 if ($this->getContactID() === 0 && !$this->_values
['event']['is_multiple_registrations']) {
391 //@todo we are blocking for multiple registrations because we haven't tested
392 $this->addCidZeroOptions($onlinePaymentProcessorEnabled);
394 if (!empty($this->_values
['event']['is_pay_later']) &&
395 ($this->_allowConfirmation ||
(!$this->_requireApproval
&& !$this->_allowWaitlist
))
397 $pps[0] = $this->_values
['event']['pay_later_text'];
400 if ($this->_values
['event']['is_monetary']) {
401 if (count($pps) > 1) {
402 $this->addRadio('payment_processor_id', ts('Payment Method'), $pps,
406 elseif (!empty($pps)) {
407 $ppKeys = array_keys($pps);
408 $currentPP = array_pop($ppKeys);
409 $this->addElement('hidden', 'payment_processor_id', $currentPP);
413 //lets add some qf element to bypass payment validations, CRM-4320
414 if ($bypassPayment) {
415 $this->addElement('hidden', 'bypass_payment', NULL, array('id' => 'bypass_payment'));
417 $this->assign('bypassPayment', $bypassPayment);
418 $this->assign('showHidePaymentInformation', $showHidePaymentInformation);
420 $userID = $this->getContactID();
423 $createCMSUser = FALSE;
425 if ($this->_values
['custom_pre_id']) {
426 $profileID = $this->_values
['custom_pre_id'];
427 $createCMSUser = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'is_cms_user');
430 if (!$createCMSUser &&
431 $this->_values
['custom_post_id']
433 if (!is_array($this->_values
['custom_post_id'])) {
434 $profileIDs = array($this->_values
['custom_post_id']);
437 $profileIDs = $this->_values
['custom_post_id'];
439 foreach ($profileIDs as $pid) {
440 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $pid, 'is_cms_user')) {
442 $createCMSUser = TRUE;
448 if ($createCMSUser) {
449 CRM_Core_BAO_CMSUser
::buildForm($this, $profileID, TRUE);
453 //we have to load confirm contribution button in template
454 //when multiple payment processor as the user
455 //can toggle with payment processor selection
456 $billingModePaymentProcessors = 0;
457 if (!CRM_Utils_System
::isNull($this->_paymentProcessors
)) {
458 foreach ($this->_paymentProcessors
as $key => $values) {
459 if ($values['billing_mode'] == CRM_Core_Payment
::BILLING_MODE_BUTTON
) {
460 $billingModePaymentProcessors++
;
465 if ($billingModePaymentProcessors && count($this->_paymentProcessors
) == $billingModePaymentProcessors) {
466 $allAreBillingModeProcessors = TRUE;
469 $allAreBillingModeProcessors = FALSE;
472 if (!$allAreBillingModeProcessors ||
!empty($this->_values
['event']['is_pay_later']) ||
$bypassPayment
475 //freeze button to avoid multiple calls.
478 if (empty($this->_values
['event']['is_monetary'])) {
479 $js = array('onclick' => "return submitOnce(this,'" . $this->_name
. "','" . ts('Processing') . "');");
482 // CRM-11182 - Optional confirmation screen
483 // Change button label depending on whether the next action is confirm or register
485 !$this->_values
['event']['is_multiple_registrations']
486 && !$this->_values
['event']['is_monetary']
487 && !$this->_values
['event']['is_confirm_enabled']
489 $buttonLabel = ts('Register');
492 $buttonLabel = ts('Continue');
495 $this->addButtons(array(
498 'name' => $buttonLabel,
499 'spacing' => ' ',
507 $this->addFormRule(array('CRM_Event_Form_Registration_Register', 'formRule'), $this);
508 $this->unsavedChangesWarn
= TRUE;
512 CRM_PCP_BAO_PCP
::buildPcp($this->_pcpId
, $this);
517 * Build the radio/text form elements for the amount field
519 * @param CRM_Core_Form $form
521 * @param bool $required
522 * True if you want to add formRule.
523 * @param int $discountId
524 * Discount id for the event.
528 static public function buildAmount(&$form, $required = TRUE, $discountId = NULL) {
529 // build amount only when needed, skip incase of event full and waitlisting is enabled
530 // and few other conditions check preProcess()
531 if (property_exists($form, '_noFees') && $form->_noFees
) {
535 //if payment done, no need to build the fee block.
536 if (!empty($form->_paymentId
)) {
537 //fix to display line item in update mode.
538 $form->assign('priceSet', isset($form->_priceSet
) ?
$form->_priceSet
: NULL);
542 $feeFields = CRM_Utils_Array
::value('fee', $form->_values
);
544 if (is_array($feeFields)) {
545 $form->_feeBlock
= &$form->_values
['fee'];
548 //check for discount.
549 $discountedFee = CRM_Utils_Array
::value('discount', $form->_values
);
550 if (is_array($discountedFee) && !empty($discountedFee)) {
552 $form->_discountId
= $discountId = CRM_Core_BAO_Discount
::findSet($form->_eventId
, 'civicrm_event');
555 $form->_feeBlock
= &$form->_values
['discount'][$discountId];
558 if (!is_array($form->_feeBlock
)) {
559 $form->_feeBlock
= array();
562 //its time to call the hook.
563 CRM_Utils_Hook
::buildAmount('event', $form, $form->_feeBlock
);
565 //reset required if participant is skipped.
566 $button = substr($form->controller
->getButtonName(), -4);
567 if ($required && $button == 'skip') {
571 $className = CRM_Utils_System
::getClassName($form);
573 //build the priceset fields.
574 if (isset($form->_priceSetId
) && $form->_priceSetId
) {
576 //format price set fields across option full.
577 self
::formatFieldsForOptionFull($form);
579 if (!empty($form->_priceSet
['is_quick_config'])) {
580 $form->_quickConfig
= $form->_priceSet
['is_quick_config'];
582 $form->add('hidden', 'priceSetId', $form->_priceSetId
);
584 // CRM-14492 Admin price fields should show up on event registration if user has 'administer CiviCRM' permissions
585 $adminFieldVisible = FALSE;
586 if (CRM_Core_Permission
::check('administer CiviCRM')) {
587 $adminFieldVisible = TRUE;
590 foreach ($form->_feeBlock
as $field) {
591 // public AND admin visibility fields are included for back-office registration and back-office change selections
592 if (CRM_Utils_Array
::value('visibility', $field) == 'public' ||
593 (CRM_Utils_Array
::value('visibility', $field) == 'admin' && $adminFieldVisible == TRUE) ||
594 $className == 'CRM_Event_Form_Participant' ||
595 $className == 'CRM_Event_Form_ParticipantFeeSelection'
597 $fieldId = $field['id'];
598 $elementName = 'price_' . $fieldId;
600 $isRequire = CRM_Utils_Array
::value('is_required', $field);
601 if ($button == 'skip') {
605 //user might modified w/ hook.
606 $options = CRM_Utils_Array
::value('options', $field);
607 if (!is_array($options)) {
611 $optionFullIds = CRM_Utils_Array
::value('option_full_ids', $field, array());
613 //soft suppress required rule when option is full.
614 if (!empty($optionFullIds) && (count($options) == count($optionFullIds))) {
619 CRM_Price_BAO_PriceField
::addQuickFormElement($form,
630 $form->assign('priceSet', $form->_priceSet
);
633 $eventFeeBlockValues = array();
634 foreach ($form->_feeBlock
as $fee) {
635 if (is_array($fee)) {
638 $totalAmountJs = NULL;
639 if ($className == 'CRM_Event_Form_Participant') {
640 $totalAmountJs = array('onClick' => "fillTotalAmount(" . $fee['value'] . ")");
643 $eventFeeBlockValues['amount_id_' . $fee['amount_id']] = $fee['value'];
644 $elements[] = &$form->createElement('radio', NULL, '',
645 CRM_Utils_Money
::format($fee['value']) . ' ' .
652 $form->assign('eventFeeBlockValues', json_encode($eventFeeBlockValues));
654 $form->_defaults
['amount'] = CRM_Utils_Array
::value('default_fee_id', $form->_values
['event']);
655 $element = &$form->addGroup($elements, 'amount', ts('Event Fee(s)'), '<br />');
656 if (isset($form->_online
) && $form->_online
) {
660 $form->addRule('amount', ts('Fee Level is a required field.'), 'required');
666 * @param CRM_Core_Form $form
668 public static function formatFieldsForOptionFull(&$form) {
669 $priceSet = $form->get('priceSet');
670 $priceSetId = $form->get('priceSetId');
671 $defaultPricefieldIds = array();
672 if (!empty($form->_values
['line_items'])) {
673 foreach ($form->_values
['line_items'] as $lineItem) {
674 $defaultPricefieldIds[] = $lineItem['price_field_value_id'];
678 !is_array($priceSet) ||
679 empty($priceSet) ||
empty($priceSet['optionsMaxValueTotal'])
684 $skipParticipants = $formattedPriceSetDefaults = array();
685 if (!empty($form->_allowConfirmation
) && (isset($form->_pId
) ||
isset($form->_additionalParticipantId
))) {
686 $participantId = isset($form->_pId
) ?
$form->_pId
: $form->_additionalParticipantId
;
687 $pricesetDefaults = CRM_Event_Form_EventFees
::setDefaultPriceSet($participantId,
690 // modify options full to respect the selected fields
691 // options on confirmation.
692 $formattedPriceSetDefaults = self
::formatPriceSetParams($form, $pricesetDefaults);
694 // to skip current registered participants fields option count on confirmation.
695 $skipParticipants[] = $form->_participantId
;
696 if (!empty($form->_additionalParticipantIds
)) {
697 $skipParticipants = array_merge($skipParticipants, $form->_additionalParticipantIds
);
701 $className = CRM_Utils_System
::getClassName($form);
703 //get the current price event price set options count.
704 $currentOptionsCount = self
::getPriceSetOptionCount($form);
705 $recordedOptionsCount = CRM_Event_BAO_Participant
::priceSetOptionsCount($form->_eventId
, $skipParticipants);
706 $optionFullTotalAmount = 0;
707 $currentParticipantNo = (int) substr($form->_name
, 12);
708 foreach ($form->_feeBlock
as & $field) {
709 $optionFullIds = array();
710 $fieldId = $field['id'];
711 if (!is_array($field['options'])) {
714 foreach ($field['options'] as & $option) {
715 $optId = $option['id'];
716 $count = CRM_Utils_Array
::value('count', $option, 0);
717 $maxValue = CRM_Utils_Array
::value('max_value', $option, 0);
718 $dbTotalCount = CRM_Utils_Array
::value($optId, $recordedOptionsCount, 0);
719 $currentTotalCount = CRM_Utils_Array
::value($optId, $currentOptionsCount, 0);
721 $totalCount = $currentTotalCount +
$dbTotalCount;
724 (($totalCount >= $maxValue) &&
725 (empty($form->_lineItem
[$currentParticipantNo][$optId]['price_field_id']) ||
$dbTotalCount >= $maxValue))
728 $optionFullIds[$optId] = $optId;
729 if ($field['html_type'] != 'Select') {
730 if (in_array($optId, $defaultPricefieldIds)) {
731 $optionFullTotalAmount +
= CRM_Utils_Array
::value('amount', $option);
735 if (!empty($defaultPricefieldIds) && in_array($optId, $defaultPricefieldIds)) {
736 unset($optionFullIds[$optId]);
740 //here option is not full,
741 //but we don't want to allow participant to increase
742 //seats at the time of re-walking registration.
744 !empty($form->_allowConfirmation
) &&
745 !empty($formattedPriceSetDefaults)
747 if (empty($formattedPriceSetDefaults["price_{$field}"]) ||
empty($formattedPriceSetDefaults["price_{$fieldId}"][$optId])) {
748 $optionFullIds[$optId] = $optId;
752 $option['is_full'] = $isFull;
753 $option['db_total_count'] = $dbTotalCount;
754 $option['total_option_count'] = $dbTotalCount +
$currentTotalCount;
757 //ignore option full for offline registration.
758 if ($className == 'CRM_Event_Form_Participant') {
759 $optionFullIds = array();
762 //finally get option ids in.
763 $field['option_full_ids'] = $optionFullIds;
765 $form->assign('optionFullTotalAmount', $optionFullTotalAmount);
771 * @param array $fields
772 * The input form values.
773 * @param array $files
774 * The uploaded files if any.
779 * true if no errors, else array of errors
781 public static function formRule($fields, $files, $self) {
783 //check that either an email or firstname+lastname is included in the form(CRM-9587)
784 self
::checkProfileComplete($fields, $errors, $self->_eventId
);
785 //To check if the user is already registered for the event(CRM-2426)
786 if (!$self->_skipDupeRegistrationCheck
) {
787 self
::checkRegistration($fields, $self);
789 //check for availability of registrations.
790 if (!$self->_allowConfirmation
&& empty($fields['bypass_payment']) &&
791 is_numeric($self->_availableRegistrations
) &&
792 CRM_Utils_Array
::value('additional_participants', $fields) >= $self->_availableRegistrations
794 $errors['additional_participants'] = ts("There is only enough space left on this event for %1 participant(s).", array(1 => $self->_availableRegistrations
));
797 // during confirmation don't allow to increase additional participants, CRM-4320
798 if ($self->_allowConfirmation
&& !empty($fields['additional_participants']) &&
799 is_array($self->_additionalParticipantIds
) &&
800 $fields['additional_participants'] > count($self->_additionalParticipantIds
)
802 $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($self->_additionalParticipantIds
)));
805 //don't allow to register w/ waiting if enough spaces available.
806 if (!empty($fields['bypass_payment'])) {
807 if (!is_numeric($self->_availableRegistrations
) ||
808 (empty($fields['priceSetId']) && CRM_Utils_Array
::value('additional_participants', $fields) < $self->_availableRegistrations
)
810 $errors['bypass_payment'] = ts("Oops. There are enough available spaces in this event. You can not add yourself to the waiting list.");
814 if (!empty($fields['additional_participants']) &&
815 !CRM_Utils_Rule
::positiveInteger($fields['additional_participants'])
817 $errors['additional_participants'] = ts('Please enter a whole number for Number of additional people.');
820 // priceset validations
821 if (!empty($fields['priceSetId']) &&
822 !$self->_requireApproval
&& !$self->_allowWaitlist
825 $formatted = self
::formatPriceSetParams($self, $fields);
826 $ppParams = array($formatted);
827 $priceSetErrors = self
::validatePriceSet($self, $ppParams);
828 $primaryParticipantCount = self
::getParticipantCount($self, $ppParams);
830 //get price set fields errors in.
831 $errors = array_merge($errors, CRM_Utils_Array
::value(0, $priceSetErrors, array()));
833 $totalParticipants = $primaryParticipantCount;
834 if (!empty($fields['additional_participants'])) {
835 $totalParticipants +
= $fields['additional_participants'];
838 if (empty($fields['bypass_payment']) &&
839 !$self->_allowConfirmation
&&
840 is_numeric($self->_availableRegistrations
) &&
841 $self->_availableRegistrations
< $totalParticipants
843 $errors['_qf_default'] = ts("Only %1 Registrations available.", array(1 => $self->_availableRegistrations
));
847 CRM_Price_BAO_PriceSet
::processAmount($self->_values
['fee'], $fields, $lineItem);
848 if ($fields['amount'] < 0) {
849 $errors['_qf_default'] = ts('Event Fee(s) can not be less than zero. Please select the options accordingly');
853 // @todo - can we remove the 'is_monetary' concept?
854 if ($self->_values
['event']['is_monetary']) {
855 if (empty($self->_requireApproval
) && !empty($fields['amount']) && $fields['amount'] > 0 && !isset
856 ($fields['payment_processor_id'])) {
857 $errors['payment_processor_id'] = ts('Please select a Payment Method');
860 $isZeroAmount = $skipPaymentValidation = FALSE;
861 if (!empty($fields['priceSetId'])) {
862 if (CRM_Utils_Array
::value('amount', $fields) == 0) {
863 $isZeroAmount = TRUE;
866 elseif (!empty($fields['amount']) &&
867 (isset($self->_values
['discount'][$fields['amount']])
868 && CRM_Utils_Array
::value('value', $self->_values
['discount'][$fields['amount']]) == 0
871 $isZeroAmount = TRUE;
873 elseif (!empty($fields['amount']) &&
874 (isset($self->_values
['fee'][$fields['amount']])
875 && CRM_Utils_Array
::value('value', $self->_values
['fee'][$fields['amount']]) == 0
878 $isZeroAmount = TRUE;
881 if ($isZeroAmount && !($self->_forcePayement
&& !empty($fields['additional_participants']))) {
882 $skipPaymentValidation = TRUE;
885 // also return if zero fees for valid members
886 if (!empty($fields['bypass_payment']) ||
887 $skipPaymentValidation ||
888 (!$self->_allowConfirmation
&& ($self->_requireApproval ||
$self->_allowWaitlist
))
890 return empty($errors) ?
TRUE : $errors;
892 CRM_Core_Payment_Form
::validatePaymentInstrument(
893 $fields['payment_processor_id'],
896 (!$self->_isBillingAddressRequiredForPayLater ?
NULL : 'billing')
900 foreach (CRM_Contact_BAO_Contact
::$_greetingTypes as $greeting) {
901 if ($greetingType = CRM_Utils_Array
::value($greeting, $fields)) {
902 $customizedValue = CRM_Core_OptionGroup
::getValue($greeting, 'Customized', 'name');
903 if ($customizedValue == $greetingType && empty($fields[$greeting . '_custom'])) {
904 $errors[$greeting . '_custom'] = ts('Custom %1 is a required field if %1 is of type Customized.',
905 array(1 => ucwords(str_replace('_', ' ', $greeting)))
910 return empty($errors) ?
TRUE : $errors;
914 * Check if profiles are complete when event registration occurs(CRM-9587).
916 * @param array $fields
917 * @param array $errors
918 * @param int $eventId
920 public static function checkProfileComplete($fields, &$errors, $eventId) {
922 foreach ($fields as $fieldname => $fieldvalue) {
923 if (substr($fieldname, 0, 6) == 'email-' && $fieldvalue) {
924 $email = $fieldvalue;
928 if (!$email && !(!empty($fields['first_name']) && !empty($fields['last_name']))) {
929 $defaults = $params = array('id' => $eventId);
930 CRM_Event_BAO_Event
::retrieve($params, $defaults);
931 $message = ts("Mandatory fields (first name and last name, OR email address) are missing from this form.");
932 $errors['_qf_default'] = $message;
937 * Process the form submission.
939 public function postProcess() {
940 // get the submitted form values.
941 $params = $this->controller
->exportValues($this->_name
);
943 //set as Primary participant
944 $params['is_primary'] = 1;
946 if ($this->_values
['event']['is_pay_later']
947 && (!array_key_exists('hidden_processor', $params) ||
$params['payment_processor_id'] == 0)
949 $params['is_pay_later'] = 1;
952 $params['is_pay_later'] = 0;
955 $this->set('is_pay_later', $params['is_pay_later']);
957 // assign pay later stuff
958 $this->_params
['is_pay_later'] = CRM_Utils_Array
::value('is_pay_later', $params, FALSE);
959 $this->assign('is_pay_later', $params['is_pay_later']);
960 if ($params['is_pay_later']) {
961 $this->assign('pay_later_text', $this->_values
['event']['pay_later_text']);
962 $this->assign('pay_later_receipt', $this->_values
['event']['pay_later_receipt']);
965 if (!$this->_allowConfirmation
) {
966 // check if the participant is already registered
967 if (!$this->_skipDupeRegistrationCheck
) {
968 $params['contact_id'] = self
::checkRegistration($params, $this, FALSE, TRUE, TRUE);
972 if (!empty($params['image_URL'])) {
973 CRM_Contact_BAO_Contact
::processImageParams($params);
976 //carry campaign to partcipants.
977 if (array_key_exists('participant_campaign_id', $params)) {
978 $params['campaign_id'] = $params['participant_campaign_id'];
981 $params['campaign_id'] = CRM_Utils_Array
::value('campaign_id', $this->_values
['event']);
984 //hack to allow group to register w/ waiting
985 $primaryParticipantCount = self
::getParticipantCount($this, $params);
987 $totalParticipants = $primaryParticipantCount;
988 if (!empty($params['additional_participants'])) {
989 $totalParticipants +
= $params['additional_participants'];
991 if (!$this->_allowConfirmation
&& !empty($params['bypass_payment']) &&
992 is_numeric($this->_availableRegistrations
) &&
993 $totalParticipants > $this->_availableRegistrations
995 $this->_allowWaitlist
= TRUE;
996 $this->set('allowWaitlist', TRUE);
999 //carry participant id if pre-registered.
1000 if ($this->_allowConfirmation
&& $this->_participantId
) {
1001 $params['participant_id'] = $this->_participantId
;
1004 $params['defaultRole'] = 1;
1005 if (array_key_exists('participant_role', $params)) {
1006 $params['participant_role_id'] = $params['participant_role'];
1009 if (array_key_exists('participant_role_id', $params)) {
1010 $params['defaultRole'] = 0;
1012 if (empty($params['participant_role_id']) &&
1013 $this->_values
['event']['default_role_id']
1015 $params['participant_role_id'] = $this->_values
['event']['default_role_id'];
1018 $config = CRM_Core_Config
::singleton();
1019 $params['currencyID'] = $config->defaultCurrency
;
1021 if ($this->_values
['event']['is_monetary']) {
1022 // we first reset the confirm page so it accepts new values
1023 $this->controller
->resetPage('Confirm');
1025 //added for discount
1026 $discountId = CRM_Core_BAO_Discount
::findSet($this->_eventId
, 'civicrm_event');
1028 if (!empty($this->_values
['discount'][$discountId])) {
1029 $params['discount_id'] = $discountId;
1030 $params['amount_level'] = $this->_values
['discount'][$discountId][$params['amount']]['label'];
1032 $params['amount'] = $this->_values
['discount'][$discountId][$params['amount']]['value'];
1034 elseif (empty($params['priceSetId'])) {
1035 if (!empty($params['amount'])) {
1036 $params['amount_level'] = $this->_values
['fee'][$params['amount']]['label'];
1037 $params['amount'] = $this->_values
['fee'][$params['amount']]['value'];
1040 $params['amount_level'] = $params['amount'] = '';
1044 $lineItem = array();
1045 CRM_Price_BAO_PriceSet
::processAmount($this->_values
['fee'], $params, $lineItem);
1046 if ($params['tax_amount']) {
1047 $this->set('tax_amount', $params['tax_amount']);
1049 $submittedLineItems = $this->get('lineItem');
1050 if (!empty($submittedLineItems) && is_array($submittedLineItems)) {
1051 $submittedLineItems[0] = $lineItem;
1054 $submittedLineItems = array($lineItem);
1056 $this->set('lineItem', $submittedLineItems);
1057 $this->set('lineItemParticipantsCount', array($primaryParticipantCount));
1060 $this->set('amount', $params['amount']);
1061 $this->set('amount_level', $params['amount_level']);
1063 // generate and set an invoiceID for this transaction
1064 $invoiceID = md5(uniqid(rand(), TRUE));
1065 $this->set('invoiceID', $invoiceID);
1067 if (is_array($this->_paymentProcessor
)) {
1068 $payment = $this->_paymentProcessor
['object'];
1069 $payment->setBaseReturnUrl('civicrm/event/register');
1071 // default mode is direct
1072 $this->set('contributeMode', 'direct');
1074 if (isset($params["state_province_id-{$this->_bltID}"]) &&
1075 $params["state_province_id-{$this->_bltID}"]
1077 $params["state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($params["state_province_id-{$this->_bltID}"]);
1080 if (isset($params["country_id-{$this->_bltID}"]) &&
1081 $params["country_id-{$this->_bltID}"]
1083 $params["country-{$this->_bltID}"] = CRM_Core_PseudoConstant
::countryIsoCode($params["country_id-{$this->_bltID}"]);
1085 if (isset($params['credit_card_exp_date'])) {
1086 $params['year'] = CRM_Core_Payment_Form
::getCreditCardExpirationYear($params);
1087 $params['month'] = CRM_Core_Payment_Form
::getCreditCardExpirationMonth($params);
1089 if ($this->_values
['event']['is_monetary']) {
1090 $params['ip_address'] = CRM_Utils_System
::ipAddress();
1091 $params['currencyID'] = $config->defaultCurrency
;
1092 $params['invoiceID'] = $invoiceID;
1094 $this->_params
= $this->get('params');
1095 // Set the button so we know what
1096 $params['button'] = $this->controller
->getButtonName();
1097 if (!empty($this->_params
) && is_array($this->_params
)) {
1098 $this->_params
[0] = $params;
1101 $this->_params
= array();
1102 $this->_params
[] = $params;
1104 $this->set('params', $this->_params
);
1105 if ($this->_paymentProcessor
&&
1106 // Actually we don't really need to check if it supports pre-approval - we could just call
1107 // it regardless as the function we call re-acts tot the rests of the preApproval call.
1108 $this->_paymentProcessor
['object']->supports('preApproval')
1109 && !$this->_allowWaitlist
&&
1110 !$this->_requireApproval
1113 // The concept of contributeMode is deprecated - but still needs removal from the message templates.
1114 $this->set('contributeMode', 'express');
1116 // Send Event Name & Id in Params
1117 $params['eventName'] = $this->_values
['event']['title'];
1118 $params['eventId'] = $this->_values
['event']['id'];
1120 $params['cancelURL'] = CRM_Utils_System
::url('civicrm/event/register',
1121 "_qf_Register_display=1&qfKey={$this->controller->_key}",
1124 if (CRM_Utils_Array
::value('additional_participants', $params, FALSE)) {
1125 $urlArgs = "_qf_Participant_1_display=1&rfp=1&qfKey={$this->controller->_key}";
1128 $urlArgs = "_qf_Confirm_display=1&rfp=1&qfKey={$this->controller->_key}";
1130 $params['returnURL'] = CRM_Utils_System
::url('civicrm/event/register',
1134 $params['invoiceID'] = $invoiceID;
1136 $params['component'] = 'event';
1137 $this->handlePreApproval($params);
1139 elseif ($this->_paymentProcessor
&&
1140 $this->_paymentProcessor
['billing_mode'] & CRM_Core_Payment
::BILLING_MODE_NOTIFY
1142 // The concept of contributeMode is deprecated - but still needs removal from the message templates.
1143 $this->set('contributeMode', 'notify');
1147 $params['description'] = ts('Online Event Registration') . ' ' . $this->_values
['event']['title'];
1149 $this->_params
= array();
1150 $this->_params
[] = $params;
1151 $this->set('params', $this->_params
);
1154 empty($params['additional_participants'])
1155 && !$this->_values
['event']['is_confirm_enabled'] // CRM-11182 - Optional confirmation screen
1157 self
::processRegistration($this->_params
);
1161 // If registering > 1 participant, give status message
1162 if (CRM_Utils_Array
::value('additional_participants', $params, FALSE)) {
1163 $statusMsg = ts('Registration information for participant 1 has been saved.');
1164 CRM_Core_Session
::setStatus($statusMsg, ts('Saved'), 'success');
1169 * Process Registration of free event.
1171 * @param array $params
1173 * @param int $contactID
1175 public function processRegistration($params, $contactID = NULL) {
1176 $session = CRM_Core_Session
::singleton();
1177 $this->_participantInfo
= array();
1179 // CRM-4320, lets build array of cancelled additional participant ids
1180 // those are drop or skip by primary at the time of confirmation.
1181 // get all in and then unset those are confirmed.
1182 $cancelledIds = $this->_additionalParticipantIds
;
1184 $participantCount = array();
1185 foreach ($params as $participantNum => $record) {
1186 if ($record == 'skip') {
1187 $participantCount[$participantNum] = 'skip';
1189 elseif ($participantNum) {
1190 $participantCount[$participantNum] = 'participant';
1194 $registerByID = NULL;
1195 foreach ($params as $key => $value) {
1196 if ($value != 'skip') {
1199 // setting register by Id and unset contactId.
1200 if (empty($value['is_primary'])) {
1202 $registerByID = $this->get('registerByID');
1203 if ($registerByID) {
1204 $value['registered_by_id'] = $registerByID;
1206 // get an email if one exists for the participant
1207 $participantEmail = '';
1208 foreach (array_keys($value) as $valueName) {
1209 if (substr($valueName, 0, 6) == 'email-') {
1210 $participantEmail = $value[$valueName];
1213 if ($participantEmail) {
1214 $this->_participantInfo
[] = $participantEmail;
1217 $this->_participantInfo
[] = $value['first_name'] . ' ' . $value['last_name'];
1220 elseif (!empty($value['contact_id'])) {
1221 $contactID = $value['contact_id'];
1224 $contactID = $this->getContactID();
1227 CRM_Event_Form_Registration_Confirm
::fixLocationFields($value, $fields, $this);
1228 //for free event or additional participant, dont create billing email address.
1229 if (empty($value['is_primary']) ||
!$this->_values
['event']['is_monetary']) {
1230 unset($value["email-{$this->_bltID}"]);
1233 $contactID = CRM_Event_Form_Registration_Confirm
::updateContactFields($contactID, $value, $fields, $this);
1235 // lets store the contactID in the session
1236 // we dont store in userID in case the user is doing multiple
1238 // for things like tell a friend
1239 if (!$this->getContactID() && !empty($value['is_primary'])) {
1240 $session->set('transaction.userID', $contactID);
1243 //lets get the status if require approval or waiting.
1245 $waitingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Waiting'");
1246 if ($this->_allowWaitlist
&& !$this->_allowConfirmation
) {
1247 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
1249 elseif ($this->_requireApproval
&& !$this->_allowConfirmation
) {
1250 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
1253 $this->set('value', $value);
1254 $this->confirmPostProcess($contactID, NULL, NULL);
1256 //lets get additional participant id to cancel.
1257 if ($this->_allowConfirmation
&& is_array($cancelledIds)) {
1258 $additonalId = CRM_Utils_Array
::value('participant_id', $value);
1259 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
1260 unset($cancelledIds[$key]);
1266 // update status and send mail to cancelled additional participants, CRM-4320
1267 if ($this->_allowConfirmation
&& is_array($cancelledIds) && !empty($cancelledIds)) {
1268 $cancelledId = array_search('Cancelled',
1269 CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'")
1271 CRM_Event_BAO_Participant
::transitionParticipants($cancelledIds, $cancelledId);
1274 //set information about additional participants if exists
1275 if (count($this->_participantInfo
)) {
1276 $this->set('participantInfo', $this->_participantInfo
);
1279 //send mail Confirmation/Receipt
1280 if ($this->_contributeMode
!= 'checkout' ||
1281 $this->_contributeMode
!= 'notify'
1284 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
1288 //handle if no additional participant.
1289 if (!$registerByID) {
1290 $registerByID = $this->get('registerByID');
1292 $primaryContactId = $this->get('primaryContactId');
1294 //build an array of custom profile and assigning it to template.
1295 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, NULL,
1296 $primaryContactId, $isTest, TRUE
1299 //lets carry all participant params w/ values.
1300 foreach ($additionalIDs as $participantID => $contactId) {
1301 $participantNum = NULL;
1302 if ($participantID == $registerByID) {
1303 $participantNum = 0;
1306 if ($participantNum = array_search('participant', $participantCount)) {
1307 unset($participantCount[$participantNum]);
1311 if ($participantNum === NULL) {
1315 //carry the participant submitted values.
1316 $this->_values
['params'][$participantID] = $params[$participantNum];
1319 //lets send mails to all with meanigful text, CRM-4320.
1320 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
1321 $this->assign('isRequireApproval', $this->_requireApproval
);
1323 foreach ($additionalIDs as $participantID => $contactId) {
1324 if ($participantID == $registerByID) {
1325 //set as Primary Participant
1326 $this->assign('isPrimary', 1);
1328 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($participantID, $this->_values
, NULL, $isTest);
1330 if (count($customProfile)) {
1331 $this->assign('customProfile', $customProfile);
1332 $this->set('customProfile', $customProfile);
1336 $this->assign('isPrimary', 0);
1337 $this->assign('customProfile', NULL);
1340 //send Confirmation mail to Primary & additional Participants if exists
1341 CRM_Event_BAO_Event
::sendMail($contactId, $this->_values
, $participantID, $isTest);
1347 * Method to check if the user is already registered for the event.
1348 * and if result found redirect to the event info page
1350 * @param array $fields
1351 * The input form values(anonymous user).
1352 * @param CRM_Event_Form_Registration_Register $self
1354 * @param bool $isAdditional
1355 * Treat isAdditional participants a bit differently.
1356 * @param bool $returnContactId
1357 * Just find and return the contactID match to use.
1358 * @param bool $useDedupeRules
1359 * Force usage of dedupe rules.
1363 public static function checkRegistration($fields, &$self, $isAdditional = FALSE, $returnContactId = FALSE, $useDedupeRules = FALSE) {
1364 // CRM-3907, skip check for preview registrations
1365 // CRM-4320 participant need to walk wizard
1366 if (!$returnContactId &&
1367 ($self->_mode
== 'test' ||
$self->_allowConfirmation
)
1373 $session = CRM_Core_Session
::singleton();
1374 if (!$isAdditional) {
1375 $contactID = $self->getContactID();
1378 if (!$contactID && is_array($fields) && $fields) {
1380 //CRM-14134 use Unsupervised rule for everyone
1381 $dedupeParams = CRM_Dedupe_Finder
::formatParams($fields, 'Individual');
1383 // disable permission based on cache since event registration is public page/feature.
1384 $dedupeParams['check_permission'] = FALSE;
1386 // find event dedupe rule
1387 if (CRM_Utils_Array
::value('dedupe_rule_group_id', $self->_values
['event'], 0) > 0) {
1388 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, 'Individual', 'Unsupervised', array(), $self->_values
['event']['dedupe_rule_group_id']);
1391 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, 'Individual', 'Unsupervised');
1393 $contactID = CRM_Utils_Array
::value(0, $ids);
1397 if ($returnContactId) {
1399 // return contactID if contact already exists
1404 $participant = new CRM_Event_BAO_Participant();
1405 $participant->contact_id
= $contactID;
1406 $participant->event_id
= $self->_values
['event']['id'];
1407 if (!empty($fields['participant_role']) && is_numeric($fields['participant_role'])) {
1408 $participant->role_id
= $fields['participant_role'];
1411 $participant->role_id
= $self->_values
['event']['default_role_id'];
1413 $participant->is_test
= 0;
1414 $participant->find();
1415 $statusTypes = CRM_Event_PseudoConstant
::participantStatus(NULL, 'is_counted = 1');
1416 while ($participant->fetch()) {
1417 if (array_key_exists($participant->status_id
, $statusTypes)) {
1418 if (!$isAdditional && !$self->_values
['event']['allow_same_participant_emails']) {
1419 $registerUrl = CRM_Utils_System
::url('civicrm/event/register',
1420 "reset=1&id={$self->_values['event']['id']}&cid=0"
1422 if ($self->_pcpId
) {
1423 $registerUrl .= '&pcpId=' . $self->_pcpId
;
1426 $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 gotten this message in error, please contact the site administrator.") . ' ' . ts('You can also <a href="%1">register another participant</a>.', array(1 => $registerUrl));
1427 $session->setStatus($status, ts('Oops.'), 'alert');
1428 $url = CRM_Utils_System
::url('civicrm/event/info',
1429 "reset=1&id={$self->_values['event']['id']}&noFullMsg=true"
1431 if ($self->_action
& CRM_Core_Action
::PREVIEW
) {
1432 $url .= '&action=preview';
1435 if ($self->_pcpId
) {
1436 $url .= '&pcpId=' . $self->_pcpId
;
1439 CRM_Utils_System
::redirect($url);
1442 if ($isAdditional) {
1443 $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 gotten this message in error, please contact the site administrator.");
1444 $session->setStatus($status, ts('Oops.'), 'alert');
1445 return $participant->id
;