TYPO3  7.6
ClassLoader.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of Composer.
5  *
6  * (c) Nils Adermann <naderman@naderman.de>
7  * Jordi Boggiano <j.boggiano@seld.be>
8  *
9  * For the full copyright and license information, please view the LICENSE
10  * file that was distributed with this source code.
11  */
12 
13 namespace Composer\Autoload;
14 
44 {
45  // PSR-4
46  private $prefixLengthsPsr4 = array();
47  private $prefixDirsPsr4 = array();
48  private $fallbackDirsPsr4 = array();
49 
50  // PSR-0
51  private $prefixesPsr0 = array();
52  private $fallbackDirsPsr0 = array();
53 
54  private $useIncludePath = false;
55  private $classMap = array();
56 
57  private $classMapAuthoritative = false;
58 
59  public function getPrefixes()
60  {
61  if (!empty($this->prefixesPsr0)) {
62  return call_user_func_array('array_merge', $this->prefixesPsr0);
63  }
64 
65  return array();
66  }
67 
68  public function getPrefixesPsr4()
69  {
70  return $this->prefixDirsPsr4;
71  }
72 
73  public function getFallbackDirs()
74  {
76  }
77 
78  public function getFallbackDirsPsr4()
79  {
81  }
82 
83  public function getClassMap()
84  {
85  return $this->classMap;
86  }
87 
91  public function addClassMap(array $classMap)
92  {
93  if ($this->classMap) {
94  $this->classMap = array_merge($this->classMap, $classMap);
95  } else {
96  $this->classMap = $classMap;
97  }
98  }
99 
108  public function add($prefix, $paths, $prepend = false)
109  {
110  if (!$prefix) {
111  if ($prepend) {
112  $this->fallbackDirsPsr0 = array_merge(
113  (array) $paths,
114  $this->fallbackDirsPsr0
115  );
116  } else {
117  $this->fallbackDirsPsr0 = array_merge(
118  $this->fallbackDirsPsr0,
119  (array) $paths
120  );
121  }
122 
123  return;
124  }
125 
126  $first = $prefix[0];
127  if (!isset($this->prefixesPsr0[$first][$prefix])) {
128  $this->prefixesPsr0[$first][$prefix] = (array) $paths;
129 
130  return;
131  }
132  if ($prepend) {
133  $this->prefixesPsr0[$first][$prefix] = array_merge(
134  (array) $paths,
135  $this->prefixesPsr0[$first][$prefix]
136  );
137  } else {
138  $this->prefixesPsr0[$first][$prefix] = array_merge(
139  $this->prefixesPsr0[$first][$prefix],
140  (array) $paths
141  );
142  }
143  }
144 
155  public function addPsr4($prefix, $paths, $prepend = false)
156  {
157  if (!$prefix) {
158  // Register directories for the root namespace.
159  if ($prepend) {
160  $this->fallbackDirsPsr4 = array_merge(
161  (array) $paths,
162  $this->fallbackDirsPsr4
163  );
164  } else {
165  $this->fallbackDirsPsr4 = array_merge(
166  $this->fallbackDirsPsr4,
167  (array) $paths
168  );
169  }
170  } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
171  // Register directories for a new namespace.
172  $length = strlen($prefix);
173  if ('\\' !== $prefix[$length - 1]) {
174  throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
175  }
176  $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
177  $this->prefixDirsPsr4[$prefix] = (array) $paths;
178  } elseif ($prepend) {
179  // Prepend directories for an already registered namespace.
180  $this->prefixDirsPsr4[$prefix] = array_merge(
181  (array) $paths,
182  $this->prefixDirsPsr4[$prefix]
183  );
184  } else {
185  // Append directories for an already registered namespace.
186  $this->prefixDirsPsr4[$prefix] = array_merge(
187  $this->prefixDirsPsr4[$prefix],
188  (array) $paths
189  );
190  }
191  }
192 
200  public function set($prefix, $paths)
201  {
202  if (!$prefix) {
203  $this->fallbackDirsPsr0 = (array) $paths;
204  } else {
205  $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
206  }
207  }
208 
218  public function setPsr4($prefix, $paths)
219  {
220  if (!$prefix) {
221  $this->fallbackDirsPsr4 = (array) $paths;
222  } else {
223  $length = strlen($prefix);
224  if ('\\' !== $prefix[$length - 1]) {
225  throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
226  }
227  $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
228  $this->prefixDirsPsr4[$prefix] = (array) $paths;
229  }
230  }
231 
238  {
239  $this->useIncludePath = $useIncludePath;
240  }
241 
248  public function getUseIncludePath()
249  {
250  return $this->useIncludePath;
251  }
252 
260  {
261  $this->classMapAuthoritative = $classMapAuthoritative;
262  }
263 
269  public function isClassMapAuthoritative()
270  {
272  }
273 
279  public function register($prepend = false)
280  {
281  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
282  }
283 
287  public function unregister()
288  {
289  spl_autoload_unregister(array($this, 'loadClass'));
290  }
291 
298  public function loadClass($class)
299  {
300  if ($file = $this->findFile($class)) {
301  includeFile($file);
302 
303  return true;
304  }
305  }
306 
314  public function findFile($class)
315  {
316  // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317  if ('\\' == $class[0]) {
318  $class = substr($class, 1);
319  }
320 
321  // class map lookup
322  if (isset($this->classMap[$class])) {
323  return $this->classMap[$class];
324  }
325  if ($this->classMapAuthoritative) {
326  return false;
327  }
328 
329  $file = $this->findFileWithExtension($class, '.php');
330 
331  // Search for Hack files if we are running on HHVM
332  if ($file === null && defined('HHVM_VERSION')) {
333  $file = $this->findFileWithExtension($class, '.hh');
334  }
335 
336  if ($file === null) {
337  // Remember that this class does not exist.
338  return $this->classMap[$class] = false;
339  }
340 
341  return $file;
342  }
343 
344  private function findFileWithExtension($class, $ext)
345  {
346  // PSR-4 lookup
347  $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
348 
349  $first = $class[0];
350  if (isset($this->prefixLengthsPsr4[$first])) {
351  foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352  if (0 === strpos($class, $prefix)) {
353  foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354  if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
355  return $file;
356  }
357  }
358  }
359  }
360  }
361 
362  // PSR-4 fallback dirs
363  foreach ($this->fallbackDirsPsr4 as $dir) {
364  if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365  return $file;
366  }
367  }
368 
369  // PSR-0 lookup
370  if (false !== $pos = strrpos($class, '\\')) {
371  // namespaced class name
372  $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
373  . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
374  } else {
375  // PEAR-like class name
376  $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
377  }
378 
379  if (isset($this->prefixesPsr0[$first])) {
380  foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381  if (0 === strpos($class, $prefix)) {
382  foreach ($dirs as $dir) {
383  if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384  return $file;
385  }
386  }
387  }
388  }
389  }
390 
391  // PSR-0 fallback dirs
392  foreach ($this->fallbackDirsPsr0 as $dir) {
393  if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394  return $file;
395  }
396  }
397 
398  // PSR-0 include paths.
399  if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400  return $file;
401  }
402  }
403 }
404 
410 function includeFile($file)
411 {
412  include $file;
413 }