Compare commits

...

61 Commits

Author SHA1 Message Date
Alessandro Lai
45b2136377 Avoid warning with Xdebug 3 with develop mode disabled 2021-04-02 09:50:12 +02:00
Jérôme Deuchnord
157bbec4fd [ErrorHandler] Fix strpos error when trying to call a method without a name 2021-01-28 17:54:48 +01:00
Oskar Stark
af4987aa4a Use createMock() and use import instead of FQCN 2021-01-27 10:09:26 +01:00
Fabien Potencier
edfa86f186 Use ::class keyword when possible 2021-01-11 09:57:50 +01:00
Fabien Potencier
462dbe3a63 minor #39775 [WIP] Use ::class keyword when possible (fabpot)
This PR was merged into the 4.4 branch.

Discussion
----------

[WIP] Use ::class keyword when possible

| Q             | A
| ------------- | ---
| Branch?       | 4.4 <!-- see below -->
| Bug fix?      | no
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | n/a  <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT
| Doc PR        | n/a

Commits
-------

036a36cb14 Use ::class keyword when possible
2021-01-11 07:02:33 +01:00
Fabien Potencier
84de62e42e Use ::class keyword when possible 2021-01-10 17:45:22 +01:00
Fabien Potencier
7f265ded6f Improve composer.json descriptions 2021-01-10 17:25:35 +01:00
Fabien Potencier
ebcaaad20c Bump license year 2021-01-01 10:24:35 +01:00
Alexander M. Turek
5768cc007b CS: Apply ternary_to_null_coalescing fixer 2020-12-27 00:49:32 +01:00
Jérémy Derussé
5dfc7825f3 Fix CS in changelogs 2020-12-10 17:34:26 +01:00
Alexander M. Turek
65fe7b4986 Use short array deconstruction syntax. 2020-10-28 21:42:29 +01:00
Nicolas Grekas
c87adf3fc1 Merge branch '3.4' into 4.4
* 3.4:
  Remove branch-version (keep them for contracts only)
  [Serializer] fix decoding float XML attributes starting with 0
  add missing dutch translations
  [Validator] Add missing romanian translations
  do not translate null placeholders or titles
2020-10-24 13:50:19 +02:00
Nicolas Grekas
ab42889de5 Remove branch-version (keep them for contracts only) 2020-10-24 12:57:07 +02:00
Nicolas Grekas
ba95c0aa9b Merge branch '3.4' into 4.4
* 3.4:
  Fix branch-version
2020-10-13 15:20:53 +02:00
Nicolas Grekas
bfcf449c91 Fix branch-version 2020-10-13 15:20:16 +02:00
Nicolas Grekas
5a40526df8 Merge branch '3.4' into 4.4
* 3.4:
  Remove "version" from composer.json files, use "branch-version" instead
2020-10-13 14:30:56 +02:00
Nicolas Grekas
90c931ffd0 Remove "version" from composer.json files, use "branch-version" instead 2020-10-13 14:21:16 +02:00
Nicolas Grekas
888525fe28 Merge branch '3.4' into 4.4
* 3.4:
  Update versions in composer.json
2020-10-06 17:45:41 +02:00
Nicolas Grekas
34a8785ac1 Update versions in composer.json 2020-10-06 17:25:25 +02:00
Nicolas Grekas
434a1f80c9 Merge branch '3.4' into 4.4
* 3.4:
  Remove "branch-alias", populate "version"
2020-10-06 13:41:17 +02:00
Nicolas Grekas
0a7f96d51e Remove "branch-alias", populate "version" 2020-10-06 13:22:52 +02:00
Fabien Potencier
726b85e693 Remove some leftover for HHVM support 2020-09-09 07:20:36 +02:00
Alexander M. Turek
9109e4414e [Debug] Skip a test that was meant for HHVM. 2020-09-09 00:19:14 +02:00
Nicolas Grekas
4bbe6b724d [Debug] fix merge 2020-09-08 16:30:03 +02:00
Christian Flothmann
2be6712492 [Debug] fix test 2020-09-08 15:04:06 +02:00
Christian Flothmann
0bce050543 Merge branch '3.4' into 4.4
* 3.4:
  Prevent parsing invalid octal digits as octal numbers
  [DI] fix ContainerBuilder on PHP8
  [Console] Make sure $maxAttempts is an int or null.
  [VarDumper] Fix caster for invalid SplFileInfo objects on php 8.
  [Intl] Skip test cases that produce a TypeError on php 8.
  [PhpUnitBridge] Adjust output parsing for PHPUnit 9.3.
  [PhpUnitBridge] CoverageListenerTrait update for PHPUnit 8.5/9.x
  add bosnian (bs) translation
  [Debug] Parse "x not found" errors correctly on php 8.
2020-09-08 13:16:46 +02:00
Alexander M. Turek
5422b88cf9 [Debug] Parse "x not found" errors correctly on php 8. 2020-09-04 00:12:04 +02:00
Nicolas Grekas
bd7b1cba1f Merge branch '3.4' into 4.4
* 3.4:
  Enable "native_constant_invocation" CS rule
  Make AbstractPhpFileCacheWarmer public
2020-09-02 18:08:58 +02:00
Nicolas Grekas
093e4e512f Enable "native_constant_invocation" CS rule 2020-09-02 18:06:40 +02:00
Fabien Potencier
aeb73aca16 Fix typo 2020-08-10 09:47:39 +02:00
Fabien Potencier
600aa0e19e Merge branch '3.4' into 4.4
* 3.4:
  Add Tagalog translations for validator messages 94, 95, 96 and 99
  PHPUnit's assertContains() performs strict comparisons now.
  [ClassLoader][Routing] Fix namespace parsing on php 8.
  Fix deprecated libxml_disable_entity_loader
  Made reference to PHPUnit\Util\XML::loadfile php5-compatible.
  [Validator] Add missing translations for german and vietnamese
  Modernized deprecated PHPUnit assertion calls
  [Console] The message of "class not found" errors has changed in php 8.
  The PHPUnit\Util\XML class has been removed in PHPUnit 9.3.
  [Console] Make sure we pass a numeric array of arguments to call_user_func_array().
  [Serializer] Fix that it will never reach DOMNode
  [Validator] sync translations
  [VarDumper] Improve previous fix on light array coloration
  [Cache] Fix #37667
2020-08-10 09:27:51 +02:00
Alexander M. Turek
0893a0b07c Modernized deprecated PHPUnit assertion calls 2020-08-09 10:13:48 +02:00
Nicolas Grekas
47aa9064d7 Merge branch '3.4' into 4.4
* 3.4:
  [Cache] fix catching auth errors
  Fix CS
  [FrameworkBundle] set default session.handler alias if handler_id is not provided
  Fix CS
  Readability update
  Fix checks for phpunit releases on Composer 2 (resolves #37601)
  [SCA] Minor fixes on tests
2020-07-23 10:31:43 +02:00
Thomas Calvet
7ce874f443 [SCA] Minor fixes on tests 2020-07-16 11:41:49 +02:00
Nicolas Grekas
bd613a9662 Merge branch '3.4' into 4.4
* 3.4:
  [ErrorHandler] fix throwing from __toString()
  Removed comments and requirements relative to php <5.5 (not supported anymore)
  fix validating lazy properties that evaluate to null
2020-06-30 19:40:09 +02:00
Nicolas Grekas
f34d2bf035 [ErrorHandler] fix throwing from __toString() 2020-06-30 19:28:29 +02:00
Alexander M. Turek
28f92d08bb Parse and render anonymous classes correctly on php 8 2020-05-24 10:33:35 +02:00
Nicolas Grekas
8f904cac22 Merge branch '3.4' into 4.4
* 3.4:
  Skip Doctrine DBAL on php 8 until we have a compatible version.
  [DomCrawler] Catch expected ValueError.
  [Validator] Catch expected ValueError.
  [VarDumper] ReflectionFunction::isDisabled() is deprecated.
  [PropertyAccess] Parse php 8 TypeErrors correctly.
  [Intl] Fix call to ReflectionProperty::getValue() for static properties.
  [HttpKernel] Prevent calling method_exists() with non-string values.
  [Debug] php 8 does not pass $context to error handlers.
  [Config] Removed implicit cast of ReflectionProperty to string.
  [Debug] Undefined variables raise a warning in php 8.
  [Debug] Skip test that would trigger a fatal error on php 8.
  Address deprecation of ReflectionType::getClass().
  Properties $originalName and $mimeType are never null in UploadedFile
2020-05-23 11:11:46 +02:00
Nicolas Grekas
518c6a00d0 minor #36898 [Debug] php 8 does not pass $context to error handlers (derrabus)
This PR was merged into the 3.4 branch.

Discussion
----------

[Debug] php 8 does not pass $context to error handlers

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #36872
| License       | MIT
| Doc PR        | N/A

php 8 will call error handlers without the optional `$context` parameter. Thus, error handlers that make that parameter mandatory will break.

Commits
-------

593897c9e1 [Debug] php 8 does not pass $context to error handlers.
2020-05-22 20:25:20 +02:00
Alexander M. Turek
2560754c36 [Debug] php 8 does not pass $context to error handlers. 2020-05-22 13:12:29 +02:00
Alexander M. Turek
44897cd605 [Debug] Undefined variables raise a warning in php 8. 2020-05-22 12:23:23 +02:00
Alexander M. Turek
7e9cd457b4 [Debug] Skip test that would trigger a fatal error on php 8. 2020-05-21 16:02:48 +02:00
Nicolas Grekas
6aa62a36bc Use ">=" for the "php" requirement 2020-05-20 10:37:50 +02:00
Nicolas Grekas
4431584a89 [Debug][ErrorHandler] cleanup phpunit.xml.dist files 2020-05-01 18:55:10 +02:00
Tobias Schultze
346636d2ca add missing gitattributes for phpunit-bridge 2020-03-27 17:54:36 +01:00
Nicolas Grekas
f0ae2b4150 Merge branch '3.4' into 4.4
* 3.4:
  [Http Foundation] Fix clear cookie samesite
  [Security] Check if firewall is stateless before checking for session/previous session
  [Form] Support customized intl php.ini settings
  [Security] Remember me: allow to set the samesite cookie flag
  [Debug] fix for PHP 7.3.16+/7.4.4+
  [Validator] Backport translations
  Prevent warning in proc_open()
2020-03-23 13:37:11 +01:00
Nicolas Grekas
ce9f3b5e8e [Debug] fix for PHP 7.3.16+/7.4.4+ 2020-03-23 11:22:40 +01:00
Fabien Potencier
f9385709e7 Merge branch '3.4' into 4.4
* 3.4:
  Add missing dots at the end of exception messages
2020-03-15 11:05:03 +01:00
Fabien Potencier
ed3231ef38 Add missing dots at the end of exception messages 2020-03-15 10:38:08 +01:00
Jules Pietri
a980d87a65 [Debug][ErrorHandler] improved deprecation notices for methods new args and return type 2020-02-23 15:41:43 +01:00
Fabien Potencier
ef8d82f96d Merge branch '3.4' into 4.4
* 3.4:
  [Translation] Add missing use statement
  [Translation][Debug] Add installation and minimal example to README
  [Validator] try to call __get method if property is uninitialized
  Fix handling of empty_data's \Closure value in Date/Time form types
2020-02-04 08:40:16 +01:00
Wouter de Jong
a99278d50a [Translation][Debug] Add installation and minimal example to README 2020-02-03 16:10:40 +01:00
Nicolas Grekas
2023647105 Merge branch '4.3' into 4.4
* 4.3:
  Fix displaying anonymous classes on PHP >= 7.4.2
2020-01-25 13:44:29 +01:00
Nicolas Grekas
8e36299635 Fix displaying anonymous classes on PHP >= 7.4.2 2020-01-25 13:32:28 +01:00
Nicolas Grekas
89c3fd5c29 Merge branch '4.3' into 4.4
* 4.3:
  [Debug] fix ClassNotFoundFatalErrorHandler
  [Routing] Fix using a custom matcher & generator dumper class
  [Dotenv] Fixed infinite loop with missing quote followed by quoted value
  [HttpClient] Added missing sprintf
  [TwigBridge] button_widget now has its title attr translated even if its label = null or false
  [PhpUnitBridge] When using phpenv + phpenv-composer plugin, composer executable is wrapped into a bash script
  [Messenger] Added check if json_encode succeeded
  [Security] Prevent canceled remember-me cookie from being accepted
  [FrameworkBundle][TranslationUpdateCommand] Do not output positive feedback on stderr
  [Security\Guard] Fix missing typehints
2020-01-08 18:29:02 +01:00
Nicolas Grekas
1eff904a95 Merge branch '3.4' into 4.3
* 3.4:
  [Debug] fix ClassNotFoundFatalErrorHandler
  [Dotenv] Fixed infinite loop with missing quote followed by quoted value
  [TwigBridge] button_widget now has its title attr translated even if its label = null or false
  [PhpUnitBridge] When using phpenv + phpenv-composer plugin, composer executable is wrapped into a bash script
  [Security] Prevent canceled remember-me cookie from being accepted
  [FrameworkBundle][TranslationUpdateCommand] Do not output positive feedback on stderr
2020-01-08 18:19:22 +01:00
Nicolas Grekas
70dd18e93b [Debug] fix ClassNotFoundFatalErrorHandler 2020-01-08 17:36:15 +01:00
Nicolas Grekas
bb2ab8bc2d Merge branch '4.3' into 4.4
* 4.3:
  [Mailer] Remove line breaks in email attachment content
  Update links to documentation
  [Validator] Add the missing translations for the Arabic (ar) locale
  ensure to expect no validation for the right reasons
  [PhpUnitBridge] Add test case for @expectedDeprecation annotation
  [PhpUnitBridge][SymfonyTestsListenerTrait] Remove $testsWithWarnings stack
  [Mailer][MailchimpBridge] Fix missing attachments when sending via Mandrill API
  [Mailer][MailchimpBridge] Fix incorrect sender address when sender has name
  [HttpClient] fix capturing SSL certificates with NativeHttpClient
  [TwigBridge][Form] Added missing help messages in form themes
  Update year in license files
  Update year in license files
  [HttpClient] fix typo
  [Console][FormatterHelper] Use helper strlen statically and remove duplicated code
  [Routing] Fix i18n routing when the url contains the locale
  Fix BC issue in phpDoc Reflection library
  [Translator] Performance improvement in MessageCatalogue and catalogue operations.
2020-01-04 14:00:46 +01:00
Nicolas Grekas
e45fa0c74a Merge branch '3.4' into 4.3
* 3.4:
  Update links to documentation
  [Validator] Add the missing translations for the Arabic (ar) locale
  ensure to expect no validation for the right reasons
  [PhpUnitBridge] Add test case for @expectedDeprecation annotation
  Update year in license files
  [Console][FormatterHelper] Use helper strlen statically and remove duplicated code
  Fix BC issue in phpDoc Reflection library
  [Translator] Performance improvement in MessageCatalogue and catalogue operations.
2020-01-04 13:24:57 +01:00
Shaharia Azam
9a81b6360b Update links to documentation 2020-01-04 13:05:51 +01:00
Jan Rosier
cbe127b719 Update year in license files 2020-01-01 12:03:25 +01:00
31 changed files with 370 additions and 297 deletions

1
.gitattributes vendored
View File

@@ -1,3 +1,4 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore

View File

@@ -13,7 +13,7 @@ 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);
@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.

View File

@@ -10,67 +10,66 @@ CHANGELOG
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
* 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`
* removed the symfony_debug extension
* removed `ContextErrorException`
3.4.0
-----
* deprecated `ErrorHandler::stackErrors()` and `ErrorHandler::unstackErrors()`
* deprecated `ErrorHandler::stackErrors()` and `ErrorHandler::unstackErrors()`
3.3.0
-----
* deprecated the `ContextErrorException` class: use \ErrorException directly now
* deprecated the `ContextErrorException` class: use \ErrorException directly now
3.2.0
-----
* `FlattenException::getTrace()` now returns additional type descriptions
`integer` and `float`.
* `FlattenException::getTrace()` now returns additional type descriptions
`integer` and `float`.
3.0.0
-----
* removed classes, methods and interfaces deprecated in 2.x
* 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
* 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
* 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
* 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
* added ExceptionHandler::setHandler()
* added UndefinedMethodFatalErrorHandler
* deprecated DummyException
2.4.0
-----

View File

@@ -11,7 +11,7 @@
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);
@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.
@@ -32,7 +32,7 @@ class Debug
* @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)
public static function enable($errorReportingLevel = \E_ALL, $displayErrors = true)
{
if (static::$enabled) {
return;
@@ -43,13 +43,13 @@ class Debug
if (null !== $errorReportingLevel) {
error_reporting($errorReportingLevel);
} else {
error_reporting(E_ALL);
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'))) {
} 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);
}

View File

@@ -13,7 +13,7 @@ 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);
@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.
@@ -64,7 +64,7 @@ class DebugClassLoader
} 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')) {
} 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 {
@@ -90,8 +90,8 @@ class DebugClassLoader
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');
class_exists(\Symfony\Component\Debug\ErrorHandler::class);
class_exists(\Psr\Log\LogLevel::class);
if (!\is_array($functions = spl_autoload_functions())) {
return;
@@ -149,7 +149,7 @@ class DebugClassLoader
*/
public function loadClass($class)
{
$e = error_reporting(error_reporting() | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
$e = error_reporting(error_reporting() | \E_PARSE | \E_ERROR | \E_CORE_ERROR | \E_COMPILE_ERROR);
try {
if ($this->isFinder && !isset($this->loaded[$class])) {
@@ -201,7 +201,7 @@ class DebugClassLoader
$deprecations = $this->checkAnnotations($refl, $name);
foreach ($deprecations as $message) {
@trigger_error($message, E_USER_DEPRECATED);
@trigger_error($message, \E_USER_DEPRECATED);
}
}
@@ -242,7 +242,7 @@ class DebugClassLoader
}
}
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)) {
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];
@@ -300,7 +300,7 @@ class DebugClassLoader
$hasCall = $refl->hasMethod('__call');
$hasStaticCall = $refl->hasMethod('__callStatic');
foreach (self::$method[$use] as $method) {
list($interface, $name, $static, $description) = $method;
[$interface, $name, $static, $description] = $method;
if ($static ? $hasStaticCall : $hasCall) {
continue;
}
@@ -335,12 +335,12 @@ class DebugClassLoader
}
if ($parent && isset(self::$finalMethods[$parent][$method->name])) {
list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
[$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];
[$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);
}
@@ -379,7 +379,7 @@ class DebugClassLoader
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)) {
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])) {
@@ -388,10 +388,10 @@ class DebugClassLoader
$definedParameters[$parameter->name] = true;
}
}
foreach ($matches as list(, $parameterType, $parameterName)) {
foreach ($matches as [, $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);
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 %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($class) ? 'interface' : 'parent class', $method->class);
}
}
}

View File

@@ -23,7 +23,7 @@ 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);
@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.
@@ -55,39 +55,39 @@ use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
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',
\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],
\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
@@ -158,7 +158,7 @@ class ErrorHandler
$handler->setExceptionHandler($prev);
}
$handler->throwAt(E_ALL & $handler->thrownErrors, true);
$handler->throwAt(\E_ALL & $handler->thrownErrors, true);
return $handler;
}
@@ -169,7 +169,7 @@ class ErrorHandler
$this->bootstrappingLogger = $bootstrappingLogger;
$this->setDefaultLogger($bootstrappingLogger);
}
$this->traceReflector = new \ReflectionProperty('Exception', 'trace');
$this->traceReflector = new \ReflectionProperty(\Exception::class, 'trace');
$this->traceReflector->setAccessible(true);
}
@@ -179,7 +179,7 @@ class ErrorHandler
* @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)
public function setDefaultLogger(LoggerInterface $logger, $levels = \E_ALL, $replace = false)
{
$loggers = [];
@@ -191,7 +191,7 @@ class ErrorHandler
}
} else {
if (null === $levels) {
$levels = E_ALL;
$levels = \E_ALL;
}
foreach ($this->loggers as $type => $log) {
if (($type & $levels) && (empty($log[0]) || $replace || $log[0] === $this->bootstrappingLogger)) {
@@ -226,14 +226,14 @@ class ErrorHandler
if (!\is_array($log)) {
$log = [$log];
} elseif (!\array_key_exists(0, $log)) {
throw new \InvalidArgumentException('No logger provided');
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');
throw new \InvalidArgumentException('Invalid logger provided.');
}
$this->loggers[$type] = $log + $prev[$type];
@@ -245,7 +245,7 @@ class ErrorHandler
if ($flush) {
foreach ($this->bootstrappingLogger->cleanLogs() as $log) {
$type = $log[2]['exception'] instanceof \ErrorException ? $log[2]['exception']->getSeverity() : E_ERROR;
$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]) {
@@ -283,7 +283,7 @@ class ErrorHandler
public function throwAt($levels, $replace = false)
{
$prev = $this->thrownErrors;
$this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
$this->thrownErrors = ($levels | \E_RECOVERABLE_ERROR | \E_USER_ERROR) & ~\E_USER_DEPRECATED & ~\E_DEPRECATED;
if (!$replace) {
$this->thrownErrors |= $prev;
}
@@ -385,15 +385,15 @@ class ErrorHandler
*/
public function handleError($type, $message, $file, $line)
{
if (\PHP_VERSION_ID >= 70300 && E_WARNING === $type && '"' === $message[0] && false !== strpos($message, '" targeting switch is equivalent to "break')) {
$type = E_DEPRECATED;
if (\PHP_VERSION_ID >= 70300 && \E_WARNING === $type && '"' === $message[0] && false !== strpos($message, '" targeting switch is equivalent to "break')) {
$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;
$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;
@@ -403,19 +403,7 @@ class ErrorHandler
}
$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")) {
if (false !== strpos($message, "@anonymous\0")) {
$logMessage = $this->levels[$type].': '.(new FlattenException())->setMessage($message)->getMessage();
} else {
$logMessage = $this->levels[$type].': '.$message;
@@ -426,7 +414,7 @@ class ErrorHandler
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) : [];
$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;
@@ -461,7 +449,7 @@ class ErrorHandler
}
if ($throw) {
if (\PHP_VERSION_ID < 70400 && E_USER_ERROR & $type) {
if (\PHP_VERSION_ID < 70400 && \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']
@@ -476,6 +464,8 @@ class ErrorHandler
// `return trigger_error($e, E_USER_ERROR);` allows this error handler
// to make $e get through the __toString() barrier.
$context = 4 < \func_num_args() ? (func_get_arg(4) ?: []) : [];
foreach ($context as $e) {
if ($e instanceof \Throwable && $e->__toString() === $message) {
self::$toStringException = $e;
@@ -499,7 +489,7 @@ class ErrorHandler
if ($this->isRecursive) {
$log = 0;
} else {
if (!\defined('HHVM_VERSION')) {
if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404)) {
$currentErrorHandler = set_error_handler('var_dump');
restore_error_handler();
}
@@ -511,7 +501,7 @@ class ErrorHandler
} finally {
$this->isRecursive = false;
if (!\defined('HHVM_VERSION')) {
if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404)) {
set_error_handler($currentErrorHandler);
}
}
@@ -536,11 +526,11 @@ class ErrorHandler
if (!$exception instanceof \Exception) {
$exception = new FatalThrowableError($exception);
}
$type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
$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")) {
if (false !== strpos($message = $exception->getMessage(), "@anonymous\0")) {
$message = (new FlattenException())->setMessage($message)->getMessage();
}
if ($exception instanceof FatalErrorException) {
@@ -643,10 +633,10 @@ class ErrorHandler
$error = error_get_last();
}
if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) {
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;
$trace = $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);

View File

@@ -11,7 +11,7 @@
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\Error\ClassNotFoundError::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ClassNotFoundException::class, \Symfony\Component\ErrorHandler\Error\ClassNotFoundError::class), \E_USER_DEPRECATED);
/**
* Class (or Trait or Interface) Not Found Exception.

View File

@@ -11,7 +11,7 @@
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\Error\FatalError::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalErrorException::class, \Symfony\Component\ErrorHandler\Error\FatalError::class), \E_USER_DEPRECATED);
/**
* Fatal Error Exception.
@@ -35,8 +35,7 @@ class FatalErrorException extends \ErrorException
$this->setTrace($trace);
} elseif (null !== $traceOffset) {
if (\function_exists('xdebug_get_function_stack')) {
$trace = xdebug_get_function_stack();
if (\function_exists('xdebug_get_function_stack') && $trace = @xdebug_get_function_stack()) {
if (0 < $traceOffset) {
array_splice($trace, -$traceOffset);
}
@@ -74,7 +73,7 @@ class FatalErrorException extends \ErrorException
protected function setTrace($trace)
{
$traceReflector = new \ReflectionProperty('Exception', 'trace');
$traceReflector = new \ReflectionProperty(\Exception::class, 'trace');
$traceReflector->setAccessible(true);
$traceReflector->setValue($this, $trace);
}

View File

@@ -11,7 +11,7 @@
namespace Symfony\Component\Debug\Exception;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4.', FatalThrowableError::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4.', FatalThrowableError::class), \E_USER_DEPRECATED);
/**
* Fatal Throwable Error.
@@ -26,14 +26,14 @@ class FatalThrowableError extends FatalErrorException
public function __construct(\Throwable $e)
{
$this->originalClassName = \get_class($e);
$this->originalClassName = get_debug_type($e);
if ($e instanceof \ParseError) {
$severity = E_PARSE;
$severity = \E_PARSE;
} elseif ($e instanceof \TypeError) {
$severity = E_RECOVERABLE_ERROR;
$severity = \E_RECOVERABLE_ERROR;
} else {
$severity = E_ERROR;
$severity = \E_ERROR;
}
\ErrorException::__construct(

View File

@@ -67,7 +67,7 @@ class FlattenException
$e->setStatusCode($statusCode);
$e->setHeaders($headers);
$e->setTraceFromThrowable($exception);
$e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : \get_class($exception));
$e->setClass($exception instanceof FatalThrowableError ? $exception->getOriginalClassName() : get_debug_type($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());
@@ -134,7 +134,7 @@ class FlattenException
*/
public function setClass($class)
{
$this->class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
$this->class = false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class;
return $this;
}
@@ -179,9 +179,9 @@ class FlattenException
*/
public function setMessage($message)
{
if (false !== strpos($message, "class@anonymous\0")) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:)[0-9a-fA-F]++/', function ($m) {
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
if (false !== strpos($message, "@anonymous\0")) {
$message = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
return class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0];
}, $message);
}
@@ -241,7 +241,7 @@ class FlattenException
*/
public function setTraceFromException(\Exception $exception)
{
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use "setTraceFromThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use "setTraceFromThrowable()" instead.', __METHOD__), \E_USER_DEPRECATED);
$this->setTraceFromThrowable($exception);
}
@@ -281,11 +281,11 @@ class FlattenException
$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,
'class' => $entry['class'] ?? '',
'type' => $entry['type'] ?? '',
'function' => $entry['function'] ?? null,
'file' => $entry['file'] ?? null,
'line' => $entry['line'] ?? null,
'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : [],
];
}

View File

@@ -11,7 +11,7 @@
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\Error\OutOfMemoryError::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', OutOfMemoryException::class, \Symfony\Component\ErrorHandler\Error\OutOfMemoryError::class), \E_USER_DEPRECATED);
/**
* Out of memory exception.

View File

@@ -11,7 +11,7 @@
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);
@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.

View File

@@ -11,7 +11,7 @@
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\Error\UndefinedFunctionError::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', UndefinedFunctionException::class, \Symfony\Component\ErrorHandler\Error\UndefinedFunctionError::class), \E_USER_DEPRECATED);
/**
* Undefined Function Exception.

View File

@@ -11,7 +11,7 @@
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\Error\UndefinedMethodError::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', UndefinedMethodException::class, \Symfony\Component\ErrorHandler\Error\UndefinedMethodError::class), \E_USER_DEPRECATED);
/**
* Undefined Method Exception.

View File

@@ -15,7 +15,7 @@ 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\ErrorHandler::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', ExceptionHandler::class, \Symfony\Component\ErrorHandler\ErrorHandler::class), \E_USER_DEPRECATED);
/**
* ExceptionHandler converts an exception to a Response object.
@@ -398,7 +398,7 @@ EOF;
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);
$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++])) {
@@ -451,7 +451,7 @@ EOF;
*/
private function escapeHtml(string $str): string
{
return htmlspecialchars($str, ENT_COMPAT | ENT_SUBSTITUTE, $this->charset);
return htmlspecialchars($str, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset);
}
private function getSymfonyGhostAsSvg(): string

View File

@@ -17,7 +17,7 @@ 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);
@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.
@@ -33,50 +33,34 @@ class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
*/
public function handleError(array $error, FatalErrorException $exception)
{
$messageLen = \strlen($error['message']);
$notFoundSuffix = '\' not found';
$notFoundSuffixLen = \strlen($notFoundSuffix);
if ($notFoundSuffixLen > $messageLen) {
if (!preg_match('/^(Class|Interface|Trait) [\'"]([^\'"]+)[\'"] not found$/', $error['message'], $matches)) {
return null;
}
$typeName = strtolower($matches[1]);
$fullyQualifiedClassName = $matches[2];
if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
return null;
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 = '?';
}
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?';
if ($candidates = $this->getClassCandidates($className)) {
$tail = array_pop($candidates).'"?';
if ($candidates) {
$tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
} else {
$className = $fullyQualifiedClassName;
$message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
$tail = '?';
$tail = ' for "'.$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);
}
$message .= "\nDid you forget a \"use\" statement".$tail;
return null;
return new ClassNotFoundException($message, $exception);
}
/**

View File

@@ -13,7 +13,7 @@ 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);
@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.

View File

@@ -14,7 +14,7 @@ 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\ErrorEnhancer\UndefinedFunctionErrorEnhancer::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', UndefinedFunctionFatalErrorHandler::class, \Symfony\Component\ErrorHandler\ErrorEnhancer\UndefinedFunctionErrorEnhancer::class), \E_USER_DEPRECATED);
/**
* ErrorHandler for undefined functions.

View File

@@ -14,7 +14,7 @@ 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\ErrorEnhancer\UndefinedMethodErrorEnhancer::class), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', UndefinedMethodFatalErrorHandler::class, \Symfony\Component\ErrorHandler\ErrorEnhancer\UndefinedMethodErrorEnhancer::class), \E_USER_DEPRECATED);
/**
* ErrorHandler for undefined methods.
@@ -40,7 +40,7 @@ class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
$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)) {
if ('' === $methodName || !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);
}

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2021 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

View File

@@ -8,6 +8,19 @@ Debug Component
The Debug component provides tools to ease debugging PHP code.
Getting Started
---------------
```
$ composer install symfony/debug
```
```php
use Symfony\Component\Debug\Debug;
Debug::enable();
```
Resources
---------

View File

@@ -12,6 +12,7 @@
namespace Symfony\Component\Debug\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent;
use Symfony\Component\Debug\DebugClassLoader;
/**
@@ -54,7 +55,7 @@ class DebugClassLoaderTest extends TestCase
$reflProp = $reflClass->getProperty('classLoader');
$reflProp->setAccessible(true);
$this->assertNotInstanceOf('Symfony\Component\Debug\DebugClassLoader', $reflProp->getValue($function[0]));
$this->assertNotInstanceOf(DebugClassLoader::class, $reflProp->getValue($function[0]));
return;
}
@@ -65,7 +66,7 @@ class DebugClassLoaderTest extends TestCase
public function testThrowingClass()
{
$this->expectException('Exception');
$this->expectException(\Exception::class);
$this->expectExceptionMessage('boo');
try {
class_exists(Fixtures\Throwing::class);
@@ -80,14 +81,14 @@ class DebugClassLoaderTest extends TestCase
public function testNameCaseMismatch()
{
$this->expectException('RuntimeException');
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Case mismatch between loaded and declared class names');
class_exists(TestingCaseMismatch::class, true);
}
public function testFileCaseMismatch()
{
$this->expectException('RuntimeException');
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Case mismatch between class and real file names');
if (!file_exists(__DIR__.'/Fixtures/CaseMismatch.php')) {
$this->markTestSkipped('Can only be run on case insensitive filesystems');
@@ -98,7 +99,7 @@ class DebugClassLoaderTest extends TestCase
public function testPsr4CaseMismatch()
{
$this->expectException('RuntimeException');
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Case mismatch between loaded and declared class names');
class_exists(__NAMESPACE__.'\Fixtures\Psr4CaseMismatch', true);
}
@@ -179,7 +180,7 @@ class DebugClassLoaderTest extends TestCase
$e = error_reporting(0);
trigger_error('', E_USER_NOTICE);
class_exists('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent', true);
class_exists(ExtendsDeprecatedParent::class, true);
error_reporting($e);
restore_error_handler();
@@ -292,12 +293,12 @@ class DebugClassLoaderTest extends TestCase
$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::whereAmI()" method will require a new "bool $matrix" argument in the next major version of its interface "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 interface "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 interface "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 interface "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 interface "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 interface "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);
}

View File

@@ -12,10 +12,12 @@
namespace Symfony\Component\Debug\Tests;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
use Symfony\Component\Debug\BufferingLogger;
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\Exception\ClassNotFoundException;
use Symfony\Component\Debug\Exception\SilencedErrorContext;
use Symfony\Component\Debug\Tests\Fixtures\ErrorHandlerThatUsesThePreviousOne;
use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler;
@@ -35,7 +37,7 @@ class ErrorHandlerTest extends TestCase
$handler = ErrorHandler::register();
try {
$this->assertInstanceOf('Symfony\Component\Debug\ErrorHandler', $handler);
$this->assertInstanceOf(ErrorHandler::class, $handler);
$this->assertSame($handler, ErrorHandler::register());
$newHandler = new ErrorHandler();
@@ -72,15 +74,15 @@ class ErrorHandlerTest extends TestCase
public function testErrorGetLast()
{
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$logger = $this->createMock(LoggerInterface::class);
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger);
$handler->screamAt(E_ALL);
$handler->screamAt(\E_ALL);
try {
@trigger_error('Hello', E_USER_WARNING);
@trigger_error('Hello', \E_USER_WARNING);
$expected = [
'type' => E_USER_WARNING,
'type' => \E_USER_WARNING,
'message' => 'Hello',
'file' => __FILE__,
'line' => __LINE__ - 5,
@@ -103,9 +105,14 @@ class ErrorHandlerTest extends TestCase
$this->fail('ErrorException expected');
} catch (\ErrorException $exception) {
// if an exception is thrown, the test passed
$this->assertEquals(E_NOTICE, $exception->getSeverity());
if (\PHP_VERSION_ID < 80000) {
$this->assertEquals(\E_NOTICE, $exception->getSeverity());
$this->assertMatchesRegularExpression('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
} else {
$this->assertEquals(\E_WARNING, $exception->getSeverity());
$this->assertMatchesRegularExpression('/^Warning: Undefined variable \$(foo|bar)/', $exception->getMessage());
}
$this->assertEquals(__FILE__, $exception->getFile());
$this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage());
$trace = $exception->getTrace();
@@ -135,7 +142,7 @@ class ErrorHandlerTest extends TestCase
try {
$handler = ErrorHandler::register();
$handler->throwAt(3, true);
$this->assertEquals(3 | E_RECOVERABLE_ERROR | E_USER_ERROR, $handler->throwAt(0));
$this->assertEquals(3 | \E_RECOVERABLE_ERROR | \E_USER_ERROR, $handler->throwAt(0));
} finally {
restore_error_handler();
restore_exception_handler();
@@ -145,28 +152,28 @@ class ErrorHandlerTest extends TestCase
public function testDefaultLogger()
{
try {
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$logger = $this->createMock(LoggerInterface::class);
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_NOTICE);
$handler->setDefaultLogger($logger, [E_USER_NOTICE => LogLevel::CRITICAL]);
$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],
\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 {
@@ -207,20 +214,20 @@ class ErrorHandlerTest extends TestCase
restore_exception_handler();
$handler = ErrorHandler::register();
$handler->throwAt(E_USER_DEPRECATED, true);
$this->assertFalse($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
$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, []));
$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();
$logger = $this->createMock(LoggerInterface::class);
$warnArgCheck = function ($logLevel, $message, $context) {
$this->assertEquals('info', $logLevel);
@@ -229,7 +236,7 @@ class ErrorHandlerTest extends TestCase
$exception = $context['exception'];
$this->assertInstanceOf(\ErrorException::class, $exception);
$this->assertSame('User Deprecated: foo', $exception->getMessage());
$this->assertSame(E_USER_DEPRECATED, $exception->getSeverity());
$this->assertSame(\E_USER_DEPRECATED, $exception->getSeverity());
};
$logger
@@ -239,21 +246,27 @@ class ErrorHandlerTest extends TestCase
;
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_USER_DEPRECATED);
$this->assertTrue($handler->handleError(E_USER_DEPRECATED, 'foo', 'foo.php', 12, []));
$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();
$logger = $this->createMock(LoggerInterface::class);
$line = null;
$logArgCheck = function ($level, $message, $context) use (&$line) {
$this->assertEquals('Notice: Undefined variable: undefVar', $message);
$this->assertArrayHasKey('exception', $context);
$exception = $context['exception'];
if (\PHP_VERSION_ID < 80000) {
$this->assertEquals('Notice: Undefined variable: undefVar', $message);
$this->assertSame(\E_NOTICE, $exception->getSeverity());
} else {
$this->assertEquals('Warning: Undefined variable $undefVar', $message);
$this->assertSame(\E_WARNING, $exception->getSeverity());
}
$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());
@@ -267,8 +280,13 @@ class ErrorHandlerTest extends TestCase
;
$handler = ErrorHandler::register();
$handler->setDefaultLogger($logger, E_NOTICE);
$handler->screamAt(E_NOTICE);
if (\PHP_VERSION_ID < 80000) {
$handler->setDefaultLogger($logger, \E_NOTICE);
$handler->screamAt(\E_NOTICE);
} else {
$handler->setDefaultLogger($logger, \E_WARNING);
$handler->screamAt(\E_WARNING);
}
unset($undefVar);
$line = __LINE__ + 1;
@$undefVar++;
@@ -309,6 +327,26 @@ class ErrorHandlerTest extends TestCase
}
}
public function testHandleErrorWithAnonymousClass()
{
$handler = ErrorHandler::register();
$handler->throwAt(\E_USER_WARNING, true);
try {
$handler->handleError(\E_USER_WARNING, 'foo '.\get_class(new class() extends \stdClass {
}).' bar', 'foo.php', 12);
$this->fail('Exception expected.');
} catch (\ErrorException $e) {
} finally {
restore_error_handler();
restore_exception_handler();
}
$this->assertSame('User Warning: foo stdClass@anonymous bar', $e->getMessage());
$this->assertSame(\E_USER_WARNING, $e->getSeverity());
$this->assertSame('foo.php', $e->getFile());
$this->assertSame(12, $e->getLine());
}
public function testHandleDeprecation()
{
$logArgCheck = function ($level, $message, $context) {
@@ -319,7 +357,7 @@ class ErrorHandlerTest extends TestCase
$this->assertSame('User Deprecated: Foo deprecation', $exception->getMessage());
};
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$logger = $this->createMock(LoggerInterface::class);
$logger
->expects($this->once())
->method('log')
@@ -328,15 +366,13 @@ class ErrorHandlerTest extends TestCase
$handler = new ErrorHandler();
$handler->setDefaultLogger($logger);
@$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
restore_error_handler();
@$handler->handleError(\E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []);
}
public function testHandleException()
{
try {
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$logger = $this->createMock(LoggerInterface::class);
$handler = ErrorHandler::register();
$exception = new \Exception('foo');
@@ -353,7 +389,7 @@ class ErrorHandlerTest extends TestCase
->willReturnCallback($logArgCheck)
;
$handler->setDefaultLogger($logger, E_ERROR);
$handler->setDefaultLogger($logger, \E_ERROR);
try {
$handler->handleException($exception);
@@ -379,26 +415,26 @@ class ErrorHandlerTest extends TestCase
$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],
\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, []);
$handler->handleError(\E_DEPRECATED, 'Foo message', __FILE__, 123, []);
$logs = $bootLogger->cleanLogs();
@@ -412,16 +448,16 @@ class ErrorHandlerTest extends TestCase
$this->assertSame('Deprecated: Foo message', $exception->getMessage());
$this->assertSame(__FILE__, $exception->getFile());
$this->assertSame(123, $exception->getLine());
$this->assertSame(E_DEPRECATED, $exception->getSeverity());
$this->assertSame(\E_DEPRECATED, $exception->getSeverity());
$bootLogger->log(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
$mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$mockLogger = $this->createMock(LoggerInterface::class);
$mockLogger->expects($this->once())
->method('log')
->with(LogLevel::WARNING, 'Foo message', ['exception' => $exception]);
$handler->setLoggers([E_DEPRECATED => [$mockLogger, LogLevel::WARNING]]);
$handler->setLoggers([\E_DEPRECATED => [$mockLogger, LogLevel::WARNING]]);
}
public function testSettingLoggerWhenExceptionIsBuffered()
@@ -431,7 +467,7 @@ class ErrorHandlerTest extends TestCase
$exception = new \Exception('Foo message');
$mockLogger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$mockLogger = $this->createMock(LoggerInterface::class);
$mockLogger->expects($this->once())
->method('log')
->with(LogLevel::CRITICAL, 'Uncaught Exception: Foo message', ['exception' => $exception]);
@@ -446,11 +482,11 @@ class ErrorHandlerTest extends TestCase
public function testHandleFatalError()
{
try {
$logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
$logger = $this->createMock(LoggerInterface::class);
$handler = ErrorHandler::register();
$error = [
'type' => E_PARSE,
'type' => \E_PARSE,
'message' => 'foo',
'file' => 'bar',
'line' => 123,
@@ -468,7 +504,7 @@ class ErrorHandlerTest extends TestCase
->willReturnCallback($logArgCheck)
;
$handler->setDefaultLogger($logger, E_PARSE);
$handler->setDefaultLogger($logger, \E_PARSE);
$handler->handleFatalError($error);
@@ -493,13 +529,13 @@ class ErrorHandlerTest extends TestCase
$handler->handleException($exception);
$this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $args[0]);
$this->assertInstanceOf(ClassNotFoundException::class, $args[0]);
$this->assertStringStartsWith("Attempted to load class \"IReallyReallyDoNotExistAnywhereInTheRepositoryISwear\" from the global namespace.\nDid you forget a \"use\" statement", $args[0]->getMessage());
}
public function testCustomExceptionHandler()
{
$this->expectException('Exception');
$this->expectException(\Exception::class);
$handler = new ErrorHandler();
$handler->setExceptionHandler(function ($e) use ($handler) {
$handler->handleException($e);
@@ -527,8 +563,8 @@ class ErrorHandlerTest extends TestCase
$handler = ErrorHandlerThatUsesThePreviousOne::register();
}
@trigger_error('foo', E_USER_DEPRECATED);
@trigger_error('bar', E_USER_DEPRECATED);
@trigger_error('foo', \E_USER_DEPRECATED);
@trigger_error('bar', \E_USER_DEPRECATED);
$this->assertSame([$handler, 'handleError'], set_error_handler('var_dump'));

View File

@@ -174,9 +174,9 @@ class FlattenExceptionTest extends TestCase
$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');
$this->assertEquals('Oh noes!', $flattened->getMessage(), 'The message is copied from the original exception.');
$this->assertEquals(42, $flattened->getCode(), 'The code is copied from the original exception.');
$this->assertEquals('ParseError', $flattened->getClass(), 'The class is set to the class of the original exception');
}
/**
@@ -265,8 +265,8 @@ class FlattenExceptionTest extends TestCase
0.0,
'0',
'',
INF,
NAN,
\INF,
\NAN,
]);
$flattened = FlattenException::create($exception);
@@ -286,7 +286,7 @@ class FlattenExceptionTest extends TestCase
$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->assertTrue('Closure' === $args[1] || is_subclass_of($args[1], \Closure::class), '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++]);
@@ -297,10 +297,10 @@ class FlattenExceptionTest extends TestCase
$this->assertSame(['float', 0.0], $array[$i++]);
$this->assertSame(['string', '0'], $array[$i++]);
$this->assertSame(['string', ''], $array[$i++]);
$this->assertSame(['float', INF], $array[$i++]);
$this->assertSame(['float', \INF], $array[$i++]);
// assertEquals() does not like NAN values.
$this->assertEquals($array[$i][0], 'float');
$this->assertEquals('float', $array[$i][0]);
$this->assertNan($array[$i][1]);
}
@@ -355,6 +355,11 @@ class FlattenExceptionTest extends TestCase
$this->assertSame('RuntimeException@anonymous', $flattened->getClass());
$flattened->setClass(\get_class(new class('Oops') extends NotFoundHttpException {
}));
$this->assertSame('Symfony\Component\HttpKernel\Exception\NotFoundHttpException@anonymous', $flattened->getClass());
$flattened = FlattenException::create(new \Exception(sprintf('Class "%s" blah.', \get_class(new class() extends \RuntimeException {
}))));

View File

@@ -64,7 +64,7 @@ content="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg"
$handler->sendPhpResponse(new \RuntimeException($htmlWithXss));
$response = ob_get_clean();
$this->assertStringContainsString(sprintf('<h1 class="break-long-words exception-message">%s</h1>', htmlspecialchars($htmlWithXss, ENT_COMPAT | ENT_SUBSTITUTE, 'UTF-8')), $response);
$this->assertStringContainsString(sprintf('<h1 class="break-long-words exception-message">%s</h1>', htmlspecialchars($htmlWithXss, \ENT_COMPAT | \ENT_SUBSTITUTE, 'UTF-8')), $response);
}
public function testStatusCode()
@@ -165,7 +165,7 @@ content="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg"
$this->fail('OutOfMemoryException should bypass the handler');
});
$handler->handle(new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__));
$handler->handle(new OutOfMemoryException('foo', 0, \E_ERROR, __FILE__, __LINE__));
$this->assertThatTheExceptionWasOutput(ob_get_clean(), OutOfMemoryException::class, 'OutOfMemoryException', 'foo');
}

View File

@@ -14,6 +14,7 @@ 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\ClassNotFoundException;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
@@ -32,6 +33,10 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
// 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) {
@@ -63,8 +68,8 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
array_map('spl_autoload_register', $autoloaders);
}
$this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
$this->assertSame($translatedMessage, $exception->getMessage());
$this->assertInstanceOf(ClassNotFoundException::class, $exception);
$this->assertMatchesRegularExpression($translatedMessage, $exception->getMessage());
$this->assertSame($error['type'], $exception->getSeverity());
$this->assertSame($error['file'], $exception->getFile());
$this->assertSame($error['line'], $exception->getLine());
@@ -79,6 +84,15 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
$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,
@@ -86,7 +100,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
'file' => 'foo.php',
'message' => 'Class \'WhizBangFactory\' not found',
],
"Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement?",
"/^Attempted to load class \"WhizBangFactory\" from the global namespace.\nDid you forget a \"use\" statement\?$/",
],
[
[
@@ -95,7 +109,34 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
'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?",
"/^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 "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' => 'Interface "Foo\\Bar\\WhizBangInterface" not found',
],
"/^Attempted to load interface \"WhizBangInterface\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/",
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Trait "Foo\\Bar\\WhizBangTrait" not found',
],
"/^Attempted to load trait \"WhizBangTrait\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/",
],
[
[
@@ -104,7 +145,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
'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\"?",
"/^Attempted to load class \"UndefinedFunctionException\" from the global namespace.\nDid you forget a \"use\" statement for .*\"Symfony\\\\Component\\\\Debug\\\\Exception\\\\UndefinedFunctionException\"\?$/",
[$debugClassLoader, 'loadClass'],
],
[
@@ -114,7 +155,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
'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\"?",
"/^Attempted to load class \"PEARClass\" from the global namespace.\nDid you forget a \"use\" statement for \"Symfony_Component_Debug_Tests_Fixtures_PEARClass\"\?$/",
[$debugClassLoader, 'loadClass'],
],
[
@@ -124,7 +165,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
'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\"?",
"/^Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for .*\"Symfony\\\\Component\\\\Debug\\\\Exception\\\\UndefinedFunctionException\"\?$/",
[$debugClassLoader, 'loadClass'],
],
[
@@ -134,7 +175,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
'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\"?",
"/^Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for \"Symfony\\\\Component\\\\Debug\\\\Exception\\\\UndefinedFunctionException\"\?$/",
[$autoloader, 'loadClass'],
],
[
@@ -144,7 +185,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
'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\"?",
"/^Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for \"Symfony\\\\Component\\\\Debug\\\\Exception\\\\UndefinedFunctionException\"\?/",
[$debugClassLoader, 'loadClass'],
],
[
@@ -154,7 +195,7 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
'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?",
"/^Attempted to load class \"UndefinedFunctionException\" from namespace \"Foo\\\\Bar\".\nDid you forget a \"use\" statement for another namespace\?$/",
function ($className) { /* do nothing here */ },
],
];
@@ -178,6 +219,6 @@ class ClassNotFoundFatalErrorHandlerTest extends TestCase
$handler = new ClassNotFoundFatalErrorHandler();
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));
$this->assertInstanceOf('Symfony\Component\Debug\Exception\ClassNotFoundException', $exception);
$this->assertInstanceOf(ClassNotFoundException::class, $exception);
}
}

View File

@@ -13,6 +13,7 @@ namespace Symfony\Component\Debug\Tests\FatalErrorHandler;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\Exception\UndefinedFunctionException;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
/**
@@ -28,7 +29,7 @@ class UndefinedFunctionFatalErrorHandlerTest extends TestCase
$handler = new UndefinedFunctionFatalErrorHandler();
$exception = $handler->handleError($error, new FatalErrorException('', 0, $error['type'], $error['file'], $error['line']));
$this->assertInstanceOf('Symfony\Component\Debug\Exception\UndefinedFunctionException', $exception);
$this->assertInstanceOf(UndefinedFunctionException::class, $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());

View File

@@ -13,6 +13,7 @@ namespace Symfony\Component\Debug\Tests\FatalErrorHandler;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Debug\Exception\FatalErrorException;
use Symfony\Component\Debug\Exception\UndefinedMethodException;
use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
/**
@@ -28,7 +29,7 @@ class UndefinedMethodFatalErrorHandlerTest extends TestCase
$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->assertInstanceOf(UndefinedMethodException::class, $exception);
$this->assertSame($translatedMessage, $exception->getMessage());
$this->assertSame($error['type'], $exception->getSeverity());
$this->assertSame($error['file'], $exception->getFile());
@@ -47,6 +48,15 @@ class UndefinedMethodFatalErrorHandlerTest extends TestCase
],
'Attempted to call an undefined method named "what" of class "SplObjectStorage".',
],
[
[
'type' => 1,
'line' => 12,
'file' => 'foo.php',
'message' => 'Call to undefined method SplObjectStorage::()',
],
'Attempted to call an undefined method named "" of class "SplObjectStorage".',
],
[
[
'type' => 1,

View File

@@ -15,8 +15,8 @@ class ErrorHandlerThatUsesThePreviousOne
return $handler;
}
public function handleError($type, $message, $file, $line, $context)
public function handleError()
{
return \call_user_func(self::$previous, $type, $message, $file, $line, $context);
return \call_user_func_array(self::$previous, \func_get_args());
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "symfony/debug",
"type": "library",
"description": "Symfony Debug Component",
"description": "Provides tools to ease debugging PHP code",
"keywords": [],
"homepage": "https://symfony.com",
"license": "MIT",
@@ -16,8 +16,9 @@
}
],
"require": {
"php": "^7.1.3",
"psr/log": "~1.0"
"php": ">=7.1.3",
"psr/log": "~1.0",
"symfony/polyfill-php80": "^1.15"
},
"conflict": {
"symfony/http-kernel": "<3.4"
@@ -31,10 +32,5 @@
"/Tests/"
]
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "4.4-dev"
}
}
"minimum-stability": "dev"
}

View File

@@ -14,10 +14,7 @@
<testsuites>
<testsuite name="Symfony Debug Component Test Suite">
<directory>./Tests/</directory>
</testsuite>
<testsuite name="Symfony Debug Extension Test Suite">
<directory suffix=".phpt">./Resources/ext/tests/</directory>
<directory suffix=".phpt">./Tests/</directory>
</testsuite>
</testsuites>