Merge pull request #17395 from seamuslee001/update_DAO
[civicrm-core.git] / CRM / Core / BAO / CustomValue.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
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 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17
18 /**
19 * Business objects for managing custom data values.
20 */
21 class CRM_Core_BAO_CustomValue extends CRM_Core_DAO {
22
23 /**
24 * Validate a value against a CustomField type.
25 *
26 * @param string $type
27 * The type of the data.
28 * @param string $value
29 * The data to be validated.
30 *
31 * @return bool
32 * True if the value is of the specified type
33 */
34 public static function typecheck($type, $value) {
35 switch ($type) {
36 case 'Memo':
37 return TRUE;
38
39 case 'String':
40 return CRM_Utils_Rule::string($value);
41
42 case 'Int':
43 return CRM_Utils_Rule::integer($value);
44
45 case 'Float':
46 case 'Money':
47 return CRM_Utils_Rule::numeric($value);
48
49 case 'Date':
50 if (is_numeric($value)) {
51 return CRM_Utils_Rule::dateTime($value);
52 }
53 else {
54 return CRM_Utils_Rule::date($value);
55 }
56 case 'Boolean':
57 return CRM_Utils_Rule::boolean($value);
58
59 case 'ContactReference':
60 return CRM_Utils_Rule::validContact($value);
61
62 case 'StateProvince':
63
64 //fix for multi select state, CRM-3437
65 $valid = FALSE;
66 $mulValues = explode(',', $value);
67 foreach ($mulValues as $key => $state) {
68 $valid = array_key_exists(strtolower(trim($state)),
69 array_change_key_case(array_flip(CRM_Core_PseudoConstant::stateProvinceAbbreviation()), CASE_LOWER)
70 ) || array_key_exists(strtolower(trim($state)),
71 array_change_key_case(array_flip(CRM_Core_PseudoConstant::stateProvince()), CASE_LOWER)
72 );
73 if (!$valid) {
74 break;
75 }
76 }
77 return $valid;
78
79 case 'Country':
80
81 //fix multi select country, CRM-3437
82 $valid = FALSE;
83 $mulValues = explode(',', $value);
84 foreach ($mulValues as $key => $country) {
85 $valid = array_key_exists(strtolower(trim($country)),
86 array_change_key_case(array_flip(CRM_Core_PseudoConstant::countryIsoCode()), CASE_LOWER)
87 ) || array_key_exists(strtolower(trim($country)),
88 array_change_key_case(array_flip(CRM_Core_PseudoConstant::country()), CASE_LOWER)
89 );
90 if (!$valid) {
91 break;
92 }
93 }
94 return $valid;
95
96 case 'Link':
97 return CRM_Utils_Rule::url($value);
98 }
99 return FALSE;
100 }
101
102 /**
103 * Given a 'civicrm' type string, return the mysql data store area
104 *
105 * @param string $type
106 * The civicrm type string.
107 *
108 * @return string|null
109 * the mysql data store placeholder
110 */
111 public static function typeToField($type) {
112 switch ($type) {
113 case 'String':
114 case 'File':
115 return 'char_data';
116
117 case 'Boolean':
118 case 'Int':
119 case 'StateProvince':
120 case 'Country':
121 case 'Auto-complete':
122 return 'int_data';
123
124 case 'Float':
125 return 'float_data';
126
127 case 'Money':
128 return 'decimal_data';
129
130 case 'Memo':
131 return 'memo_data';
132
133 case 'Date':
134 return 'date_data';
135
136 case 'Link':
137 return 'char_data';
138
139 default:
140 return NULL;
141 }
142 }
143
144 /**
145 * @param array $formValues
146 * @return null
147 */
148 public static function fixCustomFieldValue(&$formValues) {
149 if (empty($formValues)) {
150 return NULL;
151 }
152 foreach (array_keys($formValues) as $key) {
153 if (substr($key, 0, 7) != 'custom_') {
154 continue;
155 }
156 elseif (empty($formValues[$key])) {
157 continue;
158 }
159
160 $htmlType = CRM_Core_DAO::getFieldValue('CRM_Core_BAO_CustomField',
161 substr($key, 7), 'html_type'
162 );
163 $dataType = CRM_Core_DAO::getFieldValue('CRM_Core_BAO_CustomField',
164 substr($key, 7), 'data_type'
165 );
166
167 if (is_array($formValues[$key])) {
168 if (!in_array(key($formValues[$key]), CRM_Core_DAO::acceptedSQLOperators(), TRUE)) {
169 $formValues[$key] = ['IN' => $formValues[$key]];
170 }
171 }
172 elseif (($htmlType == 'TextArea' ||
173 ($htmlType == 'Text' && $dataType == 'String')
174 ) && strstr($formValues[$key], '%')
175 ) {
176 $formValues[$key] = ['LIKE' => $formValues[$key]];
177 }
178 }
179 }
180
181 /**
182 * Delete option value give an option value and custom group id.
183 *
184 * @param int $customValueID
185 * Custom value ID.
186 * @param int $customGroupID
187 * Custom group ID.
188 */
189 public static function deleteCustomValue($customValueID, $customGroupID) {
190 // first we need to find custom value table, from custom group ID
191 $tableName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $customGroupID, 'table_name');
192
193 // Retrieve the $entityId so we can pass that to the hook.
194 $entityID = CRM_Core_DAO::singleValueQuery("SELECT entity_id FROM {$tableName} WHERE id = %1", [
195 1 => [$customValueID, 'Integer'],
196 ]);
197
198 // delete custom value from corresponding custom value table
199 $sql = "DELETE FROM {$tableName} WHERE id = {$customValueID}";
200 CRM_Core_DAO::executeQuery($sql);
201
202 CRM_Utils_Hook::custom('delete',
203 $customGroupID,
204 $entityID,
205 $customValueID
206 );
207 }
208
209 /**
210 * ACL clause for an APIv4 custom pseudo-entity (aka multi-record custom group extending Contact).
211 * @return array
212 */
213 public function addSelectWhereClause() {
214 $clauses = [
215 'entity_id' => CRM_Utils_SQL::mergeSubquery('Contact'),
216 ];
217 CRM_Utils_Hook::selectWhereClause($this, $clauses);
218 return $clauses;
219 }
220
221 }