[Debug] fixed class lookup when using PSR-0 with a target dir

This commit is contained in:
Fabien Potencier 2014-09-28 15:04:39 +02:00
parent 3a1661bb38
commit f5b38ec995

View File

@ -108,9 +108,9 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
} }
if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader) { if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader) {
foreach ($function[0]->getPrefixes() as $paths) { foreach ($function[0]->getPrefixes() as $prefix => $paths) {
foreach ($paths as $path) { foreach ($paths as $path) {
$classes = array_merge($classes, $this->findClassInPath($path, $class)); $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
} }
} }
} }
@ -122,10 +122,11 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
/** /**
* @param string $path * @param string $path
* @param string $class * @param string $class
* @param string $prefix
* *
* @return array * @return array
*/ */
private function findClassInPath($path, $class) private function findClassInPath($path, $class, $prefix)
{ {
if (!$path = realpath($path)) { if (!$path = realpath($path)) {
return array(); return array();
@ -134,7 +135,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
$classes = array(); $classes = array();
$filename = $class.'.php'; $filename = $class.'.php';
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName())) { if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) {
$classes[] = $class; $classes[] = $class;
} }
} }
@ -145,27 +146,38 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
/** /**
* @param string $path * @param string $path
* @param string $file * @param string $file
* @param string $prefix
* *
* @return string|null * @return string|null
*/ */
private function convertFileToClass($path, $file) private function convertFileToClass($path, $file, $prefix)
{ {
$namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file); $candidates = array(
$pearClass = str_replace('\\', '_', $namespacedClass); // namespaced class
$namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
// namespaced class (with target dir)
$namespacedClassTargetDir = $prefix.str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
// PEAR class
str_replace('\\', '_', $namespacedClass),
// PEAR class (with target dir)
str_replace('\\', '_', $namespacedClassTargetDir),
);
// We cannot use the autoloader here as most of them use require; but if the class // We cannot use the autoloader here as most of them use require; but if the class
// is not found, the new autoloader call will require the file again leading to a // is not found, the new autoloader call will require the file again leading to a
// "cannot redeclare class" error. // "cannot redeclare class" error.
if (!$this->classExists($namespacedClass) && !$this->classExists($pearClass)) { foreach ($candidates as $candidate) {
require_once $file; if ($this->classExists($candidate)) {
return $candidate;
}
} }
if ($this->classExists($namespacedClass)) { require_once $file;
return $namespacedClass;
}
if ($this->classExists($pearClass)) { foreach ($candidates as $candidate) {
return $pearClass; if ($this->classExists($candidate)) {
return $candidate;
}
} }
} }