diff --git a/src/Symfony/Bridge/Monolog/CHANGELOG.md b/src/Symfony/Bridge/Monolog/CHANGELOG.md index 9bce3eacd7cc9..e644f71d64a38 100644 --- a/src/Symfony/Bridge/Monolog/CHANGELOG.md +++ b/src/Symfony/Bridge/Monolog/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.3 +--- + + * Add `$handleSilent` constructor argument to `ConsoleHandler` to force the bubbling of message when output verbosity is set to `OutputInterface::VERBOSITY_SILENT` + 7.0 --- diff --git a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php index 56e70976008ff..16033b71ba411 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php @@ -64,6 +64,7 @@ public function __construct( bool $bubble = true, array $verbosityLevelMap = [], private array $consoleFormatterOptions = [], + private bool $handleSilent = true, ) { parent::__construct(Level::Debug, $bubble); @@ -167,6 +168,8 @@ private function updateLevel(): bool $verbosity = $this->output->getVerbosity(); if (isset($this->verbosityLevelMap[$verbosity])) { $this->setLevel($this->verbosityLevelMap[$verbosity]); + } elseif (!$this->handleSilent && OutputInterface::VERBOSITY_SILENT === $verbosity) { + return false; } else { $this->setLevel(Level::Debug); } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php index 626c94ce0ccf8..fe06f638584d5 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/ConsoleHandlerTest.php @@ -101,6 +101,56 @@ public static function provideVerbosityMappingTests(): array ]; } + /** + * @dataProvider provideHandleSilentTests + */ + public function testHandleSilent(bool $silenced, int $verbosity, Level $level, bool $isHandling, bool $isBubbling, array $map = []) + { + $output = $this->createMock(OutputInterface::class); + $output + ->expects($this->atLeastOnce()) + ->method('getVerbosity') + ->willReturn($verbosity) + ; + $handler = new ConsoleHandler($output, false, $map, handleSilent: $silenced); + $this->assertSame($isHandling, $handler->isHandling(RecordFactory::create($level)), '->isHandling returns correct value depending on console verbosity and log level'); + + // check that the handler actually outputs the record if it handles it at verbosity above SILENT + $levelName = Logger::getLevelName($level); + $levelName = \sprintf('%-9s', $levelName); + + $realOutput = $this->getMockBuilder(Output::class)->onlyMethods(['doWrite'])->getMock(); + $realOutput->setVerbosity($verbosity); + $log = "16:21:54 $levelName [app] My info message\n"; + $realOutput + ->expects($isHandling && $verbosity > OutputInterface::VERBOSITY_SILENT ? $this->once() : $this->never()) + ->method('doWrite') + ->with($log, false); + $handler = new ConsoleHandler($realOutput, false, $map, handleSilent: $silenced); + + $infoRecord = RecordFactory::create($level, 'My info message', 'app', datetime: new \DateTimeImmutable('2013-05-29 16:21:54')); + $this->assertSame(!$isBubbling, $handler->handle($infoRecord), 'The handler bubbled correctly when it did not output the message.'); + } + + public static function provideHandleSilentTests(): array + { + return [ + [true, OutputInterface::VERBOSITY_SILENT, Level::Warning, true, false], + [true, OutputInterface::VERBOSITY_NORMAL, Level::Warning, true, false], + [true, OutputInterface::VERBOSITY_SILENT, Level::Warning, true, false, [OutputInterface::VERBOSITY_SILENT => Level::Warning]], + [true, OutputInterface::VERBOSITY_SILENT, Level::Warning, false, true, [OutputInterface::VERBOSITY_SILENT => Level::Error]], + [true, OutputInterface::VERBOSITY_SILENT, Level::Emergency, true, false], + [true, OutputInterface::VERBOSITY_SILENT, Level::Emergency, true, false, [OutputInterface::VERBOSITY_SILENT => Level::Emergency]], + [false, OutputInterface::VERBOSITY_SILENT, Level::Warning, false, true], + [false, OutputInterface::VERBOSITY_NORMAL, Level::Warning, true, false], + [false, OutputInterface::VERBOSITY_SILENT, Level::Warning, true, false, [OutputInterface::VERBOSITY_SILENT => Level::Warning]], + [false, OutputInterface::VERBOSITY_SILENT, Level::Warning, false, true, [OutputInterface::VERBOSITY_SILENT => Level::Error]], + [false, OutputInterface::VERBOSITY_SILENT, Level::Emergency, false, true], + [false, OutputInterface::VERBOSITY_SILENT, Level::Emergency, true, false, [OutputInterface::VERBOSITY_SILENT => Level::Emergency]], + ]; + } + + public function testVerbosityChanged() { $output = $this->createMock(OutputInterface::class);