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