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