diff --git a/docs/en/configuration.rst b/docs/en/configuration.rst index 1ce46b83..c34fe0cb 100644 --- a/docs/en/configuration.rst +++ b/docs/en/configuration.rst @@ -220,6 +220,8 @@ Configuration Reference proxy_namespace: Proxies # Enables the new implementation of proxies based on lazy ghosts instead of using the legacy implementation enable_lazy_ghost_objects: false + # Enables the new native implementation of PHP lazy objects instead of generated proxies + enable_native_lazy_objects: false identity_generation_preferences: Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity @@ -257,8 +259,6 @@ Configuration Reference class_metadata_factory_name: Doctrine\ORM\Mapping\ClassMetadataFactory default_repository_class: Doctrine\ORM\EntityRepository auto_mapping: false - # Opt-in to PHP native lazy objects - enable_native_lazy_objects: false # Opt-in to new mapping driver mode as of Doctrine ORM 2.16, https://github.com/doctrine/orm/pull/10455 report_fields_where_declared: false # 0pt-in to the new mapping driver mode as of Doctrine ORM 2.14. See https://github.com/doctrine/orm/pull/6728. diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 87f4d389..50a68281 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -428,6 +428,7 @@ private function addOrmSection(ArrayNodeDefinition $node): void 'default_entity_manager' => true, 'auto_generate_proxy_classes' => true, 'enable_lazy_ghost_objects' => true, + 'enable_native_lazy_objects' => true, 'proxy_dir' => true, 'proxy_namespace' => true, 'resolve_target_entities' => true, @@ -506,6 +507,10 @@ private function addOrmSection(ArrayNodeDefinition $node): void ->defaultValue(! method_exists(ProxyFactory::class, 'resetUninitializedProxy')) ->info('Enables the new implementation of proxies based on lazy ghosts instead of using the legacy implementation') ->end() + ->booleanNode('enable_native_lazy_objects') + ->defaultFalse() + ->info('Enables the new native implementation of PHP lazy objects instead of generated proxies') + ->end() ->scalarNode('proxy_dir') ->defaultValue('%kernel.build_dir%/doctrine/orm/Proxies') ->info('Configures the path where generated proxy classes are saved when using non-native lazy objects, this option is ignored when the "enable_native_lazy_objects" option is true') @@ -658,10 +663,6 @@ private function getOrmEntityManagersNode(): ArrayNodeDefinition ->scalarNode('class_metadata_factory_name')->defaultValue(ClassMetadataFactory::class)->end() ->scalarNode('default_repository_class')->defaultValue(EntityRepository::class)->end() ->scalarNode('auto_mapping')->defaultFalse()->end() - ->booleanNode('enable_native_lazy_objects') - ->defaultFalse() - ->info('Enables the new native implementation of PHP lazy objects instead of generated proxies') - ->end() ->scalarNode('naming_strategy')->defaultValue('doctrine.orm.naming_strategy.default')->end() ->scalarNode('quote_strategy')->defaultValue('doctrine.orm.quote_strategy.default')->end() ->scalarNode('typed_field_mapper')->defaultValue('doctrine.orm.typed_field_mapper.default')->end() diff --git a/src/DependencyInjection/DoctrineExtension.php b/src/DependencyInjection/DoctrineExtension.php index 215b4baa..5f993445 100644 --- a/src/DependencyInjection/DoctrineExtension.php +++ b/src/DependencyInjection/DoctrineExtension.php @@ -18,6 +18,7 @@ use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection; use Doctrine\DBAL\Driver\Middleware as MiddlewareInterface; use Doctrine\DBAL\Schema\LegacySchemaManagerFactory; +use Doctrine\ORM\Configuration as ORMConfiguration; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Events; use Doctrine\ORM\Id\AbstractIdGenerator; @@ -71,8 +72,10 @@ use function array_intersect_key; use function array_keys; use function array_merge; +use function assert; use function class_exists; use function interface_exists; +use function is_bool; use function is_dir; use function method_exists; use function reset; @@ -577,7 +580,19 @@ protected function ormLoad(array $config, ContainerBuilder $container) trigger_deprecation('doctrine/doctrine-bundle', '2.11', 'Not setting "doctrine.orm.enable_lazy_ghost_objects" to true is deprecated.'); } - $options = ['auto_generate_proxy_classes', 'enable_lazy_ghost_objects', 'proxy_dir', 'proxy_namespace']; + if ($config['enable_native_lazy_objects'] ?? false) { + /** @phpstan-ignore function.alreadyNarrowedType */ + if (! method_exists(ORMConfiguration::class, 'enableNativeLazyObjects')) { + throw new LogicException( + 'Native lazy objects are not supported with your installed version of the ORM. Please upgrade to "doctrine/orm:^3.4".', + ); + } + } elseif (! class_exists(AnnotationDriver::class)) { + // Only emit the deprecation notice for ORM 3 users + trigger_deprecation('doctrine/doctrine-bundle', '2.16', 'Not setting "doctrine.orm.enable_native_lazy_objects" to true is deprecated.'); + } + + $options = ['auto_generate_proxy_classes', 'enable_lazy_ghost_objects', 'enable_native_lazy_objects', 'proxy_dir', 'proxy_namespace']; foreach ($options as $key) { $container->setParameter('doctrine.orm.' . $key, $config[$key]); } @@ -703,11 +718,15 @@ protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $ ]; if (PHP_VERSION_ID >= 80400 && class_exists(LegacyReflectionFields::class)) { - $methods['enableNativeLazyObjects'] = $entityManager['enable_native_lazy_objects']; + $enableNativeLazyObjects = $container->getParameter('doctrine.orm.enable_native_lazy_objects'); + + assert(is_bool($enableNativeLazyObjects)); + + $methods['enableNativeLazyObjects'] = $enableNativeLazyObjects; // Do not set deprecated proxy configurations when native lazy objects are enabled with `doctrine/orm:^3.5` /** @phpstan-ignore function.alreadyNarrowedType */ - if ($entityManager['enable_native_lazy_objects'] && method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) { + if ($enableNativeLazyObjects && method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) { unset( $methods['setProxyDir'], $methods['setProxyNamespace'],