PageRenderTime 28ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/fof/autoloader/component.php

https://github.com/J2MTecnologia/joomla-3.x
PHP | 819 lines | 472 code | 166 blank | 181 comment | 114 complexity | 549ae82b07ecb968db448ca48d2025c7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * @package FrameworkOnFramework
  4. * @subpackage autoloader
  5. * @copyright Copyright (c)2010-2014 Nicholas K. Dionysopoulos
  6. * @license GNU General Public License version 2, or later
  7. */
  8. defined('FOF_INCLUDED') or die();
  9. /**
  10. * An autoloader for FOF-powered components. It allows the autoloading of
  11. * various classes related to the operation of a component, from Controllers
  12. * and Models to Helpers and Fields. If a class doesn't exist, it will be
  13. * created on the fly.
  14. *
  15. * @package FrameworkOnFramework
  16. * @subpackage autoloader
  17. * @since 2.1
  18. */
  19. class FOFAutoloaderComponent
  20. {
  21. /**
  22. * An instance of this autoloader
  23. *
  24. * @var FOFAutoloaderComponent
  25. */
  26. public static $autoloader = null;
  27. /**
  28. * The path to the FOF root directory
  29. *
  30. * @var string
  31. */
  32. public static $fofPath = null;
  33. /**
  34. * An array holding component names and their FOF-ness status
  35. *
  36. * @var array
  37. */
  38. protected static $fofComponents = array();
  39. /**
  40. * Initialise this autoloader
  41. *
  42. * @return FOFAutoloaderComponent
  43. */
  44. public static function init()
  45. {
  46. if (self::$autoloader == null)
  47. {
  48. self::$autoloader = new self;
  49. }
  50. return self::$autoloader;
  51. }
  52. /**
  53. * Public constructor. Registers the autoloader with PHP.
  54. */
  55. public function __construct()
  56. {
  57. self::$fofPath = realpath(__DIR__ . '/../');
  58. spl_autoload_register(array($this,'autoload_fof_controller'));
  59. spl_autoload_register(array($this,'autoload_fof_model'));
  60. spl_autoload_register(array($this,'autoload_fof_view'));
  61. spl_autoload_register(array($this,'autoload_fof_table'));
  62. spl_autoload_register(array($this,'autoload_fof_helper'));
  63. spl_autoload_register(array($this,'autoload_fof_toolbar'));
  64. spl_autoload_register(array($this,'autoload_fof_field'));
  65. }
  66. /**
  67. * Returns true if this is a FOF-powered component, i.e. if it has a fof.xml
  68. * file in its main directory.
  69. *
  70. * @param string $component The component's name
  71. *
  72. * @return boolean
  73. */
  74. public function isFOFComponent($component)
  75. {
  76. if (!isset($fofComponents[$component]))
  77. {
  78. $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component);
  79. $fofComponents[$component] = file_exists($componentPaths['admin'] . '/fof.xml');
  80. }
  81. return $fofComponents[$component];
  82. }
  83. /**
  84. * Creates class aliases. On systems where eval() is enabled it creates a
  85. * real class. On other systems it merely creates an alias. The eval()
  86. * method is preferred as class_aliases result in the name of the class
  87. * being instanciated not being available, making it impossible to create
  88. * a class instance without passing a $config array :(
  89. *
  90. * @param string $original The name of the original (existing) class
  91. * @param string $alias The name of the new (aliased) class
  92. * @param boolean $autoload Should I try to autoload the $original class?
  93. *
  94. * @return void
  95. */
  96. private function class_alias($original, $alias, $autoload = true)
  97. {
  98. static $hasEval = null;
  99. if (is_null($hasEval))
  100. {
  101. $hasEval = false;
  102. if (function_exists('ini_get'))
  103. {
  104. $disabled_functions = ini_get('disabled_functions');
  105. if (!is_string($disabled_functions))
  106. {
  107. $hasEval = true;
  108. }
  109. else
  110. {
  111. $disabled_functions = explode(',', $disabled_functions);
  112. $hasEval = !in_array('eval', $disabled_functions);
  113. }
  114. }
  115. }
  116. if (!class_exists($original, $autoload))
  117. {
  118. return;
  119. }
  120. if ($hasEval)
  121. {
  122. $phpCode = "class $alias extends $original {}";
  123. eval($phpCode);
  124. }
  125. else
  126. {
  127. class_alias($original, $alias, $autoload);
  128. }
  129. }
  130. /**
  131. * Autoload Controllers
  132. *
  133. * @param string $class_name The name of the class to load
  134. *
  135. * @return void
  136. */
  137. public function autoload_fof_controller($class_name)
  138. {
  139. FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
  140. static $isCli = null, $isAdmin = null;
  141. if (is_null($isCli) && is_null($isAdmin))
  142. {
  143. list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin();
  144. }
  145. if (strpos($class_name, 'Controller') === false)
  146. {
  147. return;
  148. }
  149. // Change from camel cased into a lowercase array
  150. $class_modified = preg_replace('/(\s)+/', '_', $class_name);
  151. $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
  152. $parts = explode('_', $class_modified);
  153. // We need three parts in the name
  154. if (count($parts) != 3)
  155. {
  156. return;
  157. }
  158. // We need the second part to be "controller"
  159. if ($parts[1] != 'controller')
  160. {
  161. return;
  162. }
  163. // Get the information about this class
  164. $component_raw = $parts[0];
  165. $component = 'com_' . $parts[0];
  166. $view = $parts[2];
  167. // Is this an FOF 2.1 or later component?
  168. if (!$this->isFOFComponent($component))
  169. {
  170. return;
  171. }
  172. // Get the alternate view and class name (opposite singular/plural name)
  173. $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
  174. $alt_class = FOFInflector::camelize($component_raw . '_controller_' . $alt_view);
  175. // Get the component's paths
  176. $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component);
  177. // Get the proper and alternate paths and file names
  178. $file = "/controllers/$view.php";
  179. $altFile = "/controllers/$alt_view.php";
  180. $path = $componentPaths['main'];
  181. $altPath = $componentPaths['alt'];
  182. // Try to find the proper class in the proper path
  183. if (file_exists($path . $file))
  184. {
  185. @include_once $path . $file;
  186. }
  187. // Try to find the proper class in the alternate path
  188. if (!class_exists($class_name) && file_exists($altPath . $file))
  189. {
  190. @include_once $altPath . $file;
  191. }
  192. // Try to find the alternate class in the proper path
  193. if (!class_exists($alt_class) && file_exists($path . $altFile))
  194. {
  195. @include_once $path . $altFile;
  196. }
  197. // Try to find the alternate class in the alternate path
  198. if (!class_exists($alt_class) && file_exists($altPath . $altFile))
  199. {
  200. @include_once $altPath . $altFile;
  201. }
  202. // If the alternate class exists just map the class to the alternate
  203. if (!class_exists($class_name) && class_exists($alt_class))
  204. {
  205. $this->class_alias($alt_class, $class_name);
  206. }
  207. // No class found? Map to FOFController
  208. elseif (!class_exists($class_name))
  209. {
  210. if ($view != 'default')
  211. {
  212. $defaultClass = FOFInflector::camelize($component_raw . '_controller_default');
  213. $this->class_alias($defaultClass, $class_name);
  214. }
  215. else
  216. {
  217. $this->class_alias('FOFController', $class_name);
  218. }
  219. }
  220. }
  221. /**
  222. * Autoload Models
  223. *
  224. * @param string $class_name The name of the class to load
  225. *
  226. * @return void
  227. */
  228. public function autoload_fof_model($class_name)
  229. {
  230. FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
  231. static $isCli = null, $isAdmin = null;
  232. if (is_null($isCli) && is_null($isAdmin))
  233. {
  234. list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin();
  235. }
  236. if (strpos($class_name, 'Model') === false)
  237. {
  238. return;
  239. }
  240. // Change from camel cased into a lowercase array
  241. $class_modified = preg_replace('/(\s)+/', '_', $class_name);
  242. $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
  243. $parts = explode('_', $class_modified);
  244. // We need three parts in the name
  245. if (count($parts) != 3)
  246. {
  247. return;
  248. }
  249. // We need the second part to be "model"
  250. if ($parts[1] != 'model')
  251. {
  252. return;
  253. }
  254. // Get the information about this class
  255. $component_raw = $parts[0];
  256. $component = 'com_' . $parts[0];
  257. $view = $parts[2];
  258. // Is this an FOF 2.1 or later component?
  259. if (!$this->isFOFComponent($component))
  260. {
  261. return;
  262. }
  263. // Get the alternate view and class name (opposite singular/plural name)
  264. $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
  265. $alt_class = FOFInflector::camelize($component_raw . '_model_' . $alt_view);
  266. // Get the proper and alternate paths and file names
  267. $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component);
  268. $file = "/models/$view.php";
  269. $altFile = "/models/$alt_view.php";
  270. $path = $componentPaths['main'];
  271. $altPath = $componentPaths['alt'];
  272. // Try to find the proper class in the proper path
  273. if (file_exists($path . $file))
  274. {
  275. @include_once $path . $file;
  276. }
  277. // Try to find the proper class in the alternate path
  278. if (!class_exists($class_name) && file_exists($altPath . $file))
  279. {
  280. @include_once $altPath . $file;
  281. }
  282. // Try to find the alternate class in the proper path
  283. if (!class_exists($alt_class) && file_exists($path . $altFile))
  284. {
  285. @include_once $path . $altFile;
  286. }
  287. // Try to find the alternate class in the alternate path
  288. if (!class_exists($alt_class) && file_exists($altPath . $altFile))
  289. {
  290. @include_once $altPath . $altFile;
  291. }
  292. // If the alternate class exists just map the class to the alternate
  293. if (!class_exists($class_name) && class_exists($alt_class))
  294. {
  295. $this->class_alias($alt_class, $class_name);
  296. }
  297. // No class found? Map to FOFModel
  298. elseif (!class_exists($class_name))
  299. {
  300. if ($view != 'default')
  301. {
  302. $defaultClass = FOFInflector::camelize($component_raw . '_model_default');
  303. $this->class_alias($defaultClass, $class_name);
  304. }
  305. else
  306. {
  307. $this->class_alias('FOFModel', $class_name, true);
  308. }
  309. }
  310. }
  311. /**
  312. * Autoload Views
  313. *
  314. * @param string $class_name The name of the class to load
  315. *
  316. * @return void
  317. */
  318. public function autoload_fof_view($class_name)
  319. {
  320. FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
  321. static $isCli = null, $isAdmin = null;
  322. if (is_null($isCli) && is_null($isAdmin))
  323. {
  324. list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin();
  325. }
  326. if (strpos($class_name, 'View') === false)
  327. {
  328. return;
  329. }
  330. // Change from camel cased into a lowercase array
  331. $class_modified = preg_replace('/(\s)+/', '_', $class_name);
  332. $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
  333. $parts = explode('_', $class_modified);
  334. // We need at least three parts in the name
  335. if (count($parts) < 3)
  336. {
  337. return;
  338. }
  339. // We need the second part to be "view"
  340. if ($parts[1] != 'view')
  341. {
  342. return;
  343. }
  344. // Get the information about this class
  345. $component_raw = $parts[0];
  346. $component = 'com_' . $parts[0];
  347. $view = $parts[2];
  348. if (count($parts) > 3)
  349. {
  350. $format = $parts[3];
  351. }
  352. else
  353. {
  354. $input = new FOFInput;
  355. $format = $input->getCmd('format', 'html', 'cmd');
  356. }
  357. // Is this an FOF 2.1 or later component?
  358. if (!$this->isFOFComponent($component))
  359. {
  360. return;
  361. }
  362. // Get the alternate view and class name (opposite singular/plural name)
  363. $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
  364. $alt_class = FOFInflector::camelize($component_raw . '_view_' . $alt_view);
  365. // Get the proper and alternate paths and file names
  366. $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component);
  367. $protoFile = "/models/$view";
  368. $protoAltFile = "/models/$alt_view";
  369. $path = $componentPaths['main'];
  370. $altPath = $componentPaths['alt'];
  371. $formats = array($format);
  372. if ($format != 'html')
  373. {
  374. $formats[] = 'raw';
  375. }
  376. foreach ($formats as $currentFormat)
  377. {
  378. $file = $protoFile . '.' . $currentFormat . '.php';
  379. $altFile = $protoAltFile . '.' . $currentFormat . '.php';
  380. // Try to find the proper class in the proper path
  381. if (!class_exists($class_name) && file_exists($path . $file))
  382. {
  383. @include_once $path . $file;
  384. }
  385. // Try to find the proper class in the alternate path
  386. if (!class_exists($class_name) && file_exists($altPath . $file))
  387. {
  388. @include_once $altPath . $file;
  389. }
  390. // Try to find the alternate class in the proper path
  391. if (!class_exists($alt_class) && file_exists($path . $altFile))
  392. {
  393. @include_once $path . $altFile;
  394. }
  395. // Try to find the alternate class in the alternate path
  396. if (!class_exists($alt_class) && file_exists($altPath . $altFile))
  397. {
  398. @include_once $altPath . $altFile;
  399. }
  400. }
  401. // If the alternate class exists just map the class to the alternate
  402. if (!class_exists($class_name) && class_exists($alt_class))
  403. {
  404. $this->class_alias($alt_class, $class_name);
  405. }
  406. // No class found? Map to FOFModel
  407. elseif (!class_exists($class_name))
  408. {
  409. if ($view != 'default')
  410. {
  411. $defaultClass = FOFInflector::camelize($component_raw . '_view_default');
  412. $this->class_alias($defaultClass, $class_name);
  413. }
  414. else
  415. {
  416. if (!file_exists(self::$fofPath . '/view/' . $format . '.php'))
  417. {
  418. $default_class = 'FOFView';
  419. }
  420. else
  421. {
  422. $default_class = 'FOFView' . ucfirst($format);
  423. }
  424. $this->class_alias($default_class, $class_name, true);
  425. }
  426. }
  427. }
  428. /**
  429. * Autoload Tables
  430. *
  431. * @param string $class_name The name of the class to load
  432. *
  433. * @return void
  434. */
  435. public function autoload_fof_table($class_name)
  436. {
  437. FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
  438. static $isCli = null, $isAdmin = null;
  439. if (is_null($isCli) && is_null($isAdmin))
  440. {
  441. list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin();
  442. }
  443. if (strpos($class_name, 'Table') === false)
  444. {
  445. return;
  446. }
  447. // Change from camel cased into a lowercase array
  448. $class_modified = preg_replace('/(\s)+/', '_', $class_name);
  449. $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
  450. $parts = explode('_', $class_modified);
  451. // We need three parts in the name
  452. if (count($parts) != 3)
  453. {
  454. return;
  455. }
  456. // We need the second part to be "model"
  457. if ($parts[1] != 'table')
  458. {
  459. return;
  460. }
  461. // Get the information about this class
  462. $component_raw = $parts[0];
  463. $component = 'com_' . $parts[0];
  464. $view = $parts[2];
  465. // Is this an FOF 2.1 or later component?
  466. if (!$this->isFOFComponent($component))
  467. {
  468. return;
  469. }
  470. // Get the alternate view and class name (opposite singular/plural name)
  471. $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
  472. $alt_class = FOFInflector::camelize($component_raw . '_table_' . $alt_view);
  473. // Get the proper and alternate paths and file names
  474. $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component);
  475. $file = "/tables/$view.php";
  476. $altFile = "/tables/$alt_view.php";
  477. $path = $componentPaths['admin'];
  478. // Try to find the proper class in the proper path
  479. if (file_exists($path . $file))
  480. {
  481. @include_once $path . $file;
  482. }
  483. // Try to find the alternate class in the proper path
  484. if (!class_exists($alt_class) && file_exists($path . $altFile))
  485. {
  486. @include_once $path . $altFile;
  487. }
  488. // If the alternate class exists just map the class to the alternate
  489. if (!class_exists($class_name) && class_exists($alt_class))
  490. {
  491. $this->class_alias($alt_class, $class_name);
  492. }
  493. // No class found? Map to FOFModel
  494. elseif (!class_exists($class_name))
  495. {
  496. if ($view != 'default')
  497. {
  498. $defaultClass = FOFInflector::camelize($component_raw . '_table_default');
  499. $this->class_alias($defaultClass, $class_name);
  500. }
  501. else
  502. {
  503. $this->class_alias('FOFTable', $class_name, true);
  504. }
  505. }
  506. }
  507. /**
  508. * Autoload Helpers
  509. *
  510. * @param string $class_name The name of the class to load
  511. *
  512. * @return void
  513. */
  514. public function autoload_fof_helper($class_name)
  515. {
  516. FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
  517. static $isCli = null, $isAdmin = null;
  518. if (is_null($isCli) && is_null($isAdmin))
  519. {
  520. list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin();
  521. }
  522. if (strpos($class_name, 'Helper') === false)
  523. {
  524. return;
  525. }
  526. // Change from camel cased into a lowercase array
  527. $class_modified = preg_replace('/(\s)+/', '_', $class_name);
  528. $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
  529. $parts = explode('_', $class_modified);
  530. // We need three parts in the name
  531. if (count($parts) != 3)
  532. {
  533. return;
  534. }
  535. // We need the second part to be "model"
  536. if ($parts[1] != 'helper')
  537. {
  538. return;
  539. }
  540. // Get the information about this class
  541. $component_raw = $parts[0];
  542. $component = 'com_' . $parts[0];
  543. $view = $parts[2];
  544. // Is this an FOF 2.1 or later component?
  545. if (!$this->isFOFComponent($component))
  546. {
  547. return;
  548. }
  549. // Get the alternate view and class name (opposite singular/plural name)
  550. $alt_view = FOFInflector::isSingular($view) ? FOFInflector::pluralize($view) : FOFInflector::singularize($view);
  551. $alt_class = FOFInflector::camelize($component_raw . '_helper_' . $alt_view);
  552. // Get the proper and alternate paths and file names
  553. $componentPaths = FOFPlatform::getInstance()->getComponentBaseDirs($component);
  554. $file = "/helpers/$view.php";
  555. $altFile = "/helpers/$alt_view.php";
  556. $path = $componentPaths['main'];
  557. $altPath = $componentPaths['alt'];
  558. // Try to find the proper class in the proper path
  559. if (file_exists($path . $file))
  560. {
  561. @include_once $path . $file;
  562. }
  563. // Try to find the proper class in the alternate path
  564. if (!class_exists($class_name) && file_exists($altPath . $file))
  565. {
  566. @include_once $altPath . $file;
  567. }
  568. // Try to find the alternate class in the proper path
  569. if (!class_exists($alt_class) && file_exists($path . $altFile))
  570. {
  571. @include_once $path . $altFile;
  572. }
  573. // Try to find the alternate class in the alternate path
  574. if (!class_exists($alt_class) && file_exists($altPath . $altFile))
  575. {
  576. @include_once $altPath . $altFile;
  577. }
  578. // If the alternate class exists just map the class to the alternate
  579. if (!class_exists($class_name) && class_exists($alt_class))
  580. {
  581. $this->class_alias($alt_class, $class_name);
  582. }
  583. }
  584. /**
  585. * Autoload Toolbars
  586. *
  587. * @param string $class_name The name of the class to load
  588. *
  589. * @return void
  590. */
  591. public function autoload_fof_toolbar($class_name)
  592. {
  593. FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
  594. static $isCli = null, $isAdmin = null;
  595. if (is_null($isCli) && is_null($isAdmin))
  596. {
  597. list($isCli, $isAdmin) = FOFDispatcher::isCliAdmin();
  598. }
  599. if (strpos($class_name, 'Toolbar') === false)
  600. {
  601. return;
  602. }
  603. // Change from camel cased into a lowercase array
  604. $class_modified = preg_replace('/(\s)+/', '_', $class_name);
  605. $class_modified = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $class_modified));
  606. $parts = explode('_', $class_modified);
  607. // We need two parts in the name
  608. if (count($parts) != 2)
  609. {
  610. return;
  611. }
  612. // We need the second part to be "model"
  613. if ($parts[1] != 'toolbar')
  614. {
  615. return;
  616. }
  617. // Get the information about this class
  618. $component_raw = $parts[0];
  619. $component = 'com_' . $parts[0];
  620. $platformDirs = FOFPlatform::getInstance()->getPlatformBaseDirs();
  621. // Get the proper and alternate paths and file names
  622. $file = "/components/$component/toolbar.php";
  623. $path = ($isAdmin || $isCli) ? $platformDirs['admin'] : $platformDirs['public'];
  624. $altPath = ($isAdmin || $isCli) ? $platformDirs['public'] : $platformDirs['admin'];
  625. // Try to find the proper class in the proper path
  626. if (file_exists($path . $file))
  627. {
  628. @include_once $path . $file;
  629. }
  630. // Try to find the proper class in the alternate path
  631. if (!class_exists($class_name) && file_exists($altPath . $file))
  632. {
  633. @include_once $altPath . $file;
  634. }
  635. // No class found? Map to FOFToolbar
  636. if (!class_exists($class_name))
  637. {
  638. $this->class_alias('FOFToolbar', $class_name, true);
  639. }
  640. }
  641. /**
  642. * Autoload Fields
  643. *
  644. * @param string $class_name The name of the class to load
  645. *
  646. * @return void
  647. */
  648. public function autoload_fof_field($class_name)
  649. {
  650. FOFPlatform::getInstance()->logDebug(__METHOD__ . "() autoloading $class_name");
  651. // @todo
  652. }
  653. }