diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml
index 786158dd89..fb0b99255a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml
@@ -15,12 +15,13 @@
null
-
+
null
%debug.error_handler.throw_at%
%kernel.debug%
%kernel.debug%
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index 55332ab60b..f175975896 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -425,7 +425,7 @@ abstract class FrameworkExtensionTest extends TestCase
$container = $this->createContainerFromFile('php_errors_enabled');
$definition = $container->getDefinition('debug.debug_handlers_listener');
- $this->assertEquals(new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
+ $this->assertEquals(new Reference('monolog.logger.php', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
$this->assertNull($definition->getArgument(2));
$this->assertSame(-1, $container->getParameter('debug.error_handler.throw_at'));
}
@@ -445,7 +445,7 @@ abstract class FrameworkExtensionTest extends TestCase
$container = $this->createContainerFromFile('php_errors_log_level');
$definition = $container->getDefinition('debug.debug_handlers_listener');
- $this->assertEquals(new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
+ $this->assertEquals(new Reference('monolog.logger.php', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
$this->assertSame(8, $definition->getArgument(2));
}
diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md
index 1b766484b6..e48612f5f9 100644
--- a/src/Symfony/Component/HttpKernel/CHANGELOG.md
+++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+5.2.0
+-----
+
+ * allowed to use a specific logger channel for deprecations
+
5.1.0
-----
diff --git a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
index 9cecf164bc..44b1ddb187 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
@@ -32,6 +32,7 @@ class DebugHandlersListener implements EventSubscriberInterface
{
private $exceptionHandler;
private $logger;
+ private $deprecationLogger;
private $levels;
private $throwAt;
private $scream;
@@ -48,7 +49,7 @@ class DebugHandlersListener implements EventSubscriberInterface
* @param string|FileLinkFormatter|null $fileLinkFormat The format for links to source files
* @param bool $scope Enables/disables scoping mode
*/
- public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true)
+ public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true, LoggerInterface $deprecationLogger = null)
{
$this->exceptionHandler = $exceptionHandler;
$this->logger = $logger;
@@ -57,6 +58,7 @@ class DebugHandlersListener implements EventSubscriberInterface
$this->scream = $scream;
$this->fileLinkFormat = $fileLinkFormat;
$this->scope = $scope;
+ $this->deprecationLogger = $deprecationLogger;
}
/**
@@ -76,31 +78,30 @@ class DebugHandlersListener implements EventSubscriberInterface
$handler = \is_array($handler) ? $handler[0] : null;
restore_exception_handler();
- if ($this->logger || null !== $this->throwAt) {
- if ($handler instanceof ErrorHandler) {
- if ($this->logger) {
- $handler->setDefaultLogger($this->logger, $this->levels);
- if (\is_array($this->levels)) {
- $levels = 0;
- foreach ($this->levels as $type => $log) {
- $levels |= $type;
- }
- } else {
- $levels = $this->levels;
+ if ($handler instanceof ErrorHandler) {
+ if ($this->logger || $this->deprecationLogger) {
+ $this->setDefaultLoggers($handler);
+ if (\is_array($this->levels)) {
+ $levels = 0;
+ foreach ($this->levels as $type => $log) {
+ $levels |= $type;
}
- if ($this->scream) {
- $handler->screamAt($levels);
- }
- if ($this->scope) {
- $handler->scopeAt($levels & ~E_USER_DEPRECATED & ~E_DEPRECATED);
- } else {
- $handler->scopeAt(0, true);
- }
- $this->logger = $this->levels = null;
+ } else {
+ $levels = $this->levels;
}
- if (null !== $this->throwAt) {
- $handler->throwAt($this->throwAt, true);
+
+ if ($this->scream) {
+ $handler->screamAt($levels);
}
+ if ($this->scope) {
+ $handler->scopeAt($levels & ~E_USER_DEPRECATED & ~E_DEPRECATED);
+ } else {
+ $handler->scopeAt(0, true);
+ }
+ $this->logger = $this->deprecationLogger = $this->levels = null;
+ }
+ if (null !== $this->throwAt) {
+ $handler->throwAt($this->throwAt, true);
}
}
if (!$this->exceptionHandler) {
@@ -135,6 +136,34 @@ class DebugHandlersListener implements EventSubscriberInterface
}
}
+ private function setDefaultLoggers(ErrorHandler $handler): void
+ {
+ if (\is_array($this->levels)) {
+ $levelsDeprecatedOnly = [];
+ $levelsWithoutDeprecated = [];
+ foreach ($this->levels as $type => $log) {
+ if (E_DEPRECATED == $type || E_USER_DEPRECATED == $type) {
+ $levelsDeprecatedOnly[$type] = $log;
+ } else {
+ $levelsWithoutDeprecated[$type] = $log;
+ }
+ }
+ } else {
+ $levelsDeprecatedOnly = $this->levels & (E_DEPRECATED | E_USER_DEPRECATED);
+ $levelsWithoutDeprecated = $this->levels & ~E_DEPRECATED & ~E_USER_DEPRECATED;
+ }
+
+ $defaultLoggerLevels = $this->levels;
+ if ($this->deprecationLogger && $levelsDeprecatedOnly) {
+ $handler->setDefaultLogger($this->deprecationLogger, $levelsDeprecatedOnly);
+ $defaultLoggerLevels = $levelsWithoutDeprecated;
+ }
+
+ if ($this->logger && $defaultLoggerLevels) {
+ $handler->setDefaultLogger($this->logger, $defaultLoggerLevels);
+ }
+ }
+
public static function getSubscribedEvents(): array
{
$events = [KernelEvents::REQUEST => ['configure', 2048]];
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php
index 6f04c0a4c6..abd202f381 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
+use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
@@ -150,4 +151,89 @@ class DebugHandlersListenerTest extends TestCase
$this->assertSame($userHandler, $eHandler->setExceptionHandler('var_dump'));
}
+
+ public function provideLevelsAssignedToLoggers(): array
+ {
+ return [
+ [false, false, '0', null, null],
+ [false, false, E_ALL, null, null],
+ [false, false, [], null, null],
+ [false, false, [E_WARNING => LogLevel::WARNING, E_USER_DEPRECATED => LogLevel::NOTICE], null, null],
+
+ [true, false, E_ALL, E_ALL, null],
+ [true, false, E_DEPRECATED, E_DEPRECATED, null],
+ [true, false, [], null, null],
+ [true, false, [E_WARNING => LogLevel::WARNING, E_DEPRECATED => LogLevel::NOTICE], [E_WARNING => LogLevel::WARNING, E_DEPRECATED => LogLevel::NOTICE], null],
+
+ [false, true, '0', null, null],
+ [false, true, E_ALL, null, E_DEPRECATED | E_USER_DEPRECATED],
+ [false, true, E_ERROR, null, null],
+ [false, true, [], null, null],
+ [false, true, [E_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::DEBUG], null, [E_DEPRECATED => LogLevel::DEBUG]],
+
+ [true, true, '0', null, null],
+ [true, true, E_ALL, E_ALL & ~(E_DEPRECATED | E_USER_DEPRECATED), E_DEPRECATED | E_USER_DEPRECATED],
+ [true, true, E_ERROR, E_ERROR, null],
+ [true, true, E_USER_DEPRECATED, null, E_USER_DEPRECATED],
+ [true, true, [E_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::DEBUG], [E_ERROR => LogLevel::ERROR], [E_DEPRECATED => LogLevel::DEBUG]],
+ [true, true, [E_ERROR => LogLevel::ALERT], [E_ERROR => LogLevel::ALERT], null],
+ [true, true, [E_USER_DEPRECATED => LogLevel::NOTICE], null, [E_USER_DEPRECATED => LogLevel::NOTICE]],
+ ];
+ }
+
+ /**
+ * @dataProvider provideLevelsAssignedToLoggers
+ *
+ * @param array|string $levels
+ * @param array|string|null $expectedLoggerLevels
+ * @param array|string|null $expectedDeprecationLoggerLevels
+ */
+ public function testLevelsAssignedToLoggers(bool $hasLogger, bool $hasDeprecationLogger, $levels, $expectedLoggerLevels, $expectedDeprecationLoggerLevels)
+ {
+ if (!class_exists(ErrorHandler::class)) {
+ $this->markTestSkipped('ErrorHandler component is required to run this test.');
+ }
+
+ $handler = $this->createMock(ErrorHandler::class);
+
+ $expectedCalls = [];
+ $logger = null;
+
+ $deprecationLogger = null;
+ if ($hasDeprecationLogger) {
+ $deprecationLogger = $this->createMock(LoggerInterface::class);
+ if (null !== $expectedDeprecationLoggerLevels) {
+ $expectedCalls[] = [$deprecationLogger, $expectedDeprecationLoggerLevels];
+ }
+ }
+
+ if ($hasLogger) {
+ $logger = $this->createMock(LoggerInterface::class);
+ if (null !== $expectedLoggerLevels) {
+ $expectedCalls[] = [$logger, $expectedLoggerLevels];
+ }
+ }
+
+ $handler
+ ->expects($this->exactly(\count($expectedCalls)))
+ ->method('setDefaultLogger')
+ ->withConsecutive(...$expectedCalls);
+
+ $sut = new DebugHandlersListener(null, $logger, $levels, null, true, null, true, $deprecationLogger);
+ $prevHander = set_exception_handler([$handler, 'handleError']);
+
+ try {
+ $handler
+ ->method('handleError')
+ ->willReturnCallback(function () use ($prevHander) {
+ $prevHander(...\func_get_args());
+ });
+
+ $sut->configure();
+ set_exception_handler($prevHander);
+ } catch (\Exception $e) {
+ set_exception_handler($prevHander);
+ throw $e;
+ }
+ }
}