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