INFRA-132 - Remove @static annotation
[civicrm-core.git] / CRM / Custom / Form / Option.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2014
32 * $Id$
33 *
34 */
35
36 /**
37 * form to process actions on the field aspect of Custom
38 */
39 class CRM_Custom_Form_Option extends CRM_Core_Form {
40
41 /**
42 * The custom field id saved to the session for an update
43 *
44 * @var int
45 */
46 protected $_fid;
47
48 /**
49 * The custom group id saved to the session for an update
50 *
51 * @var int
52 */
53 protected $_gid;
54
55 /**
56 * The option group ID
57 */
58 protected $_optionGroupID = NULL;
59
60 /**
61 * The Option id, used when editing the Option
62 *
63 * @var int
64 */
65 protected $_id;
66
67 /**
68 * Set variables up before form is built
69 *
70 * @param null
71 *
72 * @return void
73 */
74 public function preProcess() {
75 $this->_fid = CRM_Utils_Request::retrieve('fid', 'Positive', $this);
76
77 $this->_gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this);
78
79 if (!isset($this->_gid) && $this->_fid) {
80 $this->_gid = CRM_Core_DAO::getFieldValue(
81 'CRM_Core_DAO_CustomField',
82 $this->_fid,
83 'custom_group_id'
84 );
85 }
86
87 if ($this->_fid) {
88 $this->_optionGroupID = CRM_Core_DAO::getFieldValue(
89 'CRM_Core_DAO_CustomField',
90 $this->_fid,
91 'option_group_id'
92 );
93 }
94
95 if ($isReserved = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $this->_gid, 'is_reserved', 'id')) {
96 CRM_Core_Error::fatal("You cannot add or edit muliple choice options in a reserved custom field-set.");
97 }
98
99 $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this);
100 }
101
102 /**
103 * Set default values for the form. Note that in edit/view mode
104 * the default values are retrieved from the database
105 *
106 * @param null
107 *
108 * @return array
109 * array of default values
110 */
111 public function setDefaultValues() {
112 $defaults = $fieldDefaults = array();
113 if (isset($this->_id)) {
114 $params = array('id' => $this->_id);
115 CRM_Core_BAO_CustomOption::retrieve($params, $defaults);
116
117 $paramsField = array('id' => $this->_fid);
118 CRM_Core_BAO_CustomField::retrieve($paramsField, $fieldDefaults);
119
120 if ($fieldDefaults['html_type'] == 'CheckBox'
121 || $fieldDefaults['html_type'] == 'Multi-Select'
122 || $fieldDefaults['html_type'] == 'AdvMulti-Select'
123 ) {
124 if (!empty($fieldDefaults['default_value'])) {
125 $defaultCheckValues = explode(CRM_Core_DAO::VALUE_SEPARATOR,
126 substr($fieldDefaults['default_value'], 1, -1)
127 );
128 if (in_array($defaults['value'], $defaultCheckValues)) {
129 $defaults['default_value'] = 1;
130 }
131 }
132 }
133 else {
134 if (CRM_Utils_Array::value('default_value', $fieldDefaults) == CRM_Utils_Array::value('value', $defaults)) {
135 $defaults['default_value'] = 1;
136 }
137 }
138 }
139 else {
140 $defaults['is_active'] = 1;
141 }
142
143 if ($this->_action & CRM_Core_Action::ADD) {
144 $fieldValues = array('option_group_id' => $this->_optionGroupID);
145 $defaults['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Core_DAO_OptionValue', $fieldValues);
146 }
147
148 return $defaults;
149 }
150
151 /**
152 * Build the form object
153 *
154 * @param null
155 *
156 * @return void
157 */
158 public function buildQuickForm() {
159 if ($this->_action == CRM_Core_Action::DELETE) {
160 $option = civicrm_api3('option_value', 'getsingle', array('id' => $this->_id));
161 $this->assign('label', $option['label']);
162 $this->addButtons(array(
163 array(
164 'type' => 'next',
165 'name' => ts('Delete'),
166 'isDefault' => TRUE,
167 ),
168 array(
169 'type' => 'cancel',
170 'name' => ts('Cancel'),
171 ),
172 )
173 );
174 }
175 else {
176 // lets trim all the whitespace
177 $this->applyFilter('__ALL__', 'trim');
178
179 // hidden Option Id for validation use
180 $this->add('hidden', 'optionId', $this->_id);
181
182 //hidden field ID for validation use
183 $this->add('hidden', 'fieldId', $this->_fid);
184
185 // label
186 $this->add('text', 'label', ts('Option Label'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'label'), TRUE);
187
188 $this->add('text', 'value', ts('Option Value'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'value'), TRUE);
189
190 // weight
191 $this->add('text', 'weight', ts('Order'), CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'weight'), TRUE);
192 $this->addRule('weight', ts('is a numeric field'), 'numeric');
193
194 // is active ?
195 $this->add('checkbox', 'is_active', ts('Active?'));
196
197 // Set the default value for Custom Field
198 $this->add('checkbox', 'default_value', ts('Default'));
199
200 // add a custom form rule
201 $this->addFormRule(array('CRM_Custom_Form_Option', 'formRule'), $this);
202
203 // add buttons
204 $this->addButtons(array(
205 array(
206 'type' => 'next',
207 'name' => ts('Save'),
208 'isDefault' => TRUE,
209 ),
210 array(
211 'type' => 'next',
212 'name' => ts('Save and New'),
213 'subName' => 'new',
214 ),
215 array(
216 'type' => 'cancel',
217 'name' => ts('Cancel'),
218 ),
219 )
220 );
221
222 // if view mode pls freeze it with the done button.
223 if ($this->_action & CRM_Core_Action::VIEW) {
224 $this->freeze();
225 $url = CRM_Utils_System::url('civicrm/admin/custom/group/field/option',
226 'reset=1&action=browse&fid=' . $this->_fid . '&gid=' . $this->_gid,
227 TRUE, NULL, FALSE
228 );
229 $this->addElement('button',
230 'done',
231 ts('Done'),
232 array('onclick' => "location.href='$url'", 'class' => 'crm-form-submit')
233 );
234 }
235 }
236 $this->assign('id', $this->_id);
237 }
238
239 /**
240 * Global validation rules for the form
241 *
242 * @param array $fields
243 * Posted values of the form.
244 *
245 * @param $files
246 * @param CRM_Core_Form $form
247 *
248 * @return array
249 * list of errors to be posted back to the form
250 */
251 public static function formRule($fields, $files, $form) {
252 $optionLabel = $fields['label'];
253 $optionValue = $fields['value'];
254 $fieldId = $form->_fid;
255 $optionGroupId = $form->_optionGroupID;
256
257 $temp = array();
258 if (empty($form->_id)) {
259 $query = "
260 SELECT count(*)
261 FROM civicrm_option_value
262 WHERE option_group_id = %1
263 AND label = %2";
264 $params = array(
265 1 => array($optionGroupId, 'Integer'),
266 2 => array($optionLabel, 'String'),
267 );
268 if (CRM_Core_DAO::singleValueQuery($query, $params) > 0) {
269 $errors['label'] = ts('There is an entry with the same label.');
270 }
271
272 $query = "
273 SELECT count(*)
274 FROM civicrm_option_value
275 WHERE option_group_id = %1
276 AND value = %2";
277 $params = array(
278 1 => array($optionGroupId, 'Integer'),
279 2 => array($optionValue, 'String'),
280 );
281 if (CRM_Core_DAO::singleValueQuery($query, $params) > 0) {
282 $errors['value'] = ts('There is an entry with the same value.');
283 }
284 }
285 else {
286 //capture duplicate entries while updating Custom Options
287 $optionId = CRM_Utils_Type::escape($fields['optionId'], 'Integer');
288
289 //check label duplicates within a custom field
290 $query = "
291 SELECT count(*)
292 FROM civicrm_option_value
293 WHERE option_group_id = %1
294 AND id != %2
295 AND label = %3";
296 $params = array(
297 1 => array($optionGroupId, 'Integer'),
298 2 => array($optionId, 'Integer'),
299 3 => array($optionLabel, 'String'),
300 );
301 if (CRM_Core_DAO::singleValueQuery($query, $params) > 0) {
302 $errors['label'] = ts('There is an entry with the same label.');
303 }
304
305 //check value duplicates within a custom field
306 $query = "
307 SELECT count(*)
308 FROM civicrm_option_value
309 WHERE option_group_id = %1
310 AND id != %2
311 AND value = %3";
312 $params = array(
313 1 => array($optionGroupId, 'Integer'),
314 2 => array($optionId, 'Integer'),
315 3 => array($optionValue, 'String'),
316 );
317 if (CRM_Core_DAO::singleValueQuery($query, $params) > 0) {
318 $errors['value'] = ts('There is an entry with the same value.');
319 }
320 }
321
322 $query = "
323 SELECT data_type
324 FROM civicrm_custom_field
325 WHERE id = %1";
326 $params = array(1 => array($fieldId, 'Integer'));
327 $dao = CRM_Core_DAO::executeQuery($query, $params);
328 if ($dao->fetch()) {
329 switch ($dao->data_type) {
330 case 'Int':
331 if (!CRM_Utils_Rule::integer($fields["value"])) {
332 $errors['value'] = ts('Please enter a valid integer value.');
333 }
334 break;
335
336 case 'Float':
337 // case 'Money':
338 if (!CRM_Utils_Rule::numeric($fields["value"])) {
339 $errors['value'] = ts('Please enter a valid number.');
340 }
341 break;
342
343 case 'Money':
344 if (!CRM_Utils_Rule::money($fields["value"])) {
345 $errors['value'] = ts('Please enter a valid value.');
346 }
347 break;
348
349 case 'Date':
350 if (!CRM_Utils_Rule::date($fields["value"])) {
351 $errors['value'] = ts('Please enter a valid date using YYYY-MM-DD format. Example: 2004-12-31.');
352 }
353 break;
354
355 case 'Boolean':
356 if (!CRM_Utils_Rule::integer($fields["value"]) &&
357 ($fields["value"] != '1' || $fields["value"] != '0')
358 ) {
359 $errors['value'] = ts('Please enter 1 or 0 as value.');
360 }
361 break;
362
363 case 'Country':
364 if (!empty($fields["value"])) {
365 $params = array(1 => array($fields['value'], 'String'));
366 $query = "SELECT count(*) FROM civicrm_country WHERE name = %1 OR iso_code = %1";
367 if (CRM_Core_DAO::singleValueQuery($query, $params) <= 0) {
368 $errors['value'] = ts('Invalid default value for country.');
369 }
370 }
371 break;
372
373 case 'StateProvince':
374 if (!empty($fields["value"])) {
375 $params = array(1 => array($fields['value'], 'String'));
376 $query = "
377 SELECT count(*)
378 FROM civicrm_state_province
379 WHERE name = %1
380 OR abbreviation = %1";
381 if (CRM_Core_DAO::singleValueQuery($query, $params) <= 0) {
382 $errors['value'] = ts('The invalid value for State/Province data type');
383 }
384 }
385 break;
386 }
387 }
388
389 return empty($errors) ? TRUE : $errors;
390 }
391
392 /**
393 * Process the form
394 *
395 * @param null
396 *
397 * @return void
398 */
399 public function postProcess() {
400 // store the submitted values in an array
401 $params = $this->controller->exportValues('Option');
402
403 if ($this->_action == CRM_Core_Action::DELETE) {
404 $option = civicrm_api3('option_value', 'getsingle', array('id' => $this->_id));
405 $fieldValues = array('option_group_id' => $this->_optionGroupID);
406 CRM_Utils_Weight::delWeight('CRM_Core_DAO_OptionValue', $this->_id, $fieldValues);
407 CRM_Core_BAO_CustomOption::del($this->_id);
408 CRM_Core_Session::setStatus(ts('Option "%1" has been deleted.', array(1 => $option['label'])), ts('Deleted'), 'success');
409 return;
410 }
411
412 // set values for custom field properties and save
413 $customOption = new CRM_Core_DAO_OptionValue();
414 $customOption->label = $params['label'];
415 $customOption->name = CRM_Utils_String::titleToVar($params['label']);
416 $customOption->weight = $params['weight'];
417 $customOption->value = $params['value'];
418 $customOption->is_active = CRM_Utils_Array::value('is_active', $params, FALSE);
419
420 $oldWeight = NULL;
421 if ($this->_id) {
422 $customOption->id = $this->_id;
423 CRM_Core_BAO_CustomOption::updateCustomValues($params);
424 $oldWeight = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $this->_id, 'weight', 'id');
425 }
426
427 $fieldValues = array('option_group_id' => $this->_optionGroupID);
428 $customOption->weight =
429 CRM_Utils_Weight::updateOtherWeights(
430 'CRM_Core_DAO_OptionValue',
431 $oldWeight,
432 $params['weight'],
433 $fieldValues);
434
435 $customOption->option_group_id = $this->_optionGroupID;
436
437 $customField = new CRM_Core_DAO_CustomField();
438 $customField->id = $this->_fid;
439 if (
440 $customField->find(TRUE) &&
441 (
442 $customField->html_type == 'CheckBox' ||
443 $customField->html_type == 'AdvMulti-Select' ||
444 $customField->html_type == 'Multi-Select'
445 )
446 ) {
447 $defVal = explode(
448 CRM_Core_DAO::VALUE_SEPARATOR,
449 substr($customField->default_value, 1, -1)
450 );
451 if (!empty($params['default_value'])) {
452 if (!in_array($customOption->value, $defVal)) {
453 if (empty($defVal[0])) {
454 $defVal = array($customOption->value);
455 }
456 else {
457 $defVal[] = $customOption->value;
458 }
459 $customField->default_value =
460 CRM_Core_DAO::VALUE_SEPARATOR .
461 implode(CRM_Core_DAO::VALUE_SEPARATOR, $defVal) .
462 CRM_Core_DAO::VALUE_SEPARATOR;
463 $customField->save();
464 }
465 }
466 elseif (in_array($customOption->value, $defVal)) {
467 $tempVal = array();
468 foreach ($defVal as $v) {
469 if ($v != $customOption->value) {
470 $tempVal[] = $v;
471 }
472 }
473
474 $customField->default_value =
475 CRM_Core_DAO::VALUE_SEPARATOR .
476 implode(CRM_Core_DAO::VALUE_SEPARATOR, $tempVal) .
477 CRM_Core_DAO::VALUE_SEPARATOR;
478 $customField->save();
479 }
480 }
481 else {
482 switch ($customField->data_type) {
483 case 'Money':
484 $customOption->value = CRM_Utils_Rule::cleanMoney($customOption->value);
485 break;
486
487 case 'Int':
488 $customOption->value = intval($customOption->value);
489 break;
490
491 case 'Float':
492 $customOption->value = floatval($customOption->value);
493 break;
494 }
495
496 if (!empty($params['default_value'])) {
497 $customField->default_value = $customOption->value;
498 $customField->save();
499 }
500 elseif ($customField->find(TRUE) && $customField->default_value == $customOption->value) {
501 // this is the case where this option is the current default value and we have been reset
502 $customField->default_value = 'null';
503 $customField->save();
504 }
505 }
506
507 $customOption->save();
508
509 $msg = ts('Your multiple choice option \'%1\' has been saved', array(1 => $customOption->label));
510 CRM_Core_Session::setStatus($msg, '', 'success');
511 $buttonName = $this->controller->getButtonName();
512 $session = CRM_Core_Session::singleton();
513 if ($buttonName == $this->getButtonName('next', 'new')) {
514 CRM_Core_Session::setStatus(ts('You can add another option.'), '', 'info');
515 $session->replaceUserContext(
516 CRM_Utils_System::url(
517 'civicrm/admin/custom/group/field/option',
518 'reset=1&action=add&fid=' . $this->_fid . '&gid=' . $this->_gid
519 )
520 );
521 }
522 }
523 }