diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php index 67a1337a659..5fb8d936021 100644 --- a/core/lib/Drupal/Core/CoreServiceProvider.php +++ b/core/lib/Drupal/Core/CoreServiceProvider.php @@ -9,22 +9,24 @@ use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass; use Drupal\Core\DependencyInjection\Compiler\CorsCompilerPass; use Drupal\Core\DependencyInjection\Compiler\DeprecatedServicePass; use Drupal\Core\DependencyInjection\Compiler\DevelopmentSettingsPass; +use Drupal\Core\DependencyInjection\Compiler\LoggerAwarePass; +use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass; use Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass; +use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass; +use Drupal\Core\DependencyInjection\Compiler\RegisterEventSubscribersPass; +use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass; +use Drupal\Core\DependencyInjection\Compiler\RegisterStreamWrappersPass; use Drupal\Core\DependencyInjection\Compiler\StackedKernelPass; use Drupal\Core\DependencyInjection\Compiler\StackedSessionHandlerPass; -use Drupal\Core\DependencyInjection\Compiler\RegisterStreamWrappersPass; +use Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass; use Drupal\Core\DependencyInjection\Compiler\TwigExtensionPass; +use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceModifierInterface; use Drupal\Core\DependencyInjection\ServiceProviderInterface; -use Drupal\Core\DependencyInjection\ContainerBuilder; -use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass; -use Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass; -use Drupal\Core\DependencyInjection\Compiler\RegisterEventSubscribersPass; -use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass; -use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass; use Drupal\Core\Plugin\PluginManagerPass; use Drupal\Core\Render\MainContent\MainContentRenderersPass; use Drupal\Core\Site\Settings; +use Psr\Log\LoggerAwareInterface; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -81,6 +83,7 @@ class CoreServiceProvider implements ServiceProviderInterface, ServiceModifierIn // Add a compiler pass for registering event subscribers. $container->addCompilerPass(new RegisterEventSubscribersPass(), PassConfig::TYPE_AFTER_REMOVING); + $container->addCompilerPass(new LoggerAwarePass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new RegisterAccessChecksPass()); @@ -99,6 +102,10 @@ class CoreServiceProvider implements ServiceProviderInterface, ServiceModifierIn $container->registerForAutoconfiguration(EventSubscriberInterface::class) ->addTag('event_subscriber'); + + $container->registerForAutoconfiguration(LoggerAwareInterface::class) + ->addTag('logger_aware'); + } /** diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/LoggerAwarePass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/LoggerAwarePass.php new file mode 100644 index 00000000000..4dd9e37de00 --- /dev/null +++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/LoggerAwarePass.php @@ -0,0 +1,37 @@ +findTaggedServiceIds('logger_aware') as $id => $attributes) { + $definition = $container->getDefinition($id); + // Skip services that are already calling setLogger(). + if ($definition->hasMethodCall('setLogger')) { + continue; + } + if (!is_subclass_of($definition->getClass(), $interface)) { + throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); + } + $providerTag = $definition->getTag('_provider'); + $loggerId = 'logger.channel.' . $providerTag[0]['provider']; + if ($container->has($loggerId)) { + $definition->addMethodCall('setLogger', [new Reference($loggerId)]); + } + } + } + +} diff --git a/core/modules/system/tests/modules/logger_aware_test/logger_aware_test.info.yml b/core/modules/system/tests/modules/logger_aware_test/logger_aware_test.info.yml new file mode 100644 index 00000000000..4dd160a8bed --- /dev/null +++ b/core/modules/system/tests/modules/logger_aware_test/logger_aware_test.info.yml @@ -0,0 +1,5 @@ +name: 'Logger Aware Autoconfigure Test' +type: module +description: 'Test logger aware auto-configuration support' +package: Testing +version: VERSION diff --git a/core/modules/system/tests/modules/logger_aware_test/logger_aware_test.services.yml b/core/modules/system/tests/modules/logger_aware_test/logger_aware_test.services.yml new file mode 100644 index 00000000000..8fc353b61d5 --- /dev/null +++ b/core/modules/system/tests/modules/logger_aware_test/logger_aware_test.services.yml @@ -0,0 +1,18 @@ +services: + _defaults: + autoconfigure: true + + logger_aware_test.logger_aware_stub: + class: Drupal\logger_aware_test\LoggerAwareStub + + logger.channel.logger_aware_test: + parent: logger.channel_base + arguments: ['logger_aware_test'] + + logger.channel.logger_stub: + class: Drupal\logger_aware_test\LoggerStub + + logger_aware_test.logger_aware_existing: + class: Drupal\logger_aware_test\LoggerAwareStub + calls: + - [setLogger, ['@logger.channel.logger_stub']] diff --git a/core/modules/system/tests/modules/logger_aware_test/src/LoggerAwareStub.php b/core/modules/system/tests/modules/logger_aware_test/src/LoggerAwareStub.php new file mode 100644 index 00000000000..a11a6daef8e --- /dev/null +++ b/core/modules/system/tests/modules/logger_aware_test/src/LoggerAwareStub.php @@ -0,0 +1,25 @@ +logger; + } + +} diff --git a/core/modules/system/tests/modules/logger_aware_test/src/LoggerStub.php b/core/modules/system/tests/modules/logger_aware_test/src/LoggerStub.php new file mode 100644 index 00000000000..734f7200de7 --- /dev/null +++ b/core/modules/system/tests/modules/logger_aware_test/src/LoggerStub.php @@ -0,0 +1,19 @@ +container; + $logger = $container->get('logger.channel.logger_aware_test'); + $this->assertInstanceOf(LoggerInterface::class, $logger); + $logger_aware_stub = $container->get('logger_aware_test.logger_aware_stub'); + $this->assertInstanceOf(LoggerAwareStub::class, $logger_aware_stub); + $this->assertSame($logger, $logger_aware_stub->getLogger()); + } + + /** + * Tests that existing loggers are not overwritten. + * + * @covers ::process + */ + public function testExistingLogger(): void { + $container = $this->container; + $logger_aware_stub = $container->get('logger_aware_test.logger_aware_existing'); + $logger = $logger_aware_stub->getLogger(); + $this->assertInstanceOf(LoggerStub::class, $logger); + } + +}