3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
29 * Component stores all the static and dynamic information of the various
33 * @copyright CiviCRM LLC (c) 2004-2019
37 class CRM_Core_Component
{
40 * End part (filename) of the component information class'es name
41 * that needs to be present in components main directory.
43 const COMPONENT_INFO_CLASS
= 'Info';
48 public static $_contactSubTypes = NULL;
53 * @return CRM_Core_Component_Info[]
55 private static function &_info($force = FALSE) {
56 if (!isset(Civi
::$statics[__CLASS__
]['info'])||
$force) {
57 Civi
::$statics[__CLASS__
]['info'] = [];
60 $config = CRM_Core_Config
::singleton();
61 $c = self
::getComponents();
63 foreach ($c as $name => $comp) {
64 if (in_array($name, $config->enableComponents
)) {
65 Civi
::$statics[__CLASS__
]['info'][$name] = $comp;
70 return Civi
::$statics[__CLASS__
]['info'];
75 * @param null $attribute
79 public static function get($name, $attribute = NULL) {
80 $comp = CRM_Utils_Array
::value($name, self
::_info());
82 return CRM_Utils_Array
::value($attribute, $comp->info
);
90 * @return CRM_Core_Component_Info[]
93 public static function &getComponents($force = FALSE) {
94 if (!isset(Civi
::$statics[__CLASS__
]['all']) ||
$force) {
95 Civi
::$statics[__CLASS__
]['all'] = [];
97 $cr = new CRM_Core_DAO_Component();
99 while ($cr->fetch()) {
100 $infoClass = $cr->namespace . '_' . self
::COMPONENT_INFO_CLASS
;
101 $infoClassFile = str_replace('_', DIRECTORY_SEPARATOR
, $infoClass) . '.php';
102 if (!CRM_Utils_File
::isIncludable($infoClassFile)) {
105 require_once $infoClassFile;
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}).");
110 Civi
::$statics[__CLASS__
]['all'][$cr->name
] = $infoObject;
115 return Civi
::$statics[__CLASS__
]['all'];
120 * Array(string $name => int $id).
122 public static function &getComponentIDs() {
125 $cr = new CRM_Core_DAO_Component();
127 while ($cr->fetch()) {
128 $componentIDs[$cr->name
] = $cr->id
;
131 return $componentIDs;
137 * @return CRM_Core_Component_Info[]
139 public static function &getEnabledComponents($force = FALSE) {
140 return self
::_info($force);
143 public static function flushEnabledComponents() {
144 unset(Civi
::$statics[__CLASS__
]);
145 CRM_Core_BAO_Navigation
::resetNavigation();
149 * @param bool $translated
153 public static function &getNames($translated = FALSE) {
154 $allComponents = self
::getComponents();
157 foreach ($allComponents as $name => $comp) {
159 $names[$comp->componentID
] = $comp->info
['translatedName'];
162 $names[$comp->componentID
] = $name;
174 public static function invoke(&$args, $type) {
175 $info = self
::_info();
176 $config = CRM_Core_Config
::singleton();
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')
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);
190 if (!empty($comp->info
[$name]['formTpl'])) {
191 $template->assign('formTpl', $comp->info
[$name]['formTpl']);
193 if (!empty($comp->info
[$name]['css'])) {
194 $styleSheets = '<style type="text/css">@import url(' . "{$config->resourceBase}css/{$comp->info[$name]['css']});</style>";
195 CRM_Utils_System
::addHTMLHead($styleSheet);
198 $inv = $comp->getInvokeObject();
209 public static function xmlMenu() {
211 // lets build the menu for all components
212 $info = self
::getComponents(TRUE);
215 foreach ($info as $name => $comp) {
216 $files = array_merge($files,
227 public static function &menu() {
228 $info = self
::_info();
230 foreach ($info as $name => $comp) {
231 $mnu = $comp->getMenuObject();
233 $ret = $mnu->permissioned();
234 $items = array_merge($items, $ret);
236 $ret = $mnu->main($task);
237 $items = array_merge($items, $ret);
243 * @param string $componentName
247 public static function getComponentID($componentName) {
248 $info = self
::_info();
249 if (!empty($info[$componentName])) {
250 return $info[$componentName]->componentID
;
258 * @param int $componentID
260 * @return int|null|string
262 public static function getComponentName($componentID) {
263 $info = self
::_info();
265 $componentName = NULL;
266 foreach ($info as $compName => $component) {
267 if ($component->componentID
== $componentID) {
268 $componentName = $compName;
273 return $componentName;
279 public static function &getQueryFields($checkPermission = TRUE) {
280 $info = self
::_info();
282 foreach ($info as $name => $comp) {
283 if ($comp->usesSearch()) {
284 $bqr = $comp->getBAOQueryObject();
285 $flds = $bqr->getFields($checkPermission);
286 $fields = array_merge($fields, $flds);
294 * @param string $fnName
296 public static function alterQuery(&$query, $fnName) {
297 $info = self
::_info();
299 foreach ($info as $name => $comp) {
300 if ($comp->usesSearch()) {
301 $bqr = $comp->getBAOQueryObject();
302 $bqr->$fnName($query);
308 * @param string $fieldName
314 public static function from($fieldName, $mode, $side) {
315 $info = self
::_info();
318 foreach ($info as $name => $comp) {
319 if ($comp->usesSearch()) {
320 $bqr = $comp->getBAOQueryObject();
321 $from = $bqr->from($fieldName, $mode, $side);
332 * @param bool $includeCustomFields
336 public static function &defaultReturnProperties(
338 $includeCustomFields = TRUE
340 $info = self
::_info();
343 foreach ($info as $name => $comp) {
344 if ($comp->usesSearch()) {
345 $bqr = $comp->getBAOQueryObject();
346 $properties = $bqr->defaultReturnProperties($mode, $includeCustomFields);
356 * @param CRM_Core_Form $form
358 public static function &buildSearchForm(&$form) {
359 $info = self
::_info();
361 foreach ($info as $name => $comp) {
362 if ($comp->usesSearch()) {
363 $bqr = $comp->getBAOQueryObject();
364 $bqr->buildSearchForm($form);
373 public static function searchAction(&$row, $id) {
374 $info = self
::_info();
376 foreach ($info as $name => $comp) {
377 if ($comp->usesSearch()) {
378 $bqr = $comp->getBAOQueryObject();
379 $bqr->searchAction($row, $id);
387 public static function &contactSubTypes() {
388 if (self
::$_contactSubTypes == NULL) {
389 self
::$_contactSubTypes = [];
391 return self
::$_contactSubTypes;
400 public static function &contactSubTypeProperties($subType, $op) {
401 $properties = self
::contactSubTypes();
402 if (array_key_exists($subType, $properties) &&
403 array_key_exists($op, $properties[$subType])
405 return $properties[$subType][$op];
407 return CRM_Core_DAO
::$_nullObject;
411 * Handle table dependencies of components.
413 * @param array $tables
417 public static function tableNames(&$tables) {
418 $info = self
::_info();
420 foreach ($info as $name => $comp) {
421 if ($comp->usesSearch()) {
422 $bqr = $comp->getBAOQueryObject();
423 $bqr->tableNames($tables);
429 * Get components info from info file.
431 * @param string $crmFolderDir
435 public static function getComponentsFromFile($crmFolderDir) {
437 //traverse CRM folder and check for Info file
438 if (is_dir($crmFolderDir) && $dir = opendir($crmFolderDir)) {
439 while ($subDir = readdir($dir)) {
440 // skip the extensions diretory since it has an Info.php file also
441 if ($subDir == 'Extension') {
445 $infoFile = $crmFolderDir . "/{$subDir}/" . self
::COMPONENT_INFO_CLASS
. '.php';
446 if (file_exists($infoFile)) {
447 $infoClass = 'CRM_' . $subDir . '_' . self
::COMPONENT_INFO_CLASS
;
448 require_once str_replace('_', DIRECTORY_SEPARATOR
, $infoClass) . '.php';
449 $infoObject = new $infoClass(NULL, NULL, NULL);
450 $components[$infoObject->info
['name']] = $infoObject;