|
4 | 4 |
|
5 | 5 | namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler; |
6 | 6 |
|
| 7 | +use Doctrine\Bundle\DoctrineBundle\Attribute\AsDatabaseType; |
7 | 8 | use Doctrine\DBAL\Types\Type; |
| 9 | +use ReflectionClass; |
| 10 | +use Symfony\Component\DependencyInjection\ChildDefinition; |
8 | 11 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; |
9 | 12 | use Symfony\Component\DependencyInjection\ContainerBuilder; |
10 | 13 | use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
|
17 | 20 | /** @internal */ |
18 | 21 | final class RegisterDbalTypePass implements CompilerPassInterface |
19 | 22 | { |
| 23 | + private const string TAG = 'doctrine.dbal.type'; |
| 24 | + |
| 25 | + /** |
| 26 | + * @param ReflectionClass<T> $reflector |
| 27 | + * |
| 28 | + * @template T of ReflectionClass |
| 29 | + */ |
| 30 | + public static function autoconfigureFromAttribute(ChildDefinition $definition, AsDatabaseType $type, ReflectionClass $reflector): void |
| 31 | + { |
| 32 | + $attributes = [ |
| 33 | + 'name' => $type->name ?? $reflector->name, |
| 34 | + ]; |
| 35 | + |
| 36 | + // Determine if the version of symfony/dependency-injection is >= 7.3 |
| 37 | + /** @phpstan-ignore function.alreadyNarrowedType */ |
| 38 | + if (method_exists($definition, 'addResourceTag')) { |
| 39 | + $definition->addResourceTag(self::TAG, $attributes); |
| 40 | + } else { |
| 41 | + // Needed to keep compatibility with symfony/dependency-injection < 7.3 |
| 42 | + $definition->addTag(self::TAG, $attributes) |
| 43 | + ->addTag('container.excluded', ['source' => sprintf('by tag "%s"', self::TAG)]); |
| 44 | + } |
| 45 | + } |
| 46 | + |
20 | 47 | public function process(ContainerBuilder $container): void |
21 | 48 | { |
22 | 49 | $types = $container->getParameter('doctrine.dbal.connection_factory.types'); |
@@ -46,35 +73,33 @@ public function process(ContainerBuilder $container): void |
46 | 73 | /** @return array<string, array<array{name?: string}>> */ |
47 | 74 | private function findTaggedResourceIds(ContainerBuilder $container): array |
48 | 75 | { |
49 | | - $tagName = 'doctrine.dbal.type'; |
50 | | - |
51 | 76 | // Determine if the version of symfony/dependency-injection is >= 7.3 |
52 | 77 | /** @phpstan-ignore function.alreadyNarrowedType */ |
53 | 78 | if (method_exists($container, 'findTaggedResourceIds')) { |
54 | | - return $container->findTaggedResourceIds($tagName); |
| 79 | + return $container->findTaggedResourceIds(self::TAG); |
55 | 80 | } |
56 | 81 |
|
57 | 82 | // Needed to keep compatibility with symfony/dependency-injection < 7.3 |
58 | 83 | $tags = []; |
59 | 84 | foreach ($container->getDefinitions() as $id => $definition) { |
60 | | - if (! $definition->hasTag($tagName)) { |
| 85 | + if (! $definition->hasTag(self::TAG)) { |
61 | 86 | continue; |
62 | 87 | } |
63 | 88 |
|
64 | 89 | if (! $definition->hasTag('container.excluded')) { |
65 | | - throw new InvalidArgumentException(sprintf('The resource "%s" tagged "%s" is missing the "container.excluded" tag.', $id, $tagName)); |
| 90 | + throw new InvalidArgumentException(sprintf('The resource "%s" tagged "%s" is missing the "container.excluded" tag.', $id, self::TAG)); |
66 | 91 | } |
67 | 92 |
|
68 | 93 | $class = $container->getParameterBag()->resolveValue($definition->getClass()); |
69 | 94 | if (! $class || $definition->isAbstract()) { |
70 | | - throw new InvalidArgumentException(sprintf('The resource "%s" tagged "%s" must have a class and not be abstract.', $id, $tagName)); |
| 95 | + throw new InvalidArgumentException(sprintf('The resource "%s" tagged "%s" must have a class and not be abstract.', $id, self::TAG)); |
71 | 96 | } |
72 | 97 |
|
73 | 98 | if ($definition->getClass() !== $class) { |
74 | 99 | $definition->setClass($class); |
75 | 100 | } |
76 | 101 |
|
77 | | - $tags[$id] = $definition->getTag($tagName); |
| 102 | + $tags[$id] = $definition->getTag(self::TAG); |
78 | 103 | } |
79 | 104 |
|
80 | 105 | return $tags; |
|
0 commit comments