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