PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Opl/Autoloader/GenericLoader.php

https://github.com/OPL/opl3-autoloader
PHP | 207 lines | 104 code | 17 blank | 86 comment | 15 complexity | f9f4008167c8b7ee21972a2c1dfade9b MD5 | raw file
  1. <?php
  2. /*
  3. * OPEN POWER LIBS <http://www.invenzzia.org>
  4. *
  5. * This file is subject to the new BSD license that is bundled
  6. * with this package in the file LICENSE. It is also available through
  7. * WWW at this URL: <http://www.invenzzia.org/license/new-bsd>
  8. *
  9. * Copyright (c) Invenzzia Group <http://www.invenzzia.org>
  10. * and other contributors. See website for details.
  11. */
  12. namespace Opl\Autoloader;
  13. use DomainException;
  14. /**
  15. * The generic class autoloader is a slightly enhanced version of the
  16. * AggregateAutoloader <http://github.com/zyxist/AggregateAutoloader>
  17. * originally distributed under the terms of MIT license.
  18. *
  19. * @author Tomasz Jędrzejewski
  20. * @copyright Invenzzia Group <http://www.invenzzia.org/> and contributors.
  21. * @license http://www.invenzzia.org/license/new-bsd New BSD License
  22. */
  23. class GenericLoader
  24. {
  25. /**
  26. * The default autoloader path.
  27. * @static
  28. * @var string
  29. */
  30. private $defaultPath = '';
  31. /**
  32. * The list of available top-level namespaces.
  33. * @var array
  34. */
  35. private $namespaces = array();
  36. /**
  37. * The file extensions in the namespaces.
  38. * @var array
  39. */
  40. private $extensions = array();
  41. /**
  42. * The namespace separator
  43. * @var string
  44. */
  45. private $namespaceSeparator = '\\';
  46. /**
  47. * Constructs the autoloader.
  48. *
  49. * @param string $defaultPath The default namespace path.
  50. * @param string $namespaceSeparator The namespace separator used in this autoloader.
  51. */
  52. public function __construct($defaultPath = './', $namespaceSeparator = '\\')
  53. {
  54. $this->namespaceSeparator = $namespaceSeparator;
  55. $length = strlen($defaultPath);
  56. if($length == 0 || $defaultPath[$length - 1] != '/')
  57. {
  58. $defaultPath .= '/';
  59. }
  60. $this->defaultPath = $defaultPath;
  61. } // end __construct();
  62. /**
  63. * Registers a new top-level namespace to match.
  64. *
  65. * @param string $namespace The namespace name to add.
  66. * @param string $path The path to the namespace (without the namespace name itself).
  67. * @param string $extension The namespace file extension.
  68. */
  69. public function addNamespace($namespace, $path = null, $extension = '.php')
  70. {
  71. if(isset($this->namespaces[(string)$namespace]))
  72. {
  73. throw new DomainException('The namespace '.$namespace.' is already added.');
  74. }
  75. if($path !== null)
  76. {
  77. $length = strlen($path);
  78. if($length == 0 || $path[$length - 1] != '/')
  79. {
  80. $path .= '/';
  81. }
  82. $this->namespaces[(string)$namespace] = $path;
  83. }
  84. else
  85. {
  86. $this->namespaces[(string)$namespace] = $this->defaultPath;
  87. }
  88. $this->extensions[(string)$namespace] = $extension;
  89. } // end addNamespace();
  90. /**
  91. * Checks if the specified top-level namespace is available.
  92. *
  93. * @param string $namespace The namespace name to check.
  94. */
  95. public function hasNamespace($namespace)
  96. {
  97. return isset($this->namespaces[(string)$namespace]);
  98. } // end hasNamespace();
  99. /**
  100. * Removes a registered top-level namespace.
  101. *
  102. * @param string $namespace The namespace name to remove.
  103. */
  104. public function removeNamespace($namespace)
  105. {
  106. if(!isset($this->namespaces[(string)$namespace]))
  107. {
  108. throw new DomainException('The namespace '.$namespace.' is not available.');
  109. }
  110. unset($this->namespaces[(string)$namespace]);
  111. unset($this->extensions[(string)$namespace]);
  112. } // end removeNamespace();
  113. /**
  114. * Sets the namespace separator used by classes in the namespace of this class loader.
  115. *
  116. * @param string $sep The separator to use.
  117. */
  118. public function setNamespaceSeparator($sep)
  119. {
  120. $this->namespaceSeparator = $sep;
  121. } // end setNamespaceSeparator();
  122. /**
  123. * Gets the namespace seperator used by classes in the namespace of this class loader.
  124. *
  125. * @return string
  126. */
  127. public function getNamespaceSeparator()
  128. {
  129. return $this->namespaceSeparator;
  130. } // end getNamespaceSeparator();
  131. /**
  132. * Sets the default path used by the namespaces. Note that it does not affect
  133. * the already added namespaces.
  134. *
  135. * @param string $defaultPath The new default path.
  136. */
  137. public function setDefaultPath($defaultPath)
  138. {
  139. if($defaultPath[strlen($defaultPath) - 1] != '/')
  140. {
  141. $defaultPath .= '/';
  142. }
  143. $this->defaultPath = $defaultPath;
  144. } // end setDefaultPath();
  145. /**
  146. * Returns the default path used by the namespaces.
  147. *
  148. * @return string The current default path.
  149. */
  150. public function getDefaultPath()
  151. {
  152. return $this->defaultPath;
  153. } // end getDefaultPath();
  154. /**
  155. * Installs this class loader on the SPL autoload stack.
  156. */
  157. public function register()
  158. {
  159. spl_autoload_register(array($this, 'loadClass'));
  160. } // end register();
  161. /**
  162. * Uninstalls this class loader from the SPL autoloader stack.
  163. */
  164. public function unregister()
  165. {
  166. spl_autoload_unregister(array($this, 'loadClass'));
  167. } // end unregister();
  168. /**
  169. * Loads the given class or interface.
  170. *
  171. * @param string $className The name of the class to load.
  172. * @return void
  173. */
  174. public function loadClass($className)
  175. {
  176. $className = ltrim($className, $this->namespaceSeparator);
  177. $match = strstr($className, $this->namespaceSeparator, true);
  178. if(false === $match || !isset($this->namespaces[$match]))
  179. {
  180. return false;
  181. }
  182. $rest = strrchr($className, $this->namespaceSeparator);
  183. $replacement =
  184. str_replace($this->namespaceSeparator, '/', substr($className, 0, strlen($className) - strlen($rest))).
  185. str_replace(array('_', $this->namespaceSeparator), '/', $rest);
  186. require($this->namespaces[$match].$replacement.$this->extensions[$match]);
  187. return true;
  188. } // end loadClass();
  189. } // end GenericLoader;