Loading core/lib/Drupal/Core/DependencyInjection/Compiler/BackendCompilerPass.php +2 −3 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ class BackendCompilerPass implements CompilerPassInterface { * {@inheritdoc} */ public function process(ContainerBuilder $container): void { $driver_backend = NULL; if ($container->hasParameter('default_backend')) { $default_backend = $container->getParameter('default_backend'); // Opt out from the default backend. Loading @@ -64,10 +63,10 @@ public function process(ContainerBuilder $container): void { if ($container->hasAlias($id)) { continue; } if ($container->hasDefinition("$driver_backend.$id") || $container->hasAlias("$driver_backend.$id")) { if (isset($driver_backend) && ($container->hasDefinition("$driver_backend.$id") || $container->hasAlias("$driver_backend.$id"))) { $container->setAlias($id, new Alias("$driver_backend.$id")); } elseif ($container->hasDefinition("$default_backend.$id") || $container->hasAlias("$default_backend.$id")) { elseif (!empty($default_backend) && ($container->hasDefinition("$default_backend.$id") || $container->hasAlias("$default_backend.$id"))) { $container->setAlias($id, new Alias("$default_backend.$id")); } } Loading core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/BackendCompilerPassTest.php +88 −0 Original line number Diff line number Diff line Loading @@ -4,8 +4,10 @@ namespace Drupal\Tests\Core\DependencyInjection\Compiler; use Drupal\Core\Database\Connection; use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass; use Drupal\Tests\UnitTestCase; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; Loading Loading @@ -92,6 +94,16 @@ public function testProcess(): void { $container->setDefinition('DriverTestMysql.service', new Definition(__NAMESPACE__ . '\\ServiceClassDriverTestMysql')); $this->backendPass->process($container); $this->assertEquals($prefix . 'DriverTestMysql', get_class($container->get('service'))); // Verify that if the container has a default_backend parameter, // and there is a service named ".my-service", the right alias is created. $container = $this->getMockDriverContainerWithDefaultBackendParameterArgumentAndDotPrefixedService(); $this->backendPass->process($container); // Verify that if the db service returns no driver, no invalid aliases are // created. $container = $this->getMockDriverContainerWithNullDriverBackend(); $this->backendPass->process($container); } /** Loading Loading @@ -154,6 +166,82 @@ protected function getDriverTestMysqlContainer($service) { return $container; } /** * Creates a container with a database mock definition in it. * * This mock won't declare a driver nor databaseType to ensure no invalid * aliases are set. * * @return \Symfony\Component\DependencyInjection\ContainerBuilder * The container with a mock database service in it. */ protected function getMockDriverContainerWithNullDriverBackend(): ContainerBuilder&MockObject { $container = $this->getMockBuilder(ContainerBuilder::class)->getMock(); $mock = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); $mock->expects($this->once()) ->method('driver') ->willReturn(NULL); $mock->expects($this->once()) ->method('databaseType') ->willReturn(NULL); $container->expects($this->any()) ->method('get') ->with('database') ->willReturn($mock); $container->expects($this->once()) ->method('findTaggedServiceIds') ->willReturn(['fakeService' => ['class' => 'fakeServiceClass']]); $container->expects($this->never()) ->method('hasDefinition') ->with('.fakeService') ->willReturn(TRUE); $container->expects($this->never()) ->method('setAlias'); return $container; } /** * Creates a container with a database mock definition in it. * * This mock container has a default_backend parameter and a dot-prefixed * service to verify the right aliases are set. * * @return \Symfony\Component\DependencyInjection\ContainerBuilder * The container with a mock database service in it. */ protected function getMockDriverContainerWithDefaultBackendParameterArgumentAndDotPrefixedService(): ContainerBuilder&MockObject { $container = $this->getMockBuilder(ContainerBuilder::class)->getMock(); $container->expects($this->once()) ->method('hasParameter') ->with('default_backend') ->willReturn(TRUE); $container->expects($this->once()) ->method('getParameter') ->with('default_backend') ->willReturn('a_valid_default_backend'); $mock = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); $mock->expects($this->never()) ->method('driver'); $mock->expects($this->never()) ->method('databaseType'); $container->expects($this->any()) ->method('get') ->with('database') ->willReturn($mock); $container->expects($this->once()) ->method('findTaggedServiceIds') ->willReturn(['fakeService' => ['class' => 'fakeServiceClass']]); $container->expects($this->once()) ->method('hasDefinition') ->with('a_valid_default_backend.fakeService') ->willReturn(TRUE); $container->expects($this->once()) ->method('setAlias') ->with('fakeService', new Alias('a_valid_default_backend.fakeService')); return $container; } } /** Loading Loading
core/lib/Drupal/Core/DependencyInjection/Compiler/BackendCompilerPass.php +2 −3 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ class BackendCompilerPass implements CompilerPassInterface { * {@inheritdoc} */ public function process(ContainerBuilder $container): void { $driver_backend = NULL; if ($container->hasParameter('default_backend')) { $default_backend = $container->getParameter('default_backend'); // Opt out from the default backend. Loading @@ -64,10 +63,10 @@ public function process(ContainerBuilder $container): void { if ($container->hasAlias($id)) { continue; } if ($container->hasDefinition("$driver_backend.$id") || $container->hasAlias("$driver_backend.$id")) { if (isset($driver_backend) && ($container->hasDefinition("$driver_backend.$id") || $container->hasAlias("$driver_backend.$id"))) { $container->setAlias($id, new Alias("$driver_backend.$id")); } elseif ($container->hasDefinition("$default_backend.$id") || $container->hasAlias("$default_backend.$id")) { elseif (!empty($default_backend) && ($container->hasDefinition("$default_backend.$id") || $container->hasAlias("$default_backend.$id"))) { $container->setAlias($id, new Alias("$default_backend.$id")); } } Loading
core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/BackendCompilerPassTest.php +88 −0 Original line number Diff line number Diff line Loading @@ -4,8 +4,10 @@ namespace Drupal\Tests\Core\DependencyInjection\Compiler; use Drupal\Core\Database\Connection; use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass; use Drupal\Tests\UnitTestCase; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; Loading Loading @@ -92,6 +94,16 @@ public function testProcess(): void { $container->setDefinition('DriverTestMysql.service', new Definition(__NAMESPACE__ . '\\ServiceClassDriverTestMysql')); $this->backendPass->process($container); $this->assertEquals($prefix . 'DriverTestMysql', get_class($container->get('service'))); // Verify that if the container has a default_backend parameter, // and there is a service named ".my-service", the right alias is created. $container = $this->getMockDriverContainerWithDefaultBackendParameterArgumentAndDotPrefixedService(); $this->backendPass->process($container); // Verify that if the db service returns no driver, no invalid aliases are // created. $container = $this->getMockDriverContainerWithNullDriverBackend(); $this->backendPass->process($container); } /** Loading Loading @@ -154,6 +166,82 @@ protected function getDriverTestMysqlContainer($service) { return $container; } /** * Creates a container with a database mock definition in it. * * This mock won't declare a driver nor databaseType to ensure no invalid * aliases are set. * * @return \Symfony\Component\DependencyInjection\ContainerBuilder * The container with a mock database service in it. */ protected function getMockDriverContainerWithNullDriverBackend(): ContainerBuilder&MockObject { $container = $this->getMockBuilder(ContainerBuilder::class)->getMock(); $mock = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); $mock->expects($this->once()) ->method('driver') ->willReturn(NULL); $mock->expects($this->once()) ->method('databaseType') ->willReturn(NULL); $container->expects($this->any()) ->method('get') ->with('database') ->willReturn($mock); $container->expects($this->once()) ->method('findTaggedServiceIds') ->willReturn(['fakeService' => ['class' => 'fakeServiceClass']]); $container->expects($this->never()) ->method('hasDefinition') ->with('.fakeService') ->willReturn(TRUE); $container->expects($this->never()) ->method('setAlias'); return $container; } /** * Creates a container with a database mock definition in it. * * This mock container has a default_backend parameter and a dot-prefixed * service to verify the right aliases are set. * * @return \Symfony\Component\DependencyInjection\ContainerBuilder * The container with a mock database service in it. */ protected function getMockDriverContainerWithDefaultBackendParameterArgumentAndDotPrefixedService(): ContainerBuilder&MockObject { $container = $this->getMockBuilder(ContainerBuilder::class)->getMock(); $container->expects($this->once()) ->method('hasParameter') ->with('default_backend') ->willReturn(TRUE); $container->expects($this->once()) ->method('getParameter') ->with('default_backend') ->willReturn('a_valid_default_backend'); $mock = $this->getMockBuilder(Connection::class)->disableOriginalConstructor()->getMock(); $mock->expects($this->never()) ->method('driver'); $mock->expects($this->never()) ->method('databaseType'); $container->expects($this->any()) ->method('get') ->with('database') ->willReturn($mock); $container->expects($this->once()) ->method('findTaggedServiceIds') ->willReturn(['fakeService' => ['class' => 'fakeServiceClass']]); $container->expects($this->once()) ->method('hasDefinition') ->with('a_valid_default_backend.fakeService') ->willReturn(TRUE); $container->expects($this->once()) ->method('setAlias') ->with('fakeService', new Alias('a_valid_default_backend.fakeService')); return $container; } } /** Loading