Commit | Line | Data |
---|---|---|
4ef04170 TO |
1 | <?php |
2 | ||
3 | /* | |
4 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 5 | | Copyright CiviCRM LLC. All rights reserved. | |
4ef04170 | 6 | | | |
bc77d7c0 TO |
7 | | This work is published under the GNU AGPLv3 license with some | |
8 | | permitted exceptions and without any warranty. For full license | | |
9 | | and copyright information, see https://civicrm.org/licensing | | |
4ef04170 TO |
10 | +--------------------------------------------------------------------+ |
11 | */ | |
12 | ||
13 | /** | |
14 | * | |
15 | * @package CRM | |
ca5cec67 | 16 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
4ef04170 TO |
17 | */ |
18 | class CRM_Core_DAO_AllCoreTables { | |
19 | ||
95b9a42e TO |
20 | private static $tables = NULL; |
21 | private static $daoToClass = NULL; | |
22 | private static $entityTypes = NULL; | |
4ef04170 | 23 | |
8246bca4 | 24 | /** |
25 | * Initialise. | |
26 | * | |
27 | * @param bool $fresh | |
28 | */ | |
95b9a42e | 29 | public static function init($fresh = FALSE) { |
4ef04170 | 30 | static $init = FALSE; |
95b9a42e TO |
31 | if ($init && !$fresh) { |
32 | return; | |
4ef04170 | 33 | } |
be2fb01f | 34 | Civi::$statics[__CLASS__] = []; |
4ef04170 TO |
35 | |
36 | $file = preg_replace('/\.php$/', '.data.php', __FILE__); | |
37 | $entityTypes = require $file; | |
38 | CRM_Utils_Hook::entityTypes($entityTypes); | |
39 | ||
be2fb01f CW |
40 | self::$entityTypes = []; |
41 | self::$tables = []; | |
42 | self::$daoToClass = []; | |
4ef04170 | 43 | foreach ($entityTypes as $entityType) { |
740dd877 TO |
44 | self::registerEntityType( |
45 | $entityType['name'], | |
46 | $entityType['class'], | |
47 | $entityType['table'], | |
2e1f50d6 CW |
48 | $entityType['fields_callback'] ?? NULL, |
49 | $entityType['links_callback'] ?? NULL | |
740dd877 | 50 | ); |
4ef04170 TO |
51 | } |
52 | ||
53 | $init = TRUE; | |
54 | } | |
55 | ||
56 | /** | |
57 | * (Quasi-Private) Do not call externally (except for unit-testing) | |
8246bca4 | 58 | * |
59 | * @param string $daoName | |
60 | * @param string $className | |
61 | * @param string $tableName | |
62 | * @param string $fields_callback | |
63 | * @param string $links_callback | |
4ef04170 | 64 | */ |
740dd877 | 65 | public static function registerEntityType($daoName, $className, $tableName, $fields_callback = NULL, $links_callback = NULL) { |
4ef04170 TO |
66 | self::$daoToClass[$daoName] = $className; |
67 | self::$tables[$tableName] = $className; | |
be2fb01f | 68 | self::$entityTypes[$className] = [ |
4ef04170 TO |
69 | 'name' => $daoName, |
70 | 'class' => $className, | |
71 | 'table' => $tableName, | |
740dd877 TO |
72 | 'fields_callback' => $fields_callback, |
73 | 'links_callback' => $links_callback, | |
be2fb01f | 74 | ]; |
4ef04170 TO |
75 | } |
76 | ||
95b9a42e TO |
77 | /** |
78 | * @return array | |
79 | * Ex: $result['CRM_Contact_DAO_Contact']['table'] == 'civicrm_contact'; | |
80 | */ | |
81 | public static function get() { | |
4ef04170 TO |
82 | self::init(); |
83 | return self::$entityTypes; | |
84 | } | |
85 | ||
95b9a42e TO |
86 | /** |
87 | * @return array | |
88 | * List of SQL table names. | |
89 | */ | |
90 | public static function tables() { | |
4ef04170 TO |
91 | self::init(); |
92 | return self::$tables; | |
93 | } | |
94 | ||
6b86d84f AS |
95 | /** |
96 | * @return array | |
97 | * List of indices. | |
98 | */ | |
99 | public static function indices($localize = TRUE) { | |
be2fb01f | 100 | $indices = []; |
6b86d84f AS |
101 | self::init(); |
102 | foreach (self::$daoToClass as $class) { | |
be2fb01f | 103 | if (is_callable([$class, 'indices'])) { |
6b86d84f AS |
104 | $indices[$class::getTableName()] = $class::indices($localize); |
105 | } | |
106 | } | |
107 | return $indices; | |
108 | } | |
109 | ||
110 | /** | |
111 | * Modify indices to account for localization options. | |
112 | * | |
8a4fede3 | 113 | * @param string $class DAO class |
6b86d84f AS |
114 | * @param array $originalIndices index definitions before localization |
115 | * | |
116 | * @return array | |
117 | * index definitions after localization | |
118 | */ | |
119 | public static function multilingualize($class, $originalIndices) { | |
120 | $domain = new CRM_Core_DAO_Domain(); | |
121 | $domain->find(TRUE); | |
122 | $locales = explode(CRM_Core_DAO::VALUE_SEPARATOR, $domain->locales); | |
123 | if (CRM_Utils_System::isNull($locales)) { | |
124 | return $originalIndices; | |
125 | } | |
126 | $classFields = $class::fields(); | |
127 | ||
be2fb01f | 128 | $finalIndices = []; |
6b86d84f AS |
129 | foreach ($originalIndices as $index) { |
130 | if ($index['localizable']) { | |
131 | foreach ($locales as $locale) { | |
132 | $localIndex = $index; | |
133 | $localIndex['name'] .= "_" . $locale; | |
be2fb01f | 134 | $fields = []; |
6b86d84f AS |
135 | foreach ($localIndex['field'] as $field) { |
136 | $baseField = explode('(', $field); | |
137 | if ($classFields[$baseField[0]]['localizable']) { | |
138 | // field name may have eg (3) at end for prefix length | |
139 | // last_name => last_name_fr_FR | |
140 | // last_name(3) => last_name_fr_FR(3) | |
141 | $fields[] = preg_replace('/^([^(]+)(\(\d+\)|)$/', '${1}_' . $locale . '${2}', $field); | |
142 | } | |
143 | else { | |
144 | $fields[] = $field; | |
145 | } | |
146 | } | |
147 | $localIndex['field'] = $fields; | |
148 | $finalIndices[$localIndex['name']] = $localIndex; | |
149 | } | |
150 | } | |
151 | else { | |
152 | $finalIndices[$index['name']] = $index; | |
153 | } | |
154 | } | |
155 | CRM_Core_BAO_SchemaHandler::addIndexSignature(self::getTableForClass($class), $finalIndices); | |
156 | return $finalIndices; | |
157 | } | |
158 | ||
95b9a42e TO |
159 | /** |
160 | * @return array | |
161 | * Mapping from brief-names to class-names. | |
162 | * Ex: $result['Contact'] == 'CRM_Contact_DAO_Contact'. | |
163 | */ | |
164 | public static function daoToClass() { | |
4ef04170 TO |
165 | self::init(); |
166 | return self::$daoToClass; | |
167 | } | |
168 | ||
95b9a42e TO |
169 | /** |
170 | * @return array | |
171 | * Mapping from table-names to class-names. | |
172 | * Ex: $result['civicrm_contact'] == 'CRM_Contact_DAO_Contact'. | |
173 | */ | |
174 | public static function getCoreTables() { | |
4ef04170 TO |
175 | return self::tables(); |
176 | } | |
177 | ||
95b9a42e TO |
178 | /** |
179 | * Determine whether $tableName is a core table. | |
180 | * | |
181 | * @param string $tableName | |
182 | * @return bool | |
183 | */ | |
184 | public static function isCoreTable($tableName) { | |
4c1bd923 | 185 | return array_key_exists($tableName, self::tables()); |
4ef04170 TO |
186 | } |
187 | ||
8246bca4 | 188 | /** |
3ab49d54 | 189 | * Get the DAO for a BAO class. |
8246bca4 | 190 | * |
3ab49d54 | 191 | * @param string $baoName |
8246bca4 | 192 | * |
3ab49d54 CW |
193 | * @return string|CRM_Core_DAO |
194 | */ | |
195 | public static function getCanonicalClassName($baoName) { | |
196 | return str_replace('_BAO_', '_DAO_', $baoName); | |
197 | } | |
198 | ||
199 | /** | |
200 | * Get the BAO for a DAO class. | |
201 | * | |
202 | * @param string $daoName | |
203 | * | |
204 | * @return string|CRM_Core_DAO | |
8246bca4 | 205 | */ |
3ab49d54 CW |
206 | public static function getBAOClassName($daoName) { |
207 | $baoName = str_replace('_DAO_', '_BAO_', $daoName); | |
208 | return class_exists($baoName) ? $baoName : $daoName; | |
4ef04170 TO |
209 | } |
210 | ||
95b9a42e | 211 | /** |
8246bca4 | 212 | * Get a list of all DAO classes. |
213 | * | |
95b9a42e TO |
214 | * @return array |
215 | * List of class names. | |
216 | */ | |
217 | public static function getClasses() { | |
4ef04170 TO |
218 | return array_values(self::daoToClass()); |
219 | } | |
220 | ||
8246bca4 | 221 | /** |
222 | * Get the classname for the table. | |
223 | * | |
224 | * @param string $tableName | |
225 | * @return string | |
226 | */ | |
95b9a42e | 227 | public static function getClassForTable($tableName) { |
3a575348 | 228 | //CRM-19677: on multilingual setup, trim locale from $tableName to fetch class name |
229 | if (CRM_Core_I18n::isMultilingual()) { | |
230 | global $dbLocale; | |
231 | $tableName = str_replace($dbLocale, '', $tableName); | |
232 | } | |
4ef04170 TO |
233 | return CRM_Utils_Array::value($tableName, self::tables()); |
234 | } | |
235 | ||
95b9a42e TO |
236 | /** |
237 | * Given a brief-name, determine the full class-name. | |
238 | * | |
239 | * @param string $daoName | |
240 | * Ex: 'Contact'. | |
241 | * @return string|NULL | |
242 | * Ex: 'CRM_Contact_DAO_Contact'. | |
243 | */ | |
244 | public static function getFullName($daoName) { | |
4ef04170 TO |
245 | return CRM_Utils_Array::value($daoName, self::daoToClass()); |
246 | } | |
247 | ||
95b9a42e TO |
248 | /** |
249 | * Given a full class-name, determine the brief-name. | |
250 | * | |
251 | * @param string $className | |
252 | * Ex: 'CRM_Contact_DAO_Contact'. | |
253 | * @return string|NULL | |
254 | * Ex: 'Contact'. | |
255 | */ | |
256 | public static function getBriefName($className) { | |
3d182a04 CW |
257 | $className = self::getCanonicalClassName($className); |
258 | return array_search($className, self::daoToClass(), TRUE) ?: NULL; | |
4ef04170 TO |
259 | } |
260 | ||
261 | /** | |
262 | * @param string $className DAO or BAO name | |
263 | * @return string|FALSE SQL table name | |
264 | */ | |
95b9a42e TO |
265 | public static function getTableForClass($className) { |
266 | return array_search(self::getCanonicalClassName($className), | |
267 | self::tables()); | |
4ef04170 TO |
268 | } |
269 | ||
9d4c4ffd | 270 | /** |
271 | * Convert the entity name into a table name. | |
272 | * | |
273 | * @param string $entityBriefName | |
274 | * | |
275 | * @return FALSE|string | |
276 | */ | |
277 | public static function getTableForEntityName($entityBriefName) { | |
278 | return self::getTableForClass(self::getFullName($entityBriefName)); | |
279 | } | |
280 | ||
8246bca4 | 281 | /** |
282 | * Reinitialise cache. | |
283 | * | |
284 | * @param bool $fresh | |
285 | */ | |
95b9a42e | 286 | public static function reinitializeCache($fresh = FALSE) { |
4ef04170 TO |
287 | self::init($fresh); |
288 | } | |
289 | ||
84a0493c TO |
290 | /** |
291 | * (Quasi-Private) Do not call externally. For use by DAOs. | |
292 | * | |
293 | * @param string $dao | |
294 | * Ex: 'CRM_Core_DAO_Address'. | |
295 | * @param string $labelName | |
296 | * Ex: 'address'. | |
297 | * @param bool $prefix | |
298 | * @param array $foreignDAOs | |
299 | * @return array | |
300 | */ | |
301 | public static function getExports($dao, $labelName, $prefix, $foreignDAOs) { | |
302 | // Bug-level compatibility -- or sane behavior? | |
303 | $cacheKey = $dao . ':export'; | |
304 | // $cacheKey = $dao . ':' . ($prefix ? 'export-prefix' : 'export'); | |
305 | ||
306 | if (!isset(Civi::$statics[__CLASS__][$cacheKey])) { | |
be2fb01f | 307 | $exports = []; |
84a0493c TO |
308 | $fields = $dao::fields(); |
309 | ||
8246bca4 | 310 | foreach ($fields as $name => $field) { |
de6c59ca | 311 | if (!empty($field['export'])) { |
84a0493c TO |
312 | if ($prefix) { |
313 | $exports[$labelName] = & $fields[$name]; | |
8246bca4 | 314 | } |
315 | else { | |
84a0493c TO |
316 | $exports[$name] = & $fields[$name]; |
317 | } | |
318 | } | |
319 | } | |
320 | ||
321 | foreach ($foreignDAOs as $foreignDAO) { | |
322 | $exports = array_merge($exports, $foreignDAO::export(TRUE)); | |
323 | } | |
324 | ||
325 | Civi::$statics[__CLASS__][$cacheKey] = $exports; | |
326 | } | |
327 | return Civi::$statics[__CLASS__][$cacheKey]; | |
328 | } | |
329 | ||
330 | /** | |
331 | * (Quasi-Private) Do not call externally. For use by DAOs. | |
332 | * | |
333 | * @param string $dao | |
334 | * Ex: 'CRM_Core_DAO_Address'. | |
335 | * @param string $labelName | |
336 | * Ex: 'address'. | |
337 | * @param bool $prefix | |
338 | * @param array $foreignDAOs | |
339 | * @return array | |
340 | */ | |
341 | public static function getImports($dao, $labelName, $prefix, $foreignDAOs) { | |
342 | // Bug-level compatibility -- or sane behavior? | |
343 | $cacheKey = $dao . ':import'; | |
344 | // $cacheKey = $dao . ':' . ($prefix ? 'import-prefix' : 'import'); | |
345 | ||
346 | if (!isset(Civi::$statics[__CLASS__][$cacheKey])) { | |
be2fb01f | 347 | $imports = []; |
84a0493c TO |
348 | $fields = $dao::fields(); |
349 | ||
8246bca4 | 350 | foreach ($fields as $name => $field) { |
de6c59ca | 351 | if (!empty($field['import'])) { |
84a0493c TO |
352 | if ($prefix) { |
353 | $imports[$labelName] = & $fields[$name]; | |
8246bca4 | 354 | } |
355 | else { | |
84a0493c TO |
356 | $imports[$name] = & $fields[$name]; |
357 | } | |
358 | } | |
359 | } | |
360 | ||
361 | foreach ($foreignDAOs as $foreignDAO) { | |
362 | $imports = array_merge($imports, $foreignDAO::import(TRUE)); | |
363 | } | |
364 | ||
365 | Civi::$statics[__CLASS__][$cacheKey] = $imports; | |
366 | } | |
367 | return Civi::$statics[__CLASS__][$cacheKey]; | |
368 | } | |
369 | ||
740dd877 TO |
370 | /** |
371 | * (Quasi-Private) Do not call externally. For use by DAOs. | |
372 | * | |
373 | * Apply any third-party alterations to the `fields()`. | |
374 | * | |
375 | * @param string $className | |
376 | * @param string $event | |
377 | * @param mixed $values | |
378 | */ | |
379 | public static function invoke($className, $event, &$values) { | |
380 | self::init(); | |
381 | if (isset(self::$entityTypes[$className][$event])) { | |
382 | foreach (self::$entityTypes[$className][$event] as $filter) { | |
be2fb01f | 383 | $args = [$className, &$values]; |
740dd877 TO |
384 | \Civi\Core\Resolver::singleton()->call($filter, $args); |
385 | } | |
386 | } | |
387 | } | |
388 | ||
4ef04170 | 389 | } |