PageRenderTime 25ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/zendframework/zend-loader/src/StandardAutoloader.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 327 lines | 309 code | 3 blank | 15 comment | 0 complexity | aea739b6a1aebf6f1d742b2228970a4b MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Loader;
  10. // Grab SplAutoloader interface
  11. require_once __DIR__ . '/SplAutoloader.php';
  12. /**
  13. * PSR-0 compliant autoloader
  14. *
  15. * Allows autoloading both namespaced and vendor-prefixed classes. Class
  16. * lookups are performed on the filesystem. If a class file for the referenced
  17. * class is not found, a PHP warning will be raised by include().
  18. */
  19. class StandardAutoloader implements SplAutoloader
  20. {
  21. const NS_SEPARATOR = '\\';
  22. const PREFIX_SEPARATOR = '_';
  23. const LOAD_NS = 'namespaces';
  24. const LOAD_PREFIX = 'prefixes';
  25. const ACT_AS_FALLBACK = 'fallback_autoloader';
  26. const AUTOREGISTER_ZF = 'autoregister_zf';
  27. /**
  28. * @var array Namespace/directory pairs to search; ZF library added by default
  29. */
  30. protected $namespaces = array();
  31. /**
  32. * @var array Prefix/directory pairs to search
  33. */
  34. protected $prefixes = array();
  35. /**
  36. * @var bool Whether or not the autoloader should also act as a fallback autoloader
  37. */
  38. protected $fallbackAutoloaderFlag = false;
  39. /**
  40. * Constructor
  41. *
  42. * @param null|array|\Traversable $options
  43. */
  44. public function __construct($options = null)
  45. {
  46. if (null !== $options) {
  47. $this->setOptions($options);
  48. }
  49. }
  50. /**
  51. * Configure autoloader
  52. *
  53. * Allows specifying both "namespace" and "prefix" pairs, using the
  54. * following structure:
  55. * <code>
  56. * array(
  57. * 'namespaces' => array(
  58. * 'Zend' => '/path/to/Zend/library',
  59. * 'Doctrine' => '/path/to/Doctrine/library',
  60. * ),
  61. * 'prefixes' => array(
  62. * 'Phly_' => '/path/to/Phly/library',
  63. * ),
  64. * 'fallback_autoloader' => true,
  65. * )
  66. * </code>
  67. *
  68. * @param array|\Traversable $options
  69. * @throws Exception\InvalidArgumentException
  70. * @return StandardAutoloader
  71. */
  72. public function setOptions($options)
  73. {
  74. if (!is_array($options) && !($options instanceof \Traversable)) {
  75. require_once __DIR__ . '/Exception/InvalidArgumentException.php';
  76. throw new Exception\InvalidArgumentException('Options must be either an array or Traversable');
  77. }
  78. foreach ($options as $type => $pairs) {
  79. switch ($type) {
  80. case self::AUTOREGISTER_ZF:
  81. if ($pairs) {
  82. $this->registerNamespace('Zend', dirname(__DIR__));
  83. $this->registerNamespace('ZendXml', dirname(dirname((__DIR__))) . DIRECTORY_SEPARATOR . 'ZendXml');
  84. }
  85. break;
  86. case self::LOAD_NS:
  87. if (is_array($pairs) || $pairs instanceof \Traversable) {
  88. $this->registerNamespaces($pairs);
  89. }
  90. break;
  91. case self::LOAD_PREFIX:
  92. if (is_array($pairs) || $pairs instanceof \Traversable) {
  93. $this->registerPrefixes($pairs);
  94. }
  95. break;
  96. case self::ACT_AS_FALLBACK:
  97. $this->setFallbackAutoloader($pairs);
  98. break;
  99. default:
  100. // ignore
  101. }
  102. }
  103. return $this;
  104. }
  105. /**
  106. * Set flag indicating fallback autoloader status
  107. *
  108. * @param bool $flag
  109. * @return StandardAutoloader
  110. */
  111. public function setFallbackAutoloader($flag)
  112. {
  113. $this->fallbackAutoloaderFlag = (bool) $flag;
  114. return $this;
  115. }
  116. /**
  117. * Is this autoloader acting as a fallback autoloader?
  118. *
  119. * @return bool
  120. */
  121. public function isFallbackAutoloader()
  122. {
  123. return $this->fallbackAutoloaderFlag;
  124. }
  125. /**
  126. * Register a namespace/directory pair
  127. *
  128. * @param string $namespace
  129. * @param string $directory
  130. * @return StandardAutoloader
  131. */
  132. public function registerNamespace($namespace, $directory)
  133. {
  134. $namespace = rtrim($namespace, self::NS_SEPARATOR) . self::NS_SEPARATOR;
  135. $this->namespaces[$namespace] = $this->normalizeDirectory($directory);
  136. return $this;
  137. }
  138. /**
  139. * Register many namespace/directory pairs at once
  140. *
  141. * @param array $namespaces
  142. * @throws Exception\InvalidArgumentException
  143. * @return StandardAutoloader
  144. */
  145. public function registerNamespaces($namespaces)
  146. {
  147. if (!is_array($namespaces) && !$namespaces instanceof \Traversable) {
  148. require_once __DIR__ . '/Exception/InvalidArgumentException.php';
  149. throw new Exception\InvalidArgumentException('Namespace pairs must be either an array or Traversable');
  150. }
  151. foreach ($namespaces as $namespace => $directory) {
  152. $this->registerNamespace($namespace, $directory);
  153. }
  154. return $this;
  155. }
  156. /**
  157. * Register a prefix/directory pair
  158. *
  159. * @param string $prefix
  160. * @param string $directory
  161. * @return StandardAutoloader
  162. */
  163. public function registerPrefix($prefix, $directory)
  164. {
  165. $prefix = rtrim($prefix, self::PREFIX_SEPARATOR). self::PREFIX_SEPARATOR;
  166. $this->prefixes[$prefix] = $this->normalizeDirectory($directory);
  167. return $this;
  168. }
  169. /**
  170. * Register many namespace/directory pairs at once
  171. *
  172. * @param array $prefixes
  173. * @throws Exception\InvalidArgumentException
  174. * @return StandardAutoloader
  175. */
  176. public function registerPrefixes($prefixes)
  177. {
  178. if (!is_array($prefixes) && !$prefixes instanceof \Traversable) {
  179. require_once __DIR__ . '/Exception/InvalidArgumentException.php';
  180. throw new Exception\InvalidArgumentException('Prefix pairs must be either an array or Traversable');
  181. }
  182. foreach ($prefixes as $prefix => $directory) {
  183. $this->registerPrefix($prefix, $directory);
  184. }
  185. return $this;
  186. }
  187. /**
  188. * Defined by Autoloadable; autoload a class
  189. *
  190. * @param string $class
  191. * @return false|string
  192. */
  193. public function autoload($class)
  194. {
  195. $isFallback = $this->isFallbackAutoloader();
  196. if (false !== strpos($class, self::NS_SEPARATOR)) {
  197. if ($this->loadClass($class, self::LOAD_NS)) {
  198. return $class;
  199. } elseif ($isFallback) {
  200. return $this->loadClass($class, self::ACT_AS_FALLBACK);
  201. }
  202. return false;
  203. }
  204. if (false !== strpos($class, self::PREFIX_SEPARATOR)) {
  205. if ($this->loadClass($class, self::LOAD_PREFIX)) {
  206. return $class;
  207. } elseif ($isFallback) {
  208. return $this->loadClass($class, self::ACT_AS_FALLBACK);
  209. }
  210. return false;
  211. }
  212. if ($isFallback) {
  213. return $this->loadClass($class, self::ACT_AS_FALLBACK);
  214. }
  215. return false;
  216. }
  217. /**
  218. * Register the autoloader with spl_autoload
  219. *
  220. * @return void
  221. */
  222. public function register()
  223. {
  224. spl_autoload_register(array($this, 'autoload'));
  225. }
  226. /**
  227. * Transform the class name to a filename
  228. *
  229. * @param string $class
  230. * @param string $directory
  231. * @return string
  232. */
  233. protected function transformClassNameToFilename($class, $directory)
  234. {
  235. // $class may contain a namespace portion, in which case we need
  236. // to preserve any underscores in that portion.
  237. $matches = array();
  238. preg_match('/(?P<namespace>.+\\\)?(?P<class>[^\\\]+$)/', $class, $matches);
  239. $class = (isset($matches['class'])) ? $matches['class'] : '';
  240. $namespace = (isset($matches['namespace'])) ? $matches['namespace'] : '';
  241. return $directory
  242. . str_replace(self::NS_SEPARATOR, '/', $namespace)
  243. . str_replace(self::PREFIX_SEPARATOR, '/', $class)
  244. . '.php';
  245. }
  246. /**
  247. * Load a class, based on its type (namespaced or prefixed)
  248. *
  249. * @param string $class
  250. * @param string $type
  251. * @return bool|string
  252. * @throws Exception\InvalidArgumentException
  253. */
  254. protected function loadClass($class, $type)
  255. {
  256. if (!in_array($type, array(self::LOAD_NS, self::LOAD_PREFIX, self::ACT_AS_FALLBACK))) {
  257. require_once __DIR__ . '/Exception/InvalidArgumentException.php';
  258. throw new Exception\InvalidArgumentException();
  259. }
  260. // Fallback autoloading
  261. if ($type === self::ACT_AS_FALLBACK) {
  262. // create filename
  263. $filename = $this->transformClassNameToFilename($class, '');
  264. $resolvedName = stream_resolve_include_path($filename);
  265. if ($resolvedName !== false) {
  266. return include $resolvedName;
  267. }
  268. return false;
  269. }
  270. // Namespace and/or prefix autoloading
  271. foreach ($this->$type as $leader => $path) {
  272. if (0 === strpos($class, $leader)) {
  273. // Trim off leader (namespace or prefix)
  274. $trimmedClass = substr($class, strlen($leader));
  275. // create filename
  276. $filename = $this->transformClassNameToFilename($trimmedClass, $path);
  277. if (file_exists($filename)) {
  278. return include $filename;
  279. }
  280. }
  281. }
  282. return false;
  283. }
  284. /**
  285. * Normalize the directory to include a trailing directory separator
  286. *
  287. * @param string $directory
  288. * @return string
  289. */
  290. protected function normalizeDirectory($directory)
  291. {
  292. $last = $directory[strlen($directory) - 1];
  293. if (in_array($last, array('/', '\\'))) {
  294. $directory[strlen($directory) - 1] = DIRECTORY_SEPARATOR;
  295. return $directory;
  296. }
  297. $directory .= DIRECTORY_SEPARATOR;
  298. return $directory;
  299. }
  300. }