Merge pull request #15181 from seamuslee001/mailing_search_date_picker_conversion
[civicrm-core.git] / CRM / Core / Component.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 * Component stores all the static and dynamic information of the various
30 * CiviCRM components
31 *
32 * @package CRM
6b83d5bd 33 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
34 * $Id$
35 *
36 */
37class CRM_Core_Component {
38
c490a46a
CW
39 /**
40 * End part (filename) of the component information class'es name
41 * that needs to be present in components main directory.
42 */
7da04cde 43 const COMPONENT_INFO_CLASS = 'Info';
6a488035 44
518fa0ee
SL
45 /**
46 * @var array
47 */
48 public static $_contactSubTypes = NULL;
6a488035 49
a0ee3941
EM
50 /**
51 * @param bool $force
52 *
9a13600c 53 * @return CRM_Core_Component_Info[]
a0ee3941 54 */
6a488035 55 private static function &_info($force = FALSE) {
edbcbd96 56 if (!isset(Civi::$statics[__CLASS__]['info'])|| $force) {
be2fb01f
CW
57 Civi::$statics[__CLASS__]['info'] = [];
58 $c = [];
6a488035
TO
59
60 $config = CRM_Core_Config::singleton();
61 $c = self::getComponents();
62
63 foreach ($c as $name => $comp) {
64 if (in_array($name, $config->enableComponents)) {
edbcbd96 65 Civi::$statics[__CLASS__]['info'][$name] = $comp;
6a488035
TO
66 }
67 }
68 }
69
edbcbd96 70 return Civi::$statics[__CLASS__]['info'];
6a488035
TO
71 }
72
a0ee3941 73 /**
100fef9d 74 * @param string $name
a0ee3941
EM
75 * @param null $attribute
76 *
77 * @return mixed
78 */
00be9182 79 public static function get($name, $attribute = NULL) {
6a488035
TO
80 $comp = CRM_Utils_Array::value($name, self::_info());
81 if ($attribute) {
82 return CRM_Utils_Array::value($attribute, $comp->info);
83 }
84 return $comp;
85 }
86
a0ee3941
EM
87 /**
88 * @param bool $force
89 *
9a13600c 90 * @return CRM_Core_Component_Info[]
a0ee3941
EM
91 * @throws Exception
92 */
6a488035 93 public static function &getComponents($force = FALSE) {
edbcbd96 94 if (!isset(Civi::$statics[__CLASS__]['all']) || $force) {
be2fb01f 95 Civi::$statics[__CLASS__]['all'] = [];
6a488035
TO
96
97 $cr = new CRM_Core_DAO_Component();
98 $cr->find(FALSE);
99 while ($cr->fetch()) {
100 $infoClass = $cr->namespace . '_' . self::COMPONENT_INFO_CLASS;
4d669903 101 $infoClassFile = str_replace('_', DIRECTORY_SEPARATOR, $infoClass) . '.php';
102 if (!CRM_Utils_File::isIncludable($infoClassFile)) {
103 continue;
104 }
105 require_once $infoClassFile;
6a488035
TO
106 $infoObject = new $infoClass($cr->name, $cr->namespace, $cr->id);
107 if ($infoObject->info['name'] !== $cr->name) {
108 CRM_Core_Error::fatal("There is a discrepancy between name in component registry and in info file ({$cr->name}).");
109 }
edbcbd96 110 Civi::$statics[__CLASS__]['all'][$cr->name] = $infoObject;
6a488035
TO
111 unset($infoObject);
112 }
113 }
114
edbcbd96 115 return Civi::$statics[__CLASS__]['all'];
6a488035
TO
116 }
117
2ce81580
TO
118 /**
119 * @return array
120 * Array(string $name => int $id).
121 */
122 public static function &getComponentIDs() {
be2fb01f 123 $componentIDs = [];
2ce81580
TO
124
125 $cr = new CRM_Core_DAO_Component();
126 $cr->find(FALSE);
127 while ($cr->fetch()) {
128 $componentIDs[$cr->name] = $cr->id;
129 }
130
131 return $componentIDs;
132 }
133
a0ee3941
EM
134 /**
135 * @param bool $force
136 *
9a13600c 137 * @return CRM_Core_Component_Info[]
a0ee3941 138 */
518fa0ee 139 public static function &getEnabledComponents($force = FALSE) {
6a488035
TO
140 return self::_info($force);
141 }
2dd1b730 142
518fa0ee 143 public static function flushEnabledComponents() {
3ea36d17 144 unset(Civi::$statics[__CLASS__]);
281db812 145 CRM_Core_BAO_Navigation::resetNavigation();
3d0e24ec 146 }
6a488035 147
a0ee3941
EM
148 /**
149 * @param bool $translated
150 *
151 * @return array
152 */
6a488035
TO
153 public static function &getNames($translated = FALSE) {
154 $allComponents = self::getComponents();
155
be2fb01f 156 $names = [];
6a488035
TO
157 foreach ($allComponents as $name => $comp) {
158 if ($translated) {
159 $names[$comp->componentID] = $comp->info['translatedName'];
160 }
161 else {
162 $names[$comp->componentID] = $name;
163 }
164 }
165 return $names;
166 }
167
a0ee3941
EM
168 /**
169 * @param $args
170 * @param $type
171 *
172 * @return bool
173 */
00be9182 174 public static function invoke(&$args, $type) {
6a488035
TO
175 $info = self::_info();
176 $config = CRM_Core_Config::singleton();
177
178 $firstArg = CRM_Utils_Array::value(1, $args, '');
179 $secondArg = CRM_Utils_Array::value(2, $args, '');
180 foreach ($info as $name => $comp) {
181 if (in_array($name, $config->enableComponents) &&
182 (($comp->info['url'] === $firstArg && $type == 'main') ||
183 ($comp->info['url'] === $secondArg && $type == 'admin')
184 )
185 ) {
186 if ($type == 'main') {
187 // also set the smarty variables to the current component
188 $template = CRM_Core_Smarty::singleton();
189 $template->assign('activeComponent', $name);
a7488080 190 if (!empty($comp->info[$name]['formTpl'])) {
6a488035
TO
191 $template->assign('formTpl', $comp->info[$name]['formTpl']);
192 }
a7488080 193 if (!empty($comp->info[$name]['css'])) {
6a488035
TO
194 $styleSheets = '<style type="text/css">@import url(' . "{$config->resourceBase}css/{$comp->info[$name]['css']});</style>";
195 CRM_Utils_System::addHTMLHead($styleSheet);
196 }
197 }
198 $inv = $comp->getInvokeObject();
199 $inv->$type($args);
200 return TRUE;
201 }
202 }
203 return FALSE;
204 }
205
a0ee3941
EM
206 /**
207 * @return array
208 */
00be9182 209 public static function xmlMenu() {
6a488035
TO
210
211 // lets build the menu for all components
212 $info = self::getComponents(TRUE);
213
be2fb01f 214 $files = [];
6a488035
TO
215 foreach ($info as $name => $comp) {
216 $files = array_merge($files,
217 $comp->menuFiles()
218 );
219 }
220
221 return $files;
222 }
223
a0ee3941
EM
224 /**
225 * @return array
226 */
00be9182 227 public static function &menu() {
6a488035 228 $info = self::_info();
be2fb01f 229 $items = [];
6a488035
TO
230 foreach ($info as $name => $comp) {
231 $mnu = $comp->getMenuObject();
232
233 $ret = $mnu->permissioned();
234 $items = array_merge($items, $ret);
235
236 $ret = $mnu->main($task);
237 $items = array_merge($items, $ret);
238 }
239 return $items;
240 }
241
a0ee3941 242 /**
100fef9d 243 * @param string $componentName
a0ee3941
EM
244 *
245 * @return mixed
246 */
00be9182 247 public static function getComponentID($componentName) {
6a488035 248 $info = self::_info();
7b60d5b9 249 if (!empty($info[$componentName])) {
250 return $info[$componentName]->componentID;
251 }
252 else {
253 return;
254 }
6a488035
TO
255 }
256
a0ee3941 257 /**
100fef9d 258 * @param int $componentID
a0ee3941
EM
259 *
260 * @return int|null|string
261 */
00be9182 262 public static function getComponentName($componentID) {
6a488035
TO
263 $info = self::_info();
264
265 $componentName = NULL;
266 foreach ($info as $compName => $component) {
267 if ($component->componentID == $componentID) {
268 $componentName = $compName;
269 break;
270 }
271 }
272
273 return $componentName;
274 }
275
a0ee3941
EM
276 /**
277 * @return array
278 */
5837835b 279 public static function &getQueryFields($checkPermission = TRUE) {
6a488035 280 $info = self::_info();
be2fb01f 281 $fields = [];
6a488035
TO
282 foreach ($info as $name => $comp) {
283 if ($comp->usesSearch()) {
353ffa53 284 $bqr = $comp->getBAOQueryObject();
5837835b 285 $flds = $bqr->getFields($checkPermission);
6a488035
TO
286 $fields = array_merge($fields, $flds);
287 }
288 }
289 return $fields;
290 }
291
a0ee3941
EM
292 /**
293 * @param $query
100fef9d 294 * @param string $fnName
a0ee3941 295 */
00be9182 296 public static function alterQuery(&$query, $fnName) {
6a488035
TO
297 $info = self::_info();
298
299 foreach ($info as $name => $comp) {
300 if ($comp->usesSearch()) {
301 $bqr = $comp->getBAOQueryObject();
302 $bqr->$fnName($query);
303 }
304 }
305 }
306
a0ee3941 307 /**
100fef9d 308 * @param string $fieldName
a0ee3941
EM
309 * @param $mode
310 * @param $side
311 *
312 * @return null
313 */
00be9182 314 public static function from($fieldName, $mode, $side) {
6a488035
TO
315 $info = self::_info();
316
317 $from = NULL;
318 foreach ($info as $name => $comp) {
319 if ($comp->usesSearch()) {
320 $bqr = $comp->getBAOQueryObject();
321 $from = $bqr->from($fieldName, $mode, $side);
322 if ($from) {
323 return $from;
324 }
325 }
326 }
327 return $from;
328 }
329
a0ee3941
EM
330 /**
331 * @param $mode
332 * @param bool $includeCustomFields
333 *
334 * @return null
335 */
317fceb4 336 public static function &defaultReturnProperties(
f9f40af3 337 $mode,
6a488035
TO
338 $includeCustomFields = TRUE
339 ) {
340 $info = self::_info();
341
342 $properties = NULL;
343 foreach ($info as $name => $comp) {
344 if ($comp->usesSearch()) {
345 $bqr = $comp->getBAOQueryObject();
346 $properties = $bqr->defaultReturnProperties($mode, $includeCustomFields);
347 if ($properties) {
348 return $properties;
349 }
350 }
351 }
352 return $properties;
353 }
354
a0ee3941 355 /**
c490a46a 356 * @param CRM_Core_Form $form
a0ee3941 357 */
00be9182 358 public static function &buildSearchForm(&$form) {
6a488035
TO
359 $info = self::_info();
360
361 foreach ($info as $name => $comp) {
362 if ($comp->usesSearch()) {
363 $bqr = $comp->getBAOQueryObject();
364 $bqr->buildSearchForm($form);
365 }
366 }
367 }
368
a0ee3941
EM
369 /**
370 * @param $row
100fef9d 371 * @param int $id
a0ee3941 372 */
00be9182 373 public static function searchAction(&$row, $id) {
6a488035
TO
374 $info = self::_info();
375
376 foreach ($info as $name => $comp) {
377 if ($comp->usesSearch()) {
378 $bqr = $comp->getBAOQueryObject();
379 $bqr->searchAction($row, $id);
380 }
381 }
382 }
383
a0ee3941
EM
384 /**
385 * @return array|null
386 */
00be9182 387 public static function &contactSubTypes() {
6a488035 388 if (self::$_contactSubTypes == NULL) {
be2fb01f 389 self::$_contactSubTypes = [];
6a488035
TO
390 }
391 return self::$_contactSubTypes;
392 }
393
a0ee3941
EM
394 /**
395 * @param $subType
396 * @param $op
397 *
398 * @return null
399 */
00be9182 400 public static function &contactSubTypeProperties($subType, $op) {
6a488035
TO
401 $properties = self::contactSubTypes();
402 if (array_key_exists($subType, $properties) &&
403 array_key_exists($op, $properties[$subType])
404 ) {
405 return $properties[$subType][$op];
406 }
407 return CRM_Core_DAO::$_nullObject;
408 }
409
6a488035 410 /**
0880a9d0 411 * Handle table dependencies of components.
6a488035 412 *
6a0b768e
TO
413 * @param array $tables
414 * Array of tables.
6a488035 415 *
6a488035 416 */
00be9182 417 public static function tableNames(&$tables) {
6a488035
TO
418 $info = self::_info();
419
420 foreach ($info as $name => $comp) {
421 if ($comp->usesSearch()) {
422 $bqr = $comp->getBAOQueryObject();
423 $bqr->tableNames($tables);
424 }
425 }
426 }
427
428 /**
0880a9d0 429 * Get components info from info file.
ea3ddccf 430 *
431 * @param string $crmFolderDir
432 *
433 * @return array
6a488035 434 */
00be9182 435 public static function getComponentsFromFile($crmFolderDir) {
be2fb01f 436 $components = [];
6a488035 437 //traverse CRM folder and check for Info file
948d11bf 438 if (is_dir($crmFolderDir) && $dir = opendir($crmFolderDir)) {
6a488035
TO
439 while ($subDir = readdir($dir)) {
440 // skip the extensions diretory since it has an Info.php file also
441 if ($subDir == 'Extension') {
442 continue;
443 }
444
445 $infoFile = $crmFolderDir . "/{$subDir}/" . self::COMPONENT_INFO_CLASS . '.php';
446 if (file_exists($infoFile)) {
447 $infoClass = 'CRM_' . $subDir . '_' . self::COMPONENT_INFO_CLASS;
2aa397bc 448 require_once str_replace('_', DIRECTORY_SEPARATOR, $infoClass) . '.php';
6a488035
TO
449 $infoObject = new $infoClass(NULL, NULL, NULL);
450 $components[$infoObject->info['name']] = $infoObject;
451 unset($infoObject);
452 }
453 }
454 }
455
456 return $components;
457 }
96025800 458
6a488035 459}