diff --git a/composer.json b/composer.json
index 2e6fd64f1795b..b45299e83b5f8 100644
--- a/composer.json
+++ b/composer.json
@@ -42,7 +42,6 @@
"symfony/console": "self.version",
"symfony/css-selector": "self.version",
"symfony/dependency-injection": "self.version",
- "symfony/debug": "self.version",
"symfony/debug-bundle": "self.version",
"symfony/doctrine-bridge": "self.version",
"symfony/dom-crawler": "self.version",
diff --git a/src/Symfony/Component/Debug/.gitignore b/src/Symfony/Component/Debug/.gitignore
deleted file mode 100644
index c49a5d8df5c65..0000000000000
--- a/src/Symfony/Component/Debug/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-vendor/
-composer.lock
-phpunit.xml
diff --git a/src/Symfony/Component/Debug/BufferingLogger.php b/src/Symfony/Component/Debug/BufferingLogger.php
deleted file mode 100644
index 6e308f2247286..0000000000000
--- a/src/Symfony/Component/Debug/BufferingLogger.php
+++ /dev/null
@@ -1,41 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug;
-
-use Psr\Log\AbstractLogger;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', BufferingLogger::class, \Symfony\Component\ErrorHandler\BufferingLogger::class), E_USER_DEPRECATED);
-
-/**
- * A buffering logger that stacks logs for later.
- *
- * @author Nicolas Grekas
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\BufferingLogger instead.
- */
-class BufferingLogger extends AbstractLogger
-{
- private $logs = [];
-
- public function log($level, $message, array $context = [])
- {
- $this->logs[] = [$level, $message, $context];
- }
-
- public function cleanLogs()
- {
- $logs = $this->logs;
- $this->logs = [];
-
- return $logs;
- }
-}
diff --git a/src/Symfony/Component/Debug/CHANGELOG.md b/src/Symfony/Component/Debug/CHANGELOG.md
deleted file mode 100644
index b2e17f38211a8..0000000000000
--- a/src/Symfony/Component/Debug/CHANGELOG.md
+++ /dev/null
@@ -1,84 +0,0 @@
-CHANGELOG
-=========
-
-4.4.0
------
-
- * deprecated `FlattenException`, use the `FlattenException` of the `ErrorRenderer` component
- * deprecated the whole component in favor of the `ErrorHandler` component
-
-4.3.0
------
-
-* made the `ErrorHandler` and `ExceptionHandler` classes final
-* added `Exception\FlattenException::getAsString` and
-`Exception\FlattenException::getTraceAsString` to increase compatibility to php
-exception objects
-
-4.0.0
------
-
-* removed the symfony_debug extension
-* removed `ContextErrorException`
-
-3.4.0
------
-
-* deprecated `ErrorHandler::stackErrors()` and `ErrorHandler::unstackErrors()`
-
-3.3.0
------
-
-* deprecated the `ContextErrorException` class: use \ErrorException directly now
-
-3.2.0
------
-
-* `FlattenException::getTrace()` now returns additional type descriptions
- `integer` and `float`.
-
-
-3.0.0
------
-
-* removed classes, methods and interfaces deprecated in 2.x
-
-2.8.0
------
-
-* added BufferingLogger for errors that happen before a proper logger is configured
-* allow throwing from `__toString()` with `return trigger_error($e, E_USER_ERROR);`
-* deprecate ExceptionHandler::createResponse
-
-2.7.0
------
-
-* added deprecations checking for parent interfaces/classes to DebugClassLoader
-* added ZTS support to symfony_debug extension
-* added symfony_debug_backtrace() to symfony_debug extension
- to track the backtrace of fatal errors
-
-2.6.0
------
-
-* generalized ErrorHandler and ExceptionHandler,
- with some new methods and others deprecated
-* enhanced error messages for uncaught exceptions
-
-2.5.0
------
-
-* added ExceptionHandler::setHandler()
-* added UndefinedMethodFatalErrorHandler
-* deprecated DummyException
-
-2.4.0
------
-
- * added a DebugClassLoader able to wrap any autoloader providing a findFile method
- * improved error messages for not found classes and functions
-
-2.3.0
------
-
- * added the component
diff --git a/src/Symfony/Component/Debug/Debug.php b/src/Symfony/Component/Debug/Debug.php
deleted file mode 100644
index 788ad7d9243ff..0000000000000
--- a/src/Symfony/Component/Debug/Debug.php
+++ /dev/null
@@ -1,64 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', Debug::class, \Symfony\Component\ErrorHandler\Debug::class), E_USER_DEPRECATED);
-
-/**
- * Registers all the debug tools.
- *
- * @author Fabien Potencier
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Debug instead.
- */
-class Debug
-{
- private static $enabled = false;
-
- /**
- * Enables the debug tools.
- *
- * This method registers an error handler and an exception handler.
- *
- * @param int $errorReportingLevel The level of error reporting you want
- * @param bool $displayErrors Whether to display errors (for development) or just log them (for production)
- */
- public static function enable($errorReportingLevel = E_ALL, $displayErrors = true)
- {
- if (static::$enabled) {
- return;
- }
-
- static::$enabled = true;
-
- if (null !== $errorReportingLevel) {
- error_reporting($errorReportingLevel);
- } else {
- error_reporting(E_ALL);
- }
-
- if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
- ini_set('display_errors', 0);
- ExceptionHandler::register();
- } elseif ($displayErrors && (!filter_var(ini_get('log_errors'), FILTER_VALIDATE_BOOLEAN) || ini_get('error_log'))) {
- // CLI - display errors only if they're not already logged to STDERR
- ini_set('display_errors', 1);
- }
- if ($displayErrors) {
- ErrorHandler::register(new ErrorHandler(new BufferingLogger()));
- } else {
- ErrorHandler::register()->throwAt(0, true);
- }
-
- DebugClassLoader::enable();
- }
-}
diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php
deleted file mode 100644
index f422e557267f9..0000000000000
--- a/src/Symfony/Component/Debug/DebugClassLoader.php
+++ /dev/null
@@ -1,529 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug;
-
-use PHPUnit\Framework\MockObject\Matcher\StatelessInvocation;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', DebugClassLoader::class, \Symfony\Component\ErrorHandler\DebugClassLoader::class), E_USER_DEPRECATED);
-
-/**
- * Autoloader checking if the class is really defined in the file found.
- *
- * The ClassLoader will wrap all registered autoloaders
- * and will throw an exception if a file is found but does
- * not declare the class.
- *
- * @author Fabien Potencier
- * @author Christophe Coevoet
- * @author Nicolas Grekas
- * @author Guilhem Niot
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\DebugClassLoader instead.
- */
-class DebugClassLoader
-{
- private $classLoader;
- private $isFinder;
- private $loaded = [];
- private static $caseCheck;
- private static $checkedClasses = [];
- private static $final = [];
- private static $finalMethods = [];
- private static $deprecated = [];
- private static $internal = [];
- private static $internalMethods = [];
- private static $annotatedParameters = [];
- private static $darwinCache = ['/' => ['/', []]];
- private static $method = [];
-
- public function __construct(callable $classLoader)
- {
- $this->classLoader = $classLoader;
- $this->isFinder = \is_array($classLoader) && method_exists($classLoader[0], 'findFile');
-
- if (!isset(self::$caseCheck)) {
- $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), \DIRECTORY_SEPARATOR);
- $i = strrpos($file, \DIRECTORY_SEPARATOR);
- $dir = substr($file, 0, 1 + $i);
- $file = substr($file, 1 + $i);
- $test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file);
- $test = realpath($dir.$test);
-
- if (false === $test || false === $i) {
- // filesystem is case sensitive
- self::$caseCheck = 0;
- } elseif (substr($test, -\strlen($file)) === $file) {
- // filesystem is case insensitive and realpath() normalizes the case of characters
- self::$caseCheck = 1;
- } elseif (false !== stripos(PHP_OS, 'darwin')) {
- // on MacOSX, HFS+ is case insensitive but realpath() doesn't normalize the case of characters
- self::$caseCheck = 2;
- } else {
- // filesystem case checks failed, fallback to disabling them
- self::$caseCheck = 0;
- }
- }
- }
-
- /**
- * Gets the wrapped class loader.
- *
- * @return callable The wrapped class loader
- */
- public function getClassLoader()
- {
- return $this->classLoader;
- }
-
- /**
- * Wraps all autoloaders.
- */
- public static function enable()
- {
- // Ensures we don't hit https://bugs.php.net/42098
- class_exists('Symfony\Component\Debug\ErrorHandler');
- class_exists('Psr\Log\LogLevel');
-
- if (!\is_array($functions = spl_autoload_functions())) {
- return;
- }
-
- foreach ($functions as $function) {
- spl_autoload_unregister($function);
- }
-
- foreach ($functions as $function) {
- if (!\is_array($function) || !$function[0] instanceof self) {
- $function = [new static($function), 'loadClass'];
- }
-
- spl_autoload_register($function);
- }
- }
-
- /**
- * Disables the wrapping.
- */
- public static function disable()
- {
- if (!\is_array($functions = spl_autoload_functions())) {
- return;
- }
-
- foreach ($functions as $function) {
- spl_autoload_unregister($function);
- }
-
- foreach ($functions as $function) {
- if (\is_array($function) && $function[0] instanceof self) {
- $function = $function[0]->getClassLoader();
- }
-
- spl_autoload_register($function);
- }
- }
-
- /**
- * @return string|null
- */
- public function findFile($class)
- {
- return $this->isFinder ? $this->classLoader[0]->findFile($class) ?: null : null;
- }
-
- /**
- * Loads the given class or interface.
- *
- * @param string $class The name of the class
- *
- * @throws \RuntimeException
- */
- public function loadClass($class)
- {
- $e = error_reporting(error_reporting() | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
-
- try {
- if ($this->isFinder && !isset($this->loaded[$class])) {
- $this->loaded[$class] = true;
- if (!$file = $this->classLoader[0]->findFile($class) ?: false) {
- // no-op
- } elseif (\function_exists('opcache_is_script_cached') && @opcache_is_script_cached($file)) {
- include $file;
-
- return;
- } elseif (false === include $file) {
- return;
- }
- } else {
- ($this->classLoader)($class);
- $file = false;
- }
- } finally {
- error_reporting($e);
- }
-
- $this->checkClass($class, $file);
- }
-
- private function checkClass($class, $file = null)
- {
- $exists = null === $file || class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false);
-
- if (null !== $file && $class && '\\' === $class[0]) {
- $class = substr($class, 1);
- }
-
- if ($exists) {
- if (isset(self::$checkedClasses[$class])) {
- return;
- }
- self::$checkedClasses[$class] = true;
-
- $refl = new \ReflectionClass($class);
- if (null === $file && $refl->isInternal()) {
- return;
- }
- $name = $refl->getName();
-
- if ($name !== $class && 0 === strcasecmp($name, $class)) {
- throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name));
- }
-
- $deprecations = $this->checkAnnotations($refl, $name);
-
- foreach ($deprecations as $message) {
- @trigger_error($message, E_USER_DEPRECATED);
- }
- }
-
- if (!$file) {
- return;
- }
-
- if (!$exists) {
- if (false !== strpos($class, '/')) {
- throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
- }
-
- throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
- }
-
- if (self::$caseCheck && $message = $this->checkCase($refl, $file, $class)) {
- throw new \RuntimeException(sprintf('Case mismatch between class and real file names: "%s" vs "%s" in "%s".', $message[0], $message[1], $message[2]));
- }
- }
-
- public function checkAnnotations(\ReflectionClass $refl, $class)
- {
- $deprecations = [];
-
- // Don't trigger deprecations for classes in the same vendor
- if (2 > $len = 1 + (strpos($class, '\\') ?: strpos($class, '_'))) {
- $len = 0;
- $ns = '';
- } else {
- $ns = str_replace('_', '\\', substr($class, 0, $len));
- }
-
- // Detect annotations on the class
- if (false !== $doc = $refl->getDocComment()) {
- foreach (['final', 'deprecated', 'internal'] as $annotation) {
- if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) {
- self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : '';
- }
- }
-
- if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+(?:[\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, PREG_SET_ORDER)) {
- foreach ($notice as $method) {
- $static = '' !== $method[1];
- $name = $method[2];
- $description = $method[3] ?? null;
- if (false === strpos($name, '(')) {
- $name .= '()';
- }
- if (null !== $description) {
- $description = trim($description);
- if (!isset($method[4])) {
- $description .= '.';
- }
- }
- self::$method[$class][] = [$class, $name, $static, $description];
- }
- }
- }
-
- $parent = get_parent_class($class);
- $parentAndOwnInterfaces = $this->getOwnInterfaces($class, $parent);
- if ($parent) {
- $parentAndOwnInterfaces[$parent] = $parent;
-
- if (!isset(self::$checkedClasses[$parent])) {
- $this->checkClass($parent);
- }
-
- if (isset(self::$final[$parent])) {
- $deprecations[] = sprintf('The "%s" class is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $class);
- }
- }
-
- // Detect if the parent is annotated
- foreach ($parentAndOwnInterfaces + class_uses($class, false) as $use) {
- if (!isset(self::$checkedClasses[$use])) {
- $this->checkClass($use);
- }
- if (isset(self::$deprecated[$use]) && strncmp($ns, str_replace('_', '\\', $use), $len) && !isset(self::$deprecated[$class])) {
- $type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
- $verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
-
- $deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]);
- }
- if (isset(self::$internal[$use]) && strncmp($ns, str_replace('_', '\\', $use), $len)) {
- $deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class);
- }
- if (isset(self::$method[$use])) {
- if ($refl->isAbstract()) {
- if (isset(self::$method[$class])) {
- self::$method[$class] = array_merge(self::$method[$class], self::$method[$use]);
- } else {
- self::$method[$class] = self::$method[$use];
- }
- } elseif (!$refl->isInterface()) {
- $hasCall = $refl->hasMethod('__call');
- $hasStaticCall = $refl->hasMethod('__callStatic');
- foreach (self::$method[$use] as $method) {
- list($interface, $name, $static, $description) = $method;
- if ($static ? $hasStaticCall : $hasCall) {
- continue;
- }
- $realName = substr($name, 0, strpos($name, '('));
- if (!$refl->hasMethod($realName) || !($methodRefl = $refl->getMethod($realName))->isPublic() || ($static && !$methodRefl->isStatic()) || (!$static && $methodRefl->isStatic())) {
- $deprecations[] = sprintf('Class "%s" should implement method "%s::%s"%s', $class, ($static ? 'static ' : '').$interface, $name, null == $description ? '.' : ': '.$description);
- }
- }
- }
- }
- }
-
- if (trait_exists($class)) {
- return $deprecations;
- }
-
- // Inherit @final, @internal and @param annotations for methods
- self::$finalMethods[$class] = [];
- self::$internalMethods[$class] = [];
- self::$annotatedParameters[$class] = [];
- foreach ($parentAndOwnInterfaces as $use) {
- foreach (['finalMethods', 'internalMethods', 'annotatedParameters'] as $property) {
- if (isset(self::${$property}[$use])) {
- self::${$property}[$class] = self::${$property}[$class] ? self::${$property}[$use] + self::${$property}[$class] : self::${$property}[$use];
- }
- }
- }
-
- foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $method) {
- if ($method->class !== $class) {
- continue;
- }
-
- if ($parent && isset(self::$finalMethods[$parent][$method->name])) {
- list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
- $deprecations[] = sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class);
- }
-
- if (isset(self::$internalMethods[$class][$method->name])) {
- list($declaringClass, $message) = self::$internalMethods[$class][$method->name];
- if (strncmp($ns, $declaringClass, $len)) {
- $deprecations[] = sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $class);
- }
- }
-
- // To read method annotations
- $doc = $method->getDocComment();
-
- if (isset(self::$annotatedParameters[$class][$method->name])) {
- $definedParameters = [];
- foreach ($method->getParameters() as $parameter) {
- $definedParameters[$parameter->name] = true;
- }
-
- foreach (self::$annotatedParameters[$class][$method->name] as $parameterName => $deprecation) {
- if (!isset($definedParameters[$parameterName]) && !($doc && preg_match("/\\n\\s+\\* @param +((?(?!callable *\().*?|callable *\(.*\).*?))(?<= )\\\${$parameterName}\\b/", $doc))) {
- $deprecations[] = sprintf($deprecation, $class);
- }
- }
- }
-
- if (!$doc) {
- continue;
- }
-
- $finalOrInternal = false;
-
- foreach (['final', 'internal'] as $annotation) {
- if (false !== strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$|\r?\n)#s', $doc, $notice)) {
- $message = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : '';
- self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message];
- $finalOrInternal = true;
- }
- }
-
- if ($finalOrInternal || $method->isConstructor() || false === strpos($doc, '@param') || StatelessInvocation::class === $class) {
- continue;
- }
- if (!preg_match_all('#\n\s+\* @param +((?(?!callable *\().*?|callable *\(.*\).*?))(?<= )\$([a-zA-Z0-9_\x7f-\xff]++)#', $doc, $matches, PREG_SET_ORDER)) {
- continue;
- }
- if (!isset(self::$annotatedParameters[$class][$method->name])) {
- $definedParameters = [];
- foreach ($method->getParameters() as $parameter) {
- $definedParameters[$parameter->name] = true;
- }
- }
- foreach ($matches as list(, $parameterType, $parameterName)) {
- if (!isset($definedParameters[$parameterName])) {
- $parameterType = trim($parameterType);
- self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its parent class "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, $method->class);
- }
- }
- }
-
- return $deprecations;
- }
-
- public function checkCase(\ReflectionClass $refl, $file, $class)
- {
- $real = explode('\\', $class.strrchr($file, '.'));
- $tail = explode(\DIRECTORY_SEPARATOR, str_replace('/', \DIRECTORY_SEPARATOR, $file));
-
- $i = \count($tail) - 1;
- $j = \count($real) - 1;
-
- while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
- --$i;
- --$j;
- }
-
- array_splice($tail, 0, $i + 1);
-
- if (!$tail) {
- return;
- }
-
- $tail = \DIRECTORY_SEPARATOR.implode(\DIRECTORY_SEPARATOR, $tail);
- $tailLen = \strlen($tail);
- $real = $refl->getFileName();
-
- if (2 === self::$caseCheck) {
- $real = $this->darwinRealpath($real);
- }
-
- if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
- && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
- ) {
- return [substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)];
- }
- }
-
- /**
- * `realpath` on MacOSX doesn't normalize the case of characters.
- */
- private function darwinRealpath($real)
- {
- $i = 1 + strrpos($real, '/');
- $file = substr($real, $i);
- $real = substr($real, 0, $i);
-
- if (isset(self::$darwinCache[$real])) {
- $kDir = $real;
- } else {
- $kDir = strtolower($real);
-
- if (isset(self::$darwinCache[$kDir])) {
- $real = self::$darwinCache[$kDir][0];
- } else {
- $dir = getcwd();
- chdir($real);
- $real = getcwd().'/';
- chdir($dir);
-
- $dir = $real;
- $k = $kDir;
- $i = \strlen($dir) - 1;
- while (!isset(self::$darwinCache[$k])) {
- self::$darwinCache[$k] = [$dir, []];
- self::$darwinCache[$dir] = &self::$darwinCache[$k];
-
- while ('/' !== $dir[--$i]) {
- }
- $k = substr($k, 0, ++$i);
- $dir = substr($dir, 0, $i--);
- }
- }
- }
-
- $dirFiles = self::$darwinCache[$kDir][1];
-
- if (!isset($dirFiles[$file]) && ') : eval()\'d code' === substr($file, -17)) {
- // Get the file name from "file_name.php(123) : eval()'d code"
- $file = substr($file, 0, strrpos($file, '(', -17));
- }
-
- if (isset($dirFiles[$file])) {
- return $real .= $dirFiles[$file];
- }
-
- $kFile = strtolower($file);
-
- if (!isset($dirFiles[$kFile])) {
- foreach (scandir($real, 2) as $f) {
- if ('.' !== $f[0]) {
- $dirFiles[$f] = $f;
- if ($f === $file) {
- $kFile = $k = $file;
- } elseif ($f !== $k = strtolower($f)) {
- $dirFiles[$k] = $f;
- }
- }
- }
- self::$darwinCache[$kDir][1] = $dirFiles;
- }
-
- return $real .= $dirFiles[$kFile];
- }
-
- /**
- * `class_implements` includes interfaces from the parents so we have to manually exclude them.
- *
- * @param string $class
- * @param string|false $parent
- *
- * @return string[]
- */
- private function getOwnInterfaces($class, $parent)
- {
- $ownInterfaces = class_implements($class, false);
-
- if ($parent) {
- foreach (class_implements($parent, false) as $interface) {
- unset($ownInterfaces[$interface]);
- }
- }
-
- foreach ($ownInterfaces as $interface) {
- foreach (class_implements($interface) as $interface) {
- unset($ownInterfaces[$interface]);
- }
- }
-
- return $ownInterfaces;
- }
-}
diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php
deleted file mode 100644
index 0134a71423053..0000000000000
--- a/src/Symfony/Component/Debug/ErrorHandler.php
+++ /dev/null
@@ -1,719 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug;
-
-use Psr\Log\LoggerInterface;
-use Psr\Log\LogLevel;
-use Symfony\Component\Debug\Exception\FatalErrorException;
-use Symfony\Component\Debug\Exception\FatalThrowableError;
-use Symfony\Component\Debug\Exception\FlattenException;
-use Symfony\Component\Debug\Exception\OutOfMemoryException;
-use Symfony\Component\Debug\Exception\SilencedErrorContext;
-use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
-use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface;
-use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
-use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ErrorHandler::class, \Symfony\Component\ErrorHandler\ErrorHandler::class), E_USER_DEPRECATED);
-
-/**
- * A generic ErrorHandler for the PHP engine.
- *
- * Provides five bit fields that control how errors are handled:
- * - thrownErrors: errors thrown as \ErrorException
- * - loggedErrors: logged errors, when not @-silenced
- * - scopedErrors: errors thrown or logged with their local context
- * - tracedErrors: errors logged with their stack trace
- * - screamedErrors: never @-silenced errors
- *
- * Each error level can be logged by a dedicated PSR-3 logger object.
- * Screaming only applies to logging.
- * Throwing takes precedence over logging.
- * Uncaught exceptions are logged as E_ERROR.
- * E_DEPRECATED and E_USER_DEPRECATED levels never throw.
- * E_RECOVERABLE_ERROR and E_USER_ERROR levels always throw.
- * Non catchable errors that can be detected at shutdown time are logged when the scream bit field allows so.
- * As errors have a performance cost, repeated errors are all logged, so that the developer
- * can see them and weight them as more important to fix than others of the same level.
- *
- * @author Nicolas Grekas
- * @author Grégoire Pineau
- *
- * @final since Symfony 4.3
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\ErrorHandler instead.
- */
-class ErrorHandler
-{
- private $levels = [
- E_DEPRECATED => 'Deprecated',
- E_USER_DEPRECATED => 'User Deprecated',
- E_NOTICE => 'Notice',
- E_USER_NOTICE => 'User Notice',
- E_STRICT => 'Runtime Notice',
- E_WARNING => 'Warning',
- E_USER_WARNING => 'User Warning',
- E_COMPILE_WARNING => 'Compile Warning',
- E_CORE_WARNING => 'Core Warning',
- E_USER_ERROR => 'User Error',
- E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
- E_COMPILE_ERROR => 'Compile Error',
- E_PARSE => 'Parse Error',
- E_ERROR => 'Error',
- E_CORE_ERROR => 'Core Error',
- ];
-
- private $loggers = [
- E_DEPRECATED => [null, LogLevel::INFO],
- E_USER_DEPRECATED => [null, LogLevel::INFO],
- E_NOTICE => [null, LogLevel::WARNING],
- E_USER_NOTICE => [null, LogLevel::WARNING],
- E_STRICT => [null, LogLevel::WARNING],
- E_WARNING => [null, LogLevel::WARNING],
- E_USER_WARNING => [null, LogLevel::WARNING],
- E_COMPILE_WARNING => [null, LogLevel::WARNING],
- E_CORE_WARNING => [null, LogLevel::WARNING],
- E_USER_ERROR => [null, LogLevel::CRITICAL],
- E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL],
- E_COMPILE_ERROR => [null, LogLevel::CRITICAL],
- E_PARSE => [null, LogLevel::CRITICAL],
- E_ERROR => [null, LogLevel::CRITICAL],
- E_CORE_ERROR => [null, LogLevel::CRITICAL],
- ];
-
- private $thrownErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED
- private $scopedErrors = 0x1FFF; // E_ALL - E_DEPRECATED - E_USER_DEPRECATED
- private $tracedErrors = 0x77FB; // E_ALL - E_STRICT - E_PARSE
- private $screamedErrors = 0x55; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE
- private $loggedErrors = 0;
- private $traceReflector;
-
- private $isRecursive = 0;
- private $isRoot = false;
- private $exceptionHandler;
- private $bootstrappingLogger;
-
- private static $reservedMemory;
- private static $toStringException = null;
- private static $silencedErrorCache = [];
- private static $silencedErrorCount = 0;
- private static $exitCode = 0;
-
- /**
- * Registers the error handler.
- *
- * @param self|null $handler The handler to register
- * @param bool $replace Whether to replace or not any existing handler
- *
- * @return self The registered error handler
- */
- public static function register(self $handler = null, $replace = true)
- {
- if (null === self::$reservedMemory) {
- self::$reservedMemory = str_repeat('x', 10240);
- register_shutdown_function(__CLASS__.'::handleFatalError');
- }
-
- if ($handlerIsNew = null === $handler) {
- $handler = new static();
- }
-
- if (null === $prev = set_error_handler([$handler, 'handleError'])) {
- restore_error_handler();
- // Specifying the error types earlier would expose us to https://bugs.php.net/63206
- set_error_handler([$handler, 'handleError'], $handler->thrownErrors | $handler->loggedErrors);
- $handler->isRoot = true;
- }
-
- if ($handlerIsNew && \is_array($prev) && $prev[0] instanceof self) {
- $handler = $prev[0];
- $replace = false;
- }
- if (!$replace && $prev) {
- restore_error_handler();
- $handlerIsRegistered = \is_array($prev) && $handler === $prev[0];
- } else {
- $handlerIsRegistered = true;
- }
- if (\is_array($prev = set_exception_handler([$handler, 'handleException'])) && $prev[0] instanceof self) {
- restore_exception_handler();
- if (!$handlerIsRegistered) {
- $handler = $prev[0];
- } elseif ($handler !== $prev[0] && $replace) {
- set_exception_handler([$handler, 'handleException']);
- $p = $prev[0]->setExceptionHandler(null);
- $handler->setExceptionHandler($p);
- $prev[0]->setExceptionHandler($p);
- }
- } else {
- $handler->setExceptionHandler($prev);
- }
-
- $handler->throwAt(E_ALL & $handler->thrownErrors, true);
-
- return $handler;
- }
-
- public function __construct(BufferingLogger $bootstrappingLogger = null)
- {
- if ($bootstrappingLogger) {
- $this->bootstrappingLogger = $bootstrappingLogger;
- $this->setDefaultLogger($bootstrappingLogger);
- }
- $this->traceReflector = new \ReflectionProperty('Exception', 'trace');
- $this->traceReflector->setAccessible(true);
- }
-
- /**
- * Sets a logger to non assigned errors levels.
- *
- * @param LoggerInterface $logger A PSR-3 logger to put as default for the given levels
- * @param array|int $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants
- * @param bool $replace Whether to replace or not any existing logger
- */
- public function setDefaultLogger(LoggerInterface $logger, $levels = E_ALL, $replace = false)
- {
- $loggers = [];
-
- if (\is_array($levels)) {
- foreach ($levels as $type => $logLevel) {
- if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] === $this->bootstrappingLogger) {
- $loggers[$type] = [$logger, $logLevel];
- }
- }
- } else {
- if (null === $levels) {
- $levels = E_ALL;
- }
- foreach ($this->loggers as $type => $log) {
- if (($type & $levels) && (empty($log[0]) || $replace || $log[0] === $this->bootstrappingLogger)) {
- $log[0] = $logger;
- $loggers[$type] = $log;
- }
- }
- }
-
- $this->setLoggers($loggers);
- }
-
- /**
- * Sets a logger for each error level.
- *
- * @param array $loggers Error levels to [LoggerInterface|null, LogLevel::*] map
- *
- * @return array The previous map
- *
- * @throws \InvalidArgumentException
- */
- public function setLoggers(array $loggers)
- {
- $prevLogged = $this->loggedErrors;
- $prev = $this->loggers;
- $flush = [];
-
- foreach ($loggers as $type => $log) {
- if (!isset($prev[$type])) {
- throw new \InvalidArgumentException('Unknown error type: '.$type);
- }
- if (!\is_array($log)) {
- $log = [$log];
- } elseif (!\array_key_exists(0, $log)) {
- throw new \InvalidArgumentException('No logger provided');
- }
- if (null === $log[0]) {
- $this->loggedErrors &= ~$type;
- } elseif ($log[0] instanceof LoggerInterface) {
- $this->loggedErrors |= $type;
- } else {
- throw new \InvalidArgumentException('Invalid logger provided');
- }
- $this->loggers[$type] = $log + $prev[$type];
-
- if ($this->bootstrappingLogger && $prev[$type][0] === $this->bootstrappingLogger) {
- $flush[$type] = $type;
- }
- }
- $this->reRegister($prevLogged | $this->thrownErrors);
-
- if ($flush) {
- foreach ($this->bootstrappingLogger->cleanLogs() as $log) {
- $type = $log[2]['exception'] instanceof \ErrorException ? $log[2]['exception']->getSeverity() : E_ERROR;
- if (!isset($flush[$type])) {
- $this->bootstrappingLogger->log($log[0], $log[1], $log[2]);
- } elseif ($this->loggers[$type][0]) {
- $this->loggers[$type][0]->log($this->loggers[$type][1], $log[1], $log[2]);
- }
- }
- }
-
- return $prev;
- }
-
- /**
- * Sets a user exception handler.
- *
- * @param callable $handler A handler that will be called on Exception
- *
- * @return callable|null The previous exception handler
- */
- public function setExceptionHandler(callable $handler = null)
- {
- $prev = $this->exceptionHandler;
- $this->exceptionHandler = $handler;
-
- return $prev;
- }
-
- /**
- * Sets the PHP error levels that throw an exception when a PHP error occurs.
- *
- * @param int $levels A bit field of E_* constants for thrown errors
- * @param bool $replace Replace or amend the previous value
- *
- * @return int The previous value
- */
- public function throwAt($levels, $replace = false)
- {
- $prev = $this->thrownErrors;
- $this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
- if (!$replace) {
- $this->thrownErrors |= $prev;
- }
- $this->reRegister($prev | $this->loggedErrors);
-
- return $prev;
- }
-
- /**
- * Sets the PHP error levels for which local variables are preserved.
- *
- * @param int $levels A bit field of E_* constants for scoped errors
- * @param bool $replace Replace or amend the previous value
- *
- * @return int The previous value
- */
- public function scopeAt($levels, $replace = false)
- {
- $prev = $this->scopedErrors;
- $this->scopedErrors = (int) $levels;
- if (!$replace) {
- $this->scopedErrors |= $prev;
- }
-
- return $prev;
- }
-
- /**
- * Sets the PHP error levels for which the stack trace is preserved.
- *
- * @param int $levels A bit field of E_* constants for traced errors
- * @param bool $replace Replace or amend the previous value
- *
- * @return int The previous value
- */
- public function traceAt($levels, $replace = false)
- {
- $prev = $this->tracedErrors;
- $this->tracedErrors = (int) $levels;
- if (!$replace) {
- $this->tracedErrors |= $prev;
- }
-
- return $prev;
- }
-
- /**
- * Sets the error levels where the @-operator is ignored.
- *
- * @param int $levels A bit field of E_* constants for screamed errors
- * @param bool $replace Replace or amend the previous value
- *
- * @return int The previous value
- */
- public function screamAt($levels, $replace = false)
- {
- $prev = $this->screamedErrors;
- $this->screamedErrors = (int) $levels;
- if (!$replace) {
- $this->screamedErrors |= $prev;
- }
-
- return $prev;
- }
-
- /**
- * Re-registers as a PHP error handler if levels changed.
- */
- private function reRegister($prev)
- {
- if ($prev !== $this->thrownErrors | $this->loggedErrors) {
- $handler = set_error_handler('var_dump');
- $handler = \is_array($handler) ? $handler[0] : null;
- restore_error_handler();
- if ($handler === $this) {
- restore_error_handler();
- if ($this->isRoot) {
- set_error_handler([$this, 'handleError'], $this->thrownErrors | $this->loggedErrors);
- } else {
- set_error_handler([$this, 'handleError']);
- }
- }
- }
- }
-
- /**
- * Handles errors by filtering then logging them according to the configured bit fields.
- *
- * @param int $type One of the E_* constants
- * @param string $message
- * @param string $file
- * @param int $line
- *
- * @return bool Returns false when no handling happens so that the PHP engine can handle the error itself
- *
- * @throws \ErrorException When $this->thrownErrors requests so
- *
- * @internal
- */
- public function handleError($type, $message, $file, $line)
- {
- // @deprecated to be removed in Symfony 5.0
- if (\PHP_VERSION_ID >= 70300 && $message && '"' === $message[0] && 0 === strpos($message, '"continue') && preg_match('/^"continue(?: \d++)?" targeting switch is equivalent to "break(?: \d++)?"\. Did you mean to use "continue(?: \d++)?"\?$/', $message)) {
- $type = E_DEPRECATED;
- }
-
- // Level is the current error reporting level to manage silent error.
- $level = error_reporting();
- $silenced = 0 === ($level & $type);
- // Strong errors are not authorized to be silenced.
- $level |= E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
- $log = $this->loggedErrors & $type;
- $throw = $this->thrownErrors & $type & $level;
- $type &= $level | $this->screamedErrors;
-
- if (!$type || (!$log && !$throw)) {
- return !$silenced && $type && $log;
- }
- $scope = $this->scopedErrors & $type;
-
- if (4 < $numArgs = \func_num_args()) {
- $context = $scope ? (func_get_arg(4) ?: []) : [];
- } else {
- $context = [];
- }
-
- if (isset($context['GLOBALS']) && $scope) {
- $e = $context; // Whatever the signature of the method,
- unset($e['GLOBALS'], $context); // $context is always a reference in 5.3
- $context = $e;
- }
-
- if (false !== strpos($message, "class@anonymous\0")) {
- $logMessage = $this->levels[$type].': '.(new FlattenException())->setMessage($message)->getMessage();
- } else {
- $logMessage = $this->levels[$type].': '.$message;
- }
-
- if (null !== self::$toStringException) {
- $errorAsException = self::$toStringException;
- self::$toStringException = null;
- } elseif (!$throw && !($type & $level)) {
- if (!isset(self::$silencedErrorCache[$id = $file.':'.$line])) {
- $lightTrace = $this->tracedErrors & $type ? $this->cleanTrace(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5), $type, $file, $line, false) : [];
- $errorAsException = new SilencedErrorContext($type, $file, $line, isset($lightTrace[1]) ? [$lightTrace[0]] : $lightTrace);
- } elseif (isset(self::$silencedErrorCache[$id][$message])) {
- $lightTrace = null;
- $errorAsException = self::$silencedErrorCache[$id][$message];
- ++$errorAsException->count;
- } else {
- $lightTrace = [];
- $errorAsException = null;
- }
-
- if (100 < ++self::$silencedErrorCount) {
- self::$silencedErrorCache = $lightTrace = [];
- self::$silencedErrorCount = 1;
- }
- if ($errorAsException) {
- self::$silencedErrorCache[$id][$message] = $errorAsException;
- }
- if (null === $lightTrace) {
- return;
- }
- } else {
- $errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line);
-
- if ($throw || $this->tracedErrors & $type) {
- $backtrace = $errorAsException->getTrace();
- $lightTrace = $this->cleanTrace($backtrace, $type, $file, $line, $throw);
- $this->traceReflector->setValue($errorAsException, $lightTrace);
- } else {
- $this->traceReflector->setValue($errorAsException, []);
- $backtrace = [];
- }
- }
-
- if ($throw) {
- if (E_USER_ERROR & $type) {
- for ($i = 1; isset($backtrace[$i]); ++$i) {
- if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function'])
- && '__toString' === $backtrace[$i]['function']
- && '->' === $backtrace[$i]['type']
- && !isset($backtrace[$i - 1]['class'])
- && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])
- ) {
- // Here, we know trigger_error() has been called from __toString().
- // PHP triggers a fatal error when throwing from __toString().
- // A small convention allows working around the limitation:
- // given a caught $e exception in __toString(), quitting the method with
- // `return trigger_error($e, E_USER_ERROR);` allows this error handler
- // to make $e get through the __toString() barrier.
-
- foreach ($context as $e) {
- if ($e instanceof \Throwable && $e->__toString() === $message) {
- self::$toStringException = $e;
-
- return true;
- }
- }
-
- // Display the original error message instead of the default one.
- $this->handleException($errorAsException);
-
- // Stop the process by giving back the error to the native handler.
- return false;
- }
- }
- }
-
- throw $errorAsException;
- }
-
- if ($this->isRecursive) {
- $log = 0;
- } else {
- if (!\defined('HHVM_VERSION')) {
- $currentErrorHandler = set_error_handler('var_dump');
- restore_error_handler();
- }
-
- try {
- $this->isRecursive = true;
- $level = ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG;
- $this->loggers[$type][0]->log($level, $logMessage, $errorAsException ? ['exception' => $errorAsException] : []);
- } finally {
- $this->isRecursive = false;
-
- if (!\defined('HHVM_VERSION')) {
- set_error_handler($currentErrorHandler);
- }
- }
- }
-
- return !$silenced && $type && $log;
- }
-
- /**
- * Handles an exception by logging then forwarding it to another handler.
- *
- * @param \Exception|\Throwable $exception An exception to handle
- * @param array $error An array as returned by error_get_last()
- *
- * @internal
- */
- public function handleException($exception, array $error = null)
- {
- if (null === $error) {
- self::$exitCode = 255;
- }
- if (!$exception instanceof \Exception) {
- $exception = new FatalThrowableError($exception);
- }
- $type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
- $handlerException = null;
-
- if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
- if (false !== strpos($message = $exception->getMessage(), "class@anonymous\0")) {
- $message = (new FlattenException())->setMessage($message)->getMessage();
- }
- if ($exception instanceof FatalErrorException) {
- if ($exception instanceof FatalThrowableError) {
- $error = [
- 'type' => $type,
- 'message' => $message,
- 'file' => $exception->getFile(),
- 'line' => $exception->getLine(),
- ];
- } else {
- $message = 'Fatal '.$message;
- }
- } elseif ($exception instanceof \ErrorException) {
- $message = 'Uncaught '.$message;
- } else {
- $message = 'Uncaught Exception: '.$message;
- }
- }
- if ($this->loggedErrors & $type) {
- try {
- $this->loggers[$type][0]->log($this->loggers[$type][1], $message, ['exception' => $exception]);
- } catch (\Throwable $handlerException) {
- }
- }
- if ($exception instanceof FatalErrorException && !$exception instanceof OutOfMemoryException && $error) {
- foreach ($this->getFatalErrorHandlers() as $handler) {
- if ($e = $handler->handleError($error, $exception)) {
- $exception = $e;
- break;
- }
- }
- }
- $exceptionHandler = $this->exceptionHandler;
- $this->exceptionHandler = null;
- try {
- if (null !== $exceptionHandler) {
- return $exceptionHandler($exception);
- }
- $handlerException = $handlerException ?: $exception;
- } catch (\Throwable $handlerException) {
- }
- if ($exception === $handlerException) {
- self::$reservedMemory = null; // Disable the fatal error handler
- throw $exception; // Give back $exception to the native handler
- }
- $this->handleException($handlerException);
- }
-
- /**
- * Shutdown registered function for handling PHP fatal errors.
- *
- * @param array $error An array as returned by error_get_last()
- *
- * @internal
- */
- public static function handleFatalError(array $error = null)
- {
- if (null === self::$reservedMemory) {
- return;
- }
-
- $handler = self::$reservedMemory = null;
- $handlers = [];
- $previousHandler = null;
- $sameHandlerLimit = 10;
-
- while (!\is_array($handler) || !$handler[0] instanceof self) {
- $handler = set_exception_handler('var_dump');
- restore_exception_handler();
-
- if (!$handler) {
- break;
- }
- restore_exception_handler();
-
- if ($handler !== $previousHandler) {
- array_unshift($handlers, $handler);
- $previousHandler = $handler;
- } elseif (0 === --$sameHandlerLimit) {
- $handler = null;
- break;
- }
- }
- foreach ($handlers as $h) {
- set_exception_handler($h);
- }
- if (!$handler) {
- return;
- }
- if ($handler !== $h) {
- $handler[0]->setExceptionHandler($h);
- }
- $handler = $handler[0];
- $handlers = [];
-
- if ($exit = null === $error) {
- $error = error_get_last();
- }
-
- if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) {
- // Let's not throw anymore but keep logging
- $handler->throwAt(0, true);
- $trace = isset($error['backtrace']) ? $error['backtrace'] : null;
-
- if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
- $exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false, $trace);
- } else {
- $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace);
- }
- } else {
- $exception = null;
- }
-
- try {
- if (null !== $exception) {
- self::$exitCode = 255;
- $handler->handleException($exception, $error);
- }
- } catch (FatalErrorException $e) {
- // Ignore this re-throw
- }
-
- if ($exit && self::$exitCode) {
- $exitCode = self::$exitCode;
- register_shutdown_function('register_shutdown_function', function () use ($exitCode) { exit($exitCode); });
- }
- }
-
- /**
- * Gets the fatal error handlers.
- *
- * Override this method if you want to define more fatal error handlers.
- *
- * @return FatalErrorHandlerInterface[] An array of FatalErrorHandlerInterface
- */
- protected function getFatalErrorHandlers()
- {
- return [
- new UndefinedFunctionFatalErrorHandler(),
- new UndefinedMethodFatalErrorHandler(),
- new ClassNotFoundFatalErrorHandler(),
- ];
- }
-
- /**
- * Cleans the trace by removing function arguments and the frames added by the error handler and DebugClassLoader.
- */
- private function cleanTrace($backtrace, $type, $file, $line, $throw)
- {
- $lightTrace = $backtrace;
-
- for ($i = 0; isset($backtrace[$i]); ++$i) {
- if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
- $lightTrace = \array_slice($lightTrace, 1 + $i);
- break;
- }
- }
- if (class_exists(DebugClassLoader::class, false)) {
- for ($i = \count($lightTrace) - 2; 0 < $i; --$i) {
- if (DebugClassLoader::class === ($lightTrace[$i]['class'] ?? null)) {
- array_splice($lightTrace, --$i, 2);
- }
- }
- }
- if (!($throw || $this->scopedErrors & $type)) {
- for ($i = 0; isset($lightTrace[$i]); ++$i) {
- unset($lightTrace[$i]['args'], $lightTrace[$i]['object']);
- }
- }
-
- return $lightTrace;
- }
-}
diff --git a/src/Symfony/Component/Debug/Exception/ClassNotFoundException.php b/src/Symfony/Component/Debug/Exception/ClassNotFoundException.php
deleted file mode 100644
index 21e2c0db53a93..0000000000000
--- a/src/Symfony/Component/Debug/Exception/ClassNotFoundException.php
+++ /dev/null
@@ -1,40 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Exception;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ClassNotFoundException::class, \Symfony\Component\ErrorHandler\Exception\ClassNotFoundException::class), E_USER_DEPRECATED);
-
-/**
- * Class (or Trait or Interface) Not Found Exception.
- *
- * @author Konstanton Myakshin
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\ClassNotFoundException instead.
- */
-class ClassNotFoundException extends FatalErrorException
-{
- public function __construct(string $message, \ErrorException $previous)
- {
- parent::__construct(
- $message,
- $previous->getCode(),
- $previous->getSeverity(),
- $previous->getFile(),
- $previous->getLine(),
- null,
- true,
- null,
- $previous->getPrevious()
- );
- $this->setTrace($previous->getTrace());
- }
-}
diff --git a/src/Symfony/Component/Debug/Exception/FatalErrorException.php b/src/Symfony/Component/Debug/Exception/FatalErrorException.php
deleted file mode 100644
index 23c2ede7eb964..0000000000000
--- a/src/Symfony/Component/Debug/Exception/FatalErrorException.php
+++ /dev/null
@@ -1,81 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Exception;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalErrorException::class, \Symfony\Component\ErrorHandler\Exception\FatalErrorException::class), E_USER_DEPRECATED);
-
-/**
- * Fatal Error Exception.
- *
- * @author Konstanton Myakshin
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\FatalErrorException instead.
- */
-class FatalErrorException extends \ErrorException
-{
- public function __construct(string $message, int $code, int $severity, string $filename, int $lineno, int $traceOffset = null, bool $traceArgs = true, array $trace = null, \Throwable $previous = null)
- {
- parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
-
- if (null !== $trace) {
- if (!$traceArgs) {
- foreach ($trace as &$frame) {
- unset($frame['args'], $frame['this'], $frame);
- }
- }
-
- $this->setTrace($trace);
- } elseif (null !== $traceOffset) {
- if (\function_exists('xdebug_get_function_stack')) {
- $trace = xdebug_get_function_stack();
- if (0 < $traceOffset) {
- array_splice($trace, -$traceOffset);
- }
-
- foreach ($trace as &$frame) {
- if (!isset($frame['type'])) {
- // XDebug pre 2.1.1 doesn't currently set the call type key http://bugs.xdebug.org/view.php?id=695
- if (isset($frame['class'])) {
- $frame['type'] = '::';
- }
- } elseif ('dynamic' === $frame['type']) {
- $frame['type'] = '->';
- } elseif ('static' === $frame['type']) {
- $frame['type'] = '::';
- }
-
- // XDebug also has a different name for the parameters array
- if (!$traceArgs) {
- unset($frame['params'], $frame['args']);
- } elseif (isset($frame['params']) && !isset($frame['args'])) {
- $frame['args'] = $frame['params'];
- unset($frame['params']);
- }
- }
-
- unset($frame);
- $trace = array_reverse($trace);
- } else {
- $trace = [];
- }
-
- $this->setTrace($trace);
- }
- }
-
- protected function setTrace($trace)
- {
- $traceReflector = new \ReflectionProperty('Exception', 'trace');
- $traceReflector->setAccessible(true);
- $traceReflector->setValue($this, $trace);
- }
-}
diff --git a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php
deleted file mode 100644
index d7d36ac17e312..0000000000000
--- a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php
+++ /dev/null
@@ -1,55 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Exception;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalThrowableError::class, \Symfony\Component\ErrorHandler\Exception\FatalThrowableError::class), E_USER_DEPRECATED);
-
-/**
- * Fatal Throwable Error.
- *
- * @author Nicolas Grekas
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\FatalThrowableError instead.
- */
-class FatalThrowableError extends FatalErrorException
-{
- private $originalClassName;
-
- public function __construct(\Throwable $e)
- {
- $this->originalClassName = \get_class($e);
-
- if ($e instanceof \ParseError) {
- $severity = E_PARSE;
- } elseif ($e instanceof \TypeError) {
- $severity = E_RECOVERABLE_ERROR;
- } else {
- $severity = E_ERROR;
- }
-
- \ErrorException::__construct(
- $e->getMessage(),
- $e->getCode(),
- $severity,
- $e->getFile(),
- $e->getLine(),
- $e->getPrevious()
- );
-
- $this->setTrace($e->getTrace());
- }
-
- public function getOriginalClassName(): string
- {
- return $this->originalClassName;
- }
-}
diff --git a/src/Symfony/Component/Debug/Exception/FlattenException.php b/src/Symfony/Component/Debug/Exception/FlattenException.php
deleted file mode 100644
index f7bdcde9656c1..0000000000000
--- a/src/Symfony/Component/Debug/Exception/FlattenException.php
+++ /dev/null
@@ -1,368 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Exception;
-
-use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
-use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FlattenException::class, \Symfony\Component\ErrorRenderer\Exception\FlattenException::class), E_USER_DEPRECATED);
-
-/**
- * FlattenException wraps a PHP Error or Exception to be able to serialize it.
- *
- * Basically, this class removes all objects from the trace.
- *
- * @author Fabien Potencier
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorRenderer\Exception\FlattenException instead.
- */
-class FlattenException
-{
- private $message;
- private $code;
- private $previous;
- private $trace;
- private $traceAsString;
- private $class;
- private $statusCode;
- private $headers;
- private $file;
- private $line;
-
- /**
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorRenderer\Exception::createFromThrowable() instead.
- */
- public static function create(\Exception $exception, $statusCode = null, array $headers = [])
- {
- @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, use Symfony\Component\ErrorRenderer\Exception::createFromThrowable() instead.', __METHOD__), E_USER_DEPRECATED);
-
- return static::createFromThrowable($exception, $statusCode, $headers);
- }
-
- public static function createFromThrowable(\Throwable $exception, int $statusCode = null, array $headers = []): self
- {
- $e = new static();
- $e->setMessage($exception->getMessage());
- $e->setCode($exception->getCode());
-
- if ($exception instanceof HttpExceptionInterface) {
- $statusCode = $exception->getStatusCode();
- $headers = array_merge($headers, $exception->getHeaders());
- } elseif ($exception instanceof RequestExceptionInterface) {
- $statusCode = 400;
- }
-
- if (null === $statusCode) {
- $statusCode = 500;
- }
-
- $e->setStatusCode($statusCode);
- $e->setHeaders($headers);
- $e->setTraceFromThrowable($exception);
- $e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception));
- $e->setFile($exception->getFile());
- $e->setLine($exception->getLine());
-
- $previous = $exception->getPrevious();
-
- if ($previous instanceof \Throwable) {
- $e->setPrevious(static::createFromThrowable($previous));
- }
-
- return $e;
- }
-
- public function toArray()
- {
- $exceptions = [];
- foreach (array_merge([$this], $this->getAllPrevious()) as $exception) {
- $exceptions[] = [
- 'message' => $exception->getMessage(),
- 'class' => $exception->getClass(),
- 'trace' => $exception->getTrace(),
- ];
- }
-
- return $exceptions;
- }
-
- public function getStatusCode()
- {
- return $this->statusCode;
- }
-
- /**
- * @return $this
- */
- public function setStatusCode($code)
- {
- $this->statusCode = $code;
-
- return $this;
- }
-
- public function getHeaders()
- {
- return $this->headers;
- }
-
- /**
- * @return $this
- */
- public function setHeaders(array $headers)
- {
- $this->headers = $headers;
-
- return $this;
- }
-
- public function getClass()
- {
- return $this->class;
- }
-
- /**
- * @return $this
- */
- public function setClass($class)
- {
- $this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
-
- return $this;
- }
-
- public function getFile()
- {
- return $this->file;
- }
-
- /**
- * @return $this
- */
- public function setFile($file)
- {
- $this->file = $file;
-
- return $this;
- }
-
- public function getLine()
- {
- return $this->line;
- }
-
- /**
- * @return $this
- */
- public function setLine($line)
- {
- $this->line = $line;
-
- return $this;
- }
-
- public function getMessage()
- {
- return $this->message;
- }
-
- /**
- * @return $this
- */
- public function setMessage($message)
- {
- if (false !== strpos($message, "class@anonymous\0")) {
- $message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) {
- return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
- }, $message);
- }
-
- $this->message = $message;
-
- return $this;
- }
-
- public function getCode()
- {
- return $this->code;
- }
-
- /**
- * @return $this
- */
- public function setCode($code)
- {
- $this->code = $code;
-
- return $this;
- }
-
- public function getPrevious()
- {
- return $this->previous;
- }
-
- /**
- * @return $this
- */
- public function setPrevious(self $previous)
- {
- $this->previous = $previous;
-
- return $this;
- }
-
- public function getAllPrevious()
- {
- $exceptions = [];
- $e = $this;
- while ($e = $e->getPrevious()) {
- $exceptions[] = $e;
- }
-
- return $exceptions;
- }
-
- public function getTrace()
- {
- return $this->trace;
- }
-
- /**
- * @deprecated since 4.1, use {@see setTraceFromThrowable()} instead.
- */
- public function setTraceFromException(\Exception $exception)
- {
- @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use "setTraceFromThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);
-
- $this->setTraceFromThrowable($exception);
- }
-
- public function setTraceFromThrowable(\Throwable $throwable)
- {
- $this->traceAsString = $throwable->getTraceAsString();
-
- return $this->setTrace($throwable->getTrace(), $throwable->getFile(), $throwable->getLine());
- }
-
- /**
- * @return $this
- */
- public function setTrace($trace, $file, $line)
- {
- $this->trace = [];
- $this->trace[] = [
- 'namespace' => '',
- 'short_class' => '',
- 'class' => '',
- 'type' => '',
- 'function' => '',
- 'file' => $file,
- 'line' => $line,
- 'args' => [],
- ];
- foreach ($trace as $entry) {
- $class = '';
- $namespace = '';
- if (isset($entry['class'])) {
- $parts = explode('\\', $entry['class']);
- $class = array_pop($parts);
- $namespace = implode('\\', $parts);
- }
-
- $this->trace[] = [
- 'namespace' => $namespace,
- 'short_class' => $class,
- 'class' => isset($entry['class']) ? $entry['class'] : '',
- 'type' => isset($entry['type']) ? $entry['type'] : '',
- 'function' => isset($entry['function']) ? $entry['function'] : null,
- 'file' => isset($entry['file']) ? $entry['file'] : null,
- 'line' => isset($entry['line']) ? $entry['line'] : null,
- 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : [],
- ];
- }
-
- return $this;
- }
-
- private function flattenArgs($args, $level = 0, &$count = 0)
- {
- $result = [];
- foreach ($args as $key => $value) {
- if (++$count > 1e4) {
- return ['array', '*SKIPPED over 10000 entries*'];
- }
- if ($value instanceof \__PHP_Incomplete_Class) {
- // is_object() returns false on PHP<=7.1
- $result[$key] = ['incomplete-object', $this->getClassNameFromIncomplete($value)];
- } elseif (\is_object($value)) {
- $result[$key] = ['object', \get_class($value)];
- } elseif (\is_array($value)) {
- if ($level > 10) {
- $result[$key] = ['array', '*DEEP NESTED ARRAY*'];
- } else {
- $result[$key] = ['array', $this->flattenArgs($value, $level + 1, $count)];
- }
- } elseif (null === $value) {
- $result[$key] = ['null', null];
- } elseif (\is_bool($value)) {
- $result[$key] = ['boolean', $value];
- } elseif (\is_int($value)) {
- $result[$key] = ['integer', $value];
- } elseif (\is_float($value)) {
- $result[$key] = ['float', $value];
- } elseif (\is_resource($value)) {
- $result[$key] = ['resource', get_resource_type($value)];
- } else {
- $result[$key] = ['string', (string) $value];
- }
- }
-
- return $result;
- }
-
- private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value)
- {
- $array = new \ArrayObject($value);
-
- return $array['__PHP_Incomplete_Class_Name'];
- }
-
- public function getTraceAsString()
- {
- return $this->traceAsString;
- }
-
- public function getAsString()
- {
- $message = '';
- $next = false;
-
- foreach (array_reverse(array_merge([$this], $this->getAllPrevious())) as $exception) {
- if ($next) {
- $message .= 'Next ';
- } else {
- $next = true;
- }
- $message .= $exception->getClass();
-
- if ('' != $exception->getMessage()) {
- $message .= ': '.$exception->getMessage();
- }
-
- $message .= ' in '.$exception->getFile().':'.$exception->getLine().
- "\nStack trace:\n".$exception->getTraceAsString()."\n\n";
- }
-
- return rtrim($message);
- }
-}
diff --git a/src/Symfony/Component/Debug/Exception/OutOfMemoryException.php b/src/Symfony/Component/Debug/Exception/OutOfMemoryException.php
deleted file mode 100644
index 5b02d52ad8bb2..0000000000000
--- a/src/Symfony/Component/Debug/Exception/OutOfMemoryException.php
+++ /dev/null
@@ -1,25 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Exception;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', OutOfMemoryException::class, \Symfony\Component\ErrorHandler\Exception\OutOfMemoryException::class), E_USER_DEPRECATED);
-
-/**
- * Out of memory exception.
- *
- * @author Nicolas Grekas
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\OutOfMemoryException instead.
- */
-class OutOfMemoryException extends FatalErrorException
-{
-}
diff --git a/src/Symfony/Component/Debug/Exception/SilencedErrorContext.php b/src/Symfony/Component/Debug/Exception/SilencedErrorContext.php
deleted file mode 100644
index 7ed3d7eb52546..0000000000000
--- a/src/Symfony/Component/Debug/Exception/SilencedErrorContext.php
+++ /dev/null
@@ -1,71 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Exception;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', SilencedErrorContext::class, \Symfony\Component\ErrorHandler\Exception\SilencedErrorContext::class), E_USER_DEPRECATED);
-
-/**
- * Data Object that represents a Silenced Error.
- *
- * @author Grégoire Pineau
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\SilencedErrorContext instead.
- */
-class SilencedErrorContext implements \JsonSerializable
-{
- public $count = 1;
-
- private $severity;
- private $file;
- private $line;
- private $trace;
-
- public function __construct(int $severity, string $file, int $line, array $trace = [], int $count = 1)
- {
- $this->severity = $severity;
- $this->file = $file;
- $this->line = $line;
- $this->trace = $trace;
- $this->count = $count;
- }
-
- public function getSeverity()
- {
- return $this->severity;
- }
-
- public function getFile()
- {
- return $this->file;
- }
-
- public function getLine()
- {
- return $this->line;
- }
-
- public function getTrace()
- {
- return $this->trace;
- }
-
- public function JsonSerialize()
- {
- return [
- 'severity' => $this->severity,
- 'file' => $this->file,
- 'line' => $this->line,
- 'trace' => $this->trace,
- 'count' => $this->count,
- ];
- }
-}
diff --git a/src/Symfony/Component/Debug/Exception/UndefinedFunctionException.php b/src/Symfony/Component/Debug/Exception/UndefinedFunctionException.php
deleted file mode 100644
index fefd7d248edaa..0000000000000
--- a/src/Symfony/Component/Debug/Exception/UndefinedFunctionException.php
+++ /dev/null
@@ -1,40 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Exception;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', UndefinedFunctionException::class, \Symfony\Component\ErrorHandler\Exception\UndefinedFunctionException::class), E_USER_DEPRECATED);
-
-/**
- * Undefined Function Exception.
- *
- * @author Konstanton Myakshin
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\UndefinedFunctionException instead.
- */
-class UndefinedFunctionException extends FatalErrorException
-{
- public function __construct(string $message, \ErrorException $previous)
- {
- parent::__construct(
- $message,
- $previous->getCode(),
- $previous->getSeverity(),
- $previous->getFile(),
- $previous->getLine(),
- null,
- true,
- null,
- $previous->getPrevious()
- );
- $this->setTrace($previous->getTrace());
- }
-}
diff --git a/src/Symfony/Component/Debug/Exception/UndefinedMethodException.php b/src/Symfony/Component/Debug/Exception/UndefinedMethodException.php
deleted file mode 100644
index 48559415868de..0000000000000
--- a/src/Symfony/Component/Debug/Exception/UndefinedMethodException.php
+++ /dev/null
@@ -1,40 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Exception;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', UndefinedMethodException::class, \Symfony\Component\ErrorHandler\Exception\UndefinedMethodException::class), E_USER_DEPRECATED);
-
-/**
- * Undefined Method Exception.
- *
- * @author Grégoire Pineau
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\UndefinedMethodException instead.
- */
-class UndefinedMethodException extends FatalErrorException
-{
- public function __construct(string $message, \ErrorException $previous)
- {
- parent::__construct(
- $message,
- $previous->getCode(),
- $previous->getSeverity(),
- $previous->getFile(),
- $previous->getLine(),
- null,
- true,
- null,
- $previous->getPrevious()
- );
- $this->setTrace($previous->getTrace());
- }
-}
diff --git a/src/Symfony/Component/Debug/ExceptionHandler.php b/src/Symfony/Component/Debug/ExceptionHandler.php
deleted file mode 100644
index 2be65ab6fe46d..0000000000000
--- a/src/Symfony/Component/Debug/ExceptionHandler.php
+++ /dev/null
@@ -1,470 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug;
-
-use Symfony\Component\Debug\Exception\FlattenException;
-use Symfony\Component\Debug\Exception\OutOfMemoryException;
-use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ExceptionHandler::class, \Symfony\Component\ErrorHandler\ExceptionHandler::class), E_USER_DEPRECATED);
-
-/**
- * ExceptionHandler converts an exception to a Response object.
- *
- * It is mostly useful in debug mode to replace the default PHP/XDebug
- * output with something prettier and more useful.
- *
- * As this class is mainly used during Kernel boot, where nothing is yet
- * available, the Response content is always HTML.
- *
- * @author Fabien Potencier
- * @author Nicolas Grekas
- *
- * @final since Symfony 4.3
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\ExceptionHandler instead.
- */
-class ExceptionHandler
-{
- private const GHOST_ADDONS = [
- '02-14' => self::GHOST_HEART,
- '02-29' => self::GHOST_PLUS,
- '10-18' => self::GHOST_GIFT,
- ];
-
- private const GHOST_GIFT = 'M124.005 5.36c.396-.715 1.119-1.648-.124-1.873-.346-.177-.692-.492-1.038-.141-.769.303-1.435.728-.627 1.523.36.514.685 1.634 1.092 1.758.242-.417.47-.842.697-1.266zm-1.699 1.977c-.706-1.26-1.274-2.612-2.138-3.774-1.051-1.123-3.122-.622-3.593.825-.625 1.431.724 3.14 2.251 2.96 1.159.02 2.324.072 3.48-.011zm5.867.043c1.502-.202 2.365-2.092 1.51-3.347-.757-1.34-2.937-1.387-3.698-.025-.659 1.1-1.23 2.25-1.835 3.38 1.336.077 2.686.06 4.023-.008zm2.487 1.611c.512-.45 2.494-.981.993-1.409-.372-.105-.805-.59-1.14-.457-.726.902-1.842 1.432-3.007 1.376-.228.075-1.391-.114-1.077.1.822.47 1.623.979 2.474 1.395.595-.317 1.173-.667 1.757-1.005zm-11.696.255l1.314-.765c-1.338-.066-2.87.127-3.881-.95-.285-.319-.559-.684-.954-.282-.473.326-1.929.66-.808 1.058.976.576 1.945 1.167 2.946 1.701.476-.223.926-.503 1.383-.762zm6.416 2.846c.567-.456 1.942-.89 1.987-1.38-1.282-.737-2.527-1.56-3.87-2.183-.461-.175-.835.094-1.207.328-1.1.654-2.225 1.267-3.288 1.978 1.39.86 2.798 1.695 4.219 2.504.725-.407 1.44-.83 2.16-1.247zm5.692 1.423l1.765-1.114c-.005-1.244.015-2.488-.019-3.732a77.306 77.306 0 0 0-3.51 2.084c-.126 1.282-.062 2.586-.034 3.876.607-.358 1.2-.741 1.798-1.114zm-13.804-.784c.06-1.06.19-2.269-1.09-2.583-.807-.376-1.926-1.341-2.548-1.332-.02 1.195-.01 2.39-.011 3.585 1.192.744 2.364 1.524 3.582 2.226.119-.616.041-1.269.067-1.896zm8.541 4.105l2.117-1.336c-.003-1.284.05-2.57-.008-3.853-.776.223-1.662.91-2.48 1.337l-1.834 1.075c.012 1.37-.033 2.744.044 4.113.732-.427 1.443-.887 2.161-1.336zm-2.957-.72v-2.057c-1.416-.828-2.828-1.664-4.25-2.482-.078 1.311-.033 2.627-.045 3.94 1.416.887 2.817 1.798 4.25 2.655.057-.683.036-1.372.045-2.057zm8.255 2.755l1.731-1.153c-.024-1.218.06-2.453-.062-3.658-1.2.685-2.358 1.464-3.537 2.195.028 1.261-.058 2.536.072 3.786.609-.373 1.2-.777 1.796-1.17zm-13.851-.683l-.014-1.916c-1.193-.746-2.37-1.517-3.58-2.234-.076 1.224-.033 2.453-.044 3.679 1.203.796 2.392 1.614 3.61 2.385.048-.636.024-1.276.028-1.914zm8.584 4.199l2.102-1.396c-.002-1.298.024-2.596-.01-3.893-1.427.88-2.843 1.775-4.25 2.686-.158 1.253-.055 2.545-.056 3.811.437.266 1.553-.912 2.214-1.208zm-2.988-.556c-.085-.894.365-2.154-.773-2.5-1.146-.727-2.288-1.46-3.45-2.163-.17 1.228.008 2.508-.122 3.751a79.399 79.399 0 0 0 4.278 2.885c.117-.641.044-1.32.067-1.973zm-4.872-.236l-5.087-3.396c.002-3.493-.047-6.988.015-10.48.85-.524 1.753-.954 2.627-1.434-.564-1.616.25-3.58 1.887-4.184 1.372-.563 3.025-.055 3.9 1.13l1.906-.978 1.916.987c.915-1.086 2.483-1.706 3.842-1.097 1.631.573 2.52 2.532 1.936 4.145.88.497 1.837.886 2.644 1.492.036 3.473 0 6.946-.003 10.419-3.374 2.233-6.693 4.55-10.122 6.699-.997 0-1.858-1.083-2.783-1.522a735.316 735.316 0 0 1-2.678-1.781z';
- private const GHOST_HEART = 'M125.914 8.305c3.036-8.71 14.933 0 0 11.2-14.932-11.2-3.036-19.91 0-11.2z';
- private const GHOST_PLUS = 'M111.368 8.97h7.324V1.645h7.512v7.323h7.324v7.513h-7.324v7.323h-7.512v-7.323h-7.324z';
-
- private $debug;
- private $charset;
- private $handler;
- private $caughtBuffer;
- private $caughtLength;
- private $fileLinkFormat;
-
- public function __construct(bool $debug = true, string $charset = null, $fileLinkFormat = null)
- {
- $this->debug = $debug;
- $this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
- $this->fileLinkFormat = $fileLinkFormat;
- }
-
- /**
- * Registers the exception handler.
- *
- * @param bool $debug Enable/disable debug mode, where the stack trace is displayed
- * @param string|null $charset The charset used by exception messages
- * @param string|null $fileLinkFormat The IDE link template
- *
- * @return static
- */
- public static function register($debug = true, $charset = null, $fileLinkFormat = null)
- {
- $handler = new static($debug, $charset, $fileLinkFormat);
-
- $prev = set_exception_handler([$handler, 'handle']);
- if (\is_array($prev) && $prev[0] instanceof ErrorHandler) {
- restore_exception_handler();
- $prev[0]->setExceptionHandler([$handler, 'handle']);
- }
-
- return $handler;
- }
-
- /**
- * Sets a user exception handler.
- *
- * @param callable $handler An handler that will be called on Exception
- *
- * @return callable|null The previous exception handler if any
- */
- public function setHandler(callable $handler = null)
- {
- $old = $this->handler;
- $this->handler = $handler;
-
- return $old;
- }
-
- /**
- * Sets the format for links to source files.
- *
- * @param string|FileLinkFormatter $fileLinkFormat The format for links to source files
- *
- * @return string The previous file link format
- */
- public function setFileLinkFormat($fileLinkFormat)
- {
- $old = $this->fileLinkFormat;
- $this->fileLinkFormat = $fileLinkFormat;
-
- return $old;
- }
-
- /**
- * Sends a response for the given Exception.
- *
- * To be as fail-safe as possible, the exception is first handled
- * by our simple exception handler, then by the user exception handler.
- * The latter takes precedence and any output from the former is cancelled,
- * if and only if nothing bad happens in this handling path.
- */
- public function handle(\Exception $exception)
- {
- if (null === $this->handler || $exception instanceof OutOfMemoryException) {
- $this->sendPhpResponse($exception);
-
- return;
- }
-
- $caughtLength = $this->caughtLength = 0;
-
- ob_start(function ($buffer) {
- $this->caughtBuffer = $buffer;
-
- return '';
- });
-
- $this->sendPhpResponse($exception);
- while (null === $this->caughtBuffer && ob_end_flush()) {
- // Empty loop, everything is in the condition
- }
- if (isset($this->caughtBuffer[0])) {
- ob_start(function ($buffer) {
- if ($this->caughtLength) {
- // use substr_replace() instead of substr() for mbstring overloading resistance
- $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength);
- if (isset($cleanBuffer[0])) {
- $buffer = $cleanBuffer;
- }
- }
-
- return $buffer;
- });
-
- echo $this->caughtBuffer;
- $caughtLength = ob_get_length();
- }
- $this->caughtBuffer = null;
-
- try {
- ($this->handler)($exception);
- $this->caughtLength = $caughtLength;
- } catch (\Exception $e) {
- if (!$caughtLength) {
- // All handlers failed. Let PHP handle that now.
- throw $exception;
- }
- }
- }
-
- /**
- * Sends the error associated with the given Exception as a plain PHP response.
- *
- * This method uses plain PHP functions like header() and echo to output
- * the response.
- *
- * @param \Throwable|FlattenException $exception A \Throwable or FlattenException instance
- */
- public function sendPhpResponse($exception)
- {
- if ($exception instanceof \Throwable) {
- $exception = FlattenException::createFromThrowable($exception);
- }
-
- if (!headers_sent()) {
- header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
- foreach ($exception->getHeaders() as $name => $value) {
- header($name.': '.$value, false);
- }
- header('Content-Type: text/html; charset='.$this->charset);
- }
-
- echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
- }
-
- /**
- * Gets the full HTML content associated with the given exception.
- *
- * @param \Exception|FlattenException $exception An \Exception or FlattenException instance
- *
- * @return string The HTML content as a string
- */
- public function getHtml($exception)
- {
- if (!$exception instanceof FlattenException) {
- $exception = FlattenException::create($exception);
- }
-
- return $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
- }
-
- /**
- * Gets the HTML content associated with the given exception.
- *
- * @return string The content as a string
- */
- public function getContent(FlattenException $exception)
- {
- switch ($exception->getStatusCode()) {
- case 404:
- $title = 'Sorry, the page you are looking for could not be found.';
- break;
- default:
- $title = $this->debug ? $this->escapeHtml($exception->getMessage()) : 'Whoops, looks like something went wrong.';
- }
-
- if (!$this->debug) {
- return <<
- $title
-
-EOF;
- }
-
- $content = '';
- try {
- $count = \count($exception->getAllPrevious());
- $total = $count + 1;
- foreach ($exception->toArray() as $position => $e) {
- $ind = $count - $position + 1;
- $class = $this->formatClass($e['class']);
- $message = nl2br($this->escapeHtml($e['message']));
- $content .= sprintf(<<<'EOF'
-
-
-
-
- (%d/%d)
- %s
-
- %s
- |
-
-EOF
- , $ind, $total, $class, $message);
- foreach ($e['trace'] as $trace) {
- $content .= '';
- if ($trace['function']) {
- $content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
- }
- if (isset($trace['file']) && isset($trace['line'])) {
- $content .= $this->formatPath($trace['file'], $trace['line']);
- }
- $content .= " |
\n";
- }
-
- $content .= "\n
\n
\n";
- }
- } catch (\Exception $e) {
- // something nasty happened and we cannot throw an exception anymore
- if ($this->debug) {
- $e = FlattenException::create($e);
- $title = sprintf('Exception thrown when handling an exception (%s: %s)', $e->getClass(), $this->escapeHtml($e->getMessage()));
- } else {
- $title = 'Whoops, looks like something went wrong.';
- }
- }
-
- $symfonyGhostImageContents = $this->getSymfonyGhostAsSvg();
-
- return <<
-
-
-
$title
-
$symfonyGhostImageContents
-
-
-
-
-
- $content
-
-EOF;
- }
-
- /**
- * Gets the stylesheet associated with the given exception.
- *
- * @return string The stylesheet as a string
- */
- public function getStylesheet(FlattenException $exception)
- {
- if (!$this->debug) {
- return <<<'EOF'
- body { background-color: #fff; color: #222; font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; }
- .container { margin: 30px; max-width: 600px; }
- h1 { color: #dc3545; font-size: 24px; }
-EOF;
- }
-
- return <<<'EOF'
- body { background-color: #F9F9F9; color: #222; font: 14px/1.4 Helvetica, Arial, sans-serif; margin: 0; padding-bottom: 45px; }
-
- a { cursor: pointer; text-decoration: none; }
- a:hover { text-decoration: underline; }
- abbr[title] { border-bottom: none; cursor: help; text-decoration: none; }
-
- code, pre { font: 13px/1.5 Consolas, Monaco, Menlo, "Ubuntu Mono", "Liberation Mono", monospace; }
-
- table, tr, th, td { background: #FFF; border-collapse: collapse; vertical-align: top; }
- table { background: #FFF; border: 1px solid #E0E0E0; box-shadow: 0px 0px 1px rgba(128, 128, 128, .2); margin: 1em 0; width: 100%; }
- table th, table td { border: solid #E0E0E0; border-width: 1px 0; padding: 8px 10px; }
- table th { background-color: #E0E0E0; font-weight: bold; text-align: left; }
-
- .hidden-xs-down { display: none; }
- .block { display: block; }
- .break-long-words { -ms-word-break: break-all; word-break: break-all; word-break: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; }
- .text-muted { color: #999; }
-
- .container { max-width: 1024px; margin: 0 auto; padding: 0 15px; }
- .container::after { content: ""; display: table; clear: both; }
-
- .exception-summary { background: #B0413E; border-bottom: 2px solid rgba(0, 0, 0, 0.1); border-top: 1px solid rgba(0, 0, 0, .3); flex: 0 0 auto; margin-bottom: 30px; }
-
- .exception-message-wrapper { display: flex; align-items: center; min-height: 70px; }
- .exception-message { flex-grow: 1; padding: 30px 0; }
- .exception-message, .exception-message a { color: #FFF; font-size: 21px; font-weight: 400; margin: 0; }
- .exception-message.long { font-size: 18px; }
- .exception-message a { border-bottom: 1px solid rgba(255, 255, 255, 0.5); font-size: inherit; text-decoration: none; }
- .exception-message a:hover { border-bottom-color: #ffffff; }
-
- .exception-illustration { flex-basis: 111px; flex-shrink: 0; height: 66px; margin-left: 15px; opacity: .7; }
-
- .trace + .trace { margin-top: 30px; }
- .trace-head .trace-class { color: #222; font-size: 18px; font-weight: bold; line-height: 1.3; margin: 0; position: relative; }
-
- .trace-message { font-size: 14px; font-weight: normal; margin: .5em 0 0; }
-
- .trace-file-path, .trace-file-path a { color: #222; margin-top: 3px; font-size: 13px; }
- .trace-class { color: #B0413E; }
- .trace-type { padding: 0 2px; }
- .trace-method { color: #B0413E; font-weight: bold; }
- .trace-arguments { color: #777; font-weight: normal; padding-left: 2px; }
-
- @media (min-width: 575px) {
- .hidden-xs-down { display: initial; }
- }
-EOF;
- }
-
- private function decorate($content, $css)
- {
- return <<
-
-
-
-
-
-
-
- $content
-
-
-EOF;
- }
-
- private function formatClass($class)
- {
- $parts = explode('\\', $class);
-
- return sprintf('%s', $class, array_pop($parts));
- }
-
- private function formatPath($path, $line)
- {
- $file = $this->escapeHtml(preg_match('#[^/\\\\]*+$#', $path, $file) ? $file[0] : $path);
- $fmt = $this->fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
-
- if (!$fmt) {
- return sprintf('in %s%s', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');
- }
-
- if (\is_string($fmt)) {
- $i = strpos($f = $fmt, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f);
- $fmt = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, PREG_SPLIT_DELIM_CAPTURE);
-
- for ($i = 1; isset($fmt[$i]); ++$i) {
- if (0 === strpos($path, $k = $fmt[$i++])) {
- $path = substr_replace($path, $fmt[$i], 0, \strlen($k));
- break;
- }
- }
-
- $link = strtr($fmt[0], ['%f' => $path, '%l' => $line]);
- } else {
- try {
- $link = $fmt->format($path, $line);
- } catch (\Exception $e) {
- return sprintf('in %s%s', $this->escapeHtml($path), $file, 0 < $line ? ' line '.$line : '');
- }
- }
-
- return sprintf('in %s%s', $this->escapeHtml($link), $file, 0 < $line ? ' line '.$line : '');
- }
-
- /**
- * Formats an array as a string.
- *
- * @param array $args The argument array
- *
- * @return string
- */
- private function formatArgs(array $args)
- {
- $result = [];
- foreach ($args as $key => $item) {
- if ('object' === $item[0]) {
- $formattedValue = sprintf('object(%s)', $this->formatClass($item[1]));
- } elseif ('array' === $item[0]) {
- $formattedValue = sprintf('array(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
- } elseif ('null' === $item[0]) {
- $formattedValue = 'null';
- } elseif ('boolean' === $item[0]) {
- $formattedValue = ''.strtolower(var_export($item[1], true)).'';
- } elseif ('resource' === $item[0]) {
- $formattedValue = 'resource';
- } else {
- $formattedValue = str_replace("\n", '', $this->escapeHtml(var_export($item[1], true)));
- }
-
- $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $this->escapeHtml($key), $formattedValue);
- }
-
- return implode(', ', $result);
- }
-
- /**
- * HTML-encodes a string.
- */
- private function escapeHtml($str)
- {
- return htmlspecialchars($str, ENT_COMPAT | ENT_SUBSTITUTE, $this->charset);
- }
-
- private function getSymfonyGhostAsSvg()
- {
- return '';
- }
-
- private function addElementToGhost()
- {
- if (!isset(self::GHOST_ADDONS[date('m-d')])) {
- return '';
- }
-
- return '';
- }
-}
diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php
deleted file mode 100644
index 8211d5d0e2676..0000000000000
--- a/src/Symfony/Component/Debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php
+++ /dev/null
@@ -1,197 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\FatalErrorHandler;
-
-use Composer\Autoload\ClassLoader as ComposerClassLoader;
-use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
-use Symfony\Component\Debug\DebugClassLoader;
-use Symfony\Component\Debug\Exception\ClassNotFoundException;
-use Symfony\Component\Debug\Exception\FatalErrorException;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ClassNotFoundFatalErrorHandler::class, \Symfony\Component\ErrorHandler\FatalErrorHandler\ClassNotFoundFatalErrorHandler::class), E_USER_DEPRECATED);
-
-/**
- * ErrorHandler for classes that do not exist.
- *
- * @author Fabien Potencier
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\FatalErrorHandler\ClassNotFoundFatalErrorHandler instead.
- */
-class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
-{
- /**
- * {@inheritdoc}
- */
- public function handleError(array $error, FatalErrorException $exception)
- {
- $messageLen = \strlen($error['message']);
- $notFoundSuffix = '\' not found';
- $notFoundSuffixLen = \strlen($notFoundSuffix);
- if ($notFoundSuffixLen > $messageLen) {
- return;
- }
-
- if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
- return;
- }
-
- foreach (['class', 'interface', 'trait'] as $typeName) {
- $prefix = ucfirst($typeName).' \'';
- $prefixLen = \strlen($prefix);
- if (0 !== strpos($error['message'], $prefix)) {
- continue;
- }
-
- $fullyQualifiedClassName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
- if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) {
- $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
- $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
- $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
- $tail = ' for another namespace?';
- } else {
- $className = $fullyQualifiedClassName;
- $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
- $tail = '?';
- }
-
- if ($candidates = $this->getClassCandidates($className)) {
- $tail = array_pop($candidates).'"?';
- if ($candidates) {
- $tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
- } else {
- $tail = ' for "'.$tail;
- }
- }
- $message .= "\nDid you forget a \"use\" statement".$tail;
-
- return new ClassNotFoundException($message, $exception);
- }
- }
-
- /**
- * Tries to guess the full namespace for a given class name.
- *
- * By default, it looks for PSR-0 and PSR-4 classes registered via a Symfony or a Composer
- * autoloader (that should cover all common cases).
- *
- * @param string $class A class name (without its namespace)
- *
- * @return array An array of possible fully qualified class names
- */
- private function getClassCandidates(string $class): array
- {
- if (!\is_array($functions = spl_autoload_functions())) {
- return [];
- }
-
- // find Symfony and Composer autoloaders
- $classes = [];
-
- foreach ($functions as $function) {
- if (!\is_array($function)) {
- continue;
- }
- // get class loaders wrapped by DebugClassLoader
- if ($function[0] instanceof DebugClassLoader) {
- $function = $function[0]->getClassLoader();
-
- if (!\is_array($function)) {
- continue;
- }
- }
-
- if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader) {
- foreach ($function[0]->getPrefixes() as $prefix => $paths) {
- foreach ($paths as $path) {
- $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
- }
- }
- }
- if ($function[0] instanceof ComposerClassLoader) {
- foreach ($function[0]->getPrefixesPsr4() as $prefix => $paths) {
- foreach ($paths as $path) {
- $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
- }
- }
- }
- }
-
- return array_unique($classes);
- }
-
- private function findClassInPath(string $path, string $class, string $prefix): array
- {
- if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.\dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
- return [];
- }
-
- $classes = [];
- $filename = $class.'.php';
- foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
- if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) {
- $classes[] = $class;
- }
- }
-
- return $classes;
- }
-
- private function convertFileToClass(string $path, string $file, string $prefix): ?string
- {
- $candidates = [
- // namespaced class
- $namespacedClass = str_replace([$path.\DIRECTORY_SEPARATOR, '.php', '/'], ['', '', '\\'], $file),
- // namespaced class (with target dir)
- $prefix.$namespacedClass,
- // namespaced class (with target dir and separator)
- $prefix.'\\'.$namespacedClass,
- // PEAR class
- str_replace('\\', '_', $namespacedClass),
- // PEAR class (with target dir)
- str_replace('\\', '_', $prefix.$namespacedClass),
- // PEAR class (with target dir and separator)
- str_replace('\\', '_', $prefix.'\\'.$namespacedClass),
- ];
-
- if ($prefix) {
- $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); });
- }
-
- // 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.
- foreach ($candidates as $candidate) {
- if ($this->classExists($candidate)) {
- return $candidate;
- }
- }
-
- try {
- require_once $file;
- } catch (\Throwable $e) {
- return null;
- }
-
- foreach ($candidates as $candidate) {
- if ($this->classExists($candidate)) {
- return $candidate;
- }
- }
-
- return null;
- }
-
- private function classExists(string $class): bool
- {
- return class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false);
- }
-}
diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/FatalErrorHandlerInterface.php b/src/Symfony/Component/Debug/FatalErrorHandler/FatalErrorHandlerInterface.php
deleted file mode 100644
index a1c4a8ce547cd..0000000000000
--- a/src/Symfony/Component/Debug/FatalErrorHandler/FatalErrorHandlerInterface.php
+++ /dev/null
@@ -1,36 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\FatalErrorHandler;
-
-use Symfony\Component\Debug\Exception\FatalErrorException;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalErrorHandlerInterface::class, \Symfony\Component\ErrorHandler\FatalErrorHandler\FatalErrorHandlerInterface::class), E_USER_DEPRECATED);
-
-/**
- * Attempts to convert fatal errors to exceptions.
- *
- * @author Fabien Potencier
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\FatalErrorHandler\FatalErrorHandlerInterface instead.
- */
-interface FatalErrorHandlerInterface
-{
- /**
- * Attempts to convert an error into an exception.
- *
- * @param array $error An array as returned by error_get_last()
- * @param FatalErrorException $exception A FatalErrorException instance
- *
- * @return FatalErrorException|null A FatalErrorException instance if the class is able to convert the error, null otherwise
- */
- public function handleError(array $error, FatalErrorException $exception);
-}
diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php
deleted file mode 100644
index dc7cb85bf360c..0000000000000
--- a/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.php
+++ /dev/null
@@ -1,88 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\FatalErrorHandler;
-
-use Symfony\Component\Debug\Exception\FatalErrorException;
-use Symfony\Component\Debug\Exception\UndefinedFunctionException;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', UndefinedFunctionFatalErrorHandler::class, \Symfony\Component\ErrorHandler\FatalErrorHandler\UndefinedFunctionFatalErrorHandler::class), E_USER_DEPRECATED);
-
-/**
- * ErrorHandler for undefined functions.
- *
- * @author Fabien Potencier
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\FatalErrorHandler\UndefinedFunctionFatalErrorHandler instead.
- */
-class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
-{
- /**
- * {@inheritdoc}
- */
- public function handleError(array $error, FatalErrorException $exception)
- {
- $messageLen = \strlen($error['message']);
- $notFoundSuffix = '()';
- $notFoundSuffixLen = \strlen($notFoundSuffix);
- if ($notFoundSuffixLen > $messageLen) {
- return;
- }
-
- if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
- return;
- }
-
- $prefix = 'Call to undefined function ';
- $prefixLen = \strlen($prefix);
- if (0 !== strpos($error['message'], $prefix)) {
- return;
- }
-
- $fullyQualifiedFunctionName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
- if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\')) {
- $functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1);
- $namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex);
- $message = sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix);
- } else {
- $functionName = $fullyQualifiedFunctionName;
- $message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName);
- }
-
- $candidates = [];
- foreach (get_defined_functions() as $type => $definedFunctionNames) {
- foreach ($definedFunctionNames as $definedFunctionName) {
- if (false !== $namespaceSeparatorIndex = strrpos($definedFunctionName, '\\')) {
- $definedFunctionNameBasename = substr($definedFunctionName, $namespaceSeparatorIndex + 1);
- } else {
- $definedFunctionNameBasename = $definedFunctionName;
- }
-
- if ($definedFunctionNameBasename === $functionName) {
- $candidates[] = '\\'.$definedFunctionName;
- }
- }
- }
-
- if ($candidates) {
- sort($candidates);
- $last = array_pop($candidates).'"?';
- if ($candidates) {
- $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
- } else {
- $candidates = '"'.$last;
- }
- $message .= "\nDid you mean to call ".$candidates;
- }
-
- return new UndefinedFunctionException($message, $exception);
- }
-}
diff --git a/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php b/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php
deleted file mode 100644
index 5972327c498a8..0000000000000
--- a/src/Symfony/Component/Debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php
+++ /dev/null
@@ -1,70 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\FatalErrorHandler;
-
-use Symfony\Component\Debug\Exception\FatalErrorException;
-use Symfony\Component\Debug\Exception\UndefinedMethodException;
-
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', UndefinedMethodFatalErrorHandler::class, \Symfony\Component\ErrorHandler\FatalErrorHandler\UndefinedMethodFatalErrorHandler::class), E_USER_DEPRECATED);
-
-/**
- * ErrorHandler for undefined methods.
- *
- * @author Grégoire Pineau
- *
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\FatalErrorHandler\UndefinedMethodFatalErrorHandler instead.
- */
-class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
-{
- /**
- * {@inheritdoc}
- */
- public function handleError(array $error, FatalErrorException $exception)
- {
- preg_match('/^Call to undefined method (.*)::(.*)\(\)$/', $error['message'], $matches);
- if (!$matches) {
- return;
- }
-
- $className = $matches[1];
- $methodName = $matches[2];
-
- $message = sprintf('Attempted to call an undefined method named "%s" of class "%s".', $methodName, $className);
-
- if (!class_exists($className) || null === $methods = get_class_methods($className)) {
- // failed to get the class or its methods on which an unknown method was called (for example on an anonymous class)
- return new UndefinedMethodException($message, $exception);
- }
-
- $candidates = [];
- foreach ($methods as $definedMethodName) {
- $lev = levenshtein($methodName, $definedMethodName);
- if ($lev <= \strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {
- $candidates[] = $definedMethodName;
- }
- }
-
- if ($candidates) {
- sort($candidates);
- $last = array_pop($candidates).'"?';
- if ($candidates) {
- $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
- } else {
- $candidates = '"'.$last;
- }
-
- $message .= "\nDid you mean to call ".$candidates;
- }
-
- return new UndefinedMethodException($message, $exception);
- }
-}
diff --git a/src/Symfony/Component/Debug/LICENSE b/src/Symfony/Component/Debug/LICENSE
deleted file mode 100644
index a677f43763ca4..0000000000000
--- a/src/Symfony/Component/Debug/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2004-2019 Fabien Potencier
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is furnished
-to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/src/Symfony/Component/Debug/README.md b/src/Symfony/Component/Debug/README.md
deleted file mode 100644
index a1d16175c1a1f..0000000000000
--- a/src/Symfony/Component/Debug/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Debug Component
-===============
-
-The Debug component provides tools to ease debugging PHP code.
-
-Resources
----------
-
- * [Documentation](https://symfony.com/doc/current/components/debug/index.html)
- * [Contributing](https://symfony.com/doc/current/contributing/index.html)
- * [Report issues](https://github.com/symfony/symfony/issues) and
- [send Pull Requests](https://github.com/symfony/symfony/pulls)
- in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php
deleted file mode 100644
index 6cca7a2e19a3f..0000000000000
--- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php
+++ /dev/null
@@ -1,451 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Tests;
-
-use PHPUnit\Framework\TestCase;
-use Symfony\Component\Debug\DebugClassLoader;
-
-/**
- * @group legacy
- */
-class DebugClassLoaderTest extends TestCase
-{
- /**
- * @var int Error reporting level before running tests
- */
- private $errorReporting;
-
- private $loader;
-
- protected function setUp()
- {
- $this->errorReporting = error_reporting(E_ALL);
- $this->loader = new ClassLoader();
- spl_autoload_register([$this->loader, 'loadClass'], true, true);
- DebugClassLoader::enable();
- }
-
- protected function tearDown()
- {
- DebugClassLoader::disable();
- spl_autoload_unregister([$this->loader, 'loadClass']);
- error_reporting($this->errorReporting);
- }
-
- public function testIdempotence()
- {
- DebugClassLoader::enable();
-
- $functions = spl_autoload_functions();
- foreach ($functions as $function) {
- if (\is_array($function) && $function[0] instanceof DebugClassLoader) {
- $reflClass = new \ReflectionClass($function[0]);
- $reflProp = $reflClass->getProperty('classLoader');
- $reflProp->setAccessible(true);
-
- $this->assertNotInstanceOf('Symfony\Component\Debug\DebugClassLoader', $reflProp->getValue($function[0]));
-
- return;
- }
- }
-
- $this->fail('DebugClassLoader did not register');
- }
-
- /**
- * @expectedException \Exception
- * @expectedExceptionMessage boo
- */
- public function testThrowingClass()
- {
- try {
- class_exists(__NAMESPACE__.'\Fixtures\Throwing');
- $this->fail('Exception expected');
- } catch (\Exception $e) {
- $this->assertSame('boo', $e->getMessage());
- }
-
- // the second call also should throw
- class_exists(__NAMESPACE__.'\Fixtures\Throwing');
- }
-
- /**
- * @expectedException \RuntimeException
- */
- public function testNameCaseMismatch()
- {
- class_exists(__NAMESPACE__.'\TestingCaseMismatch', true);
- }
-
- /**
- * @expectedException \RuntimeException
- * @expectedExceptionMessage Case mismatch between class and real file names
- */
- public function testFileCaseMismatch()
- {
- if (!file_exists(__DIR__.'/Fixtures/CaseMismatch.php')) {
- $this->markTestSkipped('Can only be run on case insensitive filesystems');
- }
-
- class_exists(__NAMESPACE__.'\Fixtures\CaseMismatch', true);
- }
-
- /**
- * @expectedException \RuntimeException
- */
- public function testPsr4CaseMismatch()
- {
- class_exists(__NAMESPACE__.'\Fixtures\Psr4CaseMismatch', true);
- }
-
- public function testNotPsr0()
- {
- $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\NotPSR0', true));
- }
-
- public function testNotPsr0Bis()
- {
- $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\NotPSR0bis', true));
- }
-
- public function testClassAlias()
- {
- $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\ClassAlias', true));
- }
-
- /**
- * @dataProvider provideDeprecatedSuper
- */
- public function testDeprecatedSuper($class, $super, $type)
- {
- set_error_handler(function () { return false; });
- $e = error_reporting(0);
- trigger_error('', E_USER_DEPRECATED);
-
- class_exists('Test\\'.__NAMESPACE__.'\\'.$class, true);
-
- error_reporting($e);
- restore_error_handler();
-
- $lastError = error_get_last();
- unset($lastError['file'], $lastError['line']);
-
- $xError = [
- 'type' => E_USER_DEPRECATED,
- 'message' => 'The "Test\Symfony\Component\Debug\Tests\\'.$class.'" class '.$type.' "Symfony\Component\Debug\Tests\Fixtures\\'.$super.'" that is deprecated but this is a test deprecation notice.',
- ];
-
- $this->assertSame($xError, $lastError);
- }
-
- public function provideDeprecatedSuper()
- {
- return [
- ['DeprecatedInterfaceClass', 'DeprecatedInterface', 'implements'],
- ['DeprecatedParentClass', 'DeprecatedClass', 'extends'],
- ];
- }
-
- public function testInterfaceExtendsDeprecatedInterface()
- {
- set_error_handler(function () { return false; });
- $e = error_reporting(0);
- trigger_error('', E_USER_NOTICE);
-
- class_exists('Test\\'.__NAMESPACE__.'\\NonDeprecatedInterfaceClass', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $lastError = error_get_last();
- unset($lastError['file'], $lastError['line']);
-
- $xError = [
- 'type' => E_USER_NOTICE,
- 'message' => '',
- ];
-
- $this->assertSame($xError, $lastError);
- }
-
- public function testDeprecatedSuperInSameNamespace()
- {
- set_error_handler(function () { return false; });
- $e = error_reporting(0);
- trigger_error('', E_USER_NOTICE);
-
- class_exists('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $lastError = error_get_last();
- unset($lastError['file'], $lastError['line']);
-
- $xError = [
- 'type' => E_USER_NOTICE,
- 'message' => '',
- ];
-
- $this->assertSame($xError, $lastError);
- }
-
- public function testExtendedFinalClass()
- {
- $deprecations = [];
- set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
- $e = error_reporting(E_USER_DEPRECATED);
-
- require __DIR__.'/Fixtures/FinalClasses.php';
-
- $i = 1;
- while (class_exists($finalClass = __NAMESPACE__.'\\Fixtures\\FinalClass'.$i++, false)) {
- spl_autoload_call($finalClass);
- class_exists('Test\\'.__NAMESPACE__.'\\Extends'.substr($finalClass, strrpos($finalClass, '\\') + 1), true);
- }
-
- error_reporting($e);
- restore_error_handler();
-
- $this->assertSame([
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass1" class is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass1".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass2" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass2".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass3" class is considered final comment with @@@ and ***. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass3".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass4" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass4".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass5" class is considered final multiline comment. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass5".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass6" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass6".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass7" class is considered final another multiline comment... It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass7".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass8" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass8".',
- ], $deprecations);
- }
-
- public function testExtendedFinalMethod()
- {
- $deprecations = [];
- set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
- $e = error_reporting(E_USER_DEPRECATED);
-
- class_exists(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $xError = [
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
- ];
-
- $this->assertSame($xError, $deprecations);
- }
-
- public function testExtendedDeprecatedMethodDoesntTriggerAnyNotice()
- {
- set_error_handler(function () { return false; });
- $e = error_reporting(0);
- trigger_error('', E_USER_NOTICE);
-
- class_exists('Test\\'.__NAMESPACE__.'\\ExtendsAnnotatedClass', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $lastError = error_get_last();
- unset($lastError['file'], $lastError['line']);
-
- $this->assertSame(['type' => E_USER_NOTICE, 'message' => ''], $lastError);
- }
-
- public function testInternalsUse()
- {
- $deprecations = [];
- set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
- $e = error_reporting(E_USER_DEPRECATED);
-
- class_exists('Test\\'.__NAMESPACE__.'\\ExtendsInternals', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $this->assertSame($deprecations, [
- 'The "Symfony\Component\Debug\Tests\Fixtures\InternalInterface" interface is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass" class is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait" trait is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".',
- 'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass::internalMethod()" method is considered internal. It may change without further notice. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".',
- ]);
- }
-
- public function testExtendedMethodDefinesNewParameters()
- {
- $deprecations = [];
- set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
- $e = error_reporting(E_USER_DEPRECATED);
-
- class_exists(__NAMESPACE__.'\\Fixtures\SubClassWithAnnotatedParameters', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $this->assertSame([
- 'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::quzMethod()" method will require a new "Quz $quz" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\ClassWithAnnotatedParameters", not defining it is deprecated.',
- 'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::whereAmI()" method will require a new "bool $matrix" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
- 'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "$noType" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
- 'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "callable(\Throwable|null $reason, mixed $value) $callback" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
- 'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "string $param" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
- 'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "callable ($a, $b) $anotherOne" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
- 'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::iAmHere()" method will require a new "Type$WithDollarIsStillAType $ccc" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\InterfaceWithAnnotatedParameters", not defining it is deprecated.',
- 'The "Symfony\Component\Debug\Tests\Fixtures\SubClassWithAnnotatedParameters::isSymfony()" method will require a new "true $yes" argument in the next major version of its parent class "Symfony\Component\Debug\Tests\Fixtures\ClassWithAnnotatedParameters", not defining it is deprecated.',
- ], $deprecations);
- }
-
- public function testUseTraitWithInternalMethod()
- {
- $deprecations = [];
- set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
- $e = error_reporting(E_USER_DEPRECATED);
-
- class_exists('Test\\'.__NAMESPACE__.'\\UseTraitWithInternalMethod', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $this->assertSame([], $deprecations);
- }
-
- public function testVirtualUse()
- {
- $deprecations = [];
- set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
- $e = error_reporting(E_USER_DEPRECATED);
-
- class_exists('Test\\'.__NAMESPACE__.'\\ExtendsVirtual', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $this->assertSame([
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::sameLineInterfaceMethodNoBraces()".',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::newLineInterfaceMethod()": Some description!',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::newLineInterfaceMethodNoBraces()": Description.',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::invalidInterfaceMethod()".',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::invalidInterfaceMethodNoBraces()".',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::complexInterfaceMethod($arg, ...$args)".',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::complexInterfaceMethodTyped($arg, int ...$args)": Description ...',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "static Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::staticMethodNoBraces()".',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "static Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::staticMethodTyped(int $arg)": Description.',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtualParent" should implement method "static Symfony\Component\Debug\Tests\Fixtures\VirtualInterface::staticMethodTypedNoBraces()".',
- 'Class "Test\Symfony\Component\Debug\Tests\ExtendsVirtual" should implement method "Symfony\Component\Debug\Tests\Fixtures\VirtualSubInterface::subInterfaceMethod()".',
- ], $deprecations);
- }
-
- public function testVirtualUseWithMagicCall()
- {
- $deprecations = [];
- set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
- $e = error_reporting(E_USER_DEPRECATED);
-
- class_exists('Test\\'.__NAMESPACE__.'\\ExtendsVirtualMagicCall', true);
-
- error_reporting($e);
- restore_error_handler();
-
- $this->assertSame([], $deprecations);
- }
-
- public function testEvaluatedCode()
- {
- $this->assertTrue(class_exists(__NAMESPACE__.'\Fixtures\DefinitionInEvaluatedCode', true));
- }
-}
-
-class ClassLoader
-{
- public function loadClass($class)
- {
- }
-
- public function getClassMap()
- {
- return [__NAMESPACE__.'\Fixtures\NotPSR0bis' => __DIR__.'/Fixtures/notPsr0Bis.php'];
- }
-
- public function findFile($class)
- {
- $fixtureDir = __DIR__.\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR;
-
- if (__NAMESPACE__.'\TestingUnsilencing' === $class) {
- eval('-- parse error --');
- } elseif (__NAMESPACE__.'\TestingStacking' === $class) {
- eval('namespace '.__NAMESPACE__.'; class TestingStacking { function foo() {} }');
- } elseif (__NAMESPACE__.'\TestingCaseMismatch' === $class) {
- eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}');
- } elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) {
- return $fixtureDir.'psr4'.\DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php';
- } elseif (__NAMESPACE__.'\Fixtures\NotPSR0' === $class) {
- return $fixtureDir.'reallyNotPsr0.php';
- } elseif (__NAMESPACE__.'\Fixtures\NotPSR0bis' === $class) {
- return $fixtureDir.'notPsr0Bis.php';
- } elseif ('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent' === $class) {
- eval('namespace Symfony\Bridge\Debug\Tests\Fixtures; class ExtendsDeprecatedParent extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
- } elseif ('Test\\'.__NAMESPACE__.'\DeprecatedParentClass' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedParentClass extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
- } elseif ('Test\\'.__NAMESPACE__.'\DeprecatedInterfaceClass' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\DeprecatedInterface {}');
- } elseif ('Test\\'.__NAMESPACE__.'\NonDeprecatedInterfaceClass' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\NonDeprecatedInterface {}');
- } elseif ('Test\\'.__NAMESPACE__.'\Float' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class Float {}');
- } elseif (0 === strpos($class, 'Test\\'.__NAMESPACE__.'\ExtendsFinalClass')) {
- $classShortName = substr($class, strrpos($class, '\\') + 1);
- eval('namespace Test\\'.__NAMESPACE__.'; class '.$classShortName.' extends \\'.__NAMESPACE__.'\Fixtures\\'.substr($classShortName, 7).' {}');
- } elseif ('Test\\'.__NAMESPACE__.'\ExtendsAnnotatedClass' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsAnnotatedClass extends \\'.__NAMESPACE__.'\Fixtures\AnnotatedClass {
- public function deprecatedMethod() { }
- }');
- } elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternals' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternals extends ExtendsInternalsParent {
- use \\'.__NAMESPACE__.'\Fixtures\InternalTrait;
-
- public function internalMethod() { }
- }');
- } elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternalsParent' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternalsParent extends \\'.__NAMESPACE__.'\Fixtures\InternalClass implements \\'.__NAMESPACE__.'\Fixtures\InternalInterface { }');
- } elseif ('Test\\'.__NAMESPACE__.'\UseTraitWithInternalMethod' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class UseTraitWithInternalMethod { use \\'.__NAMESPACE__.'\Fixtures\TraitWithInternalMethod; }');
- } elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtual' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsVirtual extends ExtendsVirtualParent implements \\'.__NAMESPACE__.'\Fixtures\VirtualSubInterface {
- public function ownClassMethod() { }
- public function classMethod() { }
- public function sameLineInterfaceMethodNoBraces() { }
- }');
- } elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtualParent' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsVirtualParent extends ExtendsVirtualAbstract {
- public function ownParentMethod() { }
- public function traitMethod() { }
- public function sameLineInterfaceMethod() { }
- public function staticMethodNoBraces() { } // should be static
- }');
- } elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtualAbstract' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; abstract class ExtendsVirtualAbstract extends ExtendsVirtualAbstractBase {
- public static function staticMethod() { }
- public function ownAbstractMethod() { }
- public function interfaceMethod() { }
- }');
- } elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtualAbstractBase' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; abstract class ExtendsVirtualAbstractBase extends \\'.__NAMESPACE__.'\Fixtures\VirtualClass implements \\'.__NAMESPACE__.'\Fixtures\VirtualInterface {
- public function ownAbstractBaseMethod() { }
- }');
- } elseif ('Test\\'.__NAMESPACE__.'\ExtendsVirtualMagicCall' === $class) {
- eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsVirtualMagicCall extends \\'.__NAMESPACE__.'\Fixtures\VirtualClassMagicCall implements \\'.__NAMESPACE__.'\Fixtures\VirtualInterface {
- }');
- }
- }
-}
diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
deleted file mode 100644
index cae9878868b9a..0000000000000
--- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php
+++ /dev/null
@@ -1,562 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Tests;
-
-use PHPUnit\Framework\TestCase;
-use Psr\Log\LogLevel;
-use Psr\Log\NullLogger;
-use Symfony\Component\Debug\BufferingLogger;
-use Symfony\Component\Debug\ErrorHandler;
-use Symfony\Component\Debug\Exception\SilencedErrorContext;
-use Symfony\Component\Debug\Tests\Fixtures\ErrorHandlerThatUsesThePreviousOne;
-use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler;
-
-/**
- * ErrorHandlerTest.
- *
- * @author Robert Schönthal
- * @author Nicolas Grekas
- *
- * @group legacy
- */
-class ErrorHandlerTest extends TestCase
-{
- public function testRegister()
- {
- $handler = ErrorHandler::register();
-
- try {
- $this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler);
- $this->assertSame($handler, ErrorHandler::register());
-
- $newHandler = new ErrorHandler();
-
- $this->assertSame($handler, ErrorHandler::register($newHandler, false));
- $h = set_error_handler('var_dump');
- restore_error_handler();
- $this->assertSame([$handler, 'handleError'], $h);
-
- try {
- $this->assertSame($newHandler, ErrorHandler::register($newHandler, true));
- $h = set_error_handler('var_dump');
- restore_error_handler();
- $this->assertSame([$newHandler, 'handleError'], $h);
- } catch (\Exception $e) {
- }
-
- restore_error_handler();
- restore_exception_handler();
-
- if (isset($e)) {
- throw $e;
- }
- } catch (\Exception $e) {
- }
-
- restore_error_handler();
- restore_exception_handler();
-
- if (isset($e)) {
- throw $e;
- }
- }
-
- public function testErrorGetLast()
- {
- $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
- $handler = ErrorHandler::register();
- $handler->setDefaultLogger($logger);
- $handler->screamAt(E_ALL);
-
- try {
- @trigger_error('Hello', E_USER_WARNING);
- $expected = [
- 'type' => E_USER_WARNING,
- 'message' => 'Hello',
- 'file' => __FILE__,
- 'line' => __LINE__ - 5,
- ];
- $this->assertSame($expected, error_get_last());
- } catch (\Exception $e) {
- restore_error_handler();
- restore_exception_handler();
-
- throw $e;
- }
- }
-
- public function testNotice()
- {
- ErrorHandler::register();
-
- try {
- self::triggerNotice($this);
- $this->fail('ErrorException expected');
- } catch (\ErrorException $exception) {
- // if an exception is thrown, the test passed
- $this->assertEquals(E_NOTICE, $exception->getSeverity());
- $this->assertEquals(__FILE__, $exception->getFile());
- $this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
-
- $trace = $exception->getTrace();
-
- $this->assertEquals(__FILE__, $trace[0]['file']);
- $this->assertEquals(__CLASS__, $trace[0]['class']);
- $this->assertEquals('triggerNotice', $trace[0]['function']);
- $this->assertEquals('::', $trace[0]['type']);
-
- $this->assertEquals(__FILE__, $trace[0]['file']);
- $this->assertEquals(__CLASS__, $trace[1]['class']);
- $this->assertEquals(__FUNCTION__, $trace[1]['function']);
- $this->assertEquals('->', $trace[1]['type']);
- } finally {
- restore_error_handler();
- restore_exception_handler();
- }
- }
-
- // dummy function to test trace in error handler.
- private static function triggerNotice($that)
- {
- $that->assertSame('', $foo.$foo.$bar);
- }
-
- public function testConstruct()
- {
- try {
- $handler = ErrorHandler::register();
- $handler->throwAt(3, true);
- $this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, $handler->throwAt(0));
- } finally {
- restore_error_handler();
- restore_exception_handler();
- }
- }
-
- public function testDefaultLogger()
- {
- try {
- $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
- $handler = ErrorHandler::register();
-
- $handler->setDefaultLogger($logger, E_NOTICE);
- $handler->setDefaultLogger($logger, [E_USER_NOTICE => LogLevel::CRITICAL]);
-
- $loggers = [
- E_DEPRECATED => [null, LogLevel::INFO],
- E_USER_DEPRECATED => [null, LogLevel::INFO],
- E_NOTICE => [$logger, LogLevel::WARNING],
- E_USER_NOTICE => [$logger, LogLevel::CRITICAL],
- E_STRICT => [null, LogLevel::WARNING],
- E_WARNING => [null, LogLevel::WARNING],
- E_USER_WARNING => [null, LogLevel::WARNING],
- E_COMPILE_WARNING => [null, LogLevel::WARNING],
- E_CORE_WARNING => [null, LogLevel::WARNING],
- E_USER_ERROR => [null, LogLevel::CRITICAL],
- E_RECOVERABLE_ERROR => [null, LogLevel::CRITICAL],
- E_COMPILE_ERROR => [null, LogLevel::CRITICAL],
- E_PARSE => [null, LogLevel::CRITICAL],
- E_ERROR => [null, LogLevel::CRITICAL],
- E_CORE_ERROR => [null, LogLevel::CRITICAL],
- ];
- $this->assertSame($loggers, $handler->setLoggers([]));
- } finally {
- restore_error_handler();
- restore_exception_handler();
- }
- }
-
- public function testHandleError()
- {
- try {
- $handler = ErrorHandler::register();
- $handler->throwAt(0, true);
- $this->assertFalse($handler->handleError(0, 'foo', 'foo.php', 12, []));
-
- restore_error_handler();
- restore_exception_handler();
-
- $handler = ErrorHandler::register();
- $handler->throwAt(3, true);
- $this->assertFalse($handler->handleError(4, 'foo', 'foo.php', 12, []));
-
- restore_error_handler();
- restore_exception_handler();
-
- $handler = ErrorHandler::register();
- $handler->throwAt(3, true);
- try {
- $handler->handleError(4, 'foo', 'foo.php', 12, []);
- } catch (\ErrorException $e) {
- $this->assertSame('Parse Error: foo', $e->getMessage());
- $this->assertSame(4, $e->getSeverity());
- $this->assertSame('foo.php', $e->getFile());
- $this->assertSame(12, $e->getLine());
- }
-
- restore_error_handler();
- restore_exception_handler();
-
- $handler = ErrorHandler::register();
- $handler->throwAt(E_USER_DEPRECATED, true);
- $this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
-
- restore_error_handler();
- restore_exception_handler();
-
- $handler = ErrorHandler::register();
- $handler->throwAt(E_DEPRECATED, true);
- $this->assertFalse($handler->handleError(E_DEPRECATED, 'foo', 'foo.php', 12, []));
-
- restore_error_handler();
- restore_exception_handler();
-
- $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
-
- $warnArgCheck = function ($logLevel, $message, $context) {
- $this->assertEquals('info', $logLevel);
- $this->assertEquals('User Deprecated: foo', $message);
- $this->assertArrayHasKey('exception', $context);
- $exception = $context['exception'];
- $this->assertInstanceOf(\ErrorException::class, $exception);
- $this->assertSame('User Deprecated: foo', $exception->getMessage());
- $this->assertSame(E_USER_DEPRECATED, $exception->getSeverity());
- };
-
- $logger
- ->expects($this->once())
- ->method('log')
- ->willReturnCallback($warnArgCheck)
- ;
-
- $handler = ErrorHandler::register();
- $handler->setDefaultLogger($logger, E_USER_DEPRECATED);
- $this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
-
- restore_error_handler();
- restore_exception_handler();
-
- $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
-
- $line = null;
- $logArgCheck = function ($level, $message, $context) use (&$line) {
- $this->assertEquals('Notice: Undefined variable: undefVar', $message);
- $this->assertArrayHasKey('exception', $context);
- $exception = $context['exception'];
- $this->assertInstanceOf(SilencedErrorContext::class, $exception);
- $this->assertSame(E_NOTICE, $exception->getSeverity());
- $this->assertSame(__FILE__, $exception->getFile());
- $this->assertSame($line, $exception->getLine());
- $this->assertNotEmpty($exception->getTrace());
- $this->assertSame(1, $exception->count);
- };
-
- $logger
- ->expects($this->once())
- ->method('log')
- ->willReturnCallback($logArgCheck)
- ;
-
- $handler = ErrorHandler::register();
- $handler->setDefaultLogger($logger, E_NOTICE);
- $handler->screamAt(E_NOTICE);
- unset($undefVar);
- $line = __LINE__ + 1;
- @$undefVar++;
-
- restore_error_handler();
- restore_exception_handler();
- } catch (\Exception $e) {
- restore_error_handler();
- restore_exception_handler();
-
- throw $e;
- }
- }
-
- public function testHandleUserError()
- {
- try {
- $handler = ErrorHandler::register();
- $handler->throwAt(0, true);
-
- $e = null;
- $x = new \Exception('Foo');
-
- try {
- $f = new Fixtures\ToStringThrower($x);
- $f .= ''; // Trigger $f->__toString()
- } catch (\Exception $e) {
- }
-
- $this->assertSame($x, $e);
- } finally {
- restore_error_handler();
- restore_exception_handler();
- }
- }
-
- public function testHandleDeprecation()
- {
- $logArgCheck = function ($level, $message, $context) {
- $this->assertEquals(LogLevel::INFO, $level);
- $this->assertArrayHasKey('exception', $context);
- $exception = $context['exception'];
- $this->assertInstanceOf(\ErrorException::class, $exception);
- $this->assertSame('User Deprecated: Foo deprecation', $exception->getMessage());
- };
-
- $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
- $logger
- ->expects($this->once())
- ->method('log')
- ->willReturnCallback($logArgCheck)
- ;
-
- $handler = new ErrorHandler();
- $handler->setDefaultLogger($logger);
- @$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
-
- restore_error_handler();
- }
-
- public function testHandleException()
- {
- try {
- $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
- $handler = ErrorHandler::register();
-
- $exception = new \Exception('foo');
-
- $logArgCheck = function ($level, $message, $context) {
- $this->assertSame('Uncaught Exception: foo', $message);
- $this->assertArrayHasKey('exception', $context);
- $this->assertInstanceOf(\Exception::class, $context['exception']);
- };
-
- $logger
- ->expects($this->exactly(2))
- ->method('log')
- ->willReturnCallback($logArgCheck)
- ;
-
- $handler->setDefaultLogger($logger, E_ERROR);
-
- try {
- $handler->handleException($exception);
- $this->fail('Exception expected');
- } catch (\Exception $e) {
- $this->assertSame($exception, $e);
- }
-
- $handler->setExceptionHandler(function ($e) use ($exception) {
- $this->assertSame($exception, $e);
- });
-
- $handler->handleException($exception);
- } finally {
- restore_error_handler();
- restore_exception_handler();
- }
- }
-
- public function testBootstrappingLogger()
- {
- $bootLogger = new BufferingLogger();
- $handler = new ErrorHandler($bootLogger);
-
- $loggers = [
- E_DEPRECATED => [$bootLogger, LogLevel::INFO],
- E_USER_DEPRECATED => [$bootLogger, LogLevel::INFO],
- E_NOTICE => [$bootLogger, LogLevel::WARNING],
- E_USER_NOTICE => [$bootLogger, LogLevel::WARNING],
- E_STRICT => [$bootLogger, LogLevel::WARNING],
- E_WARNING => [$bootLogger, LogLevel::WARNING],
- E_USER_WARNING => [$bootLogger, LogLevel::WARNING],
- E_COMPILE_WARNING => [$bootLogger, LogLevel::WARNING],
- E_CORE_WARNING => [$bootLogger, LogLevel::WARNING],
- E_USER_ERROR => [$bootLogger, LogLevel::CRITICAL],
- E_RECOVERABLE_ERROR => [$bootLogger, LogLevel::CRITICAL],
- E_COMPILE_ERROR => [$bootLogger, LogLevel::CRITICAL],
- E_PARSE => [$bootLogger, LogLevel::CRITICAL],
- E_ERROR => [$bootLogger, LogLevel::CRITICAL],
- E_CORE_ERROR => [$bootLogger, LogLevel::CRITICAL],
- ];
-
- $this->assertSame($loggers, $handler->setLoggers([]));
-
- $handler->handleError(E_DEPRECATED, 'Foo message', __FILE__, 123, []);
-
- $logs = $bootLogger->cleanLogs();
-
- $this->assertCount(1, $logs);
- $log = $logs[0];
- $this->assertSame('info', $log[0]);
- $this->assertSame('Deprecated: Foo message', $log[1]);
- $this->assertArrayHasKey('exception', $log[2]);
- $exception = $log[2]['exception'];
- $this->assertInstanceOf(\ErrorException::class, $exception);
- $this->assertSame('Deprecated: Foo message', $exception->getMessage());
- $this->assertSame(__FILE__, $exception->getFile());
- $this->assertSame(123, $exception->getLine());
- $this->assertSame(E_DEPRECATED, $exception->getSeverity());
-
- $bootLogger->log(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
-
- $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
- $mockLogger->expects($this->once())
- ->method('log')
- ->with(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
-
- $handler->setLoggers([E_DEPRECATED => [$mockLogger, LogLevel::WARNING]]);
- }
-
- public function testSettingLoggerWhenExceptionIsBuffered()
- {
- $bootLogger = new BufferingLogger();
- $handler = new ErrorHandler($bootLogger);
-
- $exception = new \Exception('Foo message');
-
- $mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
- $mockLogger->expects($this->once())
- ->method('log')
- ->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', ['exception' => $exception]);
-
- $handler->setExceptionHandler(function () use ($handler, $mockLogger) {
- $handler->setDefaultLogger($mockLogger);
- });
-
- $handler->handleException($exception);
- }
-
- public function testHandleFatalError()
- {
- try {
- $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
- $handler = ErrorHandler::register();
-
- $error = [
- 'type' => E_PARSE,
- 'message' => 'foo',
- 'file' => 'bar',
- 'line' => 123,
- ];
-
- $logArgCheck = function ($level, $message, $context) {
- $this->assertEquals('Fatal Parse Error: foo', $message);
- $this->assertArrayHasKey('exception', $context);
- $this->assertInstanceOf(\Exception::class, $context['exception']);
- };
-
- $logger
- ->expects($this->once())
- ->method('log')
- ->willReturnCallback($logArgCheck)
- ;
-
- $handler->setDefaultLogger($logger, E_PARSE);
-
- $handler->handleFatalError($error);
-
- restore_error_handler();
- restore_exception_handler();
- } catch (\Exception $e) {
- restore_error_handler();
- restore_exception_handler();
-
- throw $e;
- }
- }
-
- public function testHandleErrorException()
- {
- $exception = new \Error("Class 'IReallyReallyDoNotExistAnywhereInTheRepositoryISwear' not found");
-
- $handler = new ErrorHandler();
- $handler->setExceptionHandler(function () use (&$args) {
- $args = \func_get_args();
- });
-
- $handler->handleException($exception);
-
- $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]);
- $this->assertStringStartsWith("Attempted to load class \"IReallyReallyDoNotExistAnywhereInTheRepositoryISwear\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
- }
-
- /**
- * @expectedException \Exception
- */
- public function testCustomExceptionHandler()
- {
- $handler = new ErrorHandler();
- $handler->setExceptionHandler(function ($e) use ($handler) {
- $handler->handleException($e);
- });
-
- $handler->handleException(new \Exception());
- }
-
- /**
- * @dataProvider errorHandlerWhenLoggingProvider
- */
- public function testErrorHandlerWhenLogging($previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined)
- {
- try {
- if ($previousHandlerWasDefined) {
- set_error_handler('count');
- }
-
- $logger = $loggerSetsAnotherHandler ? new LoggerThatSetAnErrorHandler() : new NullLogger();
-
- $handler = ErrorHandler::register();
- $handler->setDefaultLogger($logger);
-
- if ($nextHandlerIsDefined) {
- $handler = ErrorHandlerThatUsesThePreviousOne::register();
- }
-
- @trigger_error('foo', E_USER_DEPRECATED);
- @trigger_error('bar', E_USER_DEPRECATED);
-
- $this->assertSame([$handler, 'handleError'], set_error_handler('var_dump'));
-
- if ($logger instanceof LoggerThatSetAnErrorHandler) {
- $this->assertCount(2, $logger->cleanLogs());
- }
-
- restore_error_handler();
-
- if ($previousHandlerWasDefined) {
- restore_error_handler();
- }
-
- if ($nextHandlerIsDefined) {
- restore_error_handler();
- }
- } finally {
- restore_error_handler();
- restore_exception_handler();
- }
- }
-
- public function errorHandlerWhenLoggingProvider()
- {
- foreach ([false, true] as $previousHandlerWasDefined) {
- foreach ([false, true] as $loggerSetsAnotherHandler) {
- foreach ([false, true] as $nextHandlerIsDefined) {
- yield [$previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined];
- }
- }
- }
- }
-}
diff --git a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php
deleted file mode 100644
index f18809a5a2278..0000000000000
--- a/src/Symfony/Component/Debug/Tests/Exception/FlattenExceptionTest.php
+++ /dev/null
@@ -1,391 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Tests\Exception;
-
-use PHPUnit\Framework\TestCase;
-use Symfony\Component\Debug\Exception\FatalThrowableError;
-use Symfony\Component\Debug\Exception\FlattenException;
-use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
-use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
-use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
-use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
-use Symfony\Component\HttpKernel\Exception\GoneHttpException;
-use Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException;
-use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
-use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
-use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException;
-use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
-use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
-use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
-use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
-
-/**
- * @group legacy
- */
-class FlattenExceptionTest extends TestCase
-{
- public function testStatusCode()
- {
- $flattened = FlattenException::create(new \RuntimeException(), 403);
- $this->assertEquals('403', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new \RuntimeException());
- $this->assertEquals('500', $flattened->getStatusCode());
-
- $flattened = FlattenException::createFromThrowable(new \DivisionByZeroError(), 403);
- $this->assertEquals('403', $flattened->getStatusCode());
-
- $flattened = FlattenException::createFromThrowable(new \DivisionByZeroError());
- $this->assertEquals('500', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new NotFoundHttpException());
- $this->assertEquals('404', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"'));
- $this->assertEquals('401', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new BadRequestHttpException());
- $this->assertEquals('400', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new NotAcceptableHttpException());
- $this->assertEquals('406', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new ConflictHttpException());
- $this->assertEquals('409', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST']));
- $this->assertEquals('405', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new AccessDeniedHttpException());
- $this->assertEquals('403', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new GoneHttpException());
- $this->assertEquals('410', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new LengthRequiredHttpException());
- $this->assertEquals('411', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new PreconditionFailedHttpException());
- $this->assertEquals('412', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new PreconditionRequiredHttpException());
- $this->assertEquals('428', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new ServiceUnavailableHttpException());
- $this->assertEquals('503', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new TooManyRequestsHttpException());
- $this->assertEquals('429', $flattened->getStatusCode());
-
- $flattened = FlattenException::create(new UnsupportedMediaTypeHttpException());
- $this->assertEquals('415', $flattened->getStatusCode());
-
- if (class_exists(SuspiciousOperationException::class)) {
- $flattened = FlattenException::create(new SuspiciousOperationException());
- $this->assertEquals('400', $flattened->getStatusCode());
- }
- }
-
- public function testHeadersForHttpException()
- {
- $flattened = FlattenException::create(new MethodNotAllowedHttpException(['POST']));
- $this->assertEquals(['Allow' => 'POST'], $flattened->getHeaders());
-
- $flattened = FlattenException::create(new UnauthorizedHttpException('Basic realm="My Realm"'));
- $this->assertEquals(['WWW-Authenticate' => 'Basic realm="My Realm"'], $flattened->getHeaders());
-
- $flattened = FlattenException::create(new ServiceUnavailableHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));
- $this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders());
-
- $flattened = FlattenException::create(new ServiceUnavailableHttpException(120));
- $this->assertEquals(['Retry-After' => 120], $flattened->getHeaders());
-
- $flattened = FlattenException::create(new TooManyRequestsHttpException('Fri, 31 Dec 1999 23:59:59 GMT'));
- $this->assertEquals(['Retry-After' => 'Fri, 31 Dec 1999 23:59:59 GMT'], $flattened->getHeaders());
-
- $flattened = FlattenException::create(new TooManyRequestsHttpException(120));
- $this->assertEquals(['Retry-After' => 120], $flattened->getHeaders());
- }
-
- /**
- * @dataProvider flattenDataProvider
- */
- public function testFlattenHttpException(\Throwable $exception)
- {
- $flattened = FlattenException::createFromThrowable($exception);
- $flattened2 = FlattenException::createFromThrowable($exception);
-
- $flattened->setPrevious($flattened2);
-
- $this->assertEquals($exception->getMessage(), $flattened->getMessage(), 'The message is copied from the original exception.');
- $this->assertEquals($exception->getCode(), $flattened->getCode(), 'The code is copied from the original exception.');
- $this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception');
- }
-
- public function testWrappedThrowable()
- {
- $exception = new FatalThrowableError(new \DivisionByZeroError('Ouch', 42));
- $flattened = FlattenException::create($exception);
-
- $this->assertSame('Ouch', $flattened->getMessage(), 'The message is copied from the original error.');
- $this->assertSame(42, $flattened->getCode(), 'The code is copied from the original error.');
- $this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error');
- }
-
- public function testThrowable()
- {
- $error = new \DivisionByZeroError('Ouch', 42);
- $flattened = FlattenException::createFromThrowable($error);
-
- $this->assertSame('Ouch', $flattened->getMessage(), 'The message is copied from the original error.');
- $this->assertSame(42, $flattened->getCode(), 'The code is copied from the original error.');
- $this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error');
- }
-
- /**
- * @dataProvider flattenDataProvider
- */
- public function testPrevious(\Throwable $exception)
- {
- $flattened = FlattenException::createFromThrowable($exception);
- $flattened2 = FlattenException::createFromThrowable($exception);
-
- $flattened->setPrevious($flattened2);
-
- $this->assertSame($flattened2, $flattened->getPrevious());
-
- $this->assertSame([$flattened2], $flattened->getAllPrevious());
- }
-
- public function testPreviousError()
- {
- $exception = new \Exception('test', 123, new \ParseError('Oh noes!', 42));
-
- $flattened = FlattenException::create($exception)->getPrevious();
-
- $this->assertEquals($flattened->getMessage(), 'Oh noes!', 'The message is copied from the original exception.');
- $this->assertEquals($flattened->getCode(), 42, 'The code is copied from the original exception.');
- $this->assertEquals($flattened->getClass(), 'ParseError', 'The class is set to the class of the original exception');
- }
-
- /**
- * @dataProvider flattenDataProvider
- */
- public function testLine(\Throwable $exception)
- {
- $flattened = FlattenException::createFromThrowable($exception);
- $this->assertSame($exception->getLine(), $flattened->getLine());
- }
-
- /**
- * @dataProvider flattenDataProvider
- */
- public function testFile(\Throwable $exception)
- {
- $flattened = FlattenException::createFromThrowable($exception);
- $this->assertSame($exception->getFile(), $flattened->getFile());
- }
-
- /**
- * @dataProvider flattenDataProvider
- */
- public function testToArray(\Throwable $exception, string $expectedClass)
- {
- $flattened = FlattenException::createFromThrowable($exception);
- $flattened->setTrace([], 'foo.php', 123);
-
- $this->assertEquals([
- [
- 'message' => 'test',
- 'class' => $expectedClass,
- 'trace' => [[
- 'namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => 'foo.php', 'line' => 123,
- 'args' => [],
- ]],
- ],
- ], $flattened->toArray());
- }
-
- public function testCreate()
- {
- $exception = new NotFoundHttpException(
- 'test',
- new \RuntimeException('previous', 123)
- );
-
- $this->assertSame(
- FlattenException::createFromThrowable($exception)->toArray(),
- FlattenException::create($exception)->toArray()
- );
- }
-
- public function flattenDataProvider()
- {
- return [
- [new \Exception('test', 123), 'Exception'],
- [new \Error('test', 123), 'Error'],
- ];
- }
-
- public function testArguments()
- {
- $dh = opendir(__DIR__);
- $fh = tmpfile();
-
- $incomplete = unserialize('O:14:"BogusTestClass":0:{}');
-
- $exception = $this->createException([
- (object) ['foo' => 1],
- new NotFoundHttpException(),
- $incomplete,
- $dh,
- $fh,
- function () {},
- [1, 2],
- ['foo' => 123],
- null,
- true,
- false,
- 0,
- 0.0,
- '0',
- '',
- INF,
- NAN,
- ]);
-
- $flattened = FlattenException::create($exception);
- $trace = $flattened->getTrace();
- $args = $trace[1]['args'];
- $array = $args[0][1];
-
- closedir($dh);
- fclose($fh);
-
- $i = 0;
- $this->assertSame(['object', 'stdClass'], $array[$i++]);
- $this->assertSame(['object', 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException'], $array[$i++]);
- $this->assertSame(['incomplete-object', 'BogusTestClass'], $array[$i++]);
- $this->assertSame(['resource', 'stream'], $array[$i++]);
- $this->assertSame(['resource', 'stream'], $array[$i++]);
-
- $args = $array[$i++];
- $this->assertSame($args[0], 'object');
- $this->assertTrue('Closure' === $args[1] || is_subclass_of($args[1], '\Closure'), 'Expect object class name to be Closure or a subclass of Closure.');
-
- $this->assertSame(['array', [['integer', 1], ['integer', 2]]], $array[$i++]);
- $this->assertSame(['array', ['foo' => ['integer', 123]]], $array[$i++]);
- $this->assertSame(['null', null], $array[$i++]);
- $this->assertSame(['boolean', true], $array[$i++]);
- $this->assertSame(['boolean', false], $array[$i++]);
- $this->assertSame(['integer', 0], $array[$i++]);
- $this->assertSame(['float', 0.0], $array[$i++]);
- $this->assertSame(['string', '0'], $array[$i++]);
- $this->assertSame(['string', ''], $array[$i++]);
- $this->assertSame(['float', INF], $array[$i++]);
-
- // assertEquals() does not like NAN values.
- $this->assertEquals($array[$i][0], 'float');
- $this->assertTrue(is_nan($array[$i++][1]));
- }
-
- public function testRecursionInArguments()
- {
- $a = null;
- $a = ['foo', [2, &$a]];
- $exception = $this->createException($a);
-
- $flattened = FlattenException::create($exception);
- $trace = $flattened->getTrace();
- $this->assertContains('*DEEP NESTED ARRAY*', serialize($trace));
- }
-
- public function testTooBigArray()
- {
- $a = [];
- for ($i = 0; $i < 20; ++$i) {
- for ($j = 0; $j < 50; ++$j) {
- for ($k = 0; $k < 10; ++$k) {
- $a[$i][$j][$k] = 'value';
- }
- }
- }
- $a[20] = 'value';
- $a[21] = 'value1';
- $exception = $this->createException($a);
-
- $flattened = FlattenException::create($exception);
- $trace = $flattened->getTrace();
-
- $this->assertSame($trace[1]['args'][0], ['array', ['array', '*SKIPPED over 10000 entries*']]);
-
- $serializeTrace = serialize($trace);
-
- $this->assertContains('*SKIPPED over 10000 entries*', $serializeTrace);
- $this->assertNotContains('*value1*', $serializeTrace);
- }
-
- public function testAnonymousClass()
- {
- $flattened = FlattenException::create(new class() extends \RuntimeException {
- });
-
- $this->assertSame('RuntimeException@anonymous', $flattened->getClass());
-
- $flattened = FlattenException::create(new \Exception(sprintf('Class "%s" blah.', \get_class(new class() extends \RuntimeException {
- }))));
-
- $this->assertSame('Class "RuntimeException@anonymous" blah.', $flattened->getMessage());
- }
-
- public function testToStringEmptyMessage()
- {
- $exception = new \RuntimeException();
-
- $flattened = FlattenException::create($exception);
-
- $this->assertSame($exception->getTraceAsString(), $flattened->getTraceAsString());
- $this->assertSame($exception->__toString(), $flattened->getAsString());
- }
-
- public function testToString()
- {
- $test = function ($a, $b, $c, $d) {
- return new \RuntimeException('This is a test message');
- };
-
- $exception = $test('foo123', 1, null, 1.5);
-
- $flattened = FlattenException::create($exception);
-
- $this->assertSame($exception->getTraceAsString(), $flattened->getTraceAsString());
- $this->assertSame($exception->__toString(), $flattened->getAsString());
- }
-
- public function testToStringParent()
- {
- $exception = new \LogicException('This is message 1');
- $exception = new \RuntimeException('This is messsage 2', 500, $exception);
-
- $flattened = FlattenException::create($exception);
-
- $this->assertSame($exception->getTraceAsString(), $flattened->getTraceAsString());
- $this->assertSame($exception->__toString(), $flattened->getAsString());
- }
-
- private function createException($foo)
- {
- return new \Exception();
- }
-}
diff --git a/src/Symfony/Component/Debug/Tests/ExceptionHandlerTest.php b/src/Symfony/Component/Debug/Tests/ExceptionHandlerTest.php
deleted file mode 100644
index 0bfb680d9bba0..0000000000000
--- a/src/Symfony/Component/Debug/Tests/ExceptionHandlerTest.php
+++ /dev/null
@@ -1,148 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Tests;
-
-use PHPUnit\Framework\TestCase;
-use Symfony\Component\Debug\Exception\OutOfMemoryException;
-use Symfony\Component\Debug\ExceptionHandler;
-use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-
-require_once __DIR__.'/HeaderMock.php';
-
-/**
- * @group legacy
- */
-class ExceptionHandlerTest extends TestCase
-{
- protected function setUp()
- {
- testHeader();
- }
-
- protected function tearDown()
- {
- testHeader();
- }
-
- /**
- * @group legacy
- */
- public function testDebug()
- {
- $handler = new ExceptionHandler(false);
-
- ob_start();
- $handler->sendPhpResponse(new \RuntimeException('Foo'));
- $response = ob_get_clean();
-
- $this->assertContains('Whoops, looks like something went wrong.', $response);
- $this->assertNotContains('
', $response);
-
- $handler = new ExceptionHandler(true);
-
- ob_start();
- $handler->sendPhpResponse(new \RuntimeException('Foo'));
- $response = ob_get_clean();
-
- $this->assertContains('
Foo
', $response);
- $this->assertContains('
', $response);
-
- // taken from https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
- $htmlWithXss = '
click me!
';
- ob_start();
- $handler->sendPhpResponse(new \RuntimeException($htmlWithXss));
- $response = ob_get_clean();
-
- $this->assertContains(sprintf('
%s
', htmlspecialchars($htmlWithXss, ENT_COMPAT | ENT_SUBSTITUTE, 'UTF-8')), $response);
- }
-
- public function testStatusCode()
- {
- $handler = new ExceptionHandler(false, 'iso8859-1');
-
- ob_start();
- $handler->sendPhpResponse(new NotFoundHttpException('Foo'));
- $response = ob_get_clean();
-
- $this->assertContains('Sorry, the page you are looking for could not be found.', $response);
-
- $expectedHeaders = [
- ['HTTP/1.0 404', true, null],
- ['Content-Type: text/html; charset=iso8859-1', true, null],
- ];
-
- $this->assertSame($expectedHeaders, testHeader());
- }
-
- public function testHeaders()
- {
- $handler = new ExceptionHandler(false, 'iso8859-1');
-
- ob_start();
- $handler->sendPhpResponse(new MethodNotAllowedHttpException(['POST']));
- $response = ob_get_clean();
-
- $expectedHeaders = [
- ['HTTP/1.0 405', true, null],
- ['Allow: POST', false, null],
- ['Content-Type: text/html; charset=iso8859-1', true, null],
- ];
-
- $this->assertSame($expectedHeaders, testHeader());
- }
-
- public function testNestedExceptions()
- {
- $handler = new ExceptionHandler(true);
- ob_start();
- $handler->sendPhpResponse(new \RuntimeException('Foo', 0, new \RuntimeException('Bar')));
- $response = ob_get_clean();
-
- $this->assertStringMatchesFormat('%A
Foo
%A
Bar
%A', $response);
- }
-
- public function testHandle()
- {
- $exception = new \Exception('foo');
-
- $handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(['sendPhpResponse'])->getMock();
- $handler
- ->expects($this->exactly(2))
- ->method('sendPhpResponse');
-
- $handler->handle($exception);
-
- $handler->setHandler(function ($e) use ($exception) {
- $this->assertSame($exception, $e);
- });
-
- $handler->handle($exception);
- }
-
- public function testHandleOutOfMemoryException()
- {
- $exception = new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__);
-
- $handler = $this->getMockBuilder('Symfony\Component\Debug\ExceptionHandler')->setMethods(['sendPhpResponse'])->getMock();
- $handler
- ->expects($this->once())
- ->method('sendPhpResponse');
-
- $handler->setHandler(function ($e) {
- $this->fail('OutOfMemoryException should bypass the handler');
- });
-
- $handler->handle($exception);
- }
-}
diff --git a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php
deleted file mode 100644
index 498fafd47cd04..0000000000000
--- a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/ClassNotFoundFatalErrorHandlerTest.php
+++ /dev/null
@@ -1,183 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Tests\FatalErrorHandler;
-
-use Composer\Autoload\ClassLoader as ComposerClassLoader;
-use PHPUnit\Framework\TestCase;
-use Symfony\Component\Debug\DebugClassLoader;
-use Symfony\Component\Debug\Exception\FatalErrorException;
-use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
-
-/**
- * @group legacy
- */
-class ClassNotFoundFatalErrorHandlerTest extends TestCase
-{
- public static function setUpBeforeClass()
- {
- foreach (spl_autoload_functions() as $function) {
- if (!\is_array($function)) {
- continue;
- }
-
- // get class loaders wrapped by DebugClassLoader
- if ($function[0] instanceof DebugClassLoader) {
- $function = $function[0]->getClassLoader();
- }
-
- if ($function[0] instanceof ComposerClassLoader) {
- $function[0]->add('Symfony_Component_Debug_Tests_Fixtures', \dirname(\dirname(\dirname(\dirname(\dirname(__DIR__))))));
- break;
- }
- }
- }
-
- /**
- * @dataProvider provideClassNotFoundData
- */
- 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());
- $this->assertSame($error['file'], $exception->getFile());
- $this->assertSame($error['line'], $exception->getLine());
- }
-
- public function provideClassNotFoundData()
- {
- $autoloader = new ComposerClassLoader();
- $autoloader->add('Symfony\Component\Debug\Exception\\', realpath(__DIR__.'/../../Exception'));
- $autoloader->add('Symfony_Component_Debug_Tests_Fixtures', realpath(__DIR__.'/../../Tests/Fixtures'));
-
- $debugClassLoader = new DebugClassLoader([$autoloader, 'loadClass']);
-
- return [
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'WhizBangFactory\' not found',
- ],
- "Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?",
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'Foo\\Bar\\WhizBangFactory\' not found',
- ],
- "Attempted to load class \"WhizBangFactory\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'UndefinedFunctionException\' not found',
- ],
- "Attempted to load class \"UndefinedFunctionException\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
- [$debugClassLoader, 'loadClass'],
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'PEARClass\' not found',
- ],
- "Attempted to load class \"PEARClass\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony_Component_Debug_Tests_Fixtures_PEARClass\"?",
- [$debugClassLoader, 'loadClass'],
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
- ],
- "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
- [$debugClassLoader, 'loadClass'],
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
- ],
- "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
- [$autoloader, 'loadClass'],
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
- ],
- "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\Bar\".\nDid you forget a \"use\" statement for \"Symfony\Component\Debug\Exception\UndefinedFunctionException\"?",
- [$debugClassLoader, 'loadClass'],
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'Foo\\Bar\\UndefinedFunctionException\' not found',
- ],
- "Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\\Bar\".\nDid you forget a \"use\" statement for another namespace?",
- function ($className) { /* do nothing here */ },
- ],
- ];
- }
-
- public function testCannotRedeclareClass()
- {
- if (!file_exists(__DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP')) {
- $this->markTestSkipped('Can only be run on case insensitive filesystems');
- }
-
- require_once __DIR__.'/../FIXTURES2/REQUIREDTWICE.PHP';
-
- $error = [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Class \'Foo\\Bar\\RequiredTwice\' not found',
- ];
-
- $handler = new ClassNotFoundFatalErrorHandler();
- $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));
-
- $this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
- }
-}
diff --git a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php
deleted file mode 100644
index b827c4c67aebb..0000000000000
--- a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/UndefinedFunctionFatalErrorHandlerTest.php
+++ /dev/null
@@ -1,84 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Tests\FatalErrorHandler;
-
-use PHPUnit\Framework\TestCase;
-use Symfony\Component\Debug\Exception\FatalErrorException;
-use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
-
-/**
- * @group legacy
- */
-class UndefinedFunctionFatalErrorHandlerTest extends TestCase
-{
- /**
- * @dataProvider provideUndefinedFunctionData
- */
- public function testUndefinedFunction($error, $translatedMessage)
- {
- $handler = new UndefinedFunctionFatalErrorHandler();
- $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));
-
- $this->assertInstanceOf('Symfony\Component\Debug\Exception\UndefinedFunctionException', $exception);
- // class names are case insensitive and PHP do not return the same
- $this->assertSame(strtolower($translatedMessage), strtolower($exception->getMessage()));
- $this->assertSame($error['type'], $exception->getSeverity());
- $this->assertSame($error['file'], $exception->getFile());
- $this->assertSame($error['line'], $exception->getLine());
- }
-
- public function provideUndefinedFunctionData()
- {
- return [
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Call to undefined function test_namespaced_function()',
- ],
- "Attempted to call function \"test_namespaced_function\" from the global namespace.\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Call to undefined function Foo\\Bar\\Baz\\test_namespaced_function()',
- ],
- "Attempted to call function \"test_namespaced_function\" from namespace \"Foo\\Bar\\Baz\".\nDid you mean to call \"\\symfony\\component\\debug\\tests\\fatalerrorhandler\\test_namespaced_function\"?",
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Call to undefined function foo()',
- ],
- 'Attempted to call function "foo" from the global namespace.',
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Call to undefined function Foo\\Bar\\Baz\\foo()',
- ],
- 'Attempted to call function "foo" from namespace "Foo\Bar\Baz".',
- ],
- ];
- }
-}
-
-function test_namespaced_function()
-{
-}
diff --git a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php
deleted file mode 100644
index 7ea1b1f95e786..0000000000000
--- a/src/Symfony/Component/Debug/Tests/FatalErrorHandler/UndefinedMethodFatalErrorHandlerTest.php
+++ /dev/null
@@ -1,79 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Tests\FatalErrorHandler;
-
-use PHPUnit\Framework\TestCase;
-use Symfony\Component\Debug\Exception\FatalErrorException;
-use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
-
-/**
- * @group legacy
- */
-class UndefinedMethodFatalErrorHandlerTest extends TestCase
-{
- /**
- * @dataProvider provideUndefinedMethodData
- */
- public function testUndefinedMethod($error, $translatedMessage)
- {
- $handler = new UndefinedMethodFatalErrorHandler();
- $exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));
-
- $this->assertInstanceOf('Symfony\Component\Debug\Exception\UndefinedMethodException', $exception);
- $this->assertSame($translatedMessage, $exception->getMessage());
- $this->assertSame($error['type'], $exception->getSeverity());
- $this->assertSame($error['file'], $exception->getFile());
- $this->assertSame($error['line'], $exception->getLine());
- }
-
- public function provideUndefinedMethodData()
- {
- return [
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Call to undefined method SplObjectStorage::what()',
- ],
- 'Attempted to call an undefined method named "what" of class "SplObjectStorage".',
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Call to undefined method SplObjectStorage::walid()',
- ],
- "Attempted to call an undefined method named \"walid\" of class \"SplObjectStorage\".\nDid you mean to call \"valid\"?",
- ],
- [
- [
- 'type' => 1,
- 'line' => 12,
- 'file' => 'foo.php',
- 'message' => 'Call to undefined method SplObjectStorage::offsetFet()',
- ],
- "Attempted to call an undefined method named \"offsetFet\" of class \"SplObjectStorage\".\nDid you mean to call e.g. \"offsetGet\", \"offsetSet\" or \"offsetUnset\"?",
- ],
- [
- [
- 'type' => 1,
- 'message' => 'Call to undefined method class@anonymous::test()',
- 'file' => '/home/possum/work/symfony/test.php',
- 'line' => 11,
- ],
- 'Attempted to call an undefined method named "test" of class "class@anonymous".',
- ],
- ];
- }
-}
diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/AnnotatedClass.php b/src/Symfony/Component/Debug/Tests/Fixtures/AnnotatedClass.php
deleted file mode 100644
index 4eecb6d3f1668..0000000000000
--- a/src/Symfony/Component/Debug/Tests/Fixtures/AnnotatedClass.php
+++ /dev/null
@@ -1,13 +0,0 @@
-exception = $e;
- }
-
- public function __toString()
- {
- try {
- throw $this->exception;
- } catch (\Exception $e) {
- // Using user_error() here is on purpose so we do not forget
- // that this alias also should work alongside with trigger_error().
- return trigger_error($e, E_USER_ERROR);
- }
- }
-}
diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/TraitWithAnnotatedParameters.php b/src/Symfony/Component/Debug/Tests/Fixtures/TraitWithAnnotatedParameters.php
deleted file mode 100644
index 5eb5fbf84bc93..0000000000000
--- a/src/Symfony/Component/Debug/Tests/Fixtures/TraitWithAnnotatedParameters.php
+++ /dev/null
@@ -1,13 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug;
-
-function headers_sent()
-{
- return false;
-}
-
-function header($str, $replace = true, $status = null)
-{
- Tests\testHeader($str, $replace, $status);
-}
-
-namespace Symfony\Component\Debug\Tests;
-
-function testHeader()
-{
- static $headers = [];
-
- if (!$h = \func_get_args()) {
- $h = $headers;
- $headers = [];
-
- return $h;
- }
-
- $headers[] = \func_get_args();
-}
diff --git a/src/Symfony/Component/Debug/Tests/MockExceptionHandler.php b/src/Symfony/Component/Debug/Tests/MockExceptionHandler.php
deleted file mode 100644
index 2d6ce564d23a4..0000000000000
--- a/src/Symfony/Component/Debug/Tests/MockExceptionHandler.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\Debug\Tests;
-
-use Symfony\Component\Debug\ExceptionHandler;
-
-class MockExceptionHandler extends ExceptionHandler
-{
- public $e;
-
- public function handle(\Exception $e)
- {
- $this->e = $e;
- }
-}
diff --git a/src/Symfony/Component/Debug/Tests/phpt/debug_class_loader.phpt b/src/Symfony/Component/Debug/Tests/phpt/debug_class_loader.phpt
deleted file mode 100644
index 041affc14df65..0000000000000
--- a/src/Symfony/Component/Debug/Tests/phpt/debug_class_loader.phpt
+++ /dev/null
@@ -1,28 +0,0 @@
---TEST--
-Test DebugClassLoader with previously loaded parents
---FILE--
-
---EXPECTF--
-%A
-The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".
-The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".
diff --git a/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt b/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt
deleted file mode 100644
index 25167a2c6aaee..0000000000000
--- a/src/Symfony/Component/Debug/Tests/phpt/decorate_exception_hander.phpt
+++ /dev/null
@@ -1,48 +0,0 @@
---TEST--
-Test catching fatal errors when handlers are nested
---INI--
-display_errors=0
---FILE--
-
---EXPECTF--
-%A
-object(Symfony\Component\Debug\Exception\ClassNotFoundException)#%d (8) {
- ["message":protected]=>
- string(131) "Attempted to load class "missing" from namespace "Symfony\Component\Debug".
-Did you forget a "use" statement for another namespace?"
- ["string":"Exception":private]=>
- string(0) ""
- ["code":protected]=>
- int(0)
- ["file":protected]=>
- string(%d) "%s"
- ["line":protected]=>
- int(%d)
- ["trace":"Exception":private]=>
- array(%d) {%A}
- ["previous":"Exception":private]=>
- NULL
- ["severity":protected]=>
- int(1)
-}
diff --git a/src/Symfony/Component/Debug/Tests/phpt/exception_rethrown.phpt b/src/Symfony/Component/Debug/Tests/phpt/exception_rethrown.phpt
deleted file mode 100644
index b743d93ad7c80..0000000000000
--- a/src/Symfony/Component/Debug/Tests/phpt/exception_rethrown.phpt
+++ /dev/null
@@ -1,35 +0,0 @@
---TEST--
-Test rethrowing in custom exception handler
---FILE--
-setDefaultLogger(new TestLogger());
-ini_set('display_errors', 1);
-
-throw new \Exception('foo');
-?>
---EXPECTF--
-Uncaught Exception: foo
-123
-Fatal error: Uncaught %s:25
-Stack trace:
-%a
diff --git a/src/Symfony/Component/Debug/Tests/phpt/fatal_with_nested_handlers.phpt b/src/Symfony/Component/Debug/Tests/phpt/fatal_with_nested_handlers.phpt
deleted file mode 100644
index d0fa2411e6bd9..0000000000000
--- a/src/Symfony/Component/Debug/Tests/phpt/fatal_with_nested_handlers.phpt
+++ /dev/null
@@ -1,43 +0,0 @@
---TEST--
-Test catching fatal errors when handlers are nested
---FILE--
-setExceptionHandler('print_r');
-
-if (true) {
- class Broken implements \JsonSerializable
- {
- }
-}
-
-?>
---EXPECTF--
-array(1) {
- [0]=>
- string(37) "Error and exception handlers do match"
-}
-%A
-object(Symfony\Component\Debug\Exception\FatalErrorException)#%d (%d) {
- ["message":protected]=>
- string(179) "Error: Class Symfony\Component\Debug\Broken contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (JsonSerializable::jsonSerialize)"
-%a
-}
diff --git a/src/Symfony/Component/Debug/composer.json b/src/Symfony/Component/Debug/composer.json
deleted file mode 100644
index 1f977bad7d373..0000000000000
--- a/src/Symfony/Component/Debug/composer.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "name": "symfony/debug",
- "type": "library",
- "description": "Symfony Debug Component",
- "keywords": [],
- "homepage": "https://symfony.com",
- "license": "MIT",
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "require": {
- "php": "^7.2.9",
- "psr/log": "~1.0"
- },
- "conflict": {
- "symfony/http-kernel": "<4.4"
- },
- "require-dev": {
- "symfony/http-kernel": "^4.4|^5.0"
- },
- "autoload": {
- "psr-4": { "Symfony\\Component\\Debug\\": "" },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "minimum-stability": "dev",
- "extra": {
- "branch-alias": {
- "dev-master": "5.0-dev"
- }
- }
-}
diff --git a/src/Symfony/Component/Debug/phpunit.xml.dist b/src/Symfony/Component/Debug/phpunit.xml.dist
deleted file mode 100644
index a51bbff935861..0000000000000
--- a/src/Symfony/Component/Debug/phpunit.xml.dist
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
- ./Tests/
-
-
- ./Resources/ext/tests/
-
-
-
-
-
- ./
-
- ./Tests
- ./vendor
-
-
-
-