[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
1 changed files with 26 additions and 14 deletions

View File

@ -108,9 +108,9 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
}
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) {
$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 $class
* @param string $prefix
*
* @return array
*/
private function findClassInPath($path, $class)
private function findClassInPath($path, $class, $prefix)
{
if (!$path = realpath($path)) {
return array();
@ -134,7 +135,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
$classes = array();
$filename = $class.'.php';
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;
}
}
@ -145,27 +146,38 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
/**
* @param string $path
* @param string $file
* @param string $prefix
*
* @return string|null
*/
private function convertFileToClass($path, $file)
private function convertFileToClass($path, $file, $prefix)
{
$namespacedClass = str_replace(array($path.DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file);
$pearClass = str_replace('\\', '_', $namespacedClass);
$candidates = array(
// 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
// is not found, the new autoloader call will require the file again leading to a
// "cannot redeclare class" error.
if (!$this->classExists($namespacedClass) && !$this->classExists($pearClass)) {
require_once $file;
foreach ($candidates as $candidate) {
if ($this->classExists($candidate)) {
return $candidate;
}
}
if ($this->classExists($namespacedClass)) {
return $namespacedClass;
}
require_once $file;
if ($this->classExists($pearClass)) {
return $pearClass;
foreach ($candidates as $candidate) {
if ($this->classExists($candidate)) {
return $candidate;
}
}
}