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