PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Milk/Core/Loader.php

https://github.com/geekbuntu/milk
PHP | 195 lines | 128 code | 22 blank | 45 comment | 22 complexity | 5d0a3021dfd0c19eb5d6a07daa24f39b MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. namespace Milk\Core;
  3. // We have to include Core\Module if it doesn't exist
  4. if (!class_exists('Milk\Core\Module'))
  5. require_once 'Module.php';
  6. use Milk\Core\Module,
  7. Milk\Core\Loader\Exception,
  8. Milk\Utils\Translation;
  9. class Loader extends Module\Singleton {
  10. private static $loaded = array();
  11. private static $paths = array();
  12. private static $namespaces = array();
  13. /**
  14. Load a class/interface
  15. @param $class string
  16. @public
  17. @static
  18. **/
  19. public function autoload($class) {
  20. $list = get_included_files();
  21. // Check if the class/interface requested is in a namespace
  22. if (__NAMESPACE__ || (strpos($class, '\\') !== false)) {
  23. $nslevels = substr_count($class, '\\');
  24. if ($nslevels == 0 && __NAMESPACE__) {
  25. $namespace = __NAMESPACE__;
  26. } else {
  27. $namespace = $class;
  28. // We need to check each level to see if it's defined
  29. while ($namespace = strstr($namespace, '\\', true)) {
  30. if (isset(self::$namespaces[$namespace])) {
  31. break;
  32. }
  33. }
  34. }
  35. if (isset(self::$namespaces[$namespace])) {
  36. $path_start = self::$namespaces[$namespace];
  37. $nsclass = str_replace($namespace.'\\', '', $class);
  38. $line = $path_start;
  39. $path = explode('\\', $nsclass);
  40. foreach ($path as $sign) {
  41. $line .= '/'.$sign;
  42. $file = $line.'.php';
  43. if (is_file($file) && is_readable($file)) {
  44. // Include the file
  45. include_once $file;
  46. // Verify that class/interface exists
  47. foreach (array($class, str_replace('\\', '_', $class)) as $style) {
  48. if (class_exists($class, FALSE) || interface_exists($class, FALSE)) {
  49. self::$loaded[$class] = TRUE;
  50. return;
  51. }
  52. }
  53. }
  54. if (!is_dir($line))
  55. break;
  56. }
  57. }
  58. }
  59. $paths = array_merge( self::$paths, explode(PATH_SEPARATOR, get_include_path()) );
  60. foreach (
  61. array(
  62. str_replace('_', DIRECTORY_SEPARATOR, $class),
  63. str_replace(DIRECTORY_SEPARATOR, '_', $class)
  64. ) as $style
  65. ) {
  66. foreach ($paths as $path) {
  67. $path = realpath($path);
  68. if (!$path)
  69. continue;
  70. $file = $path . '/' . $style . '.php';
  71. $glob = glob(dirname($file).'/*.php', GLOB_NOSORT);
  72. if ($glob) {
  73. // Case-insensitive check for file presence
  74. $fkey = array_search(
  75. strtolower($file),
  76. array_map('strtolower',$glob)
  77. );
  78. if (is_int($fkey) && !in_array($glob[$fkey], $list)) {
  79. // Include the file
  80. include_once $glob[$fkey];
  81. // Verify that class/interface exists
  82. if (class_exists($class, FALSE) || interface_exists($class, FALSE)) {
  83. self::$loaded[$class] = TRUE;
  84. return;
  85. }
  86. }
  87. }
  88. }
  89. }
  90. // Trigger error if there are no other autoloaders registered
  91. if (count(spl_autoload_functions()) == 1) {
  92. if (!class_exists("Exception"))
  93. self::autoload("Milk\Core\Exception");
  94. if (class_exists("Exception")) {
  95. throw new Exception(
  96. sprintf( _("Could not load %s"), $class )
  97. );
  98. } else {
  99. trigger_error( _("Could not load %s"), $class );
  100. }
  101. }
  102. }
  103. /**
  104. Register autoloader to SPL
  105. @public
  106. @static
  107. **/
  108. public function register() {
  109. spl_autoload_register(
  110. array(self::getInstance(), 'autoload')
  111. );
  112. return self::getInstance();
  113. }
  114. /**
  115. Add path to autoloader
  116. @param $path string
  117. @public
  118. @static
  119. **/
  120. public function addPath($path) {
  121. self::$paths[] = $path;
  122. return self::$_instance;
  123. }
  124. /**
  125. Add paths to autoloader
  126. @param $paths array
  127. @public
  128. @static
  129. **/
  130. public function addPaths($paths) {
  131. foreach ($paths as $$path) {
  132. self::addPath($path);
  133. }
  134. return self::$_instance;
  135. }
  136. /**
  137. Add namespace to autoloader
  138. @param $ns string
  139. @param $path string
  140. @public
  141. @static
  142. **/
  143. public function addNamespace($ns, $path) {
  144. self::$namespaces[$ns] = $path;
  145. return self::getInstance();
  146. }
  147. /**
  148. Add namespaces to autoloader
  149. @param $namespaces array
  150. @public
  151. @static
  152. **/
  153. public function addNamespaces($namespaces) {
  154. foreach ($namespaces as $ns => $path) {
  155. self::addNamespace($ns, $path);
  156. }
  157. return self::$_instance;
  158. }
  159. }
  160. // Register autoloader
  161. Loader::register();
  162. // Add Milk namespace to loader
  163. Loader::addNamespace("Milk", realpath(__DIR__.'/..'));
  164. namespace Milk\Core\Loader;
  165. use Milk\Core\Exception as BaseException;
  166. class Exception extends BaseException {
  167. public function __construct($message=null, $code=0) {
  168. $trace = $this->getTrace();
  169. $this->file = $trace[1]['file'];
  170. $this->line = $trace[1]['line'];
  171. parent::__construct($message, $code);
  172. }
  173. }