IdGeneratorPass.php 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <?php
  2. namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
  3. use Doctrine\Bundle\DoctrineBundle\Mapping\ClassMetadataFactory;
  4. use Doctrine\Bundle\DoctrineBundle\Mapping\MappingDriver;
  5. use Doctrine\ORM\Mapping\ClassMetadataFactory as ORMClassMetadataFactory;
  6. use Symfony\Component\DependencyInjection\Alias;
  7. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  8. use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
  9. use Symfony\Component\DependencyInjection\ContainerBuilder;
  10. use Symfony\Component\DependencyInjection\Reference;
  11. use function array_combine;
  12. use function array_keys;
  13. use function array_map;
  14. use function sprintf;
  15. final class IdGeneratorPass implements CompilerPassInterface
  16. {
  17. public const ID_GENERATOR_TAG = 'doctrine.id_generator';
  18. public const CONFIGURATION_TAG = 'doctrine.orm.configuration';
  19. public function process(ContainerBuilder $container): void
  20. {
  21. $generatorIds = array_keys($container->findTaggedServiceIds(self::ID_GENERATOR_TAG));
  22. // when ORM is not enabled
  23. if (! $container->hasDefinition('doctrine.orm.configuration') || ! $generatorIds) {
  24. return;
  25. }
  26. $generatorRefs = array_map(static function ($id) {
  27. return new Reference($id);
  28. }, $generatorIds);
  29. $ref = ServiceLocatorTagPass::register($container, array_combine($generatorIds, $generatorRefs));
  30. $container->setAlias('doctrine.id_generator_locator', new Alias((string) $ref, false));
  31. foreach ($container->findTaggedServiceIds(self::CONFIGURATION_TAG) as $id => $tags) {
  32. $configurationDef = $container->getDefinition($id);
  33. $methodCalls = $configurationDef->getMethodCalls();
  34. $metadataDriverImpl = null;
  35. foreach ($methodCalls as $i => [$method, $arguments]) {
  36. if ($method === 'setMetadataDriverImpl') {
  37. $metadataDriverImpl = (string) $arguments[0];
  38. }
  39. if ($method !== 'setClassMetadataFactoryName') {
  40. continue;
  41. }
  42. if ($arguments[0] !== ORMClassMetadataFactory::class && $arguments[0] !== ClassMetadataFactory::class) {
  43. $class = $container->getReflectionClass($arguments[0]);
  44. if ($class && $class->isSubclassOf(ClassMetadataFactory::class)) {
  45. break;
  46. }
  47. continue 2;
  48. }
  49. $methodCalls[$i] = ['setClassMetadataFactoryName', [ClassMetadataFactory::class]];
  50. }
  51. if ($metadataDriverImpl === null) {
  52. continue;
  53. }
  54. $configurationDef->setMethodCalls($methodCalls);
  55. $container->register('.' . $metadataDriverImpl, MappingDriver::class)
  56. ->setDecoratedService($metadataDriverImpl)
  57. ->setArguments([
  58. new Reference(sprintf('.%s.inner', $metadataDriverImpl)),
  59. new Reference('doctrine.id_generator_locator'),
  60. ]);
  61. }
  62. }
  63. }