ClassLoader.php
9 years ago
ClassLoader52.php
11 years ago
LICENSE
10 years ago
autoload_classmap.php
9 years ago
autoload_files.php
10 years ago
autoload_namespaces.php
10 years ago
autoload_psr4.php
9 years ago
autoload_real.php
9 years ago
autoload_real_52.php
9 years ago
autoload_static.php
9 years ago
ClassLoader52.php
272 lines
| 1 | <?php |
| 2 | /* |
| 3 | * Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de |
| 4 | * |
| 5 | * This file is released under the terms of the MIT license. You can find the |
| 6 | * complete text in the attached LICENSE file or online at: |
| 7 | * |
| 8 | * http://www.opensource.org/licenses/mit-license.php |
| 9 | * |
| 10 | * -------------------------------------------------------------------------- |
| 11 | * |
| 12 | * 99% of this is copied as-is from the original Composer source code and is |
| 13 | * released under MIT license as well. Copyright goes to: |
| 14 | * |
| 15 | * - Fabien Potencier <fabien@symfony.com> |
| 16 | * - Jordi Boggiano <j.boggiano@seld.be> |
| 17 | */ |
| 18 | |
| 19 | class xrstf_Composer52_ClassLoader { |
| 20 | private $prefixes = array(); |
| 21 | private $fallbackDirs = array(); |
| 22 | private $useIncludePath = false; |
| 23 | private $classMap = array(); |
| 24 | private $classMapAuthoratative = false; |
| 25 | private $allowUnderscore = false; |
| 26 | |
| 27 | /** |
| 28 | * @param boolean $flag true to allow class names with a leading underscore, false to disable |
| 29 | */ |
| 30 | public function setAllowUnderscore($flag) { |
| 31 | $this->allowUnderscore = (boolean) $flag; |
| 32 | } |
| 33 | |
| 34 | /** |
| 35 | * @return array |
| 36 | */ |
| 37 | public function getPrefixes() { |
| 38 | return $this->prefixes; |
| 39 | } |
| 40 | |
| 41 | /** |
| 42 | * Turns off searching the prefix and fallback directories for classes |
| 43 | * that have not been registered with the class map. |
| 44 | * |
| 45 | * @param bool $classMapAuthoratative |
| 46 | */ |
| 47 | public function setClassMapAuthoritative($classMapAuthoratative) { |
| 48 | $this->classMapAuthoratative = $classMapAuthoratative; |
| 49 | } |
| 50 | |
| 51 | /** |
| 52 | * Should class lookup fail if not found in the current class map? |
| 53 | * |
| 54 | * @return bool |
| 55 | */ |
| 56 | public function getClassMapAuthoratative() { |
| 57 | return $this->classMapAuthoratative; |
| 58 | } |
| 59 | |
| 60 | /** |
| 61 | * @return array |
| 62 | */ |
| 63 | public function getFallbackDirs() { |
| 64 | return $this->fallbackDirs; |
| 65 | } |
| 66 | |
| 67 | /** |
| 68 | * @return array |
| 69 | */ |
| 70 | public function getClassMap() { |
| 71 | return $this->classMap; |
| 72 | } |
| 73 | |
| 74 | /** |
| 75 | * @param array $classMap class to filename map |
| 76 | */ |
| 77 | public function addClassMap(array $classMap) { |
| 78 | if ($this->classMap) { |
| 79 | $this->classMap = array_merge($this->classMap, $classMap); |
| 80 | } |
| 81 | else { |
| 82 | $this->classMap = $classMap; |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | /** |
| 87 | * Registers a set of classes, merging with any others previously set. |
| 88 | * |
| 89 | * @param string $prefix the classes prefix |
| 90 | * @param array|string $paths the location(s) of the classes |
| 91 | * @param bool $prepend prepend the location(s) |
| 92 | */ |
| 93 | public function add($prefix, $paths, $prepend = false) { |
| 94 | if (!$prefix) { |
| 95 | if ($prepend) { |
| 96 | $this->fallbackDirs = array_merge( |
| 97 | (array) $paths, |
| 98 | $this->fallbackDirs |
| 99 | ); |
| 100 | } |
| 101 | else { |
| 102 | $this->fallbackDirs = array_merge( |
| 103 | $this->fallbackDirs, |
| 104 | (array) $paths |
| 105 | ); |
| 106 | } |
| 107 | |
| 108 | return; |
| 109 | } |
| 110 | |
| 111 | if (!isset($this->prefixes[$prefix])) { |
| 112 | $this->prefixes[$prefix] = (array) $paths; |
| 113 | return; |
| 114 | } |
| 115 | |
| 116 | if ($prepend) { |
| 117 | $this->prefixes[$prefix] = array_merge( |
| 118 | (array) $paths, |
| 119 | $this->prefixes[$prefix] |
| 120 | ); |
| 121 | } |
| 122 | else { |
| 123 | $this->prefixes[$prefix] = array_merge( |
| 124 | $this->prefixes[$prefix], |
| 125 | (array) $paths |
| 126 | ); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | /** |
| 131 | * Registers a set of classes, replacing any others previously set. |
| 132 | * |
| 133 | * @param string $prefix the classes prefix |
| 134 | * @param array|string $paths the location(s) of the classes |
| 135 | */ |
| 136 | public function set($prefix, $paths) { |
| 137 | if (!$prefix) { |
| 138 | $this->fallbackDirs = (array) $paths; |
| 139 | return; |
| 140 | } |
| 141 | |
| 142 | $this->prefixes[$prefix] = (array) $paths; |
| 143 | } |
| 144 | |
| 145 | /** |
| 146 | * Turns on searching the include path for class files. |
| 147 | * |
| 148 | * @param bool $useIncludePath |
| 149 | */ |
| 150 | public function setUseIncludePath($useIncludePath) { |
| 151 | $this->useIncludePath = $useIncludePath; |
| 152 | } |
| 153 | |
| 154 | /** |
| 155 | * Can be used to check if the autoloader uses the include path to check |
| 156 | * for classes. |
| 157 | * |
| 158 | * @return bool |
| 159 | */ |
| 160 | public function getUseIncludePath() { |
| 161 | return $this->useIncludePath; |
| 162 | } |
| 163 | |
| 164 | /** |
| 165 | * Registers this instance as an autoloader. |
| 166 | */ |
| 167 | public function register() { |
| 168 | spl_autoload_register(array($this, 'loadClass'), true); |
| 169 | } |
| 170 | |
| 171 | /** |
| 172 | * Unregisters this instance as an autoloader. |
| 173 | */ |
| 174 | public function unregister() { |
| 175 | spl_autoload_unregister(array($this, 'loadClass')); |
| 176 | } |
| 177 | |
| 178 | /** |
| 179 | * Loads the given class or interface. |
| 180 | * |
| 181 | * @param string $class the name of the class |
| 182 | * @return bool|null true, if loaded |
| 183 | */ |
| 184 | public function loadClass($class) { |
| 185 | if ($file = $this->findFile($class)) { |
| 186 | include $file; |
| 187 | return true; |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | /** |
| 192 | * Finds the path to the file where the class is defined. |
| 193 | * |
| 194 | * @param string $class the name of the class |
| 195 | * @return string|null the path, if found |
| 196 | */ |
| 197 | public function findFile($class) { |
| 198 | if ('\\' === $class[0]) { |
| 199 | $class = substr($class, 1); |
| 200 | } |
| 201 | |
| 202 | if (isset($this->classMap[$class])) { |
| 203 | return $this->classMap[$class]; |
| 204 | } |
| 205 | elseif ($this->classMapAuthoratative) { |
| 206 | return false; |
| 207 | } |
| 208 | |
| 209 | $classPath = $this->getClassPath($class); |
| 210 | |
| 211 | foreach ($this->prefixes as $prefix => $dirs) { |
| 212 | if (0 === strpos($class, $prefix)) { |
| 213 | foreach ($dirs as $dir) { |
| 214 | if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) { |
| 215 | return $dir.DIRECTORY_SEPARATOR.$classPath; |
| 216 | } |
| 217 | } |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | foreach ($this->fallbackDirs as $dir) { |
| 222 | if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) { |
| 223 | return $dir.DIRECTORY_SEPARATOR.$classPath; |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | if ($this->useIncludePath && $file = self::resolveIncludePath($classPath)) { |
| 228 | return $file; |
| 229 | } |
| 230 | |
| 231 | return $this->classMap[$class] = false; |
| 232 | } |
| 233 | |
| 234 | private function getClassPath($class) { |
| 235 | if (false !== $pos = strrpos($class, '\\')) { |
| 236 | // namespaced class name |
| 237 | $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)).DIRECTORY_SEPARATOR; |
| 238 | $className = substr($class, $pos + 1); |
| 239 | } |
| 240 | else { |
| 241 | // PEAR-like class name |
| 242 | $classPath = null; |
| 243 | $className = $class; |
| 244 | } |
| 245 | |
| 246 | $className = str_replace('_', DIRECTORY_SEPARATOR, $className); |
| 247 | |
| 248 | // restore the prefix |
| 249 | if ($this->allowUnderscore && DIRECTORY_SEPARATOR === $className[0]) { |
| 250 | $className[0] = '_'; |
| 251 | } |
| 252 | |
| 253 | $classPath .= $className.'.php'; |
| 254 | |
| 255 | return $classPath; |
| 256 | } |
| 257 | |
| 258 | public static function resolveIncludePath($classPath) { |
| 259 | $paths = explode(PATH_SEPARATOR, get_include_path()); |
| 260 | |
| 261 | foreach ($paths as $path) { |
| 262 | $path = rtrim($path, '/\\'); |
| 263 | |
| 264 | if ($file = file_exists($path.DIRECTORY_SEPARATOR.$file)) { |
| 265 | return $file; |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | return false; |
| 270 | } |
| 271 | } |
| 272 |