PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/rokcommon/RokCommon/ClassLoader.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 412 lines | 182 code | 37 blank | 193 comment | 31 complexity | 08b933227f8bf3a92589e14689f53dff MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id: ClassLoader.php 57540 2012-10-14 18:27:59Z btowles $
  4. * @author RocketTheme http://www.rockettheme.com
  5. * @copyright Copyright (C) 2007 - ${copyright_year} RocketTheme, LLC
  6. * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
  7. *
  8. * Based on
  9. * SplClassLoader implementation that implements the technical interoperability
  10. * standards for PHP 5.3 namespaces and class names.
  11. *
  12. * http://groups.google.com/group/php-standards/web/final-proposal
  13. *
  14. * // Example which loads classes for the Doctrine Common package in the
  15. * // Doctrine\Common namespace.
  16. * $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine');
  17. * $classLoader->register();
  18. *
  19. * @author Jonathan H. Wage <jonwage@gmail.com>
  20. * @author Roman S. Borschel <roman@code-factory.org>
  21. * @author Matthew Weier O'Phinney <matthew@zend.com>
  22. * @author Kris Wallsmith <kris.wallsmith@gmail.com>
  23. * @author Fabien Potencier <fabien.potencier@symfony-project.org>
  24. * @author Juozas Kaziukenas <juozas@juokaz.com>
  25. */
  26. if (!class_exists('RokCommon_ClassLoader', false)) {
  27. /**
  28. *
  29. */
  30. interface RokCommon_ClassLoader_ILoader
  31. {
  32. /**
  33. *
  34. */
  35. const FILE_EXTENSION = '.php';
  36. /**
  37. *
  38. */
  39. const DEFAULT_FINDER_PRIORITY = 10;
  40. /**
  41. *
  42. */
  43. const DEFAULT_PATH_PRIORITY = 10;
  44. /**
  45. * @abstract
  46. *
  47. * @param string $class the class name to look for and load
  48. *
  49. * @return bool True if the class was found and loaded.
  50. */
  51. public function loadClass($class);
  52. /**
  53. * @abstract
  54. *
  55. * @param array $finders
  56. *
  57. * @return mixed
  58. */
  59. public function setFinders($finders = array());
  60. /**
  61. * @abstract
  62. *
  63. * @param int $priority
  64. *
  65. * @return mixed
  66. */
  67. public function activate($priority = RokCommon_ClassLoader::DEFAULT_LOADER_PRIORITY);
  68. }
  69. /**
  70. *
  71. */
  72. interface RokCommon_ClassLoader_IFinder
  73. {
  74. /**
  75. * @abstract
  76. *
  77. * @param string $class the class name to look for
  78. *
  79. * @return string|bool the path to the file or false if not found
  80. */
  81. public function find($class);
  82. }
  83. /**
  84. *
  85. */
  86. class RokCommon_ClassLoader_BootStrapLoader
  87. {
  88. /**
  89. * @param string $className the class name to load
  90. *
  91. * @return bool
  92. */
  93. public static function loadClass($className)
  94. {
  95. if (stripos($className, 'RokCommon') === 0) {
  96. $commonsPath = realpath(dirname(__FILE__) . '/..');
  97. $fileName = str_replace('_', DIRECTORY_SEPARATOR, $className) . ".php";
  98. $full_file_path = $commonsPath . DIRECTORY_SEPARATOR . $fileName;
  99. if (file_exists($full_file_path) && is_readable($full_file_path)) {
  100. require($full_file_path);
  101. }
  102. return true;
  103. }
  104. return false;
  105. }
  106. }
  107. /**
  108. *
  109. */
  110. class RokCommon_ClassLoader_Exception extends Exception
  111. {
  112. }
  113. /**
  114. * @todo find references to this and remove
  115. * @deprecated use RokCommon_ClassLoader_Exception instead
  116. */
  117. class RokCommon_Loader_Exception extends RokCommon_ClassLoader_Exception
  118. {
  119. }
  120. /**
  121. * @package RokCommon
  122. */
  123. class RokCommon_ClassLoader
  124. {
  125. /**
  126. *
  127. */
  128. const DEFAULT_LOADER_PRIORITY = 10;
  129. /**
  130. *
  131. */
  132. const DEFAULT_PATH_PRIORITY = 10;
  133. /**
  134. * @var RokCommon_ClassLoader
  135. */
  136. protected static $_instance;
  137. /**
  138. * @var array
  139. */
  140. protected $loaders = array();
  141. /**
  142. * @var bool
  143. */
  144. protected $bootstrap_setup = false;
  145. /**
  146. * @var bool
  147. */
  148. protected $bootstrap_used = false;
  149. /**
  150. * @static
  151. * @return RokCommon_ClassLoader
  152. */
  153. public static function getInstance()
  154. {
  155. if (!isset(self::$_instance)) {
  156. self::$_instance = new RokCommon_ClassLoader();
  157. self::$_instance->setupBootstrap();
  158. }
  159. return self::$_instance;
  160. }
  161. /**
  162. * @static
  163. *
  164. * @param RokCommon_ClassLoader_ILoader $loader the instance of the loader to register
  165. * @param int $priority priority of the loader
  166. *
  167. * @throws RokCommon_ClassLoader_Exception
  168. * @internal param string $loaderName name to register the loader under.
  169. * @return void
  170. * @deprecated use the container to get the classloader and register on it
  171. */
  172. public static function registerLoader(RokCommon_ClassLoader_ILoader &$loader, $priority = self::DEFAULT_LOADER_PRIORITY)
  173. {
  174. self::getInstance();
  175. $container = RokCommon_Service::getContainer();
  176. $container->classloader->addLoader($loader, $priority);
  177. }
  178. /**
  179. * Convenience function to add a path to the default loader
  180. * @static
  181. *
  182. * @param string $path the path to add to the default loader
  183. *
  184. * @deprecated use the container to set on the proper path
  185. * @return void
  186. */
  187. public static function addPath($path)
  188. {
  189. $container = RokCommon_Service::getContainer();
  190. $container->setParameter('classloader.classpath.' . self::DEFAULT_PATH_PRIORITY, array($path));
  191. }
  192. /**
  193. * Returns a reference to the named loader.
  194. * @static
  195. *
  196. * @param string $loaderName the named loader to return
  197. *
  198. * @throws RokCommon_ClassLoader_Exception
  199. * @return RokCommon_ClassLoader_ILoader|bool FALSE if no loader found with that name
  200. */
  201. public static function &getLoader($loaderName)
  202. {
  203. $container = RokCommon_Service::getContainer();
  204. if (!$container->hasService($loaderName)) {
  205. throw new RokCommon_ClassLoader_Exception('Loader ' . $loaderName . ' does not exists');
  206. }
  207. return $container->getService($loaderName);
  208. }
  209. /**
  210. * See if the loader is registered
  211. * @static
  212. *
  213. * @param $loaderName
  214. *
  215. * @return bool
  216. * @deprecated use the container and check if there is a service
  217. */
  218. public static function isLoaderRegistered($loaderName)
  219. {
  220. $container = RokCommon_Service::getContainer();
  221. return $container->hasService($loaderName);
  222. }
  223. /**
  224. *
  225. */
  226. protected function __construct()
  227. {
  228. //$this->register();
  229. }
  230. /**
  231. *
  232. */
  233. public function __destruct()
  234. {
  235. $this->unregister();
  236. }
  237. /**
  238. *
  239. */
  240. private function setupBootstrap()
  241. {
  242. if (!$this->bootstrap_setup && !$this->bootstrap_used) {
  243. //$this->bootstrap = new RokCommon_ClassLoader_BootStrapLoader();
  244. spl_autoload_register(array('RokCommon_ClassLoader_BootStrapLoader', 'loadClass'));
  245. $this->bootstrap_setup = true;
  246. }
  247. }
  248. /**
  249. *
  250. */
  251. private function cleanupBootstrap()
  252. {
  253. if ($this->bootstrap_setup && !$this->bootstrap_used) {
  254. spl_autoload_unregister(array('RokCommon_ClassLoader_BootStrapLoader', 'loadClass'));
  255. $this->bootstrap_setup = false;
  256. }
  257. }
  258. /**
  259. * @param RokCommon_ClassLoader_ILoader $loader
  260. * @param int $priority
  261. */
  262. public function setDefaultLoader(RokCommon_ClassLoader_ILoader $loader, $priority = self::DEFAULT_LOADER_PRIORITY)
  263. {
  264. if ($this->bootstrap_setup && !$this->bootstrap_used) {
  265. $this->cleanupBootstrap();
  266. $this->bootstrap_used = true;
  267. }
  268. $this->addLoader($loader, $priority);
  269. $this->register();
  270. }
  271. /**
  272. * @param RokCommon_ClassLoader_ILoader $loader
  273. * @param int $priority
  274. *
  275. * @throws RokCommon_ClassLoader_Exception
  276. * @return bool
  277. */
  278. public function addLoader(RokCommon_ClassLoader_ILoader &$loader, $priority = self::DEFAULT_LOADER_PRIORITY)
  279. {
  280. if ($this->bootstrap_setup && !$this->bootstrap_used) {
  281. throw new RokCommon_ClassLoader_Exception('The default loader has not been set');
  282. }
  283. if (!$this->checkIfLoaderAlreadyAdded($loader)) {
  284. $this->loaders[$priority][] =& $loader;
  285. ksort($this->loaders);
  286. } else {
  287. throw new RokCommon_ClassLoader_Exception('Loader already added');
  288. }
  289. }
  290. /**
  291. * @param RokCommon_ClassLoader_ILoader $removingloader
  292. */
  293. public function removeLoader(RokCommon_ClassLoader_ILoader &$removingloader)
  294. {
  295. foreach ($this->loaders as $priority => $priority_loaders) {
  296. foreach ($priority_loaders as $id => &$loader) {
  297. if ($loader === $removingloader) {
  298. unset($this->loaders[$priority][$id]);
  299. }
  300. }
  301. }
  302. }
  303. /**
  304. * @param RokCommon_ClassLoader_ILoader $checking_loader
  305. *
  306. * @return bool
  307. */
  308. protected function checkIfLoaderAlreadyAdded(RokCommon_ClassLoader_ILoader $checking_loader)
  309. {
  310. foreach ($this->loaders as $priority_loaders) {
  311. foreach ($priority_loaders as &$loader) {
  312. if ($loader === $checking_loader) {
  313. return true;
  314. }
  315. }
  316. }
  317. return false;
  318. }
  319. /**
  320. * Installs this class loader on the SPL autoload stack.
  321. */
  322. public function register()
  323. {
  324. $current_functions = spl_autoload_functions();
  325. $prepend = true;
  326. $already_registered = false;
  327. if ($current_functions === false) {
  328. $prepend = false;
  329. } elseif (is_array($current_functions) && count($current_functions) == 0) {
  330. // prepend original autoloader
  331. if (function_exists('__autoload')) {
  332. spl_autoload_register('__autoload');
  333. } else {
  334. $prepend = false;
  335. }
  336. } else {
  337. if (in_array(array($this, 'loadClass'), $current_functions)) {
  338. $already_registered = true;
  339. }
  340. }
  341. if (!$already_registered) {
  342. if ($prepend && version_compare(PHP_VERSION, '5.3.0') >= 0) {
  343. spl_autoload_register(array($this, 'loadClass'), true, true);
  344. } else {
  345. spl_autoload_register(array($this, 'loadClass'));
  346. }
  347. }
  348. }
  349. /**
  350. * Uninstalls this class loader from the SPL autoloader stack.
  351. */
  352. public function unregister()
  353. {
  354. spl_autoload_unregister(array($this, 'loadClass'));
  355. }
  356. /**
  357. * Loads the given class or interface.
  358. *
  359. * @param string $className The name of the class to load.
  360. *
  361. * @return void
  362. */
  363. public function loadClass($className)
  364. {
  365. if (!empty($this->loaders)) {
  366. foreach ($this->loaders as $priority => $priorityLoaders) {
  367. /** @var $priorityLoaders RokCommon_ClassLoader_ILoader[] */
  368. foreach ($priorityLoaders as $loaderName => $loader) {
  369. if ($loader->loadClass($className)) break;
  370. }
  371. }
  372. }
  373. }
  374. }
  375. }