Merge pull request #15556 from demeritcowboy/convert-label-to-name-2
[civicrm-core.git] / CRM / Core / BAO / CustomOption.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
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/**
29 *
30 * @package CRM
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 * Business objects for managing custom data options.
38 *
39 */
40class CRM_Core_BAO_CustomOption {
41
42 /**
fe482240 43 * Fetch object based on array of properties.
6a488035 44 *
6a0b768e
TO
45 * @param array $params
46 * (reference ) an assoc array of name/value pairs.
47 * @param array $defaults
48 * (reference ) an assoc array to hold the flattened values.
6a488035 49 *
16b10e64 50 * @return CRM_Core_BAO_CustomOption
6a488035 51 */
00be9182 52 public static function retrieve(&$params, &$defaults) {
6a488035
TO
53 $customOption = new CRM_Core_DAO_OptionValue();
54 $customOption->copyValues($params);
55 if ($customOption->find(TRUE)) {
56 CRM_Core_DAO::storeValues($customOption, $defaults);
57 return $customOption;
58 }
59 return NULL;
60 }
61
62 /**
fe482240 63 * Returns all active options ordered by weight for a given field.
6a488035 64 *
6a0b768e
TO
65 * @param int $fieldID
66 * Field whose options are needed.
317fceb4 67 * @param bool $inactiveNeeded Do we need inactive options ?.
6a0b768e 68 * Do we need inactive options ?.
6a488035 69 *
a6c01b45
CW
70 * @return array
71 * all active options for fieldId
6a488035 72 */
317fceb4 73 public static function getCustomOption(
6a488035
TO
74 $fieldID,
75 $inactiveNeeded = FALSE
76 ) {
be2fb01f 77 $options = [];
6a488035
TO
78 if (!$fieldID) {
79 return $options;
80 }
81
be2fb01f 82 $optionValues = CRM_Core_PseudoConstant::get('CRM_Core_BAO_CustomField', 'custom_' . $fieldID, [], $inactiveNeeded ? 'get' : 'create');
6a488035 83
e525d6af 84 foreach ((array) $optionValues as $value => $label) {
be2fb01f 85 $options[] = [
b4fb2d23
CW
86 'label' => $label,
87 'value' => $value,
be2fb01f 88 ];
6a488035
TO
89 }
90
6a488035
TO
91 return $options;
92 }
93
57c9c217 94 /**
09b6d7cd 95 * Wrapper for ajax option selector.
57c9c217 96 *
97 * @param array $params
98 * Associated array for params record id.
99 *
100 * @return array
101 * associated array of option list
102 * -rp = rowcount
103 * -page= offset
104 */
518fa0ee 105 public static function getOptionListSelector(&$params) {
be2fb01f 106 $options = [];
57c9c217 107
09b6d7cd
CW
108 $field = CRM_Core_BAO_CustomField::getFieldObject($params['fid']);
109 $defVal = CRM_Utils_Array::explodePadded($field->default_value);
57c9c217 110
111 // format the params
112 $params['offset'] = ($params['page'] - 1) * $params['rp'];
113 $params['rowCount'] = $params['rp'];
57c9c217 114
09b6d7cd 115 if (!$field->option_group_id) {
57c9c217 116 return $options;
117 }
be2fb01f 118 $queryParams = [1 => [$field->option_group_id, 'Integer']];
57c9c217 119 $total = "SELECT COUNT(*) FROM civicrm_option_value WHERE option_group_id = %1";
120 $params['total'] = CRM_Core_DAO::singleValueQuery($total, $queryParams);
121
122 $limit = " LIMIT {$params['offset']}, {$params['rowCount']} ";
57c9c217 123 $orderBy = ' ORDER BY options.weight asc';
57c9c217 124
125 $query = "SELECT * FROM civicrm_option_value as options WHERE option_group_id = %1 {$orderBy} {$limit}";
126 $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
127 $links = CRM_Custom_Page_Option::actionLinks();
128
be2fb01f 129 $fields = ['id', 'label', 'value'];
57c9c217 130 $config = CRM_Core_Config::singleton();
131 while ($dao->fetch()) {
be2fb01f 132 $options[$dao->id] = [];
57c9c217 133 foreach ($fields as $k) {
134 $options[$dao->id][$k] = $dao->$k;
135 }
136 $action = array_sum(array_keys($links));
137 $class = 'crm-entity';
138 // update enable/disable links depending on custom_field properties.
139 if ($dao->is_active) {
140 $action -= CRM_Core_Action::ENABLE;
141 }
142 else {
143 $class .= ' disabled';
144 $action -= CRM_Core_Action::DISABLE;
145 }
87660a87
MD
146
147 $isGroupLocked = (bool) CRM_Core_DAO::getFieldValue(
148 CRM_Core_DAO_OptionGroup::class,
149 $field->option_group_id,
150 'is_locked'
151 );
152
153 // disable deletion of option values for locked option groups
218d9fd2 154 if (($action & CRM_Core_Action::DELETE) && $isGroupLocked) {
87660a87
MD
155 $action -= CRM_Core_Action::DELETE;
156 }
157
6cc845ad 158 if (in_array($field->html_type, ['CheckBox', 'Multi-Select'])) {
614ff00e 159 if (isset($defVal) && in_array($dao->value, $defVal)) {
57c9c217 160 $options[$dao->id]['is_default'] = '<img src="' . $config->resourceBase . 'i/check.gif" />';
161 }
162 else {
163 $options[$dao->id]['is_default'] = '';
164 }
165 }
166 else {
09b6d7cd 167 if ($field->default_value == $dao->value) {
57c9c217 168 $options[$dao->id]['is_default'] = '<img src="' . $config->resourceBase . 'i/check.gif" />';
169 }
170 else {
171 $options[$dao->id]['is_default'] = '';
172 }
173 }
4247b886 174 $options[$dao->id]['description'] = $dao->description;
57c9c217 175 $options[$dao->id]['class'] = $dao->id . ',' . $class;
09b6d7cd 176 $options[$dao->id]['is_active'] = empty($dao->is_active) ? ts('No') : ts('Yes');
57c9c217 177 $options[$dao->id]['links'] = CRM_Core_Action::formLink($links,
178 $action,
be2fb01f 179 [
57c9c217 180 'id' => $dao->id,
181 'fid' => $params['fid'],
182 'gid' => $params['gid'],
be2fb01f 183 ],
57c9c217 184 ts('more'),
185 FALSE,
186 'customOption.row.actions',
187 'customOption',
188 $dao->id
189 );
190 }
57c9c217 191
192 return $options;
193 }
194
6a488035 195 /**
fe482240 196 * Delete Option.
6a488035 197 *
16b10e64
CW
198 * @param $optionId integer
199 * option id
6a488035 200 *
6a488035 201 */
00be9182 202 public static function del($optionId) {
6a488035
TO
203 // get the customFieldID
204 $query = "
205SELECT f.id as id, f.data_type as dataType
206FROM civicrm_option_value v,
207 civicrm_option_group g,
208 civicrm_custom_field f
209WHERE v.id = %1
210AND g.id = f.option_group_id
211AND g.id = v.option_group_id";
be2fb01f 212 $params = [1 => [$optionId, 'Integer']];
6a488035
TO
213 $dao = CRM_Core_DAO::executeQuery($query, $params);
214 if ($dao->fetch()) {
215 if (in_array($dao->dataType,
be2fb01f 216 ['Int', 'Float', 'Money', 'Boolean']
353ffa53 217 )) {
6a488035
TO
218 $value = 0;
219 }
220 else {
221 $value = '';
222 }
be2fb01f 223 $params = [
6a488035
TO
224 'optionId' => $optionId,
225 'fieldId' => $dao->id,
226 'value' => $value,
be2fb01f 227 ];
6a488035
TO
228 // delete this value from the tables
229 self::updateCustomValues($params);
230
231 // also delete this option value
232 $query = "
233DELETE
234FROM civicrm_option_value
235WHERE id = %1";
be2fb01f 236 $params = [1 => [$optionId, 'Integer']];
6a488035
TO
237 CRM_Core_DAO::executeQuery($query, $params);
238 }
239 }
240
b5c2afd0 241 /**
c490a46a 242 * @param array $params
b5c2afd0
EM
243 *
244 * @throws Exception
245 */
00be9182 246 public static function updateCustomValues($params) {
6a488035
TO
247 $optionDAO = new CRM_Core_DAO_OptionValue();
248 $optionDAO->id = $params['optionId'];
249 $optionDAO->find(TRUE);
250 $oldValue = $optionDAO->value;
251
252 // get the table, column, html_type and data type for this field
253 $query = "
254SELECT g.table_name as tableName ,
255 f.column_name as columnName,
256 f.data_type as dataType,
257 f.html_type as htmlType
258FROM civicrm_custom_group g,
259 civicrm_custom_field f
260WHERE f.custom_group_id = g.id
261 AND f.id = %1";
be2fb01f 262 $queryParams = [1 => [$params['fieldId'], 'Integer']];
6a488035
TO
263 $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
264 if ($dao->fetch()) {
265 if ($dao->dataType == 'Money') {
266 $params['value'] = CRM_Utils_Rule::cleanMoney($params['value']);
267 }
268 switch ($dao->htmlType) {
269 case 'Autocomplete-Select':
270 case 'Select':
271 case 'Radio':
272 $query = "
273UPDATE {$dao->tableName}
274SET {$dao->columnName} = %1
275WHERE id = %2";
276 if ($dao->dataType == 'Auto-complete') {
277 $dataType = "String";
278 }
279 else {
280 $dataType = $dao->dataType;
281 }
be2fb01f
CW
282 $queryParams = [
283 1 => [
353ffa53 284 $params['value'],
6a488035 285 $dataType,
be2fb01f
CW
286 ],
287 2 => [
6a488035
TO
288 $params['optionId'],
289 'Integer',
be2fb01f
CW
290 ],
291 ];
6a488035
TO
292 break;
293
6a488035
TO
294 case 'Multi-Select':
295 case 'CheckBox':
296 $oldString = CRM_Core_DAO::VALUE_SEPARATOR . $oldValue . CRM_Core_DAO::VALUE_SEPARATOR;
297 $newString = CRM_Core_DAO::VALUE_SEPARATOR . $params['value'] . CRM_Core_DAO::VALUE_SEPARATOR;
353ffa53 298 $query = "
6a488035
TO
299UPDATE {$dao->tableName}
300SET {$dao->columnName} = REPLACE( {$dao->columnName}, %1, %2 )";
be2fb01f
CW
301 $queryParams = [
302 1 => [$oldString, 'String'],
303 2 => [$newString, 'String'],
304 ];
6a488035
TO
305 break;
306
307 default:
308 CRM_Core_Error::fatal();
309 }
310 $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
311 }
312 }
313
58eaa092
CW
314 /**
315 * When changing the value of an option this is called to update all corresponding custom data
316 *
317 * @param int $optionId
318 * @param string $newValue
319 */
320 public static function updateValue($optionId, $newValue) {
321 $optionValue = new CRM_Core_DAO_OptionValue();
322 $optionValue->id = $optionId;
323 $optionValue->find(TRUE);
324 $oldValue = $optionValue->value;
325 if ($oldValue == $newValue) {
326 return;
327 }
328
329 $customField = new CRM_Core_DAO_CustomField();
330 $customField->option_group_id = $optionValue->option_group_id;
331 $customField->find();
332 while ($customField->fetch()) {
333 $customGroup = new CRM_Core_DAO_CustomGroup();
334 $customGroup->id = $customField->custom_group_id;
335 $customGroup->find(TRUE);
336 if (CRM_Core_BAO_CustomField::isSerialized($customField)) {
be2fb01f
CW
337 $params = [
338 1 => [CRM_Utils_Array::implodePadded($oldValue), 'String'],
339 2 => [CRM_Utils_Array::implodePadded($newValue), 'String'],
340 3 => ['%' . CRM_Utils_Array::implodePadded($oldValue) . '%', 'String'],
341 ];
58eaa092
CW
342 }
343 else {
be2fb01f
CW
344 $params = [
345 1 => [$oldValue, 'String'],
346 2 => [$newValue, 'String'],
347 3 => [$oldValue, 'String'],
348 ];
58eaa092
CW
349 }
350 $sql = "UPDATE `{$customGroup->table_name}` SET `{$customField->column_name}` = REPLACE(`{$customField->column_name}`, %1, %2) WHERE `{$customField->column_name}` LIKE %3";
58eaa092
CW
351 CRM_Core_DAO::executeQuery($sql, $params);
352 }
58eaa092
CW
353 }
354
6a488035 355}