3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 +--------------------------------------------------------------------+
13 * Component stores all the static and dynamic information of the various
17 * @copyright CiviCRM LLC https://civicrm.org/licensing
21 class CRM_Core_Component
{
24 * End part (filename) of the component information class'es name
25 * that needs to be present in components main directory.
27 const COMPONENT_INFO_CLASS
= 'Info';
32 public static $_contactSubTypes = NULL;
37 * @return CRM_Core_Component_Info[]
39 private static function &_info($force = FALSE) {
40 if (!isset(Civi
::$statics[__CLASS__
]['info'])||
$force) {
41 Civi
::$statics[__CLASS__
]['info'] = [];
44 $config = CRM_Core_Config
::singleton();
45 $c = self
::getComponents();
47 foreach ($c as $name => $comp) {
48 if (in_array($name, $config->enableComponents
)) {
49 Civi
::$statics[__CLASS__
]['info'][$name] = $comp;
54 return Civi
::$statics[__CLASS__
]['info'];
59 * @param null $attribute
63 public static function get($name, $attribute = NULL) {
64 $comp = CRM_Utils_Array
::value($name, self
::_info());
66 return $comp->info
[$attribute] ??
NULL;
74 * @return CRM_Core_Component_Info[]
77 public static function &getComponents($force = FALSE) {
78 if (!isset(Civi
::$statics[__CLASS__
]['all']) ||
$force) {
79 Civi
::$statics[__CLASS__
]['all'] = [];
81 $cr = new CRM_Core_DAO_Component();
83 while ($cr->fetch()) {
84 $infoClass = $cr->namespace . '_' . self
::COMPONENT_INFO_CLASS
;
85 $infoClassFile = str_replace('_', DIRECTORY_SEPARATOR
, $infoClass) . '.php';
86 if (!CRM_Utils_File
::isIncludable($infoClassFile)) {
89 require_once $infoClassFile;
90 $infoObject = new $infoClass($cr->name
, $cr->namespace, $cr->id
);
91 if ($infoObject->info
['name'] !== $cr->name
) {
92 CRM_Core_Error
::fatal("There is a discrepancy between name in component registry and in info file ({$cr->name}).");
94 Civi
::$statics[__CLASS__
]['all'][$cr->name
] = $infoObject;
99 return Civi
::$statics[__CLASS__
]['all'];
104 * Array(string $name => int $id).
106 public static function &getComponentIDs() {
109 $cr = new CRM_Core_DAO_Component();
111 while ($cr->fetch()) {
112 $componentIDs[$cr->name
] = $cr->id
;
115 return $componentIDs;
121 * @return CRM_Core_Component_Info[]
123 public static function &getEnabledComponents($force = FALSE) {
124 return self
::_info($force);
127 public static function flushEnabledComponents() {
128 unset(Civi
::$statics[__CLASS__
]);
129 CRM_Core_BAO_Navigation
::resetNavigation();
133 * @param bool $translated
137 public static function &getNames($translated = FALSE) {
138 $allComponents = self
::getComponents();
141 foreach ($allComponents as $name => $comp) {
143 $names[$comp->componentID
] = $comp->info
['translatedName'];
146 $names[$comp->componentID
] = $name;
158 public static function invoke(&$args, $type) {
159 $info = self
::_info();
160 $config = CRM_Core_Config
::singleton();
162 $firstArg = CRM_Utils_Array
::value(1, $args, '');
163 $secondArg = CRM_Utils_Array
::value(2, $args, '');
164 foreach ($info as $name => $comp) {
165 if (in_array($name, $config->enableComponents
) &&
166 (($comp->info
['url'] === $firstArg && $type == 'main') ||
167 ($comp->info
['url'] === $secondArg && $type == 'admin')
170 if ($type == 'main') {
171 // also set the smarty variables to the current component
172 $template = CRM_Core_Smarty
::singleton();
173 $template->assign('activeComponent', $name);
174 if (!empty($comp->info
[$name]['formTpl'])) {
175 $template->assign('formTpl', $comp->info
[$name]['formTpl']);
177 if (!empty($comp->info
[$name]['css'])) {
178 $styleSheets = '<style type="text/css">@import url(' . "{$config->resourceBase}css/{$comp->info[$name]['css']});</style>";
179 CRM_Utils_System
::addHTMLHead($styleSheet);
182 $inv = $comp->getInvokeObject();
193 public static function xmlMenu() {
195 // lets build the menu for all components
196 $info = self
::getComponents(TRUE);
199 foreach ($info as $name => $comp) {
200 $files = array_merge($files,
211 public static function &menu() {
212 $info = self
::_info();
214 foreach ($info as $name => $comp) {
215 $mnu = $comp->getMenuObject();
217 $ret = $mnu->permissioned();
218 $items = array_merge($items, $ret);
220 $ret = $mnu->main($task);
221 $items = array_merge($items, $ret);
227 * @param string $componentName
231 public static function getComponentID($componentName) {
232 $info = self
::_info();
233 if (!empty($info[$componentName])) {
234 return $info[$componentName]->componentID
;
242 * @param int $componentID
244 * @return int|null|string
246 public static function getComponentName($componentID) {
247 $info = self
::_info();
249 $componentName = NULL;
250 foreach ($info as $compName => $component) {
251 if ($component->componentID
== $componentID) {
252 $componentName = $compName;
257 return $componentName;
263 public static function &getQueryFields($checkPermission = TRUE) {
264 $info = self
::_info();
266 foreach ($info as $name => $comp) {
267 if ($comp->usesSearch()) {
268 $bqr = $comp->getBAOQueryObject();
269 $flds = $bqr->getFields($checkPermission);
270 $fields = array_merge($fields, $flds);
278 * @param string $fnName
280 public static function alterQuery(&$query, $fnName) {
281 $info = self
::_info();
283 foreach ($info as $name => $comp) {
284 if ($comp->usesSearch()) {
285 $bqr = $comp->getBAOQueryObject();
286 $bqr->$fnName($query);
292 * @param string $fieldName
298 public static function from($fieldName, $mode, $side) {
299 $info = self
::_info();
302 foreach ($info as $name => $comp) {
303 if ($comp->usesSearch()) {
304 $bqr = $comp->getBAOQueryObject();
305 $from = $bqr->from($fieldName, $mode, $side);
316 * @param bool $includeCustomFields
320 public static function &defaultReturnProperties(
322 $includeCustomFields = TRUE
324 $info = self
::_info();
327 foreach ($info as $name => $comp) {
328 if ($comp->usesSearch()) {
329 $bqr = $comp->getBAOQueryObject();
330 $properties = $bqr->defaultReturnProperties($mode, $includeCustomFields);
340 * @param CRM_Core_Form $form
342 public static function &buildSearchForm(&$form) {
343 $info = self
::_info();
345 foreach ($info as $name => $comp) {
346 if ($comp->usesSearch()) {
347 $bqr = $comp->getBAOQueryObject();
348 $bqr->buildSearchForm($form);
357 public static function searchAction(&$row, $id) {
358 $info = self
::_info();
360 foreach ($info as $name => $comp) {
361 if ($comp->usesSearch()) {
362 $bqr = $comp->getBAOQueryObject();
363 $bqr->searchAction($row, $id);
371 public static function &contactSubTypes() {
372 if (self
::$_contactSubTypes == NULL) {
373 self
::$_contactSubTypes = [];
375 return self
::$_contactSubTypes;
384 public static function &contactSubTypeProperties($subType, $op) {
385 $properties = self
::contactSubTypes();
386 if (array_key_exists($subType, $properties) &&
387 array_key_exists($op, $properties[$subType])
389 return $properties[$subType][$op];
391 return CRM_Core_DAO
::$_nullObject;
395 * Handle table dependencies of components.
397 * @param array $tables
401 public static function tableNames(&$tables) {
402 $info = self
::_info();
404 foreach ($info as $name => $comp) {
405 if ($comp->usesSearch()) {
406 $bqr = $comp->getBAOQueryObject();
407 $bqr->tableNames($tables);
413 * Get components info from info file.
415 * @param string $crmFolderDir
419 public static function getComponentsFromFile($crmFolderDir) {
421 //traverse CRM folder and check for Info file
422 if (is_dir($crmFolderDir) && $dir = opendir($crmFolderDir)) {
423 while ($subDir = readdir($dir)) {
424 // skip the extensions diretory since it has an Info.php file also
425 if ($subDir == 'Extension') {
429 $infoFile = $crmFolderDir . "/{$subDir}/" . self
::COMPONENT_INFO_CLASS
. '.php';
430 if (file_exists($infoFile)) {
431 $infoClass = 'CRM_' . $subDir . '_' . self
::COMPONENT_INFO_CLASS
;
432 require_once str_replace('_', DIRECTORY_SEPARATOR
, $infoClass) . '.php';
433 $infoObject = new $infoClass(NULL, NULL, NULL);
434 $components[$infoObject->info
['name']] = $infoObject;