CRM-19649 - Multiple wysiwyg presets
[civicrm-core.git] / CRM / Event / Form / ManageEvent / Registration.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
fa938177 6 | Copyright CiviCRM LLC (c) 2004-2016 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
6a488035 29 * @package CRM
fa938177 30 * @copyright CiviCRM LLC (c) 2004-2016
6a488035
TO
31 */
32
33/**
3bdf1f3a 34 * This class generates form components for processing Event.
6a488035
TO
35 */
36class CRM_Event_Form_ManageEvent_Registration extends CRM_Event_Form_ManageEvent {
37
38 /**
100fef9d 39 * What blocks should we show and hide.
6a488035
TO
40 *
41 * @var CRM_Core_ShowHideBlocks
42 */
43 protected $_showHide;
44
45 protected $_profilePostMultiple = array();
46 protected $_profilePostMultipleAdd = array();
47
48 /**
66f9e52b 49 * Set variables up before form is built.
f55dc004 50 */
00be9182 51 public function preProcess() {
6a488035
TO
52 $this->_addProfileBottom = CRM_Utils_Array::value('addProfileBottom', $_GET, FALSE);
53 $this->_profileBottomNum = CRM_Utils_Array::value('addProfileNum', $_GET, 0);
54 $this->_addProfileBottomAdd = CRM_Utils_Array::value('addProfileBottomAdd', $_GET, FALSE);
55 $this->_profileBottomNumAdd = CRM_Utils_Array::value('addProfileNumAdd', $_GET, 0);
56
57 parent::preProcess();
58
59 $this->assign('addProfileBottom', $this->_addProfileBottom);
60 $this->assign('profileBottomNum', $this->_profileBottomNum);
61
62 $urlParams = "id={$this->_id}&addProfileBottom=1&qfKey={$this->controller->_key}";
63 $this->assign('addProfileParams', $urlParams);
64
65 if ($addProfileBottom = CRM_Utils_Array::value('custom_post_id_multiple', $_POST)) {
66 foreach (array_keys($addProfileBottom) as $profileNum) {
67 self::buildMultipleProfileBottom($this, $profileNum);
68 }
69 }
70
71 $this->assign('addProfileBottomAdd', $this->_addProfileBottomAdd);
72 $this->assign('profileBottomNumAdd', $this->_profileBottomNumAdd);
73
74 $urlParamsAdd = "id={$this->_id}&addProfileBottomAdd=1&qfKey={$this->controller->_key}";
75 $this->assign('addProfileParamsAdd', $urlParamsAdd);
76
77 if ($addProfileBottomAdd = CRM_Utils_Array::value('additional_custom_post_id_multiple', $_POST)) {
78 foreach (array_keys($addProfileBottomAdd) as $profileNum) {
79 self::buildMultipleProfileBottom($this, $profileNum, 'additional_', ts('Profile for Additional Participants'));
80 }
81 }
82 }
83
84 /**
c490a46a 85 * Set default values for the form.
6a488035 86 *
3bdf1f3a 87 * The default values are retrieved from the database.
6a488035 88 */
00be9182 89 public function setDefaultValues() {
6a488035
TO
90 if ($this->_addProfileBottom || $this->_addProfileBottomAdd) {
91 return;
92 }
93 $eventId = $this->_id;
94
95 $defaults = parent::setDefaultValues();
96
97 $this->setShowHide($defaults);
98 if (isset($eventId)) {
99 $params = array('id' => $eventId);
100 CRM_Event_BAO_Event::retrieve($params, $defaults);
101
102 $ufJoinParams = array(
103 'entity_table' => 'civicrm_event',
104 'module' => 'CiviEvent',
105 'entity_id' => $eventId,
106 );
107
108 list($defaults['custom_pre_id'],
109 $defaults['custom_post']
353ffa53 110 ) = CRM_Core_BAO_UFJoin::getUFGroupIds($ufJoinParams);
6a488035
TO
111
112 // Get the id for the event registration profile
113 $eventRegistrationIdParams = $eventRegistrationIdDefaults = array(
114 'name' => 'event_registration',
115 );
116 CRM_Core_BAO_UFGroup::retrieve($eventRegistrationIdParams, $eventRegistrationIdDefaults);
117
118 // Set event registration as the default profile if none selected
119 if (!$defaults['custom_pre_id'] && count($defaults['custom_post']) == 0) {
120 $defaults['custom_pre_id'] = CRM_Utils_Array::value('id', $eventRegistrationIdDefaults);
121 }
122 if (isset($defaults['custom_post']) && is_numeric($defaults['custom_post'])) {
123 $defaults['custom_post_id'] = $defaults['custom_post'];
124 }
125 elseif (!empty($defaults['custom_post'])) {
126 $defaults['custom_post_id'] = $defaults['custom_post'][0];
127 unset($defaults['custom_post'][0]);
128 $this->_profilePostMultiple = $defaults['custom_post'];
129 foreach ($defaults['custom_post'] as $key => $value) {
130 self::buildMultipleProfileBottom($this, $key);
131 $defaults["custom_post_id_multiple[$key]"] = $value;
132 }
133 }
134
135 $this->assign('profilePostMultiple', CRM_Utils_Array::value('custom_post', $defaults));
136
f1bc01e0
J
137 // CRM-17745: Make max additional participants configurable
138 if (empty($defaults['max_additional_participants'])) {
139 $defaults['max_additional_participants'] = 9;
140 }
141
a7488080 142 if (!empty($defaults['is_multiple_registrations'])) {
6a488035
TO
143 // CRM-4377: set additional participants’ profiles – set to ‘none’ if explicitly unset (non-active)
144
145 $ufJoinAddParams = array(
146 'entity_table' => 'civicrm_event',
147 'module' => 'CiviEvent_Additional',
148 'entity_id' => $eventId,
149 );
150
151 list($defaults['additional_custom_pre_id'],
152 $defaults['additional_custom_post']
353ffa53 153 ) = CRM_Core_BAO_UFJoin::getUFGroupIds($ufJoinAddParams);
6a488035
TO
154
155 if (isset($defaults['additional_custom_post']) && is_numeric($defaults['additional_custom_post'])) {
156 $defaults['additional_custom_post_id'] = $defaults['additional_custom_post'];
157 }
158 elseif (!empty($defaults['additional_custom_post'])) {
159 $defaults['additional_custom_post_id'] = $defaults['additional_custom_post'][0];
160 unset($defaults['additional_custom_post'][0]);
161
162 $this->_profilePostMultipleAdd = $defaults['additional_custom_post'];
163 foreach ($defaults['additional_custom_post'] as $key => $value) {
164 self::buildMultipleProfileBottom($this, $key, 'additional_', ts('Profile for Additional Participants'));
165 $defaults["additional_custom_post_id_multiple[$key]"] = $value;
166 }
167 }
168 $this->assign('profilePostMultipleAdd', CRM_Utils_Array::value('additional_custom_post', $defaults));
169 }
170 }
171 else {
172 $defaults['is_email_confirm'] = 0;
173 }
174
175 // provide defaults for required fields if empty (and as a 'hint' for approval message field)
176 $defaults['registration_link_text'] = CRM_Utils_Array::value('registration_link_text', $defaults, ts('Register Now'));
177 $defaults['confirm_title'] = CRM_Utils_Array::value('confirm_title', $defaults, ts('Confirm Your Registration Information'));
178 $defaults['thankyou_title'] = CRM_Utils_Array::value('thankyou_title', $defaults, ts('Thank You for Registering'));
179 $defaults['approval_req_text'] = CRM_Utils_Array::value('approval_req_text', $defaults, ts('Participation in this event requires approval. Submit your registration request here. Once approved, you will receive an email with a link to a web page where you can complete the registration process.'));
180
a7488080 181 if (!empty($defaults['registration_start_date'])) {
006389de
TO
182 list($defaults['registration_start_date'], $defaults['registration_start_date_time'])
183 = CRM_Utils_Date::setDateDefaults($defaults['registration_start_date'], 'activityDateTime');
6a488035
TO
184 }
185
a7488080 186 if (!empty($defaults['registration_end_date'])) {
006389de
TO
187 list($defaults['registration_end_date'], $defaults['registration_end_date_time'])
188 = CRM_Utils_Date::setDateDefaults($defaults['registration_end_date'], 'activityDateTime');
6a488035
TO
189 }
190
191 return $defaults;
192 }
193
194 /**
195 * Fix what blocks to show/hide based on the default values set
196 *
d4dd1e85
TO
197 * @param array $defaults
198 * The array of default values.
77b97be7 199 *
6a488035
TO
200 * @return void
201 */
00be9182 202 public function setShowHide($defaults) {
6a488035
TO
203 $this->_showHide = new CRM_Core_ShowHideBlocks(array('registration' => 1),
204 ''
205 );
206 if (empty($defaults)) {
207 $this->_showHide->addHide('registration');
6a488035
TO
208 $this->_showHide->addHide('id-approval-text');
209 }
210 else {
a7488080 211 if (empty($defaults['requires_approval'])) {
6a488035
TO
212 $this->_showHide->addHide('id-approval-text');
213 }
214 }
215 $this->assign('defaultsEmpty', empty($defaults));
216 $this->_showHide->addToTemplate();
217 }
218
219 /**
66f9e52b 220 * Build the form object.
6a488035 221 *
355ba699 222 * @return void
6a488035
TO
223 */
224 public function buildQuickForm() {
225 if ($this->_addProfileBottom) {
226 return self::buildMultipleProfileBottom($this, $this->_profileBottomNum);
227 }
228
229 if ($this->_addProfileBottomAdd) {
230 return self::buildMultipleProfileBottom($this, $this->_profileBottomNumAdd, 'additional_', ts('Profile for Additional Participants'));
231 }
232
233 $this->applyFilter('__ALL__', 'trim');
234 $attributes = CRM_Core_DAO::getAttribute('CRM_Event_DAO_Event');
235
236 $this->addElement('checkbox',
237 'is_online_registration',
0781df9b 238 ts('Allow Online Registration'),
6a488035
TO
239 NULL,
240 array(
d5cc0fc2 241 'onclick' => "return showHideByValue('is_online_registration'," .
242 "''," .
243 "'registration_blocks'," .
244 "'block'," .
245 "'radio'," .
246 "false );",
6a488035
TO
247 )
248 );
249
250 $this->add('text', 'registration_link_text', ts('Registration Link Text'));
251
252 if (!$this->_isTemplate) {
253 $this->addDateTime('registration_start_date', ts('Registration Start Date'), FALSE, array('formatType' => 'activityDateTime'));
254 $this->addDateTime('registration_end_date', ts('Registration End Date'), FALSE, array('formatType' => 'activityDateTime'));
255 }
256
257 $params = array(
353ffa53 258 'used' => 'Supervised',
6a488035
TO
259 'contact_type' => 'Individual',
260 );
261 $dedupeRuleFields = CRM_Dedupe_BAO_Rule::dedupeRuleFields($params);
262
263 foreach ($dedupeRuleFields as $key => $fields) {
264 $ruleFields[$key] = ucwords(str_replace('_', ' ', $fields));
265 }
266
267 $this->addElement('checkbox',
268 'is_multiple_registrations',
b01353b5 269 ts('Register multiple participants?')
6a488035
TO
270 );
271
f1bc01e0
J
272 // CRM-17745: Make maximum additional participants configurable
273 $numericOptions = CRM_Core_SelectValues::getNumericOptions(1, 9);
274 $this->add('select', 'max_additional_participants', ts('Maximum additional participants'), $numericOptions, FALSE, array('class' => 'required'));
275
6a488035
TO
276 $this->addElement('checkbox',
277 'allow_same_participant_emails',
03390e26 278 ts('Same email address?')
6a488035
TO
279 );
280 $this->assign('ruleFields', json_encode($ruleFields));
281
03390e26 282 $dedupeRules = array(
283 '' => '- Unsupervised rule -',
284 );
285 $dedupeRules += CRM_Dedupe_BAO_RuleGroup::getByType('Individual');
286 $this->add('select', 'dedupe_rule_group_id', ts('Duplicate matching rule'), $dedupeRules);
287
6a488035
TO
288 $participantStatuses = CRM_Event_PseudoConstant::participantStatus();
289 if (in_array('Awaiting approval', $participantStatuses) and in_array('Pending from approval', $participantStatuses) and in_array('Rejected', $participantStatuses)) {
290 $this->addElement('checkbox',
291 'requires_approval',
292 ts('Require participant approval?'),
293 NULL,
294 array('onclick' => "return showHideByValue('requires_approval', '', 'id-approval-text', 'table-row', 'radio', false);")
295 );
296 $this->add('textarea', 'approval_req_text', ts('Approval message'), $attributes['approval_req_text']);
297 }
298
299 $this->add('text', 'expiration_time', ts('Pending participant expiration (hours)'));
300 $this->addRule('expiration_time', ts('Please enter the number of hours (as an integer).'), 'integer');
adaa01fa
DG
301 $this->addField('allow_selfcancelxfer', array('label' => ts('Allow self-service cancellation or transfer?'), 'type' => 'advcheckbox'));
302 $this->add('text', 'selfcancelxfer_time', ts('Cancellation or transfer time limit (hours)'));
97d8187a 303 $this->addRule('selfcancelxfer_time', ts('Please enter the number of hours (as an integer).'), 'integer');
6a488035
TO
304 self::buildRegistrationBlock($this);
305 self::buildConfirmationBlock($this);
306 self::buildMailBlock($this);
307 self::buildThankYouBlock($this);
308
309 parent::buildQuickForm();
310 }
311
312 /**
66f9e52b 313 * Build Registration Block.
6a488035 314 *
c490a46a 315 * @param CRM_Core_Form $form
da6b46f4 316 *
6a488035 317 */
00be9182 318 public function buildRegistrationBlock(&$form) {
7ad5ae6a 319 $attributes = CRM_Core_DAO::getAttribute('CRM_Event_DAO_Event', 'intro_text') + array('class' => 'collapsed', 'preset' => 'civievent');
5d51a2f9
CW
320 $form->add('wysiwyg', 'intro_text', ts('Introductory Text'), $attributes);
321 $form->add('wysiwyg', 'footer_text', ts('Footer Text'), $attributes);
6a488035 322
481a74f4 323 extract(self::getProfileSelectorTypes());
99e239bc 324 //CRM-15427
37375016 325 $form->addProfileSelector('custom_pre_id', ts('Include Profile') . '<br />' . ts('(top of page)'), $allowCoreTypes, $allowSubTypes, $profileEntities, TRUE, $usedFor);
326 $form->addProfileSelector('custom_post_id', ts('Include Profile') . '<br />' . ts('(bottom of page)'), $allowCoreTypes, $allowSubTypes, $profileEntities, TRUE, $usedFor);
6a488035 327
37375016 328 $form->addProfileSelector('additional_custom_pre_id', ts('Profile for Additional Participants') . '<br />' . ts('(top of page)'), $allowCoreTypes, $allowSubTypes, $profileEntities, TRUE, $usedFor);
329 $form->addProfileSelector('additional_custom_post_id', ts('Profile for Additional Participants') . '<br />' . ts('(bottom of page)'), $allowCoreTypes, $allowSubTypes, $profileEntities, TRUE, $usedFor);
6a488035
TO
330 }
331
8e8a3d81 332 /**
66f9e52b 333 * Subroutine to insert a Profile Editor widget.
8e8a3d81 334 * depends on getProfileSelectorTypes
03390e26 335 *
8e8a3d81 336 * @param array &$form
d4dd1e85
TO
337 * @param int $count
338 * Unique index.
339 * @param string $prefix
340 * Dom element ID prefix.
341 * @param string $label
342 * Label.
343 * @param array $configs
344 * Optional, for addProfileSelector(), defaults to using getProfileSelectorTypes().
a130e045 345 */
0479b4c8 346 public function buildMultipleProfileBottom(&$form, $count, $prefix = '', $label = 'Include Profile', $configs = NULL) {
481a74f4 347 extract((is_null($configs)) ? self::getProfileSelectorTypes() : $configs);
518ef837 348 $element = $prefix . "custom_post_id_multiple[$count]";
92fcb95f 349 $label .= '<br />' . ts('(bottom of page)');
37375016 350 $form->addProfileSelector($element, $label, $allowCoreTypes, $allowSubTypes, $profileEntities, TRUE, $usedFor);
518ef837 351 }
352
8e8a3d81 353 /**
66f9e52b 354 * Create initializers for addprofileSelector.
8e8a3d81 355 *
72b3a70c
CW
356 * @return array
357 * ['allowCoreTypes' => array, 'allowSubTypes' => array, 'profileEntities' => array]
a130e045 358 */
00be9182 359 public static function getProfileSelectorTypes() {
518ef837 360 $configs = array(
361 'allowCoreTypes' => array(),
362 'allowSubTypes' => array(),
363 'profileEntities' => array(),
37375016 364 'usedFor' => array(),
6a488035
TO
365 );
366
353ffa53
TO
367 $configs['allowCoreTypes'] = array_merge(array(
368 'Contact',
a130e045 369 'Individual',
353ffa53 370 ), CRM_Contact_BAO_ContactType::subTypes('Individual'));
518ef837 371 $configs['allowCoreTypes'][] = 'Participant';
37375016 372 if (CRM_Core_Permission::check('manage event profiles') && !CRM_Core_Permission::check('administer CiviCRM')) {
373 $configs['usedFor'][] = 'CiviEvent';
374 }
99e239bc 375 //CRM-15427
481a74f4 376 $id = CRM_Utils_Request::retrieve('id', 'Integer');
0b1c947e 377 if ($id) {
efd9f169 378 $participantEventType = CRM_Core_DAO::getFieldValue("CRM_Event_DAO_Event", $id, 'event_type_id', 'id');
353ffa53 379 $participantRole = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $id, 'default_role_id');
efd9f169 380 $configs['allowSubTypes']['ParticipantEventName'] = array($id);
f80ef0e2 381 $configs['allowSubTypes']['ParticipantEventType'] = array($participantEventType);
382 $configs['allowSubTypes']['ParticipantRole'] = array($participantRole);
383 }
529410b5 384 $configs['profileEntities'][] = array('entity_name' => 'contact_1', 'entity_type' => 'IndividualModel');
353ffa53
TO
385 $configs['profileEntities'][] = array(
386 'entity_name' => 'participant_1',
387 'entity_type' => 'ParticipantModel',
a130e045 388 'entity_sub_type' => '*',
353ffa53 389 );
6a488035 390
0479b4c8 391 return $configs;
6a488035
TO
392 }
393
394 /**
66f9e52b 395 * Build Confirmation Block.
6a488035 396 *
c490a46a 397 * @param CRM_Core_Form $form
2a6da8d7 398 *
6a488035 399 */
00be9182 400 public function buildConfirmationBlock(&$form) {
6a488035 401 $attributes = CRM_Core_DAO::getAttribute('CRM_Event_DAO_Event');
d6121d3e 402 // CRM-11182 - Optional confirmation page for free events
403 $is_monetary = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $form->_id, 'is_monetary');
404 $form->assign('is_monetary', $is_monetary);
405 if ($is_monetary == "0") {
406 $form->addYesNo('is_confirm_enabled', ts('Use a confirmation screen?'), NULL, NULL, array('onclick' => "return showHideByValue('is_confirm_enabled','','confirm_screen_settings','block','radio',false);"));
407 }
6a488035 408 $form->add('text', 'confirm_title', ts('Title'), $attributes['confirm_title']);
7ad5ae6a
CW
409 $form->add('wysiwyg', 'confirm_text', ts('Introductory Text'), $attributes['confirm_text'] + array('class' => 'collapsed', 'preset' => 'civievent'));
410 $form->add('wysiwyg', 'confirm_footer_text', ts('Footer Text'), $attributes['confirm_text'] + array('class' => 'collapsed', 'preset' => 'civievent'));
6a488035
TO
411 }
412
413 /**
66f9e52b 414 * Build Email Block.
6a488035 415 *
c490a46a 416 * @param CRM_Core_Form $form
2a6da8d7 417 *
6a488035 418 */
00be9182 419 public function buildMailBlock(&$form) {
6a488035
TO
420 $form->registerRule('emailList', 'callback', 'emailList', 'CRM_Utils_Rule');
421 $attributes = CRM_Core_DAO::getAttribute('CRM_Event_DAO_Event');
422 $form->addYesNo('is_email_confirm', ts('Send Confirmation Email?'), NULL, NULL, array('onclick' => "return showHideByValue('is_email_confirm','','confirmEmail','block','radio',false);"));
423 $form->add('textarea', 'confirm_email_text', ts('Text'), $attributes['confirm_email_text']);
424 $form->add('text', 'cc_confirm', ts('CC Confirmation To'), CRM_Core_DAO::getAttribute('CRM_Event_DAO_Event', 'cc_confirm'));
425 $form->addRule('cc_confirm', ts('Please enter a valid list of comma delimited email addresses'), 'emailList');
426 $form->add('text', 'bcc_confirm', ts('BCC Confirmation To'), CRM_Core_DAO::getAttribute('CRM_Event_DAO_Event', 'bcc_confirm'));
427 $form->addRule('bcc_confirm', ts('Please enter a valid list of comma delimited email addresses'), 'emailList');
428 $form->add('text', 'confirm_from_name', ts('Confirm From Name'));
429 $form->add('text', 'confirm_from_email', ts('Confirm From Email'));
430 $form->addRule('confirm_from_email', ts('Email is not valid.'), 'email');
431 }
432
0cf587a7 433 /**
c490a46a 434 * @param CRM_Core_Form $form
0cf587a7 435 */
00be9182 436 public function buildThankYouBlock(&$form) {
6a488035
TO
437 $attributes = CRM_Core_DAO::getAttribute('CRM_Event_DAO_Event');
438 $form->add('text', 'thankyou_title', ts('Title'), $attributes['thankyou_title']);
7ad5ae6a
CW
439 $form->add('wysiwyg', 'thankyou_text', ts('Introductory Text'), $attributes['thankyou_text'] + array('class' => 'collapsed', 'preset' => 'civievent'));
440 $form->add('wysiwyg', 'thankyou_footer_text', ts('Footer Text'), $attributes['thankyou_text'] + array('class' => 'collapsed', 'preset' => 'civievent'));
6a488035
TO
441 }
442
443 /**
66f9e52b 444 * Add local and global form rules.
6a488035 445 *
6a488035
TO
446 *
447 * @return void
448 */
00be9182 449 public function addRules() {
6a488035
TO
450 if ($this->_addProfileBottom || $this->_addProfileBottomAdd) {
451 return;
452 }
453 $this->addFormRule(array('CRM_Event_Form_ManageEvent_Registration', 'formRule'), $this);
454 }
455
456 /**
66f9e52b 457 * Global validation rules for the form.
6a488035 458 *
c490a46a 459 * @param array $values
2a6da8d7 460 * @param $files
c490a46a 461 * @param CRM_Core_Form $form
6a488035 462 *
a6c01b45
CW
463 * @return array
464 * list of errors to be posted back to the form
6a488035 465 */
00be9182 466 public static function formRule($values, $files, $form) {
a7488080 467 if (!empty($values['is_online_registration'])) {
6a488035
TO
468
469 if (!$values['confirm_title']) {
470 $errorMsg['confirm_title'] = ts('Please enter a Title for the registration Confirmation Page');
471 }
472 if (!$values['thankyou_title']) {
473 $errorMsg['thankyou_title'] = ts('Please enter a Title for the registration Thank-you Page');
474 }
475 if ($values['is_email_confirm']) {
476 if (!$values['confirm_from_name']) {
477 $errorMsg['confirm_from_name'] = ts('Please enter Confirmation Email FROM Name.');
478 }
479
480 if (!$values['confirm_from_email']) {
481 $errorMsg['confirm_from_email'] = ts('Please enter Confirmation Email FROM Email Address.');
482 }
483 }
f55dc004 484
ef597b45
DL
485 if (
486 isset($values['registration_start_date']) &&
487 isset($values['registration_end_date'])
488 ) {
6a488035 489 $start = CRM_Utils_Date::processDate($values['registration_start_date']);
353ffa53 490 $end = CRM_Utils_Date::processDate($values['registration_end_date']);
6a488035
TO
491 if ($end < $start) {
492 $errorMsg['registration_end_date'] = ts('Registration end date should be after Registration start date');
493 }
494 }
495
496 //check that the selected profiles have either firstname+lastname or email required
497 $profileIds = array(
498 CRM_Utils_Array::value('custom_pre_id', $values),
499 CRM_Utils_Array::value('custom_post_id', $values),
500 );
501 $additionalProfileIds = array(
502 CRM_Utils_Array::value('additional_custom_pre_id', $values),
503 CRM_Utils_Array::value('additional_custom_post_id', $values),
504 );
505 //additional profile fields default to main if not set
506 if (!is_numeric($additionalProfileIds[0])) {
507 $additionalProfileIds[0] = $profileIds[0];
508 }
509 if (!is_numeric($additionalProfileIds[1])) {
510 $additionalProfileIds[1] = $profileIds[1];
511 }
512 //add multiple profiles if set
513 self::addMultipleProfiles($profileIds, $values, 'custom_post_id_multiple');
514 self::addMultipleProfiles($additionalProfileIds, $values, 'additional_custom_post_id_multiple');
515 $isProfileComplete = self::isProfileComplete($profileIds);
516 $isAdditionalProfileComplete = self::isProfileComplete($additionalProfileIds);
03390e26 517
6a488035
TO
518 //Check main profiles have an email address available if 'send confirmation email' is selected
519 if ($values['is_email_confirm']) {
520 $emailFields = self::getEmailFields($profileIds);
521 if (!count($emailFields)) {
522 $errorMsg['is_email_confirm'] = ts("Please add a profile with an email address if 'Send Confirmation Email?' is selected");
523 }
524 }
525 $additionalCustomPreId = $additionalCustomPostId = NULL;
526 $isPreError = $isPostError = TRUE;
8cc574cf 527 if (!empty($values['allow_same_participant_emails']) && !empty($values['is_multiple_registrations'])) {
6a488035
TO
528 $types = array_merge(array('Individual'), CRM_Contact_BAO_ContactType::subTypes('Individual'));
529 $profiles = CRM_Core_BAO_UFGroup::getProfiles($types);
530
531 //check for additional custom pre profile
532 $additionalCustomPreId = CRM_Utils_Array::value('additional_custom_pre_id', $values);
533 if (!empty($additionalCustomPreId)) {
534 if (!($additionalCustomPreId == 'none')) {
535 $customPreId = $additionalCustomPreId;
536 }
537 else {
538 $isPreError = FALSE;
539 }
540 }
541 else {
0d8afee2 542 $customPreId = !empty($values['custom_pre_id']) ? $values['custom_pre_id'] : NULL;
6a488035
TO
543 }
544 //check whether the additional custom pre profile is of type 'Individual' and its subtypes
545 if (!empty($customPreId)) {
546 $profileTypes = CRM_Core_BAO_UFGroup::profileGroups($customPreId);
547 foreach ($types as $individualTypes) {
548 if (in_array($individualTypes, $profileTypes)) {
549 $isPreError = FALSE;
550 break;
551 }
552 }
553 }
554 else {
555 $isPreError = FALSE;
556 }
f55dc004 557
dbeb7efb
DG
558 // We don't have required Individual fields in the pre-custom profile, so now check the post-custom profile
559 if ($isPreError) {
560 $additionalCustomPostId = CRM_Utils_Array::value('additional_custom_post_id', $values);
561 if (!empty($additionalCustomPostId)) {
562 if (!($additionalCustomPostId == 'none')) {
563 $customPostId = $additionalCustomPostId;
564 }
565 else {
566 $isPostError = FALSE;
567 }
6a488035
TO
568 }
569 else {
0d8afee2 570 $customPostId = !empty($values['custom_post_id']) ? $values['custom_post_id'] : NULL;
6a488035 571 }
dbeb7efb
DG
572 //check whether the additional custom post profile is of type 'Individual' and its subtypes
573 if (!empty($customPostId)) {
574 $profileTypes = CRM_Core_BAO_UFGroup::profileGroups($customPostId);
575 foreach ($types as $individualTypes) {
576 if (in_array($individualTypes, $profileTypes)) {
577 $isPostError = FALSE;
578 break;
579 }
6a488035
TO
580 }
581 }
dbeb7efb
DG
582 else {
583 $isPostError = FALSE;
584 }
585
586 if (empty($customPreId) && empty($customPostId)) {
587 $errorMsg['additional_custom_pre_id'] = ts("Allow multiple registrations from the same email address requires a profile of type 'Individual'");
588 }
589 if ($isPostError) {
590 $errorMsg['additional_custom_post_id'] = ts("Allow multiple registrations from the same email address requires a profile of type 'Individual'");
591 }
6a488035
TO
592 }
593 }
594 if (!$isProfileComplete) {
595 $errorMsg['custom_pre_id'] = ts("Please include a Profile for online registration that contains an Email Address field and / or First Name + Last Name fields.");
596 }
597 if (!$isAdditionalProfileComplete) {
598 $errorMsg['additional_custom_pre_id'] = ts("Please include a Profile for online registration of additional participants that contains an Email Address field and / or First Name + Last Name fields.");
599 }
600
601 // // CRM-8485
602 // $config = CRM_Core_Config::singleton();
603 // if ( $config->doNotAttachPDFReceipt ) {
a7488080 604 // if (!empty($values['custom_post_id_multiple'])) {
6a488035
TO
605 // foreach( $values['custom_post_id_multiple'] as $count => $customPostMultiple ) {
606 // if ( $customPostMultiple ) {
607 // $errorMsg["custom_post_id_multiple[{$count}]"] = ts('Please disable PDF receipt as an attachment in <a href="%1">Miscellaneous Settings</a> if you want to add additional profiles.', array( 1 => CRM_Utils_System::url( 'civicrm/admin/setting/misc', 'reset=1' ) ) );
608 // break;
609 // }
610 // }
611 // }
612 //
a7488080 613 // if (!empty($values['is_multiple_registrations']) &&
6a488035
TO
614 // CRM_Utils_Array::value('additional_custom_post_id_multiple', $values) ) {
615 // foreach( $values['additional_custom_post_id_multiple'] as $count => $customPostMultiple ) {
616 // if ( $customPostMultiple ) {
617 // $errorMsg["additional_custom_post_id_multiple[{$count}]"] = ts('Please disable PDF receipt as an attachment in <a href="%1">Miscellaneous Settings</a> if you want to add additional profiles.', array( 1 => CRM_Utils_System::url( 'civicrm/admin/setting/misc', 'reset=1' ) ) );
618 // break;
619 // }
620 // }
621 // }
622 // }
623
624 if (!empty($errorMsg)) {
a7488080 625 if (!empty($values['custom_post_id_multiple'])) {
6a488035
TO
626 foreach ($values['custom_post_id_multiple'] as $count => $customPostMultiple) {
627 self::buildMultipleProfileBottom($form, $count);
628 }
629 $form->assign('profilePostMultiple', $values['custom_post_id_multiple']);
630 }
a7488080 631 if (!empty($values['additional_custom_post_id_multiple'])) {
6a488035
TO
632 foreach ($values['additional_custom_post_id_multiple'] as $count => $customPostMultiple) {
633 self::buildMultipleProfileBottom($form, $count, 'additional_', ts('Profile for Additional Participants'));
634 }
635 $form->assign('profilePostMultipleAdd', $values['additional_custom_post_id_multiple']);
636 }
637 }
638 }
639
640 if (!empty($errorMsg)) {
641 return $errorMsg;
642 }
643
644 return TRUE;
645 }
646
647 /**
66f9e52b 648 * Collect all email fields for an array of profile ids.
6a488035 649 *
2a6da8d7 650 * @param $profileIds
a130e045 651 * @return bool
6a488035 652 */
00be9182 653 public static function getEmailFields($profileIds) {
6a488035
TO
654 $emailFields = array();
655 foreach ($profileIds as $profileId) {
656 if ($profileId && is_numeric($profileId)) {
657 $fields = CRM_Core_BAO_UFGroup::getFields($profileId);
658 foreach ($fields as $field) {
659 if (substr_count($field['name'], 'email')) {
660 $emailFields[] = $field;
661 }
662 }
663 }
664 }
665 return $emailFields;
666 }
667
668 /**
66f9e52b 669 * Check if a profile contains required fields.
6a488035 670 *
2a6da8d7 671 * @param $profileIds
a130e045 672 * @return bool
6a488035 673 */
00be9182 674 public static function isProfileComplete($profileIds) {
6a488035
TO
675 $profileReqFields = array();
676 foreach ($profileIds as $profileId) {
677 if ($profileId && is_numeric($profileId)) {
678 $fields = CRM_Core_BAO_UFGroup::getFields($profileId);
679 foreach ($fields as $field) {
680 switch (TRUE) {
681 case substr_count($field['name'], 'email'):
682 $profileReqFields[] = 'email';
683 break;
684
685 case substr_count($field['name'], 'first_name'):
686 $profileReqFields[] = 'first_name';
687 break;
688
689 case substr_count($field['name'], 'last_name'):
690 $profileReqFields[] = 'last_name';
691 break;
692 }
693 }
694 }
695 }
696 $profileComplete = (in_array('email', $profileReqFields)
697 || (in_array('first_name', $profileReqFields) && in_array('last_name', $profileReqFields))
698 );
699 return $profileComplete;
700 }
701
03390e26 702 /**
66f9e52b 703 * Check if the profiles collect enough information to dedupe.
03390e26 704 *
2a6da8d7
EM
705 * @param $profileIds
706 * @param int $rgId
a130e045 707 * @return bool
03390e26 708 */
60fbd968 709 public static function canProfilesDedupe($profileIds, $rgId = 0) {
03390e26 710 // find the unsupervised rule
03390e26 711 $rgParams = array(
712 'used' => 'Unsupervised',
713 'contact_type' => 'Individual',
714 );
715 if ($rgId > 0) {
716 $rgParams['id'] = $rgId;
717 }
718 $activeRg = CRM_Dedupe_BAO_RuleGroup::dedupeRuleFieldsWeight($rgParams);
719
720 // get the combinations that could be a match for the rule
721 $okCombos = $combos = array();
722 CRM_Dedupe_BAO_RuleGroup::combos($activeRg[0], $activeRg[1], $combos);
723
724 // create an index of what combinations involve each field
725 $index = array();
726 foreach ($combos as $comboid => $combo) {
727 foreach ($combo as $cfield) {
0479b4c8 728 $index[$cfield][$comboid] = TRUE;
03390e26 729 }
730 $combos[$comboid] = array_fill_keys($combo, 0);
731 $okCombos[$comboid] = array_fill_keys($combo, 2);
732 }
733
734 // get profiles and see if they have the necessary combos
735 $profileReqFields = array();
736 foreach ($profileIds as $profileId) {
737 if ($profileId && is_numeric($profileId)) {
738 $fields = CRM_Core_BAO_UFGroup::getFields($profileId);
739
740 // walk through the fields in the profile
741 foreach ($fields as $field) {
742
743 // check each of the fields in the index against the profile field
744 foreach ($index as $ifield => $icombos) {
22e263ad 745 if (strpos($field['name'], $ifield) !== FALSE) {
03390e26 746
747 // we found the field in the profile, now record it in the index
748 foreach ($icombos as $icombo => $dontcare) {
749 $combos[$icombo][$ifield] = ($combos[$icombo][$ifield] != 2 && !$field['is_required']) ? 1 : 2;
750
751 if ($combos[$icombo] == $okCombos[$icombo]) {
752 // if any combo is complete with 2s (all fields are present and required), we can go home
753 return 2;
754 }
755 }
756 }
757 }
758 }
759 }
760 }
761
762 // check the combos to see if everything is > 0
763 foreach ($combos as $comboid => $combo) {
0479b4c8 764 $complete = FALSE;
03390e26 765 foreach ($combo as $cfield) {
766 if ($cfield > 0) {
0479b4c8 767 $complete = TRUE;
03390e26 768 }
769 else {
770 // this combo isn't complete--skip to the next combo
771 continue 2;
772 }
773 }
4f99ca55
TO
774 if ($complete) {
775 return 1;
0479b4c8 776 }
03390e26 777 }
778
779 // no combo succeeded
780 return 0;
781 }
782
6a488035
TO
783 /**
784 * Add additional profiles from the form to an array of profile ids.
ad37ac8e 785 *
786 * @param array $profileIds
787 * @param array $values
788 * @param string $field
6a488035 789 */
00be9182 790 public static function addMultipleProfiles(&$profileIds, $values, $field) {
6a488035
TO
791 if ($multipleProfiles = CRM_Utils_Array::value($field, $values)) {
792 foreach ($multipleProfiles as $profileId) {
793 $profileIds[] = $profileId;
794 }
795 }
796 }
797
798 /**
66f9e52b 799 * Process the form submission.
6a488035 800 *
6a488035 801 *
355ba699 802 * @return void
6a488035
TO
803 */
804 public function postProcess() {
6a488035
TO
805 $params = $this->exportValues();
806
807 $params['id'] = $this->_id;
808
1909126f 809 // format params
6a488035 810 $params['is_online_registration'] = CRM_Utils_Array::value('is_online_registration', $params, FALSE);
1909126f 811 $params['is_confirm_enabled'] = CRM_Utils_Array::value('is_confirm_enabled', $params, FALSE); // CRM-11182
6a488035
TO
812 $params['is_multiple_registrations'] = CRM_Utils_Array::value('is_multiple_registrations', $params, FALSE);
813 $params['allow_same_participant_emails'] = CRM_Utils_Array::value('allow_same_participant_emails', $params, FALSE);
814 $params['requires_approval'] = CRM_Utils_Array::value('requires_approval', $params, FALSE);
815
816 // reset is_email confirm if not online reg
817 if (!$params['is_online_registration']) {
818 $params['is_email_confirm'] = FALSE;
819 }
4abc4ee1 820 if (!empty($params['allow_selfcancelxfer'])) {
821 $params['selfcancelxfer_time'] = !empty($params['selfcancelxfer_time']) ? $params['selfcancelxfer_time'] : 0;
822 }
6a488035
TO
823
824 if (!$this->_isTemplate) {
825 $params['registration_start_date'] = CRM_Utils_Date::processDate($params['registration_start_date'],
826 $params['registration_start_date_time'],
827 TRUE
828 );
829 $params['registration_end_date'] = CRM_Utils_Date::processDate($params['registration_end_date'],
830 $params['registration_end_date_time'],
831 TRUE
832 );
833 }
834
835 CRM_Event_BAO_Event::add($params);
836
837 // also update the ProfileModule tables
838 $ufJoinParams = array(
839 'is_active' => 1,
840 'module' => 'CiviEvent',
841 'entity_table' => 'civicrm_event',
842 'entity_id' => $this->_id,
843 );
844
6a488035
TO
845 // first delete all past entries
846 CRM_Core_BAO_UFJoin::deleteAll($ufJoinParams);
847
848 $uf = array();
849 $wt = 2;
850 if (!empty($params['custom_pre_id'])) {
851 $uf[1] = $params['custom_pre_id'];
852 $wt = 1;
853 }
854
855 if (!empty($params['custom_post_id'])) {
856 $uf[2] = $params['custom_post_id'];
857 }
858
a7488080 859 if (!empty($params['custom_post_id_multiple'])) {
6a488035
TO
860 $uf = array_merge($uf, $params['custom_post_id_multiple']);
861 }
862 $uf = array_values($uf);
863 if (!empty($uf)) {
864 foreach ($uf as $weight => $ufGroupId) {
865 $ufJoinParams['weight'] = $weight + $wt;
866 $ufJoinParams['uf_group_id'] = $ufGroupId;
867 CRM_Core_BAO_UFJoin::create($ufJoinParams);
868 unset($ufJoinParams['id']);
869 }
870 }
871 // also update the ProfileModule tables
872 $ufJoinParamsAdd = array(
873 'is_active' => 1,
874 'module' => 'CiviEvent_Additional',
875 'entity_table' => 'civicrm_event',
876 'entity_id' => $this->_id,
877 );
878
879 // first delete all past entries
880 CRM_Core_BAO_UFJoin::deleteAll($ufJoinParamsAdd);
a7488080 881 if (!empty($params['is_multiple_registrations'])) {
6a488035
TO
882 $ufAdd = array();
883 $wtAdd = 2;
884
885 if (array_key_exists('additional_custom_pre_id', $params)) {
a7488080 886 if (empty($params['additional_custom_pre_id'])) {
6a488035
TO
887 $ufAdd[1] = $params['custom_pre_id'];
888 $wtAdd = 1;
889 }
353ffa53
TO
890 elseif (CRM_Utils_Array::value('additional_custom_pre_id', $params) == 'none') {
891 }
6a488035
TO
892 else {
893 $ufAdd[1] = $params['additional_custom_pre_id'];
894 $wtAdd = 1;
895 }
896 }
897
898 if (array_key_exists('additional_custom_post_id', $params)) {
a7488080 899 if (empty($params['additional_custom_post_id'])) {
6a488035
TO
900 $ufAdd[2] = $params['custom_post_id'];
901 }
353ffa53
TO
902 elseif (CRM_Utils_Array::value('additional_custom_post_id', $params) == 'none') {
903 }
6a488035
TO
904 else {
905 $ufAdd[2] = $params['additional_custom_post_id'];
906 }
907 }
908
a7488080 909 if (!empty($params['additional_custom_post_id_multiple'])) {
6a488035
TO
910 $additionalPostMultiple = array();
911 foreach ($params['additional_custom_post_id_multiple'] as $key => $value) {
85944a4e 912 if (is_null($value) && !empty($params['custom_post_id'])) {
6a488035
TO
913 $additionalPostMultiple[$key] = $params['custom_post_id'];
914 }
915 elseif ($value == 'none') {
916 continue;
917 }
918 elseif ($value) {
919 $additionalPostMultiple[$key] = $value;
920 }
921 }
922 $ufAdd = array_merge($ufAdd, $additionalPostMultiple);
923 }
924
925 $ufAdd = array_values($ufAdd);
926 if (!empty($ufAdd)) {
927 foreach ($ufAdd as $weightAdd => $ufGroupIdAdd) {
928
929 $ufJoinParamsAdd['weight'] = $weightAdd + $wtAdd;
930 $ufJoinParamsAdd['uf_group_id'] = $ufGroupIdAdd;
931
932 CRM_Core_BAO_UFJoin::create($ufJoinParamsAdd);
933 unset($ufJoinParamsAdd['id']);
934 }
935 }
936 }
937
03390e26 938 // get the profiles to evaluate what they collect
939 $profileIds = array(
940 CRM_Utils_Array::value('custom_pre_id', $params),
941 CRM_Utils_Array::value('custom_post_id', $params),
942 );
943 $additionalProfileIds = array(
944 CRM_Utils_Array::value('additional_custom_pre_id', $params),
945 CRM_Utils_Array::value('additional_custom_post_id', $params),
946 );
947 // additional profile fields default to main if not set
948 if (!is_numeric($additionalProfileIds[0])) {
949 $additionalProfileIds[0] = $profileIds[0];
950 }
951 if (!is_numeric($additionalProfileIds[1])) {
952 $additionalProfileIds[1] = $profileIds[1];
953 }
954 //add multiple profiles if set
955 self::addMultipleProfiles($profileIds, $params, 'custom_post_id_multiple');
956 self::addMultipleProfiles($additionalProfileIds, $params, 'additional_custom_post_id_multiple');
957
0479b4c8 958 $cantDedupe = FALSE;
03390e26 959 $rgId = CRM_Utils_Array::value('dedupe_rule_group_id', $params, 0);
960
961 switch (self::canProfilesDedupe($profileIds, $rgId)) {
962 case 0:
963 $dedupeTitle = 'Duplicate Matching Impossible';
964 $cantDedupe = ts("The selected profiles do not contain the fields necessary to match registrations with existing contacts. This means all anonymous registrations will result in a new contact.");
965 break;
0479b4c8 966
03390e26 967 case 1:
968 $dedupeTitle = 'Duplicate Contacts Possible';
969 $cantDedupe = ts("The selected profiles can collect enough information to match registrations with existing contacts, but not all of the relevant fields are required. Anonymous registrations may result in duplicate contacts.");
970 }
971 if (!empty($params['is_multiple_registrations'])) {
22e263ad 972 switch (self::canProfilesDedupe($additionalProfileIds, $rgId)) {
03390e26 973 case 0:
974 $dedupeTitle = 'Duplicate Matching Impossible';
975 if ($cantDedupe) {
976 $cantDedupe = ts("The selected profiles do not contain the fields necessary to match registrations with existing contacts. This means all anonymous registrations will result in a new contact.");
977 }
978 else {
979 $cantDedupe = ts("The selected profiles do not contain the fields necessary to match additional participants with existing contacts. This means all additional participants will result in a new contact.");
980 }
981 break;
0479b4c8 982
03390e26 983 case 1:
984 if (!$cantDedupe) {
985 $dedupeTitle = 'Duplicate Contacts Possible';
986 $cantDedupe = ts("The selected profiles can collect enough information to match additional participants with existing contacts, but not all of the relevant fields are required. This may result in duplicate contacts.");
987 }
988 }
989 }
990 if ($cantDedupe) {
991 CRM_Core_Session::setStatus($cantDedupe, $dedupeTitle, 'alert dedupenotify', array('expires' => 0));
992 }
993
5d92a7e7
CW
994 // Update tab "disabled" css class
995 $this->ajaxResponse['tabValid'] = !empty($params['is_online_registration']);
996
6a488035
TO
997 parent::endPostProcess();
998 }
6a488035
TO
999
1000 /**
1001 * Return a descriptive name for the page, used in wizard header
1002 *
1003 * @return string
6a488035
TO
1004 */
1005 public function getTitle() {
1006 return ts('Online Registration');
1007 }
96025800 1008
6a488035 1009}