diff --git a/config/messenger.xml b/config/messenger.xml
index aefa4017..1ca9faa9 100644
--- a/config/messenger.xml
+++ b/config/messenger.xml
@@ -52,11 +52,11 @@
-
+
-
+
diff --git a/config/orm.xml b/config/orm.xml
index 90d3de97..b99cd858 100644
--- a/config/orm.xml
+++ b/config/orm.xml
@@ -148,11 +148,11 @@
-
+
-
+
@@ -160,7 +160,7 @@
-
+
diff --git a/docs/configuration.rst b/docs/configuration.rst
index a6719cd1..dc60769e 100644
--- a/docs/configuration.rst
+++ b/docs/configuration.rst
@@ -740,7 +740,7 @@ configuration for the ORM and there are several configuration options that you
can control. The following configuration options exist for a mapping:
``type``
- One of ``annotation``, ``xml``, ``yml``, ``php`` or ``staticphp``.
+ One of ``attribute``, ``xml``, ``yml``, ``php`` or ``staticphp``.
This specifies which type of metadata type your mapping uses.
``dir``
diff --git a/docs/custom-id-generators.rst b/docs/custom-id-generators.rst
index 4c6141ef..11de3d76 100644
--- a/docs/custom-id-generators.rst
+++ b/docs/custom-id-generators.rst
@@ -7,7 +7,7 @@ and implement the custom logic in the ``generate(EntityManager $em, $entity)``
method. Before Doctrine bundle 2.3, custom ID generators were always created
without any constructor arguments.
-Starting with Doctrine bundle 2.3, the ``CustomIdGenerator`` annotation can be
+Starting with Doctrine bundle 2.3, the ``CustomIdGenerator`` attribute can be
used to reference any services tagged with the ``doctrine.id_generator`` tag.
If you enable autoconfiguration (which is the default most of the time), Symfony
will add this tag for you automatically if you implement your own id-generators.
@@ -28,12 +28,10 @@ are provided: ``doctrine.ulid_generator`` to generate ULIDs, and
*/
class User
{
- /**
- * @Id
- * @Column(type="uuid")
- * @ORM\GeneratedValue(strategy="CUSTOM")
- * @ORM\CustomIdGenerator("doctrine.uuid_generator")
- */
+ #[ORM\Id]
+ #[ORM\Column(type: 'uuid')]
+ #[ORM\GeneratedValue(strategy: 'CUSTOM')]
+ #[ORM\CustomIdGenerator('doctrine.uuid_generator')]
private $id;
// ....
diff --git a/docs/entity-listeners.rst b/docs/entity-listeners.rst
index e08c7b34..35c4483e 100644
--- a/docs/entity-listeners.rst
+++ b/docs/entity-listeners.rst
@@ -2,7 +2,7 @@ Entity Listeners
================
Entity listeners that are services must be registered with the entity listener
-resolver. On top of the annotation in the entity class, you have to tag the
+resolver. On top of the annotation/attribute in the entity class, you have to tag the
service with ``doctrine.orm.entity_listener`` for it to be automatically added
to the resolver. Use the (optional) ``entity_manager`` attribute to specify
which entity manager it should be registered with.
diff --git a/src/Command/DropDatabaseDoctrineCommand.php b/src/Command/DropDatabaseDoctrineCommand.php
index 8720d315..dc85b293 100644
--- a/src/Command/DropDatabaseDoctrineCommand.php
+++ b/src/Command/DropDatabaseDoctrineCommand.php
@@ -105,7 +105,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
try {
if ($shouldDropDatabase) {
- /** @psalm-suppress TypeDoesNotContainType Bogus error, Doctrine\DBAL\Schema\AbstractSchemaManager does contain Doctrine\DBAL\Schema\SQLiteSchemaManager */
if ($schemaManager instanceof SQLiteSchemaManager) {
// dropDatabase() is deprecated for Sqlite
$connection->close();
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 acb64f93..61b8bd9c 100644
--- a/tests/DependencyInjection/Compiler/MiddlewarePassTest.php
+++ b/tests/DependencyInjection/Compiler/MiddlewarePassTest.php
@@ -15,6 +15,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 class_exists;
@@ -306,6 +307,28 @@ public function testAddMiddlewareOrderingWithInheritedPriorityPerConnection(): v
$this->assertMiddlewareOrdering($container, 'conn2', $expectedMiddlewares);
}
+ 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
{
@@ -466,6 +489,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;
}