This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection; |
||
4 | |||
5 | use Doctrine\Bundle\DoctrineBundle\Dbal\RegexSchemaAssetFilter; |
||
6 | use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass; |
||
7 | use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; |
||
8 | use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface; |
||
9 | use Doctrine\ORM\Proxy\Autoloader; |
||
10 | use Doctrine\ORM\UnitOfWork; |
||
11 | use LogicException; |
||
12 | use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension; |
||
13 | use Symfony\Bridge\Doctrine\Messenger\DoctrineClearEntityManagerWorkerSubscriber; |
||
14 | use Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware; |
||
15 | use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor; |
||
16 | use Symfony\Bridge\Doctrine\SchemaListener\MessengerTransportDoctrineSchemaSubscriber; |
||
17 | use Symfony\Bridge\Doctrine\SchemaListener\PdoCacheAdapterDoctrineSchemaSubscriber; |
||
18 | use Symfony\Bridge\Doctrine\Validator\DoctrineLoader; |
||
19 | use Symfony\Component\Cache\Adapter\ArrayAdapter; |
||
20 | use Symfony\Component\Cache\DoctrineProvider; |
||
21 | use Symfony\Component\Config\FileLocator; |
||
22 | use Symfony\Component\DependencyInjection\Alias; |
||
23 | use Symfony\Component\DependencyInjection\ChildDefinition; |
||
24 | use Symfony\Component\DependencyInjection\ContainerBuilder; |
||
25 | use Symfony\Component\DependencyInjection\Definition; |
||
26 | use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
||
27 | use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; |
||
28 | use Symfony\Component\DependencyInjection\Reference; |
||
29 | use Symfony\Component\Form\AbstractType; |
||
30 | use Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransportFactory; |
||
31 | use Symfony\Component\Messenger\MessageBusInterface; |
||
32 | use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface; |
||
33 | use function class_exists; |
||
34 | use function sprintf; |
||
35 | |||
36 | /** |
||
37 | * DoctrineExtension is an extension for the Doctrine DBAL and ORM library. |
||
38 | */ |
||
39 | class DoctrineExtension extends AbstractDoctrineExtension |
||
40 | { |
||
41 | /** @var string */ |
||
42 | private $defaultConnection; |
||
43 | |||
44 | /** |
||
45 | * {@inheritDoc} |
||
46 | */ |
||
47 | public function load(array $configs, ContainerBuilder $container) |
||
48 | { |
||
49 | $configuration = $this->getConfiguration($configs, $container); |
||
50 | $config = $this->processConfiguration($configuration, $configs); |
||
51 | |||
52 | if (! empty($config['dbal'])) { |
||
53 | $this->dbalLoad($config['dbal'], $container); |
||
54 | |||
55 | $this->loadMessengerServices($container); |
||
56 | } |
||
57 | |||
58 | if (empty($config['orm'])) { |
||
59 | return; |
||
60 | } |
||
61 | |||
62 | if (empty($config['dbal'])) { |
||
63 | throw new LogicException('Configuring the ORM layer requires to configure the DBAL layer as well.'); |
||
64 | } |
||
65 | |||
66 | $this->ormLoad($config['orm'], $container); |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Loads the DBAL configuration. |
||
71 | * |
||
72 | * Usage example: |
||
73 | * |
||
74 | * <doctrine:dbal id="myconn" dbname="sfweb" user="root" /> |
||
75 | * |
||
76 | * @param array $config An array of configuration settings |
||
77 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
78 | */ |
||
79 | protected function dbalLoad(array $config, ContainerBuilder $container) |
||
80 | { |
||
81 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); |
||
82 | $loader->load('dbal.xml'); |
||
83 | |||
84 | if (empty($config['default_connection'])) { |
||
85 | $keys = array_keys($config['connections']); |
||
86 | $config['default_connection'] = reset($keys); |
||
87 | } |
||
88 | |||
89 | $this->defaultConnection = $config['default_connection']; |
||
90 | |||
91 | $container->setAlias('database_connection', sprintf('doctrine.dbal.%s_connection', $this->defaultConnection)); |
||
92 | $container->getAlias('database_connection')->setPublic(true); |
||
93 | $container->setAlias('doctrine.dbal.event_manager', new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $this->defaultConnection), false)); |
||
94 | |||
95 | $container->setParameter('doctrine.dbal.connection_factory.types', $config['types']); |
||
96 | |||
97 | $connections = []; |
||
98 | |||
99 | foreach (array_keys($config['connections']) as $name) { |
||
100 | $connections[$name] = sprintf('doctrine.dbal.%s_connection', $name); |
||
101 | } |
||
102 | |||
103 | $container->setParameter('doctrine.connections', $connections); |
||
104 | $container->setParameter('doctrine.default_connection', $this->defaultConnection); |
||
105 | |||
106 | foreach ($config['connections'] as $name => $connection) { |
||
107 | $this->loadDbalConnection($name, $connection, $container); |
||
108 | } |
||
109 | } |
||
110 | |||
111 | /** |
||
112 | * Loads a configured DBAL connection. |
||
113 | * |
||
114 | * @param string $name The name of the connection |
||
115 | * @param array $connection A dbal connection configuration. |
||
116 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
117 | */ |
||
118 | protected function loadDbalConnection($name, array $connection, ContainerBuilder $container) |
||
119 | { |
||
120 | $configuration = $container->setDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name), new ChildDefinition('doctrine.dbal.connection.configuration')); |
||
121 | $logger = null; |
||
122 | if ($connection['logging']) { |
||
123 | $logger = new Reference('doctrine.dbal.logger'); |
||
124 | } |
||
125 | unset($connection['logging']); |
||
126 | |||
127 | if ($connection['profiling']) { |
||
128 | $profilingAbstractId = $connection['profiling_collect_backtrace'] ? |
||
129 | 'doctrine.dbal.logger.backtrace' : |
||
130 | 'doctrine.dbal.logger.profiling'; |
||
131 | |||
132 | $profilingLoggerId = $profilingAbstractId . '.' . $name; |
||
133 | $container->setDefinition($profilingLoggerId, new ChildDefinition($profilingAbstractId)); |
||
134 | $profilingLogger = new Reference($profilingLoggerId); |
||
135 | $container->getDefinition('data_collector.doctrine') |
||
136 | ->addMethodCall('addLogger', [$name, $profilingLogger]) |
||
137 | ->replaceArgument(1, $connection['profiling_collect_schema_errors']); |
||
138 | |||
139 | if ($logger !== null) { |
||
140 | $chainLogger = new ChildDefinition('doctrine.dbal.logger.chain'); |
||
141 | $chainLogger->addMethodCall('addLogger', [$profilingLogger]); |
||
142 | |||
143 | $loggerId = 'doctrine.dbal.logger.chain.' . $name; |
||
144 | $container->setDefinition($loggerId, $chainLogger); |
||
145 | $logger = new Reference($loggerId); |
||
146 | } else { |
||
147 | $logger = $profilingLogger; |
||
148 | } |
||
149 | } |
||
150 | unset( |
||
151 | $connection['profiling'], |
||
152 | $connection['profiling_collect_backtrace'], |
||
153 | $connection['profiling_collect_schema_errors'] |
||
154 | ); |
||
155 | |||
156 | if (isset($connection['auto_commit'])) { |
||
157 | $configuration->addMethodCall('setAutoCommit', [$connection['auto_commit']]); |
||
158 | } |
||
159 | |||
160 | unset($connection['auto_commit']); |
||
161 | |||
162 | if (isset($connection['schema_filter']) && $connection['schema_filter']) { |
||
163 | $definition = new Definition(RegexSchemaAssetFilter::class, [$connection['schema_filter']]); |
||
164 | $definition->addTag('doctrine.dbal.schema_filter', ['connection' => $name]); |
||
165 | $container->setDefinition(sprintf('doctrine.dbal.%s_regex_schema_filter', $name), $definition); |
||
166 | } |
||
167 | |||
168 | unset($connection['schema_filter']); |
||
169 | |||
170 | if ($logger) { |
||
171 | $configuration->addMethodCall('setSQLLogger', [$logger]); |
||
172 | } |
||
173 | |||
174 | // event manager |
||
175 | $container->setDefinition(sprintf('doctrine.dbal.%s_connection.event_manager', $name), new ChildDefinition('doctrine.dbal.connection.event_manager')); |
||
176 | |||
177 | // connection |
||
178 | $options = $this->getConnectionOptions($connection); |
||
179 | |||
180 | $def = $container |
||
181 | ->setDefinition(sprintf('doctrine.dbal.%s_connection', $name), new ChildDefinition('doctrine.dbal.connection')) |
||
182 | ->setPublic(true) |
||
183 | ->setArguments([ |
||
184 | $options, |
||
185 | new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name)), |
||
186 | new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name)), |
||
187 | $connection['mapping_types'], |
||
188 | ]); |
||
189 | |||
190 | // Set class in case "wrapper_class" option was used to assist IDEs |
||
191 | if (isset($options['wrapperClass'])) { |
||
192 | $def->setClass($options['wrapperClass']); |
||
193 | } |
||
194 | |||
195 | if (! empty($connection['use_savepoints'])) { |
||
196 | $def->addMethodCall('setNestTransactionsWithSavepoints', [$connection['use_savepoints']]); |
||
197 | } |
||
198 | |||
199 | // Create a shard_manager for this connection |
||
200 | if (! isset($options['shards'])) { |
||
201 | return; |
||
202 | } |
||
203 | |||
204 | $shardManagerDefinition = new Definition($options['shardManagerClass'], [new Reference(sprintf('doctrine.dbal.%s_connection', $name))]); |
||
205 | $container->setDefinition(sprintf('doctrine.dbal.%s_shard_manager', $name), $shardManagerDefinition); |
||
206 | } |
||
207 | |||
208 | protected function getConnectionOptions($connection) |
||
209 | { |
||
210 | $options = $connection; |
||
211 | |||
212 | if (isset($options['platform_service'])) { |
||
213 | $options['platform'] = new Reference($options['platform_service']); |
||
214 | unset($options['platform_service']); |
||
215 | } |
||
216 | unset($options['mapping_types']); |
||
217 | |||
218 | if (isset($options['shard_choser_service'])) { |
||
219 | $options['shard_choser'] = new Reference($options['shard_choser_service']); |
||
220 | unset($options['shard_choser_service']); |
||
221 | } |
||
222 | |||
223 | foreach ([ |
||
224 | 'options' => 'driverOptions', |
||
225 | 'driver_class' => 'driverClass', |
||
226 | 'wrapper_class' => 'wrapperClass', |
||
227 | 'keep_slave' => 'keepSlave', |
||
228 | 'shard_choser' => 'shardChoser', |
||
229 | 'shard_manager_class' => 'shardManagerClass', |
||
230 | 'server_version' => 'serverVersion', |
||
231 | 'default_table_options' => 'defaultTableOptions', |
||
232 | ] as $old => $new) { |
||
233 | if (! isset($options[$old])) { |
||
234 | continue; |
||
235 | } |
||
236 | |||
237 | $options[$new] = $options[$old]; |
||
238 | unset($options[$old]); |
||
239 | } |
||
240 | |||
241 | if (! empty($options['slaves']) && ! empty($options['shards'])) { |
||
242 | throw new InvalidArgumentException('Sharding and master-slave connection cannot be used together'); |
||
243 | } |
||
244 | |||
245 | if (! empty($options['slaves'])) { |
||
246 | $nonRewrittenKeys = [ |
||
247 | 'driver' => true, |
||
248 | 'driverOptions' => true, |
||
249 | 'driverClass' => true, |
||
250 | 'wrapperClass' => true, |
||
251 | 'keepSlave' => true, |
||
252 | 'shardChoser' => true, |
||
253 | 'platform' => true, |
||
254 | 'slaves' => true, |
||
255 | 'master' => true, |
||
256 | 'shards' => true, |
||
257 | 'serverVersion' => true, |
||
258 | 'defaultTableOptions' => true, |
||
259 | // included by safety but should have been unset already |
||
260 | 'logging' => true, |
||
261 | 'profiling' => true, |
||
262 | 'mapping_types' => true, |
||
263 | 'platform_service' => true, |
||
264 | ]; |
||
265 | View Code Duplication | foreach ($options as $key => $value) { |
|
266 | if (isset($nonRewrittenKeys[$key])) { |
||
267 | continue; |
||
268 | } |
||
269 | $options['master'][$key] = $value; |
||
270 | unset($options[$key]); |
||
271 | } |
||
272 | if (empty($options['wrapperClass'])) { |
||
273 | // Change the wrapper class only if the user does not already forced using a custom one. |
||
274 | $options['wrapperClass'] = 'Doctrine\\DBAL\\Connections\\MasterSlaveConnection'; |
||
275 | } |
||
276 | } else { |
||
277 | unset($options['slaves']); |
||
278 | } |
||
279 | |||
280 | if (! empty($options['shards'])) { |
||
281 | $nonRewrittenKeys = [ |
||
282 | 'driver' => true, |
||
283 | 'driverOptions' => true, |
||
284 | 'driverClass' => true, |
||
285 | 'wrapperClass' => true, |
||
286 | 'keepSlave' => true, |
||
287 | 'shardChoser' => true, |
||
288 | 'platform' => true, |
||
289 | 'slaves' => true, |
||
290 | 'global' => true, |
||
291 | 'shards' => true, |
||
292 | 'serverVersion' => true, |
||
293 | 'defaultTableOptions' => true, |
||
294 | // included by safety but should have been unset already |
||
295 | 'logging' => true, |
||
296 | 'profiling' => true, |
||
297 | 'mapping_types' => true, |
||
298 | 'platform_service' => true, |
||
299 | ]; |
||
300 | View Code Duplication | foreach ($options as $key => $value) { |
|
301 | if (isset($nonRewrittenKeys[$key])) { |
||
302 | continue; |
||
303 | } |
||
304 | $options['global'][$key] = $value; |
||
305 | unset($options[$key]); |
||
306 | } |
||
307 | if (empty($options['wrapperClass'])) { |
||
308 | // Change the wrapper class only if the user does not already forced using a custom one. |
||
309 | $options['wrapperClass'] = 'Doctrine\\DBAL\\Sharding\\PoolingShardConnection'; |
||
310 | } |
||
311 | if (empty($options['shardManagerClass'])) { |
||
312 | // Change the shard manager class only if the user does not already forced using a custom one. |
||
313 | $options['shardManagerClass'] = 'Doctrine\\DBAL\\Sharding\\PoolingShardManager'; |
||
314 | } |
||
315 | } else { |
||
316 | unset($options['shards']); |
||
317 | } |
||
318 | |||
319 | return $options; |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * Loads the Doctrine ORM configuration. |
||
324 | * |
||
325 | * Usage example: |
||
326 | * |
||
327 | * <doctrine:orm id="mydm" connection="myconn" /> |
||
328 | * |
||
329 | * @param array $config An array of configuration settings |
||
330 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
331 | */ |
||
332 | protected function ormLoad(array $config, ContainerBuilder $container) |
||
333 | { |
||
334 | if (! class_exists(UnitOfWork::class)) { |
||
335 | throw new LogicException('To configure the ORM layer, you must first install the doctrine/orm package.'); |
||
336 | } |
||
337 | |||
338 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); |
||
339 | $loader->load('orm.xml'); |
||
340 | |||
341 | if (class_exists(AbstractType::class)) { |
||
342 | $container->getDefinition('form.type.entity')->addTag('kernel.reset', ['method' => 'reset']); |
||
343 | } |
||
344 | |||
345 | // available in Symfony 5.1 and higher |
||
346 | if (! class_exists(PdoCacheAdapterDoctrineSchemaSubscriber::class)) { |
||
347 | $container->removeDefinition('doctrine.orm.listeners.pdo_cache_adapter_doctrine_schema_subscriber'); |
||
348 | } |
||
349 | |||
350 | $entityManagers = []; |
||
351 | foreach (array_keys($config['entity_managers']) as $name) { |
||
352 | $entityManagers[$name] = sprintf('doctrine.orm.%s_entity_manager', $name); |
||
353 | } |
||
354 | $container->setParameter('doctrine.entity_managers', $entityManagers); |
||
355 | |||
356 | if (empty($config['default_entity_manager'])) { |
||
357 | $tmp = array_keys($entityManagers); |
||
358 | $config['default_entity_manager'] = reset($tmp); |
||
359 | } |
||
360 | $container->setParameter('doctrine.default_entity_manager', $config['default_entity_manager']); |
||
361 | |||
362 | $options = ['auto_generate_proxy_classes', 'proxy_dir', 'proxy_namespace']; |
||
363 | foreach ($options as $key) { |
||
364 | $container->setParameter('doctrine.orm.' . $key, $config[$key]); |
||
365 | } |
||
366 | |||
367 | $container->setAlias('doctrine.orm.entity_manager', $defaultEntityManagerDefinitionId = sprintf('doctrine.orm.%s_entity_manager', $config['default_entity_manager'])); |
||
368 | $container->getAlias('doctrine.orm.entity_manager')->setPublic(true); |
||
369 | |||
370 | $config['entity_managers'] = $this->fixManagersAutoMappings($config['entity_managers'], $container->getParameter('kernel.bundles')); |
||
371 | |||
372 | foreach ($config['entity_managers'] as $name => $entityManager) { |
||
373 | $entityManager['name'] = $name; |
||
374 | $this->loadOrmEntityManager($entityManager, $container); |
||
375 | |||
376 | if (interface_exists(PropertyInfoExtractorInterface::class)) { |
||
377 | $this->loadPropertyInfoExtractor($name, $container); |
||
378 | } |
||
379 | |||
380 | $this->loadValidatorLoader($name, $container); |
||
381 | } |
||
382 | |||
383 | if ($config['resolve_target_entities']) { |
||
384 | $def = $container->findDefinition('doctrine.orm.listeners.resolve_target_entity'); |
||
385 | foreach ($config['resolve_target_entities'] as $name => $implementation) { |
||
386 | $def->addMethodCall('addResolveTargetEntity', [ |
||
387 | $name, |
||
388 | $implementation, |
||
389 | [], |
||
390 | ]); |
||
391 | } |
||
392 | |||
393 | $def->addTag('doctrine.event_subscriber'); |
||
394 | } |
||
395 | |||
396 | $container->registerForAutoconfiguration(ServiceEntityRepositoryInterface::class) |
||
397 | ->addTag(ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG); |
||
398 | |||
399 | $container->registerForAutoconfiguration(EventSubscriberInterface::class) |
||
400 | ->addTag('doctrine.event_subscriber'); |
||
401 | |||
402 | /** |
||
403 | * @see DoctrineBundle::boot() |
||
404 | */ |
||
405 | $container->getDefinition($defaultEntityManagerDefinitionId) |
||
406 | ->addTag('container.preload', [ |
||
407 | 'class' => Autoloader::class, |
||
408 | ]); |
||
409 | } |
||
410 | |||
411 | /** |
||
412 | * Loads a configured ORM entity manager. |
||
413 | * |
||
414 | * @param array $entityManager A configured ORM entity manager. |
||
415 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
416 | */ |
||
417 | protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $container) |
||
418 | { |
||
419 | $ormConfigDef = $container->setDefinition(sprintf('doctrine.orm.%s_configuration', $entityManager['name']), new ChildDefinition('doctrine.orm.configuration')); |
||
420 | |||
421 | $this->loadOrmEntityManagerMappingInformation($entityManager, $ormConfigDef, $container); |
||
422 | $this->loadOrmCacheDrivers($entityManager, $container); |
||
423 | |||
424 | if (isset($entityManager['entity_listener_resolver']) && $entityManager['entity_listener_resolver']) { |
||
425 | $container->setAlias(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name']), $entityManager['entity_listener_resolver']); |
||
426 | } else { |
||
427 | $definition = new Definition('%doctrine.orm.entity_listener_resolver.class%'); |
||
428 | $definition->addArgument(new Reference('service_container')); |
||
429 | $container->setDefinition(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name']), $definition); |
||
430 | } |
||
431 | |||
432 | $methods = [ |
||
433 | 'setMetadataCacheImpl' => new Reference(sprintf('doctrine.orm.%s_metadata_cache', $entityManager['name'])), |
||
434 | 'setQueryCacheImpl' => new Reference(sprintf('doctrine.orm.%s_query_cache', $entityManager['name'])), |
||
435 | 'setResultCacheImpl' => new Reference(sprintf('doctrine.orm.%s_result_cache', $entityManager['name'])), |
||
436 | 'setMetadataDriverImpl' => new Reference('doctrine.orm.' . $entityManager['name'] . '_metadata_driver'), |
||
437 | 'setProxyDir' => '%doctrine.orm.proxy_dir%', |
||
438 | 'setProxyNamespace' => '%doctrine.orm.proxy_namespace%', |
||
439 | 'setAutoGenerateProxyClasses' => '%doctrine.orm.auto_generate_proxy_classes%', |
||
440 | 'setClassMetadataFactoryName' => $entityManager['class_metadata_factory_name'], |
||
441 | 'setDefaultRepositoryClassName' => $entityManager['default_repository_class'], |
||
442 | 'setNamingStrategy' => new Reference($entityManager['naming_strategy']), |
||
443 | 'setQuoteStrategy' => new Reference($entityManager['quote_strategy']), |
||
444 | 'setEntityListenerResolver' => new Reference(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name'])), |
||
445 | ]; |
||
446 | |||
447 | $listenerId = sprintf('doctrine.orm.%s_listeners.attach_entity_listeners', $entityManager['name']); |
||
448 | $listenerDef = $container->setDefinition($listenerId, new Definition('%doctrine.orm.listeners.attach_entity_listeners.class%')); |
||
449 | $listenerTagParams = ['event' => 'loadClassMetadata']; |
||
450 | if (isset($entityManager['connection'])) { |
||
451 | $listenerTagParams['connection'] = $entityManager['connection']; |
||
452 | } |
||
453 | $listenerDef->addTag('doctrine.event_listener', $listenerTagParams); |
||
454 | |||
455 | if (isset($entityManager['second_level_cache'])) { |
||
456 | $this->loadOrmSecondLevelCache($entityManager, $ormConfigDef, $container); |
||
457 | } |
||
458 | |||
459 | if ($entityManager['repository_factory']) { |
||
460 | $methods['setRepositoryFactory'] = new Reference($entityManager['repository_factory']); |
||
461 | } |
||
462 | |||
463 | foreach ($methods as $method => $arg) { |
||
464 | $ormConfigDef->addMethodCall($method, [$arg]); |
||
465 | } |
||
466 | |||
467 | foreach ($entityManager['hydrators'] as $name => $class) { |
||
468 | $ormConfigDef->addMethodCall('addCustomHydrationMode', [$name, $class]); |
||
469 | } |
||
470 | |||
471 | if (! empty($entityManager['dql'])) { |
||
472 | foreach ($entityManager['dql']['string_functions'] as $name => $function) { |
||
473 | $ormConfigDef->addMethodCall('addCustomStringFunction', [$name, $function]); |
||
474 | } |
||
475 | foreach ($entityManager['dql']['numeric_functions'] as $name => $function) { |
||
476 | $ormConfigDef->addMethodCall('addCustomNumericFunction', [$name, $function]); |
||
477 | } |
||
478 | foreach ($entityManager['dql']['datetime_functions'] as $name => $function) { |
||
479 | $ormConfigDef->addMethodCall('addCustomDatetimeFunction', [$name, $function]); |
||
480 | } |
||
481 | } |
||
482 | |||
483 | $enabledFilters = []; |
||
484 | $filtersParameters = []; |
||
485 | foreach ($entityManager['filters'] as $name => $filter) { |
||
486 | $ormConfigDef->addMethodCall('addFilter', [$name, $filter['class']]); |
||
487 | if ($filter['enabled']) { |
||
488 | $enabledFilters[] = $name; |
||
489 | } |
||
490 | if (! $filter['parameters']) { |
||
491 | continue; |
||
492 | } |
||
493 | |||
494 | $filtersParameters[$name] = $filter['parameters']; |
||
495 | } |
||
496 | |||
497 | $managerConfiguratorName = sprintf('doctrine.orm.%s_manager_configurator', $entityManager['name']); |
||
498 | $container |
||
499 | ->setDefinition($managerConfiguratorName, new ChildDefinition('doctrine.orm.manager_configurator.abstract')) |
||
500 | ->replaceArgument(0, $enabledFilters) |
||
501 | ->replaceArgument(1, $filtersParameters); |
||
502 | |||
503 | if (! isset($entityManager['connection'])) { |
||
504 | $entityManager['connection'] = $this->defaultConnection; |
||
505 | } |
||
506 | |||
507 | $container |
||
508 | ->setDefinition(sprintf('doctrine.orm.%s_entity_manager', $entityManager['name']), new ChildDefinition('doctrine.orm.entity_manager.abstract')) |
||
509 | ->setPublic(true) |
||
510 | ->setArguments([ |
||
511 | new Reference(sprintf('doctrine.dbal.%s_connection', $entityManager['connection'])), |
||
512 | new Reference(sprintf('doctrine.orm.%s_configuration', $entityManager['name'])), |
||
513 | ]) |
||
514 | ->setConfigurator([new Reference($managerConfiguratorName), 'configure']); |
||
515 | |||
516 | $container->setAlias( |
||
517 | sprintf('doctrine.orm.%s_entity_manager.event_manager', $entityManager['name']), |
||
518 | new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $entityManager['connection']), false) |
||
519 | ); |
||
520 | |||
521 | if (! isset($entityManager['entity_listeners'])) { |
||
522 | return; |
||
523 | } |
||
524 | |||
525 | if (! isset($listenerDef)) { |
||
526 | throw new InvalidArgumentException('Entity listeners configuration requires doctrine-orm 2.5.0 or newer'); |
||
527 | } |
||
528 | |||
529 | $entities = $entityManager['entity_listeners']['entities']; |
||
530 | |||
531 | foreach ($entities as $entityListenerClass => $entity) { |
||
532 | foreach ($entity['listeners'] as $listenerClass => $listener) { |
||
533 | foreach ($listener['events'] as $listenerEvent) { |
||
534 | $listenerEventName = $listenerEvent['type']; |
||
535 | $listenerMethod = $listenerEvent['method']; |
||
536 | |||
537 | $listenerDef->addMethodCall('addEntityListener', [ |
||
538 | $entityListenerClass, |
||
539 | $listenerClass, |
||
540 | $listenerEventName, |
||
541 | $listenerMethod, |
||
542 | ]); |
||
543 | } |
||
544 | } |
||
545 | } |
||
546 | } |
||
547 | |||
548 | /** |
||
549 | * Loads an ORM entity managers bundle mapping information. |
||
550 | * |
||
551 | * There are two distinct configuration possibilities for mapping information: |
||
552 | * |
||
553 | * 1. Specify a bundle and optionally details where the entity and mapping information reside. |
||
554 | * 2. Specify an arbitrary mapping location. |
||
555 | * |
||
556 | * @param array $entityManager A configured ORM entity manager |
||
557 | * @param Definition $ormConfigDef A Definition instance |
||
558 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
559 | * |
||
560 | * @example |
||
561 | * |
||
562 | * doctrine.orm: |
||
563 | * mappings: |
||
564 | * MyBundle1: ~ |
||
565 | * MyBundle2: yml |
||
566 | * MyBundle3: { type: annotation, dir: Entities/ } |
||
567 | * MyBundle4: { type: xml, dir: Resources/config/doctrine/mapping } |
||
568 | * MyBundle5: |
||
569 | * type: yml |
||
570 | * dir: bundle-mappings/ |
||
571 | * alias: BundleAlias |
||
572 | * arbitrary_key: |
||
573 | * type: xml |
||
574 | * dir: %kernel.project_dir%/src/vendor/DoctrineExtensions/lib/DoctrineExtensions/Entities |
||
575 | * prefix: DoctrineExtensions\Entities\ |
||
576 | * alias: DExt |
||
577 | * |
||
578 | * In the case of bundles everything is really optional (which leads to autodetection for this bundle) but |
||
579 | * in the mappings key everything except alias is a required argument. |
||
580 | */ |
||
581 | protected function loadOrmEntityManagerMappingInformation(array $entityManager, Definition $ormConfigDef, ContainerBuilder $container) |
||
582 | { |
||
583 | // reset state of drivers and alias map. They are only used by this methods and children. |
||
584 | $this->drivers = []; |
||
585 | $this->aliasMap = []; |
||
586 | |||
587 | $this->loadMappingInformation($entityManager, $container); |
||
588 | $this->registerMappingDrivers($entityManager, $container); |
||
589 | |||
590 | $ormConfigDef->addMethodCall('setEntityNamespaces', [$this->aliasMap]); |
||
591 | } |
||
592 | |||
593 | /** |
||
594 | * Loads an ORM second level cache bundle mapping information. |
||
595 | * |
||
596 | * @param array $entityManager A configured ORM entity manager |
||
597 | * @param Definition $ormConfigDef A Definition instance |
||
598 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
599 | * |
||
600 | * @example |
||
601 | * entity_managers: |
||
602 | * default: |
||
603 | * second_level_cache: |
||
604 | * region_cache_driver: apc |
||
605 | * log_enabled: true |
||
606 | * regions: |
||
607 | * my_service_region: |
||
608 | * type: service |
||
609 | * service : "my_service_region" |
||
610 | * |
||
611 | * my_query_region: |
||
612 | * lifetime: 300 |
||
613 | * cache_driver: array |
||
614 | * type: filelock |
||
615 | * |
||
616 | * my_entity_region: |
||
617 | * lifetime: 600 |
||
618 | * cache_driver: |
||
619 | * type: apc |
||
620 | */ |
||
621 | protected function loadOrmSecondLevelCache(array $entityManager, Definition $ormConfigDef, ContainerBuilder $container) |
||
622 | { |
||
623 | $driverId = null; |
||
624 | $enabled = $entityManager['second_level_cache']['enabled']; |
||
625 | |||
626 | if (isset($entityManager['second_level_cache']['region_cache_driver'])) { |
||
627 | $driverName = 'second_level_cache.region_cache_driver'; |
||
628 | $driverMap = $entityManager['second_level_cache']['region_cache_driver']; |
||
629 | $driverId = $this->loadCacheDriver($driverName, $entityManager['name'], $driverMap, $container); |
||
630 | } |
||
631 | |||
632 | $configId = sprintf('doctrine.orm.%s_second_level_cache.cache_configuration', $entityManager['name']); |
||
633 | $regionsId = sprintf('doctrine.orm.%s_second_level_cache.regions_configuration', $entityManager['name']); |
||
634 | $driverId = $driverId ?: sprintf('doctrine.orm.%s_second_level_cache.region_cache_driver', $entityManager['name']); |
||
635 | $configDef = $container->setDefinition($configId, new Definition('%doctrine.orm.second_level_cache.cache_configuration.class%')); |
||
636 | $regionsDef = $container->setDefinition($regionsId, new Definition('%doctrine.orm.second_level_cache.regions_configuration.class%')); |
||
637 | |||
638 | $slcFactoryId = sprintf('doctrine.orm.%s_second_level_cache.default_cache_factory', $entityManager['name']); |
||
639 | $factoryClass = isset($entityManager['second_level_cache']['factory']) ? $entityManager['second_level_cache']['factory'] : '%doctrine.orm.second_level_cache.default_cache_factory.class%'; |
||
640 | |||
641 | $definition = new Definition($factoryClass, [new Reference($regionsId), new Reference($driverId)]); |
||
642 | |||
643 | $slcFactoryDef = $container |
||
644 | ->setDefinition($slcFactoryId, $definition); |
||
645 | |||
646 | if (isset($entityManager['second_level_cache']['regions'])) { |
||
647 | foreach ($entityManager['second_level_cache']['regions'] as $name => $region) { |
||
648 | $regionRef = null; |
||
649 | $regionType = $region['type']; |
||
650 | |||
651 | if ($regionType === 'service') { |
||
652 | $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s', $entityManager['name'], $name); |
||
653 | $regionRef = new Reference($region['service']); |
||
654 | |||
655 | $container->setAlias($regionId, new Alias($region['service'], false)); |
||
656 | } |
||
657 | |||
658 | if ($regionType === 'default' || $regionType === 'filelock') { |
||
659 | $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s', $entityManager['name'], $name); |
||
660 | $driverName = sprintf('second_level_cache.region.%s_driver', $name); |
||
661 | $driverMap = $region['cache_driver']; |
||
662 | $driverId = $this->loadCacheDriver($driverName, $entityManager['name'], $driverMap, $container); |
||
663 | $regionRef = new Reference($regionId); |
||
664 | |||
665 | $container |
||
666 | ->setDefinition($regionId, new Definition('%doctrine.orm.second_level_cache.default_region.class%')) |
||
667 | ->setArguments([$name, new Reference($driverId), $region['lifetime']]); |
||
668 | } |
||
669 | |||
670 | if ($regionType === 'filelock') { |
||
671 | $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s_filelock', $entityManager['name'], $name); |
||
672 | |||
673 | $container |
||
674 | ->setDefinition($regionId, new Definition('%doctrine.orm.second_level_cache.filelock_region.class%')) |
||
675 | ->setArguments([$regionRef, $region['lock_path'], $region['lock_lifetime']]); |
||
676 | |||
677 | $regionRef = new Reference($regionId); |
||
678 | $regionsDef->addMethodCall('getLockLifetime', [$name, $region['lock_lifetime']]); |
||
679 | } |
||
680 | |||
681 | $regionsDef->addMethodCall('setLifetime', [$name, $region['lifetime']]); |
||
682 | $slcFactoryDef->addMethodCall('setRegion', [$regionRef]); |
||
683 | } |
||
684 | } |
||
685 | |||
686 | if ($entityManager['second_level_cache']['log_enabled']) { |
||
687 | $loggerChainId = sprintf('doctrine.orm.%s_second_level_cache.logger_chain', $entityManager['name']); |
||
688 | $loggerStatsId = sprintf('doctrine.orm.%s_second_level_cache.logger_statistics', $entityManager['name']); |
||
689 | $loggerChaingDef = $container->setDefinition($loggerChainId, new Definition('%doctrine.orm.second_level_cache.logger_chain.class%')); |
||
690 | $loggerStatsDef = $container->setDefinition($loggerStatsId, new Definition('%doctrine.orm.second_level_cache.logger_statistics.class%')); |
||
691 | |||
692 | $loggerChaingDef->addMethodCall('setLogger', ['statistics', $loggerStatsDef]); |
||
693 | $configDef->addMethodCall('setCacheLogger', [$loggerChaingDef]); |
||
694 | |||
695 | foreach ($entityManager['second_level_cache']['loggers'] as $name => $logger) { |
||
696 | $loggerId = sprintf('doctrine.orm.%s_second_level_cache.logger.%s', $entityManager['name'], $name); |
||
697 | $loggerRef = new Reference($logger['service']); |
||
698 | |||
699 | $container->setAlias($loggerId, new Alias($logger['service'], false)); |
||
700 | $loggerChaingDef->addMethodCall('setLogger', [$name, $loggerRef]); |
||
701 | } |
||
702 | } |
||
703 | |||
704 | $configDef->addMethodCall('setCacheFactory', [$slcFactoryDef]); |
||
705 | $configDef->addMethodCall('setRegionsConfiguration', [$regionsDef]); |
||
706 | $ormConfigDef->addMethodCall('setSecondLevelCacheEnabled', [$enabled]); |
||
707 | $ormConfigDef->addMethodCall('setSecondLevelCacheConfiguration', [$configDef]); |
||
708 | } |
||
709 | |||
710 | /** |
||
711 | * {@inheritDoc} |
||
712 | */ |
||
713 | protected function getObjectManagerElementName($name) : string |
||
714 | { |
||
715 | return 'doctrine.orm.' . $name; |
||
716 | } |
||
717 | |||
718 | protected function getMappingObjectDefaultName() : string |
||
719 | { |
||
720 | return 'Entity'; |
||
721 | } |
||
722 | |||
723 | /** |
||
724 | * {@inheritDoc} |
||
725 | */ |
||
726 | protected function getMappingResourceConfigDirectory() : string |
||
727 | { |
||
728 | return 'Resources/config/doctrine'; |
||
729 | } |
||
730 | |||
731 | /** |
||
732 | * {@inheritDoc} |
||
733 | */ |
||
734 | protected function getMappingResourceExtension() : string |
||
735 | { |
||
736 | return 'orm'; |
||
737 | } |
||
738 | |||
739 | /** |
||
740 | * {@inheritDoc} |
||
741 | */ |
||
742 | protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheDriver, ContainerBuilder $container) : string |
||
743 | { |
||
744 | $serviceId = null; |
||
0 ignored issues
–
show
|
|||
745 | $aliasId = $this->getObjectManagerElementName(sprintf('%s_%s', $objectManagerName, $cacheName)); |
||
746 | |||
747 | switch ($cacheDriver['type'] ?? 'pool') { |
||
748 | case 'service': |
||
749 | $serviceId = $cacheDriver['id']; |
||
750 | break; |
||
751 | |||
752 | case 'pool': |
||
753 | $serviceId = $this->createPoolCacheDefinition($container, $cacheDriver['pool'] ?? $this->createArrayAdapterCachePool($container, $objectManagerName, $cacheName)); |
||
754 | break; |
||
755 | |||
756 | default: |
||
757 | throw new \InvalidArgumentException(sprintf( |
||
758 | 'Unknown cache of type "%s" configured for cache "%s" in entity manager "%s".', |
||
759 | $cacheDriver['type'], |
||
760 | $cacheName, |
||
761 | $objectManagerName |
||
762 | )); |
||
763 | } |
||
764 | |||
765 | $container->setAlias($aliasId, new Alias($serviceId, false)); |
||
766 | |||
767 | return $aliasId; |
||
768 | } |
||
769 | |||
770 | /** |
||
771 | * Loads a configured entity managers cache drivers. |
||
772 | * |
||
773 | * @param array $entityManager A configured ORM entity manager. |
||
774 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
775 | */ |
||
776 | protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $container) |
||
777 | { |
||
778 | $this->loadCacheDriver('metadata_cache', $entityManager['name'], $entityManager['metadata_cache_driver'], $container); |
||
779 | $this->loadCacheDriver('result_cache', $entityManager['name'], $entityManager['result_cache_driver'], $container); |
||
780 | $this->loadCacheDriver('query_cache', $entityManager['name'], $entityManager['query_cache_driver'], $container); |
||
781 | } |
||
782 | |||
783 | /** |
||
784 | * Loads a property info extractor for each defined entity manager. |
||
785 | */ |
||
786 | private function loadPropertyInfoExtractor(string $entityManagerName, ContainerBuilder $container) : void |
||
787 | { |
||
788 | $propertyExtractorDefinition = $container->register(sprintf('doctrine.orm.%s_entity_manager.property_info_extractor', $entityManagerName), DoctrineExtractor::class); |
||
789 | $argumentId = sprintf('doctrine.orm.%s_entity_manager', $entityManagerName); |
||
790 | |||
791 | $propertyExtractorDefinition->addArgument(new Reference($argumentId)); |
||
792 | |||
793 | $propertyExtractorDefinition->addTag('property_info.list_extractor', ['priority' => -1001]); |
||
794 | $propertyExtractorDefinition->addTag('property_info.type_extractor', ['priority' => -999]); |
||
795 | $propertyExtractorDefinition->addTag('property_info.access_extractor', ['priority' => -999]); |
||
796 | } |
||
797 | |||
798 | /** |
||
799 | * Loads a validator loader for each defined entity manager. |
||
800 | */ |
||
801 | private function loadValidatorLoader(string $entityManagerName, ContainerBuilder $container) : void |
||
802 | { |
||
803 | $validatorLoaderDefinition = $container->register(sprintf('doctrine.orm.%s_entity_manager.validator_loader', $entityManagerName), DoctrineLoader::class); |
||
804 | $validatorLoaderDefinition->addArgument(new Reference(sprintf('doctrine.orm.%s_entity_manager', $entityManagerName))); |
||
805 | |||
806 | $validatorLoaderDefinition->addTag('validator.auto_mapper', ['priority' => -100]); |
||
807 | } |
||
808 | |||
809 | /** |
||
810 | * @param array $objectManager |
||
811 | * @param string $cacheName |
||
812 | */ |
||
813 | public function loadObjectManagerCacheDriver(array $objectManager, ContainerBuilder $container, $cacheName) |
||
814 | { |
||
815 | $this->loadCacheDriver($cacheName, $objectManager['name'], $objectManager[$cacheName . '_driver'], $container); |
||
816 | } |
||
817 | |||
818 | /** |
||
819 | * {@inheritDoc} |
||
820 | */ |
||
821 | public function getXsdValidationBasePath() : string |
||
822 | { |
||
823 | return __DIR__ . '/../Resources/config/schema'; |
||
824 | } |
||
825 | |||
826 | /** |
||
827 | * {@inheritDoc} |
||
828 | */ |
||
829 | public function getNamespace() : string |
||
830 | { |
||
831 | return 'http://symfony.com/schema/dic/doctrine'; |
||
832 | } |
||
833 | |||
834 | /** |
||
835 | * {@inheritDoc} |
||
836 | */ |
||
837 | public function getConfiguration(array $config, ContainerBuilder $container) : Configuration |
||
838 | { |
||
839 | return new Configuration($container->getParameter('kernel.debug')); |
||
840 | } |
||
841 | |||
842 | protected function getMetadataDriverClass(string $driverType) : string |
||
843 | { |
||
844 | return '%' . $this->getObjectManagerElementName('metadata.' . $driverType . '.class%'); |
||
845 | } |
||
846 | |||
847 | private function loadMessengerServices(ContainerBuilder $container) : void |
||
848 | { |
||
849 | // If the Messenger component is installed and the doctrine transaction middleware is available, wire it: |
||
850 | if (! interface_exists(MessageBusInterface::class) || ! class_exists(DoctrineTransactionMiddleware::class)) { |
||
851 | return; |
||
852 | } |
||
853 | |||
854 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); |
||
855 | $loader->load('messenger.xml'); |
||
856 | |||
857 | if (! class_exists(DoctrineClearEntityManagerWorkerSubscriber::class)) { |
||
858 | $container->removeDefinition('doctrine.orm.messenger.event_subscriber.doctrine_clear_entity_manager'); |
||
859 | } |
||
860 | |||
861 | // available in Symfony 5.1 and higher |
||
862 | if (! class_exists(MessengerTransportDoctrineSchemaSubscriber::class)) { |
||
863 | $container->removeDefinition('doctrine.orm.messenger.doctrine_schema_subscriber'); |
||
864 | } |
||
865 | |||
866 | $transportFactoryDefinition = $container->getDefinition('messenger.transport.doctrine.factory'); |
||
867 | if (! class_exists(DoctrineTransportFactory::class)) { |
||
868 | // If symfony/messenger < 5.1 |
||
869 | if (! class_exists(\Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransportFactory::class)) { |
||
870 | // Dont add the tag |
||
871 | return; |
||
872 | } |
||
873 | |||
874 | $transportFactoryDefinition->setClass(\Symfony\Component\Messenger\Transport\Doctrine\DoctrineTransportFactory::class); |
||
875 | } |
||
876 | |||
877 | $transportFactoryDefinition->addTag('messenger.transport_factory'); |
||
878 | } |
||
879 | |||
880 | private function createPoolCacheDefinition(ContainerBuilder $container, string $poolName) : string |
||
881 | { |
||
882 | $serviceId = sprintf('doctrine.orm.cache.provider.%s', $poolName); |
||
883 | |||
884 | $definition = $container->register($serviceId, DoctrineProvider::class); |
||
885 | $definition->addArgument(new Reference($poolName)); |
||
886 | $definition->setPrivate(true); |
||
0 ignored issues
–
show
The method
Symfony\Component\Depend...efinition::setPrivate() has been deprecated with message: since Symfony 5.2, use setPublic() instead
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead. ![]() |
|||
887 | |||
888 | return $serviceId; |
||
889 | } |
||
890 | |||
891 | private function createArrayAdapterCachePool(ContainerBuilder $container, string $objectManagerName, string $cacheName) : string |
||
892 | { |
||
893 | $id = sprintf('cache.doctrine.orm.%s.%s', $objectManagerName, str_replace('_cache', '', $cacheName)); |
||
894 | |||
895 | $poolDefinition = $container->register($id, ArrayAdapter::class); |
||
896 | $poolDefinition->addTag('cache.pool'); |
||
897 | $container->setDefinition($id, $poolDefinition); |
||
898 | |||
899 | return $id; |
||
900 | } |
||
901 | } |
||
902 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.