Skip to content

Commit

Permalink
Merge pull request #466 from derrabus/drop/symfony-4
Browse files Browse the repository at this point in the history
Drop Support for Symfony 4
  • Loading branch information
stof committed Oct 24, 2023
2 parents 67ed61d + d425367 commit d320c9e
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 213 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ci.yaml
Expand Up @@ -14,7 +14,6 @@ jobs:
php: [ '7.2', '7.3', '7.4', '8.0', '8.1' ]
monolog: [ '1.*', '2.*' ]
include:
- php: '7.1'
- php: '7.4'
deps: lowest
deprecations: max[self]=0
Expand Down
53 changes: 17 additions & 36 deletions DependencyInjection/Compiler/LoggerChannelPass.php
Expand Up @@ -66,19 +66,17 @@ public function process(ContainerBuilder $container)
}
$definition->setMethodCalls($calls);

if (\method_exists($definition, 'getBindings')) {
$binding = new BoundArgument(new Reference($loggerId));

// Mark the binding as used already, to avoid reporting it as unused if the service does not use a
// logger injected through the LoggerInterface alias.
$values = $binding->getValues();
$values[2] = true;
$binding->setValues($values);

$bindings = $definition->getBindings();
$bindings['Psr\Log\LoggerInterface'] = $binding;
$definition->setBindings($bindings);
}
$binding = new BoundArgument(new Reference($loggerId));

// Mark the binding as used already, to avoid reporting it as unused if the service does not use a
// logger injected through the LoggerInterface alias.
$values = $binding->getValues();
$values[2] = true;
$binding->setValues($values);

$bindings = $definition->getBindings();
$bindings['Psr\Log\LoggerInterface'] = $binding;
$definition->setBindings($bindings);
}
}

Expand Down Expand Up @@ -117,11 +115,9 @@ public function getChannels()
}

/**
* @param array $configuration
*
* @return array
*/
protected function processChannels($configuration)
protected function processChannels(?array $configuration)
{
if (null === $configuration) {
return $this->channels;
Expand All @@ -137,11 +133,9 @@ protected function processChannels($configuration)
/**
* Create new logger from the monolog.logger_prototype
*
* @param string $channel
* @param string $loggerId
* @param ContainerBuilder $container
* @return void
*/
protected function createLogger($channel, $loggerId, ContainerBuilder $container)
protected function createLogger(string $channel, string $loggerId, ContainerBuilder $container)
{
if (!in_array($channel, $this->channels)) {
$logger = new ChildDefinition('monolog.logger_prototype');
Expand All @@ -150,29 +144,16 @@ protected function createLogger($channel, $loggerId, ContainerBuilder $container
$this->channels[] = $channel;
}

// Allows only for Symfony 4.2+
if (\method_exists($container, 'registerAliasForArgument')) {
$parameterName = $channel . 'Logger';
$parameterName = $channel . 'Logger';

$container->registerAliasForArgument($loggerId, LoggerInterface::class, $parameterName);
}
$container->registerAliasForArgument($loggerId, LoggerInterface::class, $parameterName);
}

/**
* Creates a copy of a reference and alters the service ID.
*
* @param Reference $reference
* @param string $serviceId
*
* @return Reference
*/
private function changeReference(Reference $reference, $serviceId)
private function changeReference(Reference $reference, string $serviceId): Reference
{
if (method_exists($reference, 'isStrict')) {
// Stay compatible with Symfony 2
return new Reference($serviceId, $reference->getInvalidBehavior(), $reference->isStrict(false));
}

return new Reference($serviceId, $reference->getInvalidBehavior());
}
}
27 changes: 2 additions & 25 deletions DependencyInjection/Configuration.php
Expand Up @@ -379,7 +379,7 @@ class Configuration implements ConfigurationInterface
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('monolog');
$rootNode = method_exists(TreeBuilder::class, 'getRootNode') ? $treeBuilder->getRootNode() : $treeBuilder->root('monolog');
$rootNode = $treeBuilder->getRootNode();

$handlers = $rootNode
->fixXmlConfig('channel')
Expand Down Expand Up @@ -602,7 +602,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
// console
->variableNode('console_formater_options')
->setDeprecated(...$this->getDeprecationMsg('"%path%.%node%" is deprecated, use "%path%.console_formatter_options" instead.', 3.7))
->setDeprecated('symfony/monolog-bundle', 3.7, '"%path%.%node%" is deprecated, use "%path%.console_formatter_options" instead.')
->validate()
->ifTrue(function ($v) {
return !is_array($v);
Expand Down Expand Up @@ -1135,27 +1135,4 @@ private function addChannelsSection(ArrayNodeDefinition $handerNode)
->end()
;
}

/**
* Returns the correct deprecation param's as an array for setDeprecated.
*
* Symfony/Config v5.1 introduces a deprecation notice when calling
* setDeprecation() with less than 3 args and the getDeprecation method was
* introduced at the same time. By checking if getDeprecation() exists,
* we can determine the correct param count to use when calling setDeprecated.
*
* @return array{0:string}|array{0:string, 1: numeric-string, string}
*/
private function getDeprecationMsg(string $message, string $version): array
{
if (method_exists(BaseNode::class, 'getDeprecation')) {
return [
'symfony/monolog-bundle',
$version,
$message,
];
}

return [$message];
}
}
50 changes: 18 additions & 32 deletions DependencyInjection/MonologExtension.php
Expand Up @@ -32,7 +32,6 @@
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\HttpKernel\Log\DebugLoggerConfigurator;
use Symfony\Contracts\HttpClient\HttpClientInterface;

Expand All @@ -56,10 +55,6 @@ class MonologExtension extends Extension
*/
public function load(array $configs, ContainerBuilder $container)
{
if (class_exists(FullStack::class) && Kernel::MAJOR_VERSION < 5 && Logger::API >= 2) {
throw new \RuntimeException('Symfony 5 is required for Monolog 2 support. Please downgrade Monolog to version 1.');
}

$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);

Expand Down Expand Up @@ -107,29 +102,27 @@ public function load(array $configs, ContainerBuilder $container)

$container->setParameter('monolog.additional_channels', isset($config['channels']) ? $config['channels'] : []);

if (method_exists($container, 'registerForAutoconfiguration')) {
if (interface_exists(ProcessorInterface::class)) {
$container->registerForAutoconfiguration(ProcessorInterface::class)
->addTag('monolog.processor');
} else {
$container->registerForAutoconfiguration(WebProcessor::class)
->addTag('monolog.processor');
}
if (interface_exists(ResettableInterface::class)) {
$container->registerForAutoconfiguration(ResettableInterface::class)
->addTag('kernel.reset', ['method' => 'reset']);
}
$container->registerForAutoconfiguration(TokenProcessor::class)
if (interface_exists(ProcessorInterface::class)) {
$container->registerForAutoconfiguration(ProcessorInterface::class)
->addTag('monolog.processor');
if (interface_exists(HttpClientInterface::class)) {
$handlerAutoconfiguration = $container->registerForAutoconfiguration(HandlerInterface::class);
$handlerAutoconfiguration->setBindings($handlerAutoconfiguration->getBindings() + [
HttpClientInterface::class => new BoundArgument(new Reference('monolog.http_client'), false),
]);
}
} else {
$container->registerForAutoconfiguration(WebProcessor::class)
->addTag('monolog.processor');
}
if (interface_exists(ResettableInterface::class)) {
$container->registerForAutoconfiguration(ResettableInterface::class)
->addTag('kernel.reset', ['method' => 'reset']);
}
$container->registerForAutoconfiguration(TokenProcessor::class)
->addTag('monolog.processor');
if (interface_exists(HttpClientInterface::class)) {
$handlerAutoconfiguration = $container->registerForAutoconfiguration(HandlerInterface::class);
$handlerAutoconfiguration->setBindings($handlerAutoconfiguration->getBindings() + [
HttpClientInterface::class => new BoundArgument(new Reference('monolog.http_client'), false),
]);
}

if (80000 <= \PHP_VERSION_ID && method_exists($container, 'registerAttributeForAutoconfiguration')) {
if (80000 <= \PHP_VERSION_ID) {
$container->registerAttributeForAutoconfiguration(AsMonologProcessor::class, static function (ChildDefinition $definition, AsMonologProcessor $attribute, \Reflector $reflector): void {
$tagAttributes = get_object_vars($attribute);
if ($reflector instanceof \ReflectionMethod) {
Expand Down Expand Up @@ -431,9 +424,6 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
$container->setDefinition($handlerId.'.not_found_strategy', $activationDef);
$activation = new Reference($handlerId.'.not_found_strategy');
} elseif (!empty($handler['excluded_http_codes'])) {
if (!class_exists('Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy')) {
throw new \LogicException('"excluded_http_codes" cannot be used as your version of Monolog bridge does not support it.');
}
$activationDef = new Definition('Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy', [
new Reference('request_stack'),
$handler['excluded_http_codes'],
Expand Down Expand Up @@ -888,10 +878,6 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
]);
break;
case 'server_log':
if (!class_exists('Symfony\Bridge\Monolog\Handler\ServerLogHandler')) {
throw new \RuntimeException('The ServerLogHandler is not available. Please update "symfony/monolog-bridge" to 3.3.');
}

$definition->setArguments([
$handler['host'],
$handler['level'],
Expand Down
7 changes: 4 additions & 3 deletions MonologBundle.php
Expand Up @@ -27,21 +27,22 @@
*/
class MonologBundle extends Bundle
{
/**
* @return void
*/
public function build(ContainerBuilder $container)
{
parent::build($container);

$container->addCompilerPass($channelPass = new LoggerChannelPass());
if (!class_exists('Symfony\Bridge\Monolog\Processor\DebugProcessor') || !class_exists('Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddDebugLogProcessorPass')) {
$container->addCompilerPass(new DebugHandlerPass($channelPass));
}
$container->addCompilerPass(new FixEmptyLoggerPass($channelPass));
$container->addCompilerPass(new AddProcessorsPass());
$container->addCompilerPass(new AddSwiftMailerTransportPass());
}

/**
* @internal
* @return void
*/
public static function includeStacktraces(HandlerInterface $handler)
{
Expand Down
16 changes: 0 additions & 16 deletions Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php
Expand Up @@ -56,10 +56,6 @@ public function testProcess()

public function testTypeHintedAliasesExistForEachChannel()
{
if (!\method_exists(ContainerBuilder::class, 'registerAliasForArgument')) {
$this->markTestSkipped('Need DependencyInjection 4.2+ to register type-hinted aliases for channels.');
}

$container = $this->getContainer();
$expectedChannels = ['test', 'foo', 'bar', 'additional'];

Expand All @@ -81,10 +77,6 @@ public function testProcessSetters()

public function testAutowiredLoggerArgumentsAreReplacedWithChannelLogger()
{
if (!\method_exists('Symfony\Component\DependencyInjection\Definition', 'getBindings')) {
$this->markTestSkipped('Need DependencyInjection 3.4+ to autowire channel logger.');
}

$container = $this->getFunctionalContainer();

$dummyService = $container->register('dummy_service', 'Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler\DummyService')
Expand All @@ -99,10 +91,6 @@ public function testAutowiredLoggerArgumentsAreReplacedWithChannelLogger()

public function testAutowiredLoggerArgumentsAreReplacedWithChannelLoggerWhenAutoconfigured()
{
if (!\method_exists('Symfony\Component\DependencyInjection\Definition', 'getBindings')) {
$this->markTestSkipped('Need DependencyInjection 3.4+ to autowire channel logger.');
}

$container = $this->getFunctionalContainer();

$container->registerForAutoconfiguration('Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler\DummyService')
Expand All @@ -121,10 +109,6 @@ public function testAutowiredLoggerArgumentsAreReplacedWithChannelLoggerWhenAuto

public function testAutowiredLoggerArgumentsAreNotReplacedWithChannelLoggerIfLoggerArgumentIsConfiguredExplicitly()
{
if (!\method_exists('Symfony\Component\DependencyInjection\Definition', 'getBindings')) {
$this->markTestSkipped('Need DependencyInjection 3.4+ to autowire channel logger.');
}

$container = $this->getFunctionalContainer();

$dummyService = $container->register('dummy_service', 'Symfony\Bundle\MonologBundle\Tests\DependencyInjection\Compiler\DummyService')
Expand Down
44 changes: 2 additions & 42 deletions Tests/DependencyInjection/FixtureMonologExtensionTest.php
Expand Up @@ -22,27 +22,9 @@

abstract class FixtureMonologExtensionTest extends DependencyInjectionTest
{
/** @group legacy */
public function testLegacyLoadWithSeveralHandlers()
{
if (class_exists(SwitchUserTokenProcessor::class)) {
$this->markTestSkipped('Symfony MonologBridge < 5.2 is needed.');
}

$this->doTestLoadWithSeveralHandlers('ERROR');
}

public function testLoadWithSeveralHandlers()
{
if (!class_exists(SwitchUserTokenProcessor::class)) {
$this->markTestSkipped('Symfony MonologBridge >= 5.2 is needed.');
}

$this->doTestLoadWithSeveralHandlers(new Definition(ErrorLevelActivationStrategy::class, ['ERROR']));
}

private function doTestLoadWithSeveralHandlers($activation)
{
$activation = new Definition(ErrorLevelActivationStrategy::class, ['ERROR']);
$container = $this->getContainer('multiple_handlers');

$this->assertTrue($container->hasDefinition('monolog.logger'));
Expand Down Expand Up @@ -70,27 +52,9 @@ private function doTestLoadWithSeveralHandlers($activation)
$this->assertDICConstructorArguments($handler, [new Reference('monolog.handler.nested2'), ['WARNING', 'ERROR'], 'EMERGENCY', true]);
}

/** @group legacy */
public function testLegacyLoadWithOverwriting()
{
if (class_exists(SwitchUserTokenProcessor::class)) {
$this->markTestSkipped('Symfony MonologBridge < 5.2 is needed.');
}

$this->doTestLoadWithOverwriting('ERROR');
}

public function testLoadWithOverwriting()
{
if (!class_exists(SwitchUserTokenProcessor::class)) {
$this->markTestSkipped('Symfony MonologBridge >= 5.2 is needed.');
}

$this->doTestLoadWithOverwriting(new Definition(ErrorLevelActivationStrategy::class, ['ERROR']));
}

private function doTestLoadWithOverwriting($activation)
{
$activation = new Definition(ErrorLevelActivationStrategy::class, ['ERROR']);
$container = $this->getContainer('overwriting');

$this->assertTrue($container->hasDefinition('monolog.logger'));
Expand Down Expand Up @@ -202,10 +166,6 @@ public function testSingleEmailRecipient()

public function testServerLog()
{
if (!class_exists('Symfony\Bridge\Monolog\Handler\ServerLogHandler')) {
$this->markTestSkipped('The ServerLogHandler is not available.');
}

$container = $this->getContainer('server_log');

$this->assertEquals([
Expand Down

0 comments on commit d320c9e

Please sign in to comment.