bug #13173 [Debug] fixes ClassNotFoundFatalErrorHandler to correctly handle class not found errors with Symfony ClassLoader component autoloaders. (hhamon)
This PR was merged into the 2.5 branch.
Discussion
----------
[Debug] fixes ClassNotFoundFatalErrorHandler to correctly handle class not found errors with Symfony ClassLoader component autoloaders.
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | ~
| License | MIT
| Doc PR | ~
Commits
-------
008f2ea
[Debug] fixes ClassNotFoundFatalErrorHandler to correctly handle class not found errors with Symfony ClassLoader component autoloaders.
This commit is contained in:
commit
c3ca7ac014
@ -15,7 +15,8 @@ use Symfony\Component\Debug\Exception\ClassNotFoundException;
|
||||
use Symfony\Component\Debug\Exception\FatalErrorException;
|
||||
use Symfony\Component\Debug\DebugClassLoader;
|
||||
use Composer\Autoload\ClassLoader as ComposerClassLoader;
|
||||
use Symfony\Component\ClassLoader as SymfonyClassLoader;
|
||||
use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
|
||||
use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader;
|
||||
|
||||
/**
|
||||
* ErrorHandler for classes that do not exist.
|
||||
@ -97,11 +98,11 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
|
||||
|
||||
// find Symfony and Composer autoloaders
|
||||
$classes = array();
|
||||
|
||||
foreach ($functions as $function) {
|
||||
if (!is_array($function)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// get class loaders wrapped by DebugClassLoader
|
||||
if ($function[0] instanceof DebugClassLoader) {
|
||||
$function = $function[0]->getClassLoader();
|
||||
@ -116,7 +117,7 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
|
||||
}
|
||||
}
|
||||
|
||||
if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader) {
|
||||
if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader || $function[0] instanceof SymfonyUniversalClassLoader) {
|
||||
foreach ($function[0]->getPrefixes() as $prefix => $paths) {
|
||||
foreach ($paths as $path) {
|
||||
$classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\Debug\Tests\FatalErrorHandler;
|
||||
|
||||
use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
|
||||
use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader;
|
||||
use Symfony\Component\Debug\Exception\FatalErrorException;
|
||||
use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
|
||||
|
||||
@ -19,11 +21,25 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
/**
|
||||
* @dataProvider provideClassNotFoundData
|
||||
*/
|
||||
public function testClassNotFound($error, $translatedMessage)
|
||||
public function testHandleClassNotFound($error, $translatedMessage, $autoloader = null)
|
||||
{
|
||||
if ($autoloader) {
|
||||
// Unregister all autoloaders to ensure the custom provided
|
||||
// autoloader is the only one to be used during the test run.
|
||||
$autoloaders = spl_autoload_functions();
|
||||
array_map('spl_autoload_unregister', $autoloaders);
|
||||
spl_autoload_register($autoloader);
|
||||
}
|
||||
|
||||
$handler = new ClassNotFoundFatalErrorHandler();
|
||||
|
||||
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));
|
||||
|
||||
if ($autoloader) {
|
||||
spl_autoload_unregister($autoloader);
|
||||
array_map('spl_autoload_register', $autoloaders);
|
||||
}
|
||||
|
||||
$this->assertInstanceof('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
|
||||
$this->assertSame($translatedMessage, $exception->getMessage());
|
||||
$this->assertSame($error['type'], $exception->getSeverity());
|
||||
@ -33,6 +49,14 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function provideClassNotFoundData()
|
||||
{
|
||||
$prefixes = array('Symfony\Component\Debug\Exception\\' => realpath(__DIR__.'/../../Exception'));
|
||||
|
||||
$symfonyAutoloader = new SymfonyClassLoader();
|
||||
$symfonyAutoloader->addPrefixes($prefixes);
|
||||
|
||||
$symfonyUniversalClassLoader = new SymfonyUniversalClassLoader();
|
||||
$symfonyUniversalClassLoader->registerPrefixes($prefixes);
|
||||
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
@ -79,6 +103,36 @@ class ClassNotFoundFatalErrorHandlerTest extends \PHPUnit_Framework_TestCase
|
||||
),
|
||||
'Attempted to load class "UndefinedFunctionException" from namespace "Foo\Bar" in foo.php line 12. Do you need to "use" it from another namespace? Perhaps you need to add a use statement for one of the following: Symfony\Component\Debug\Exception\UndefinedFunctionException.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'type' => 1,
|
||||
'line' => 12,
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
|
||||
),
|
||||
'Attempted to load class "UndefinedFunctionException" from namespace "Foo\Bar" in foo.php line 12. Do you need to "use" it from another namespace? Perhaps you need to add a use statement for one of the following: Symfony\Component\Debug\Exception\UndefinedFunctionException.',
|
||||
array($symfonyAutoloader, 'loadClass'),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'type' => 1,
|
||||
'line' => 12,
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
|
||||
),
|
||||
'Attempted to load class "UndefinedFunctionException" from namespace "Foo\Bar" in foo.php line 12. Do you need to "use" it from another namespace? Perhaps you need to add a use statement for one of the following: Symfony\Component\Debug\Exception\UndefinedFunctionException.',
|
||||
array($symfonyUniversalClassLoader, 'loadClass'),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'type' => 1,
|
||||
'line' => 12,
|
||||
'file' => 'foo.php',
|
||||
'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
|
||||
),
|
||||
'Attempted to load class "UndefinedFunctionException" from namespace "Foo\Bar" in foo.php line 12. Do you need to "use" it from another namespace?',
|
||||
function ($className) { /* do nothing here */ },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/class-loader": "~2.2",
|
||||
"symfony/http-kernel": "~2.2",
|
||||
"symfony/http-foundation": "~2.1"
|
||||
},
|
||||
|
Reference in New Issue
Block a user