/library/Zend/Loader/ModuleAutoloader.php

https://github.com/stoefln/zf2 · PHP · 188 lines · 105 code · 14 blank · 69 comment · 16 complexity · 0f3887a9e1354ef4b6c46cd39826acb2 MD5 · raw file

  1. <?php
  2. namespace Zend\Loader;
  3. use SplFileInfo,
  4. Traversable;
  5. class ModuleAutoloader implements SplAutoloader
  6. {
  7. /**
  8. * @var array An array of module paths to scan
  9. */
  10. protected $paths = array();
  11. /**
  12. * Constructor
  13. *
  14. * Allow configuration of the autoloader via the constructor.
  15. *
  16. * @param null|array|Traversable $options
  17. * @return void
  18. */
  19. public function __construct($options = null)
  20. {
  21. if (null !== $options) {
  22. $this->setOptions($options);
  23. }
  24. }
  25. /**
  26. * Configure the autoloader
  27. *
  28. * In most cases, $options should be either an associative array or
  29. * Traversable object.
  30. *
  31. * @param array|Traversable $options
  32. * @return SplAutoloader
  33. */
  34. public function setOptions($options)
  35. {
  36. $this->registerPaths($options);
  37. return $this;
  38. }
  39. /**
  40. * Autoload a class
  41. *
  42. * @param $class
  43. * @return mixed
  44. * False [if unable to load $class]
  45. * get_class($class) [if $class is successfully loaded]
  46. */
  47. public function autoload($class)
  48. {
  49. // Limit scope of this autoloader
  50. if (substr($class, -7) !== '\Module') {
  51. return false;
  52. }
  53. $moduleClassPath = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
  54. foreach ($this->paths as $path) {
  55. $file = new SplFileInfo($path . $moduleClassPath);
  56. if ($file->isReadable()) {
  57. // Found directory with Module.php in it
  58. require_once $file->getRealPath();
  59. return $class;
  60. }
  61. // No directory with Module.php, searching for phars
  62. $moduleName = substr($class, 0, strpos($class, '\\'));
  63. // Find executable phars
  64. $matches = glob($path . $moduleName . '.{phar,phar.gz,phar.bz2,phar.tar,phar.tar.gz,phar.tar.bz2,phar.zip}', GLOB_BRACE);
  65. $executable = true;
  66. if (count($matches) == 0) {
  67. $matches = glob($path . $moduleName . '.{tar,tar.gz,tar.bz2,zip}', GLOB_BRACE);
  68. $executable = false;
  69. }
  70. foreach ($matches as $phar) {
  71. $file = new SplFileInfo($phar);
  72. if ($file->isReadable() && $file->isFile()) {
  73. if ($executable) {
  74. // First see if the stub makes the Module class available
  75. require_once $file->getRealPath();
  76. if (class_exists($class)) {
  77. return $class;
  78. }
  79. }
  80. // No stub, or stub did not provide Module class; try Module.php directly
  81. $moduleClassFile = 'phar://' . $file->getRealPath() . '/Module.php';
  82. $file = new SplFileInfo($moduleClassFile);
  83. if ($file->isReadable() && $file->isFile()) {
  84. require_once $moduleClassFile;
  85. if (class_exists($class)) {
  86. return $class;
  87. }
  88. }
  89. }
  90. }
  91. }
  92. return false;
  93. }
  94. /**
  95. * Register the autoloader with spl_autoload registry
  96. *
  97. * @return void
  98. */
  99. public function register()
  100. {
  101. spl_autoload_register(array($this, 'autoload'));
  102. }
  103. /**
  104. * Unregister the autoloader with spl_autoload registry
  105. *
  106. * @return void
  107. */
  108. public function unregister()
  109. {
  110. $test = spl_autoload_unregister(array($this, 'autoload'));
  111. }
  112. /**
  113. * registerPaths
  114. *
  115. * @param array|Traversable $paths
  116. * @return ModuleLoader
  117. */
  118. public function registerPaths($paths)
  119. {
  120. if (is_array($paths) || $paths instanceof Traversable) {
  121. foreach ($paths as $path) {
  122. $this->registerPath($path);
  123. }
  124. } else {
  125. throw new \InvalidArgumentException(
  126. 'Parameter to \\Zend\\Loader\\ModuleAutoloader\'s '
  127. . 'registerPaths method must be an array or '
  128. . 'implement the \\Traversable interface'
  129. );
  130. }
  131. return $this;
  132. }
  133. /**
  134. * registerPath
  135. *
  136. * @param string $path
  137. * @return ModuleLoader
  138. */
  139. public function registerPath($path)
  140. {
  141. if (!is_string($path)) {
  142. throw new \InvalidArgumentException(sprintf(
  143. 'Invalid path provided; must be a string, received %s',
  144. gettype($path)
  145. ));
  146. }
  147. $this->paths[] = static::normalizePath($path);
  148. return $this;
  149. }
  150. /**
  151. * getPaths
  152. *
  153. * This is primarily for unit testing, but could have other uses.
  154. *
  155. * @return array
  156. */
  157. public function getPaths()
  158. {
  159. return $this->paths;
  160. }
  161. /**
  162. * Normalize a path for insertion in the stack
  163. *
  164. * @param string $path
  165. * @return string
  166. */
  167. public static function normalizePath($path)
  168. {
  169. $path = rtrim($path, '/');
  170. $path = rtrim($path, '\\');
  171. $path .= DIRECTORY_SEPARATOR;
  172. return $path;
  173. }
  174. }