1 | <?php |
||
30 | class ClassLoader |
||
31 | { |
||
32 | /** @var array List of PSR-4 compatible paths by namespace */ |
||
33 | private $prefixPaths; |
||
34 | |||
35 | /** @var array List of PSR-0 compatible paths by namespace */ |
||
36 | private $basePaths; |
||
37 | |||
38 | /** @var bool Whether to look for classes in include_path or not */ |
||
39 | private $useIncludePath; |
||
40 | |||
41 | /** @var callable The autoload method used to load classes */ |
||
42 | private $loader; |
||
43 | |||
44 | /** @var \Riimu\Kit\ClassLoader\ClassFinder Finder used to find class files */ |
||
45 | private $finder; |
||
46 | |||
47 | /** @var bool Whether loadClass should return values and throw exceptions or not */ |
||
48 | protected $verbose; |
||
49 | |||
50 | /** |
||
51 | * Creates a new ClassLoader instance. |
||
52 | */ |
||
53 | 96 | public function __construct() |
|
62 | |||
63 | /** |
||
64 | * Registers this instance as a class autoloader. |
||
65 | * @return bool True if the registration was successful, false if not |
||
66 | */ |
||
67 | 18 | public function register() |
|
71 | |||
72 | /** |
||
73 | * Unregisters this instance as a class autoloader. |
||
74 | * @return bool True if the unregistration was successful, false if not |
||
75 | */ |
||
76 | 24 | public function unregister() |
|
80 | |||
81 | /** |
||
82 | * Tells if this instance is currently registered as a class autoloader. |
||
83 | * @return bool True if registered, false if not |
||
84 | */ |
||
85 | 9 | public function isRegistered() |
|
89 | |||
90 | /** |
||
91 | * Tells whether to use include_path as part of base paths. |
||
92 | * |
||
93 | * When enabled, the directory paths in include_path are treated as base |
||
94 | * paths where to look for classes. This option defaults to false for PSR-4 |
||
95 | * compliance. |
||
96 | * |
||
97 | * @param bool $enabled True to use include_path, false to not use |
||
98 | * @return ClassLoader Returns self for call chaining |
||
99 | */ |
||
100 | 3 | public function useIncludePath($enabled = true) |
|
106 | |||
107 | /** |
||
108 | * Sets whether to return values and throw exceptions from loadClass. |
||
109 | * |
||
110 | * PSR-4 requires that autoloaders do not return values and do not throw |
||
111 | * exceptions from the autoloader. By default, the verbose mode is set to |
||
112 | * false for PSR-4 compliance. |
||
113 | * |
||
114 | * @param bool $enabled True to return values and exceptions, false to not |
||
115 | * @return ClassLoader Returns self for call chaining |
||
116 | */ |
||
117 | 24 | public function setVerbose($enabled) |
|
123 | |||
124 | /** |
||
125 | * Sets list of dot included file extensions to use for finding files. |
||
126 | * |
||
127 | * If no list of extensions is provided, the extension array defaults to |
||
128 | * just '.php'. |
||
129 | * |
||
130 | * @param string[] $extensions Array of dot included file extensions to use |
||
131 | * @return ClassLoader Returns self for call chaining |
||
132 | */ |
||
133 | 3 | public function setFileExtensions(array $extensions) |
|
139 | |||
140 | /** |
||
141 | * Adds a PSR-0 compliant base path for searching classes. |
||
142 | * |
||
143 | * In PSR-0, the class namespace structure directly reflects the location |
||
144 | * in the directory tree. A base path indicates the base directory where to |
||
145 | * search for classes. For example, if the class 'Foo\Bar', is defined in |
||
146 | * '/usr/lib/Foo/Bar.php', you would simply need to add the directory |
||
147 | * '/usr/lib' by calling: |
||
148 | * |
||
149 | * <code>addBasePath('/usr/lib')</code> |
||
150 | * |
||
151 | * Additionally, you may specify that the base path applies only to a |
||
152 | * specific namespace. You can do this by adding the namespace as the second |
||
153 | * parameter. For example, if you would like the path in the previous |
||
154 | * example to only apply to the namespace 'Foo', you could do so by calling: |
||
155 | * |
||
156 | * <code>addBasePath('/usr/lib/', 'Foo')</code> |
||
157 | * |
||
158 | * Note that as per PSR-0, the underscores in the class name are treated |
||
159 | * as namespace separators. Therefore 'Foo_Bar_Baz', would need to reside |
||
160 | * in 'Foo/Bar/Baz.php'. Regardless of whether the namespace is indicated |
||
161 | * by namespace separators or underscores, the namespace parameter must be |
||
162 | * defined using namespace separators, e.g 'Foo\Bar'. |
||
163 | * |
||
164 | * In addition to providing a single path as a string, you may also provide |
||
165 | * an array of paths. It is also possible to provide an associative array |
||
166 | * where the keys indicate the namespaces. Each value in the associative |
||
167 | * array may also be a string or an array of paths. |
||
168 | * |
||
169 | * @param string|array $path Single path, array of paths or an associative array |
||
170 | * @param string|null $namespace Limit the path only to specific namespace |
||
171 | * @return ClassLoader Returns self for call chaining |
||
172 | */ |
||
173 | 63 | public function addBasePath($path, $namespace = null) |
|
179 | |||
180 | /** |
||
181 | * Returns all known base paths. |
||
182 | * |
||
183 | * The paths will be returned as an associative array. The key indicates |
||
184 | * the namespace and the values are arrays that contain all paths that |
||
185 | * apply to that specific namespace. Paths that apply to all namespaces can |
||
186 | * be found inside the key '' (i.e. empty string). Note that the array does |
||
187 | * not include the paths in include_path even if the use of include_path is |
||
188 | * enabled. |
||
189 | * |
||
190 | * @return array All known base paths |
||
191 | */ |
||
192 | 18 | public function getBasePaths() |
|
196 | |||
197 | /** |
||
198 | * Adds a PSR-4 compliant prefix path for searching classes. |
||
199 | * |
||
200 | * In PSR-4, it is possible to replace part of namespace with specific |
||
201 | * path in the directory tree instead of requiring the entire namespace |
||
202 | * structure to be present in the directory tree. For example, if the class |
||
203 | * 'Vendor\Library\Class' is located in '/usr/lib/Library/src/Class.php', |
||
204 | * You would need to add the path '/usr/lib/Library/src' to the namespace |
||
205 | * 'Vendor\Library' by calling: |
||
206 | * |
||
207 | * <code>addPrefixPath('/usr/lib/Library/src', 'Vendor\Library')</code> |
||
208 | * |
||
209 | * If the method is called without providing a namespace, then the paths |
||
210 | * work similarly to paths added via addBasePath(), except that the |
||
211 | * underscores in the file name are not treated as namespace separators. |
||
212 | * |
||
213 | * Similarly to addBasePath(), the paths may be provided as an array or you |
||
214 | * can just provide a single associative array as the parameter. |
||
215 | * |
||
216 | * @param string|array $path Single path or array of paths |
||
217 | * @param string|null $namespace The namespace prefix the given path replaces |
||
218 | * @return ClassLoader Returns self for call chaining |
||
219 | */ |
||
220 | 21 | public function addPrefixPath($path, $namespace = null) |
|
226 | |||
227 | /** |
||
228 | * Returns all known prefix paths. |
||
229 | * |
||
230 | * The paths will be returned as an associative array. The key indicates |
||
231 | * the namespace and the values are arrays that contain all paths that |
||
232 | * apply to that specific namespace. Paths that apply to all namespaces can |
||
233 | * be found inside the key '' (i.e. empty string). |
||
234 | * |
||
235 | * @return array All known prefix paths |
||
236 | */ |
||
237 | 18 | public function getPrefixPaths() |
|
241 | |||
242 | /** |
||
243 | * Adds the paths to the list of paths according to the provided parameters. |
||
244 | * @param array $list List of paths to modify |
||
245 | * @param string|array $path Single path or array of paths |
||
246 | * @param string|null $namespace The namespace definition |
||
247 | */ |
||
248 | 66 | private function addPath(& $list, $path, $namespace) |
|
260 | |||
261 | /** |
||
262 | * Canonizes the namespace and adds the paths to that specific namespace. |
||
263 | * @param array $list List of paths to modify |
||
264 | * @param string $namespace Namespace for the paths |
||
265 | * @param string[] $paths List of paths for the namespace |
||
266 | */ |
||
267 | 66 | private function addNamespacePaths(& $list, $namespace, $paths) |
|
281 | |||
282 | /** |
||
283 | * Attempts to load the class using known class paths. |
||
284 | * |
||
285 | * The classes will be searched using the prefix paths, base paths and the |
||
286 | * include_path (if enabled) in that order. Other than that, the autoloader |
||
287 | * makes no guarantees about the order of the searched paths. |
||
288 | * |
||
289 | * If verbose mode is enabled, then the method will return true if the class |
||
290 | * loading was successful and false if not. Additionally the method will |
||
291 | * throw an exception if the class already exists or if the class was not |
||
292 | * defined in the file that was included. |
||
293 | * |
||
294 | * @param string $class Full name of the class to load |
||
295 | * @return bool|null True if the class was loaded, false if not |
||
296 | * @throws \RuntimeException If the class was not defined in the included file |
||
297 | * @throws \InvalidArgumentException If the class already exists |
||
298 | */ |
||
299 | 57 | public function loadClass($class) |
|
311 | |||
312 | /** |
||
313 | * Actually loads the class without any regard to verbose setting. |
||
314 | * @param string $class Full name of the class to load |
||
315 | * @return bool True if the class was loaded, false if not |
||
316 | * @throws \InvalidArgumentException If the class already exists |
||
317 | */ |
||
318 | 57 | private function load($class) |
|
333 | |||
334 | /** |
||
335 | * Attempts to find a file for the given class using known paths. |
||
336 | * @param string $class Full name of the class |
||
337 | * @return string|false Path to the class file or false if not found |
||
338 | */ |
||
339 | 60 | public function findFile($class) |
|
343 | |||
344 | /** |
||
345 | * Includes the file and makes sure the class exists. |
||
346 | * @param string $file Full path to the file |
||
347 | * @param string $class Full name of the class |
||
348 | * @return bool Always returns true |
||
349 | * @throws \RuntimeException If the class was not defined in the included file |
||
350 | */ |
||
351 | 39 | protected function loadFile($file, $class) |
|
364 | |||
365 | /** |
||
366 | * Tells if a class, interface or trait exists with given name. |
||
367 | * @param string $class Full name of the class |
||
368 | * @return bool True if it exists, false if not |
||
369 | */ |
||
370 | 57 | private function isLoaded($class) |
|
376 | } |
||
377 |