3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * form to process actions on the field aspect of Custom
21 class CRM_Custom_Form_Option
extends CRM_Core_Form
{
24 * The custom field id saved to the session for an update
31 * The custom group id saved to the session for an update
41 protected $_optionGroupID = NULL;
44 * The Option id, used when editing the Option
51 * Set variables up before form is built.
55 public function preProcess() {
56 $this->_fid
= CRM_Utils_Request
::retrieve('fid', 'Positive', $this);
58 $this->_gid
= CRM_Utils_Request
::retrieve('gid', 'Positive', $this);
60 if (!isset($this->_gid
) && $this->_fid
) {
61 $this->_gid
= CRM_Core_DAO
::getFieldValue(
62 'CRM_Core_DAO_CustomField',
69 $this->_optionGroupID
= CRM_Core_DAO
::getFieldValue(
70 'CRM_Core_DAO_CustomField',
76 if ($isReserved = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomGroup', $this->_gid
, 'is_reserved', 'id')) {
77 CRM_Core_Error
::statusBounce("You cannot add or edit muliple choice options in a reserved custom field-set.");
80 $this->_id
= CRM_Utils_Request
::retrieve('id', 'Positive', $this);
84 * Set default values for the form. Note that in edit/view mode
85 * the default values are retrieved from the database
88 * array of default values
90 public function setDefaultValues() {
91 $defaults = $fieldDefaults = [];
92 if (isset($this->_id
)) {
93 $params = ['id' => $this->_id
];
94 CRM_Core_BAO_CustomOption
::retrieve($params, $defaults);
96 $paramsField = ['id' => $this->_fid
];
97 CRM_Core_BAO_CustomField
::retrieve($paramsField, $fieldDefaults);
98 if ($fieldDefaults['html_type'] == 'CheckBox'
100 ||
($fieldDefaults['html_type'] == 'Select' && $fieldDefaults['serialize'] == 1)
102 if (!empty($fieldDefaults['default_value'])) {
103 $defaultCheckValues = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
104 substr($fieldDefaults['default_value'], 1, -1)
106 if (in_array($defaults['value'], $defaultCheckValues)) {
107 $defaults['default_value'] = 1;
112 if (CRM_Utils_Array
::value('default_value', $fieldDefaults) == CRM_Utils_Array
::value('value', $defaults)) {
113 $defaults['default_value'] = 1;
118 $defaults['is_active'] = 1;
121 if ($this->_action
& CRM_Core_Action
::ADD
) {
122 $fieldValues = ['option_group_id' => $this->_optionGroupID
];
123 $defaults['weight'] = CRM_Utils_Weight
::getDefaultWeight('CRM_Core_DAO_OptionValue', $fieldValues);
130 * Build the form object.
134 public function buildQuickForm() {
135 if ($this->_action
== CRM_Core_Action
::DELETE
) {
136 $option = civicrm_api3('option_value', 'getsingle', ['id' => $this->_id
]);
137 $this->assign('label', $option['label']);
141 'name' => ts('Delete'),
146 'name' => ts('Cancel'),
151 // lets trim all the whitespace
152 $this->applyFilter('__ALL__', 'trim');
154 // hidden Option Id for validation use
155 $this->add('hidden', 'optionId', $this->_id
);
157 //hidden field ID for validation use
158 $this->add('hidden', 'fieldId', $this->_fid
);
161 $this->add('text', 'label', ts('Option Label'), CRM_Core_DAO
::getAttribute('CRM_Core_DAO_OptionValue', 'label'), TRUE);
163 $this->add('text', 'value', ts('Option Value'), CRM_Core_DAO
::getAttribute('CRM_Core_DAO_OptionValue', 'value'), TRUE);
165 $this->add('textarea', 'description', ts('Description'), CRM_Core_DAO
::getAttribute('CRM_Core_DAO_OptionValue', 'description'));
167 $this->add('number', 'weight', ts('Order'), CRM_Core_DAO
::getAttribute('CRM_Core_DAO_OptionValue', 'weight'), TRUE);
168 $this->addRule('weight', ts('is a numeric field'), 'numeric');
171 $this->add('checkbox', 'is_active', ts('Active?'));
173 // Set the default value for Custom Field
174 $this->add('checkbox', 'default_value', ts('Default'));
176 // add a custom form rule
177 $this->addFormRule(['CRM_Custom_Form_Option', 'formRule'], $this);
183 'name' => ts('Save'),
188 'name' => ts('Save and New'),
193 'name' => ts('Cancel'),
197 // if view mode pls freeze it with the done button.
198 if ($this->_action
& CRM_Core_Action
::VIEW
) {
200 $url = CRM_Utils_System
::url('civicrm/admin/custom/group/field/option',
201 'reset=1&action=browse&fid=' . $this->_fid
. '&gid=' . $this->_gid
,
204 $this->addElement('xbutton',
206 CRM_Core_Page
::crmIcon('fa-times') . ' ' . ts('Done'),
209 'onclick' => "location.href='$url'",
210 'class' => 'crm-form-submit cancel',
215 $this->assign('id', $this->_id
);
219 * Global validation rules for the form.
221 * @param array $fields
222 * Posted values of the form.
225 * @param CRM_Core_Form $form
228 * list of errors to be posted back to the form
230 public static function formRule($fields, $files, $form) {
231 $optionLabel = $fields['label'];
232 $optionValue = $fields['value'];
233 $fieldId = $form->_fid
;
234 $optionGroupId = $form->_optionGroupID
;
237 if (empty($form->_id
)) {
240 FROM civicrm_option_value
241 WHERE option_group_id = %1
244 1 => [$optionGroupId, 'Integer'],
245 2 => [$optionLabel, 'String'],
247 if (CRM_Core_DAO
::singleValueQuery($query, $params) > 0) {
248 $errors['label'] = ts('There is an entry with the same label.');
253 FROM civicrm_option_value
254 WHERE option_group_id = %1
257 1 => [$optionGroupId, 'Integer'],
258 2 => [$optionValue, 'String'],
260 if (CRM_Core_DAO
::singleValueQuery($query, $params) > 0) {
261 $errors['value'] = ts('There is an entry with the same value.');
265 //capture duplicate entries while updating Custom Options
266 $optionId = CRM_Utils_Type
::escape($fields['optionId'], 'Integer');
268 //check label duplicates within a custom field
271 FROM civicrm_option_value
272 WHERE option_group_id = %1
276 1 => [$optionGroupId, 'Integer'],
277 2 => [$optionId, 'Integer'],
278 3 => [$optionLabel, 'String'],
280 if (CRM_Core_DAO
::singleValueQuery($query, $params) > 0) {
281 $errors['label'] = ts('There is an entry with the same label.');
284 //check value duplicates within a custom field
287 FROM civicrm_option_value
288 WHERE option_group_id = %1
292 1 => [$optionGroupId, 'Integer'],
293 2 => [$optionId, 'Integer'],
294 3 => [$optionValue, 'String'],
296 if (CRM_Core_DAO
::singleValueQuery($query, $params) > 0) {
297 $errors['value'] = ts('There is an entry with the same value.');
303 FROM civicrm_custom_field
305 $params = [1 => [$fieldId, 'Integer']];
306 $dao = CRM_Core_DAO
::executeQuery($query, $params);
308 switch ($dao->data_type
) {
310 if (!CRM_Utils_Rule
::integer($fields["value"])) {
311 $errors['value'] = ts('Please enter a valid integer value.');
317 if (!CRM_Utils_Rule
::numeric($fields["value"])) {
318 $errors['value'] = ts('Please enter a valid number.');
323 if (!CRM_Utils_Rule
::money($fields["value"])) {
324 $errors['value'] = ts('Please enter a valid value.');
329 if (!CRM_Utils_Rule
::date($fields["value"])) {
330 $errors['value'] = ts('Please enter a valid date using YYYY-MM-DD format. Example: 2004-12-31.');
335 if (!CRM_Utils_Rule
::integer($fields["value"]) &&
336 ($fields["value"] != '1' ||
$fields["value"] != '0')
338 $errors['value'] = ts('Please enter 1 or 0 as value.');
343 if (!empty($fields["value"])) {
344 $params = [1 => [$fields['value'], 'String']];
345 $query = "SELECT count(*) FROM civicrm_country WHERE name = %1 OR iso_code = %1";
346 if (CRM_Core_DAO
::singleValueQuery($query, $params) <= 0) {
347 $errors['value'] = ts('Invalid default value for country.');
352 case 'StateProvince':
353 if (!empty($fields["value"])) {
354 $params = [1 => [$fields['value'], 'String']];
357 FROM civicrm_state_province
359 OR abbreviation = %1";
360 if (CRM_Core_DAO
::singleValueQuery($query, $params) <= 0) {
361 $errors['value'] = ts('The invalid value for State/Province data type');
368 return empty($errors) ?
TRUE : $errors;
376 public function postProcess() {
377 // store the submitted values in an array
378 $params = $this->controller
->exportValues('Option');
380 if ($this->_action
== CRM_Core_Action
::DELETE
) {
381 $option = civicrm_api3('option_value', 'getsingle', ['id' => $this->_id
]);
382 $fieldValues = ['option_group_id' => $this->_optionGroupID
];
383 CRM_Utils_Weight
::delWeight('CRM_Core_DAO_OptionValue', $this->_id
, $fieldValues);
384 CRM_Core_BAO_CustomOption
::del($this->_id
);
385 CRM_Core_Session
::setStatus(ts('Option "%1" has been deleted.', [1 => $option['label']]), ts('Deleted'), 'success');
389 // set values for custom field properties and save
390 $customOption = new CRM_Core_DAO_OptionValue();
391 $customOption->label
= $params['label'];
392 $customOption->weight
= $params['weight'];
393 $customOption->description
= $params['description'];
394 $customOption->value
= $params['value'];
395 $customOption->is_active
= $params['is_active'] ??
FALSE;
399 $customOption->id
= $this->_id
;
400 $oldWeight = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_OptionValue', $this->_id
, 'weight', 'id');
403 $customOption->name
= CRM_Utils_String
::titleToVar($params['label']);
406 $fieldValues = ['option_group_id' => $this->_optionGroupID
];
407 $customOption->weight
408 = CRM_Utils_Weight
::updateOtherWeights(
409 'CRM_Core_DAO_OptionValue',
414 $customOption->option_group_id
= $this->_optionGroupID
;
416 $customField = new CRM_Core_DAO_CustomField();
417 $customField->id
= $this->_fid
;
419 $customField->find(TRUE) &&
421 $customField->html_type
== 'CheckBox' ||
422 // Multi Value Select
423 ($customField->html_type
== 'Select' && $customField->serialize
== 1)
427 CRM_Core_DAO
::VALUE_SEPARATOR
,
428 substr($customField->default_value
, 1, -1)
430 if (!empty($params['default_value'])) {
431 if (!in_array($customOption->value
, $defVal)) {
432 if (empty($defVal[0])) {
433 $defVal = [$customOption->value
];
436 $defVal[] = $customOption->value
;
438 $customField->default_value
439 = CRM_Core_DAO
::VALUE_SEPARATOR
.
440 implode(CRM_Core_DAO
::VALUE_SEPARATOR
, $defVal) .
441 CRM_Core_DAO
::VALUE_SEPARATOR
;
442 $customField->save();
445 elseif (in_array($customOption->value
, $defVal)) {
447 foreach ($defVal as $v) {
448 if ($v != $customOption->value
) {
453 $customField->default_value
454 = CRM_Core_DAO
::VALUE_SEPARATOR
.
455 implode(CRM_Core_DAO
::VALUE_SEPARATOR
, $tempVal) .
456 CRM_Core_DAO
::VALUE_SEPARATOR
;
457 $customField->save();
461 switch ($customField->data_type
) {
463 $customOption->value
= CRM_Utils_Rule
::cleanMoney($customOption->value
);
467 $customOption->value
= intval($customOption->value
);
471 $customOption->value
= floatval($customOption->value
);
475 if (!empty($params['default_value'])) {
476 $customField->default_value
= $customOption->value
;
477 $customField->save();
479 elseif ($customField->find(TRUE) && $customField->default_value
== $customOption->value
) {
480 // this is the case where this option is the current default value and we have been reset
481 $customField->default_value
= 'null';
482 $customField->save();
487 CRM_Core_BAO_CustomOption
::updateValue($customOption->id
, $customOption->value
);
489 $customOption->save();
491 $msg = ts('Your multiple choice option \'%1\' has been saved', [1 => $customOption->label
]);
492 CRM_Core_Session
::setStatus($msg, '', 'success');
493 $buttonName = $this->controller
->getButtonName();
494 $session = CRM_Core_Session
::singleton();
495 if ($buttonName == $this->getButtonName('next', 'new')) {
496 CRM_Core_Session
::setStatus(ts('You can add another option.'), '', 'info');
497 $session->replaceUserContext(
498 CRM_Utils_System
::url(
499 'civicrm/admin/custom/group/field/option',
500 'reset=1&action=add&fid=' . $this->_fid
. '&gid=' . $this->_gid