vendor/doctrine/doctrine-bundle/src/DoctrineBundle.php line 37

Open in your IDE?
  1. <?php
  2. namespace Doctrine\Bundle\DoctrineBundle;
  3. use Closure;
  4. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheCompatibilityPass;
  5. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheSchemaSubscriberPass;
  6. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DbalSchemaFilterPass;
  7. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
  8. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\IdGeneratorPass;
  9. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\MiddlewaresPass;
  10. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\RemoveLoggingMiddlewarePass;
  11. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\RemoveProfilerControllerPass;
  12. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
  13. use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\WellKnownSchemaFilterPass;
  14. use Doctrine\ORM\EntityManagerInterface;
  15. use Doctrine\ORM\Proxy\Autoloader;
  16. use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
  17. use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\DoctrineValidationPass;
  18. use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass;
  19. use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterUidTypePass;
  20. use Symfony\Bridge\Doctrine\DependencyInjection\Security\UserProvider\EntityFactory;
  21. use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension;
  22. use Symfony\Component\Console\Application;
  23. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  24. use Symfony\Component\DependencyInjection\Compiler\PassConfig;
  25. use Symfony\Component\DependencyInjection\ContainerBuilder;
  26. use Symfony\Component\HttpKernel\Bundle\Bundle;
  27. use function assert;
  28. use function class_exists;
  29. use function clearstatcache;
  30. use function dirname;
  31. use function spl_autoload_unregister;
  32. /** @final since 2.9 */
  33. class DoctrineBundle extends Bundle
  34. {
  35. private ?Closure $autoloader = null;
  36. /** @return void */
  37. public function build(ContainerBuilder $container)
  38. {
  39. parent::build($container);
  40. $container->addCompilerPass(new class () implements CompilerPassInterface {
  41. public function process(ContainerBuilder $container): void
  42. {
  43. if ($container->has('session.handler')) {
  44. return;
  45. }
  46. $container->removeDefinition('doctrine.orm.listeners.pdo_session_handler_schema_listener');
  47. }
  48. }, PassConfig::TYPE_BEFORE_OPTIMIZATION);
  49. $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine'), PassConfig::TYPE_BEFORE_OPTIMIZATION);
  50. if ($container->hasExtension('security')) {
  51. $security = $container->getExtension('security');
  52. if ($security instanceof SecurityExtension) {
  53. $security->addUserProviderFactory(new EntityFactory('entity', 'doctrine.orm.security.user.provider'));
  54. }
  55. }
  56. $container->addCompilerPass(new CacheCompatibilityPass());
  57. $container->addCompilerPass(new DoctrineValidationPass('orm'));
  58. $container->addCompilerPass(new EntityListenerPass());
  59. $container->addCompilerPass(new ServiceRepositoryCompilerPass());
  60. $container->addCompilerPass(new IdGeneratorPass());
  61. $container->addCompilerPass(new WellKnownSchemaFilterPass());
  62. $container->addCompilerPass(new DbalSchemaFilterPass());
  63. $container->addCompilerPass(new CacheSchemaSubscriberPass(), PassConfig::TYPE_BEFORE_REMOVING, -10);
  64. $container->addCompilerPass(new RemoveProfilerControllerPass());
  65. $container->addCompilerPass(new RemoveLoggingMiddlewarePass());
  66. $container->addCompilerPass(new MiddlewaresPass());
  67. if (! class_exists(RegisterUidTypePass::class)) {
  68. return;
  69. }
  70. $container->addCompilerPass(new RegisterUidTypePass());
  71. }
  72. /** @return void */
  73. public function boot()
  74. {
  75. // Register an autoloader for proxies to avoid issues when unserializing them
  76. // when the ORM is used.
  77. if (! $this->container->hasParameter('doctrine.orm.proxy_namespace')) {
  78. return;
  79. }
  80. $namespace = (string) $this->container->getParameter('doctrine.orm.proxy_namespace');
  81. $dir = (string) $this->container->getParameter('doctrine.orm.proxy_dir');
  82. $proxyGenerator = null;
  83. if ($this->container->getParameter('doctrine.orm.auto_generate_proxy_classes')) {
  84. // See https://github.com/symfony/symfony/pull/3419 for usage of references
  85. /** @psalm-suppress UnsupportedPropertyReferenceUsage */
  86. $container = &$this->container;
  87. $proxyGenerator = static function ($proxyDir, $proxyNamespace, $class) use (&$container): void {
  88. $originalClassName = (new DefaultProxyClassNameResolver())->resolveClassName($class);
  89. $registry = $container->get('doctrine');
  90. assert($registry instanceof Registry);
  91. foreach ($registry->getManagers() as $em) {
  92. assert($em instanceof EntityManagerInterface);
  93. if (! $em->getConfiguration()->getAutoGenerateProxyClasses()) {
  94. continue;
  95. }
  96. $metadataFactory = $em->getMetadataFactory();
  97. if ($metadataFactory->isTransient($originalClassName)) {
  98. continue;
  99. }
  100. $classMetadata = $metadataFactory->getMetadataFor($originalClassName);
  101. $em->getProxyFactory()->generateProxyClasses([$classMetadata]);
  102. clearstatcache(true, Autoloader::resolveFile($proxyDir, $proxyNamespace, $class));
  103. break;
  104. }
  105. };
  106. }
  107. $this->autoloader = Autoloader::register($dir, $namespace, $proxyGenerator);
  108. }
  109. /** @return void */
  110. public function shutdown()
  111. {
  112. if ($this->autoloader !== null) {
  113. spl_autoload_unregister($this->autoloader);
  114. $this->autoloader = null;
  115. }
  116. // Clear all entity managers to clear references to entities for GC
  117. if ($this->container->hasParameter('doctrine.entity_managers')) {
  118. foreach ($this->container->getParameter('doctrine.entity_managers') as $id) {
  119. if (! $this->container->initialized($id)) {
  120. continue;
  121. }
  122. $this->container->get($id)->clear();
  123. }
  124. }
  125. // Close all connections to avoid reaching too many connections in the process when booting again later (tests)
  126. if (! $this->container->hasParameter('doctrine.connections')) {
  127. return;
  128. }
  129. foreach ($this->container->getParameter('doctrine.connections') as $id) {
  130. if (! $this->container->initialized($id)) {
  131. continue;
  132. }
  133. $this->container->get($id)->close();
  134. }
  135. }
  136. /** @return void */
  137. public function registerCommands(Application $application)
  138. {
  139. }
  140. public function getPath(): string
  141. {
  142. return dirname(__DIR__);
  143. }
  144. }