diff --git a/src/DependencyInjection/Compiler/MiddlewaresPass.php b/src/DependencyInjection/Compiler/MiddlewaresPass.php index be361991..734c5b93 100644 --- a/src/DependencyInjection/Compiler/MiddlewaresPass.php +++ b/src/DependencyInjection/Compiler/MiddlewaresPass.php @@ -6,6 +6,7 @@ use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; use function array_key_exists; use function array_keys; @@ -44,20 +45,21 @@ public function process(ContainerBuilder $container): void } foreach (array_keys($container->getParameter('doctrine.connections')) as $name) { - $middlewareDefs = []; + $middlewareRefs = []; $i = 0; foreach ($middlewareAbstractDefs as $id => $abstractDef) { if (isset($middlewareConnections[$id]) && ! array_key_exists($name, $middlewareConnections[$id])) { continue; } - $middlewareDefs[$id] = [ - $childDef = $container->setDefinition( - sprintf('%s.%s', $id, $name), - new ChildDefinition($id), - ), - ++$i, - ]; + $childDef = $container->setDefinition( + $childId = sprintf('%s.%s', $id, $name), + (new ChildDefinition($id)) + ->setTags($abstractDef->getTags())->clearTag('doctrine.middleware') + ->setAutoconfigured($abstractDef->isAutoconfigured()) + ->setAutowired($abstractDef->isAutowired()), + ); + $middlewareRefs[$id] = [new Reference($childId), ++$i]; if (! is_subclass_of($abstractDef->getClass(), ConnectionNameAwareInterface::class)) { continue; @@ -66,21 +68,21 @@ public function process(ContainerBuilder $container): void $childDef->addMethodCall('setConnectionName', [$name]); } - $middlewareDefs = array_map( - static fn ($id, $def) => [ + $middlewareRefs = array_map( + static fn (string $id, array $ref) => [ $middlewareConnections[$id][$name] ?? $middlewarePriorities[$id] ?? 0, - $def[1], - $def[0], + $ref[1], + $ref[0], ], - array_keys($middlewareDefs), - array_values($middlewareDefs), + array_keys($middlewareRefs), + array_values($middlewareRefs), ); - uasort($middlewareDefs, static fn ($a, $b) => $b[0] <=> $a[0] ?: $a[1] <=> $b[1]); - $middlewareDefs = array_map(static fn ($value) => $value[2], $middlewareDefs); + uasort($middlewareRefs, static fn (array $a, array $b): int => $b[0] <=> $a[0] ?: $a[1] <=> $b[1]); + $middlewareRefs = array_map(static fn (array $value): Reference => $value[2], $middlewareRefs); $container ->getDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name)) - ->addMethodCall('setMiddlewares', [$middlewareDefs]); + ->addMethodCall('setMiddlewares', [$middlewareRefs]); } } } diff --git a/tests/DependencyInjection/Compiler/MiddlewarePassTest.php b/tests/DependencyInjection/Compiler/MiddlewarePassTest.php index 06dc92cb..e21f3c76 100644 --- a/tests/DependencyInjection/Compiler/MiddlewarePassTest.php +++ b/tests/DependencyInjection/Compiler/MiddlewarePassTest.php @@ -13,6 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Reference; use function array_map; use function implode; @@ -296,6 +297,28 @@ public function testAddMiddlewareOrderingWithInheritedPriorityPerConnection(): v $this->assertMiddlewareOrdering($container, 'conn2', [PHP7Middleware::class, 'some_middleware_class']); } + public function testInjectedMiddlewaresPreserveParentDefinition(): void + { + $container = $this->createContainer(static function (ContainerBuilder $container): void { + $container + ->register('middleware', PHP7Middleware::class) + ->setPublic(true) + ->setAutowired(true) + ->setAutoconfigured(true) + ->addTag('doctrine.middleware')->addTag('custom.tag'); + $container + ->setAlias('conf_conn', 'doctrine.dbal.conn1_connection.configuration') + ->setPublic(true); // Avoid removal and inlining + }); + $this->assertMiddlewareInjected($container, 'conn', PHP7Middleware::class); + $this->assertNotNull($definition = $container->getDefinition('middleware.conn1')); + $this->assertCount(1, $middlewares = $this->getMiddlewaresForConn($container, 'conn', PHP7Middleware::class)); + $this->assertSame(true, $definition->isAutowired()); + $this->assertSame(true, $definition->isAutoconfigured()); + $this->assertSame(['custom.tag' => [[]]], $definition->getTags()); + $this->assertSame($middlewares[0], $definition); + } + /** @requires PHP 8 */ public function testAddMiddlewareOrderingWithAttributeForAutoconfiguration(): void { @@ -443,6 +466,10 @@ private function getMiddlewaresForConn(ContainerBuilder $container, string $conn } foreach ($call[1][0] as $middlewareDef) { + if ($middlewareDef instanceof Reference) { + $middlewareDef = $container->getDefinition($middlewareDef->__toString()); + } + if (isset($middlewareClass) && $middlewareDef->getClass() !== $middlewareClass) { continue; }