doctrine /
DoctrineBundle
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /* |
||
| 4 | * This file is part of the Doctrine Bundle |
||
| 5 | * |
||
| 6 | * The code was originally distributed inside the Symfony framework. |
||
| 7 | * |
||
| 8 | * (c) Fabien Potencier <[email protected]> |
||
| 9 | * (c) Doctrine Project, Benjamin Eberlei <[email protected]> |
||
| 10 | * |
||
| 11 | * For the full copyright and license information, please view the LICENSE |
||
| 12 | * file that was distributed with this source code. |
||
| 13 | */ |
||
| 14 | |||
| 15 | namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection; |
||
| 16 | |||
| 17 | use Doctrine\ORM\Version; |
||
| 18 | use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
||
| 19 | use Symfony\Component\DependencyInjection\Alias; |
||
| 20 | use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; |
||
| 21 | use Symfony\Component\DependencyInjection\ContainerBuilder; |
||
| 22 | use Symfony\Component\DependencyInjection\Definition; |
||
| 23 | use Symfony\Component\DependencyInjection\DefinitionDecorator; |
||
| 24 | use Symfony\Component\DependencyInjection\Reference; |
||
| 25 | use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension; |
||
| 26 | use Symfony\Component\Config\FileLocator; |
||
| 27 | use Doctrine\Bundle\DoctrineCacheBundle\DependencyInjection\SymfonyBridgeAdapter; |
||
| 28 | use Doctrine\Bundle\DoctrineCacheBundle\DependencyInjection\CacheProviderLoader; |
||
| 29 | |||
| 30 | /** |
||
| 31 | * DoctrineExtension is an extension for the Doctrine DBAL and ORM library. |
||
| 32 | * |
||
| 33 | * @author Jonathan H. Wage <[email protected]> |
||
| 34 | * @author Fabien Potencier <[email protected]> |
||
| 35 | * @author Benjamin Eberlei <[email protected]> |
||
| 36 | * @author Fabio B. Silva <[email protected]> |
||
| 37 | * @author Kinn Coelho Julião <[email protected]> |
||
| 38 | */ |
||
| 39 | class DoctrineExtension extends AbstractDoctrineExtension |
||
| 40 | { |
||
| 41 | /** |
||
| 42 | * @var string |
||
| 43 | */ |
||
| 44 | private $defaultConnection; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @var array |
||
| 48 | */ |
||
| 49 | private $entityManagers; |
||
| 50 | |||
| 51 | /** |
||
| 52 | * @var SymfonyBridgeAdapter |
||
| 53 | */ |
||
| 54 | private $adapter; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * @param SymfonyBridgeAdapter $adapter |
||
| 58 | */ |
||
| 59 | public function __construct(SymfonyBridgeAdapter $adapter = null) |
||
| 60 | { |
||
| 61 | $this->adapter = $adapter ?: new SymfonyBridgeAdapter(new CacheProviderLoader(), 'doctrine.orm', 'orm'); |
||
| 62 | } |
||
| 63 | |||
| 64 | /** |
||
| 65 | * {@inheritDoc} |
||
| 66 | */ |
||
| 67 | public function load(array $configs, ContainerBuilder $container) |
||
| 68 | { |
||
| 69 | $configuration = $this->getConfiguration($configs, $container); |
||
| 70 | $config = $this->processConfiguration($configuration, $configs); |
||
| 71 | |||
| 72 | $this->adapter->loadServicesConfiguration($container); |
||
| 73 | |||
| 74 | if (!empty($config['dbal'])) { |
||
| 75 | $this->dbalLoad($config['dbal'], $container); |
||
| 76 | } |
||
| 77 | |||
| 78 | if (!empty($config['orm'])) { |
||
| 79 | if (empty($config['dbal'])) { |
||
| 80 | throw new \LogicException('Configuring the ORM layer requires to configure the DBAL layer as well.'); |
||
| 81 | } |
||
| 82 | |||
| 83 | $this->ormLoad($config['orm'], $container); |
||
| 84 | } |
||
| 85 | |||
| 86 | $this->addClassesToCompile(array( |
||
| 87 | 'Doctrine\\Common\\Annotations\\DocLexer', |
||
| 88 | 'Doctrine\\Common\\Annotations\\FileCacheReader', |
||
| 89 | 'Doctrine\\Common\\Annotations\\PhpParser', |
||
| 90 | 'Doctrine\\Common\\Annotations\\Reader', |
||
| 91 | 'Doctrine\\Common\\Lexer', |
||
| 92 | 'Doctrine\\Common\\Persistence\\ConnectionRegistry', |
||
| 93 | 'Doctrine\\Common\\Persistence\\Proxy', |
||
| 94 | 'Doctrine\\Common\\Util\\ClassUtils', |
||
| 95 | 'Doctrine\\Bundle\\DoctrineBundle\\Registry', |
||
| 96 | )); |
||
| 97 | } |
||
| 98 | |||
| 99 | /** |
||
| 100 | * Loads the DBAL configuration. |
||
| 101 | * |
||
| 102 | * Usage example: |
||
| 103 | * |
||
| 104 | * <doctrine:dbal id="myconn" dbname="sfweb" user="root" /> |
||
| 105 | * |
||
| 106 | * @param array $config An array of configuration settings |
||
| 107 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
| 108 | */ |
||
| 109 | protected function dbalLoad(array $config, ContainerBuilder $container) |
||
| 110 | { |
||
| 111 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
||
| 112 | $loader->load('dbal.xml'); |
||
| 113 | |||
| 114 | if (empty($config['default_connection'])) { |
||
| 115 | $keys = array_keys($config['connections']); |
||
| 116 | $config['default_connection'] = reset($keys); |
||
| 117 | } |
||
| 118 | |||
| 119 | $this->defaultConnection = $config['default_connection']; |
||
| 120 | |||
| 121 | $container->setAlias('database_connection', sprintf('doctrine.dbal.%s_connection', $this->defaultConnection)); |
||
| 122 | $container->setAlias('doctrine.dbal.event_manager', new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $this->defaultConnection), false)); |
||
| 123 | |||
| 124 | $container->setParameter('doctrine.dbal.connection_factory.types', $config['types']); |
||
| 125 | |||
| 126 | $connections = array(); |
||
| 127 | |||
| 128 | foreach (array_keys($config['connections']) as $name) { |
||
| 129 | $connections[$name] = sprintf('doctrine.dbal.%s_connection', $name); |
||
| 130 | } |
||
| 131 | |||
| 132 | $container->setParameter('doctrine.connections', $connections); |
||
| 133 | $container->setParameter('doctrine.default_connection', $this->defaultConnection); |
||
| 134 | |||
| 135 | $def = $container->getDefinition('doctrine.dbal.connection'); |
||
| 136 | if (method_exists($def, 'setFactory')) { |
||
| 137 | // to be inlined in dbal.xml when dependency on Symfony DependencyInjection is bumped to 2.6 |
||
| 138 | $def->setFactory(array(new Reference('doctrine.dbal.connection_factory'), 'createConnection')); |
||
| 139 | } else { |
||
| 140 | // to be removed when dependency on Symfony DependencyInjection is bumped to 2.6 |
||
| 141 | $def->setFactoryService('doctrine.dbal.connection_factory'); |
||
| 142 | $def->setFactoryMethod('createConnection'); |
||
| 143 | } |
||
| 144 | |||
| 145 | foreach ($config['connections'] as $name => $connection) { |
||
| 146 | $this->loadDbalConnection($name, $connection, $container); |
||
| 147 | } |
||
| 148 | } |
||
| 149 | |||
| 150 | /** |
||
| 151 | * Loads a configured DBAL connection. |
||
| 152 | * |
||
| 153 | * @param string $name The name of the connection |
||
| 154 | * @param array $connection A dbal connection configuration. |
||
| 155 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
| 156 | */ |
||
| 157 | protected function loadDbalConnection($name, array $connection, ContainerBuilder $container) |
||
| 158 | { |
||
| 159 | // configuration |
||
| 160 | $configuration = $container->setDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name), new DefinitionDecorator('doctrine.dbal.connection.configuration')); |
||
| 161 | $logger = null; |
||
| 162 | if ($connection['logging']) { |
||
| 163 | $logger = new Reference('doctrine.dbal.logger'); |
||
| 164 | } |
||
| 165 | unset ($connection['logging']); |
||
| 166 | if ($connection['profiling']) { |
||
| 167 | $profilingLoggerId = 'doctrine.dbal.logger.profiling.'.$name; |
||
| 168 | $container->setDefinition($profilingLoggerId, new DefinitionDecorator('doctrine.dbal.logger.profiling')); |
||
| 169 | $profilingLogger = new Reference($profilingLoggerId); |
||
| 170 | $container->getDefinition('data_collector.doctrine')->addMethodCall('addLogger', array($name, $profilingLogger)); |
||
| 171 | |||
| 172 | if (null !== $logger) { |
||
| 173 | $chainLogger = new DefinitionDecorator('doctrine.dbal.logger.chain'); |
||
| 174 | $chainLogger->addMethodCall('addLogger', array($profilingLogger)); |
||
| 175 | |||
| 176 | $loggerId = 'doctrine.dbal.logger.chain.'.$name; |
||
| 177 | $container->setDefinition($loggerId, $chainLogger); |
||
| 178 | $logger = new Reference($loggerId); |
||
| 179 | } else { |
||
| 180 | $logger = $profilingLogger; |
||
| 181 | } |
||
| 182 | } |
||
| 183 | unset($connection['profiling']); |
||
| 184 | |||
| 185 | if (isset($connection['auto_commit'])) { |
||
| 186 | $configuration->addMethodCall('setAutoCommit', array($connection['auto_commit'])); |
||
| 187 | } |
||
| 188 | |||
| 189 | unset($connection['auto_commit']); |
||
| 190 | |||
| 191 | if (isset($connection['schema_filter']) && $connection['schema_filter']) { |
||
| 192 | $configuration->addMethodCall('setFilterSchemaAssetsExpression', array($connection['schema_filter'])); |
||
| 193 | } |
||
| 194 | |||
| 195 | unset($connection['schema_filter']); |
||
| 196 | |||
| 197 | if ($logger) { |
||
| 198 | $configuration->addMethodCall('setSQLLogger', array($logger)); |
||
| 199 | } |
||
| 200 | |||
| 201 | // event manager |
||
| 202 | $container->setDefinition(sprintf('doctrine.dbal.%s_connection.event_manager', $name), new DefinitionDecorator('doctrine.dbal.connection.event_manager')); |
||
| 203 | |||
| 204 | // connection |
||
| 205 | // PDO ignores the charset property before 5.3.6 so the init listener has to be used instead. |
||
| 206 | if (isset($connection['charset']) && version_compare(PHP_VERSION, '5.3.6', '<')) { |
||
| 207 | if ((isset($connection['driver']) && stripos($connection['driver'], 'mysql') !== false) || |
||
| 208 | (isset($connection['driver_class']) && stripos($connection['driver_class'], 'mysql') !== false)) { |
||
| 209 | $mysqlSessionInit = new Definition('%doctrine.dbal.events.mysql_session_init.class%'); |
||
| 210 | $mysqlSessionInit->setArguments(array($connection['charset'])); |
||
| 211 | $mysqlSessionInit->setPublic(false); |
||
| 212 | $mysqlSessionInit->addTag('doctrine.event_subscriber', array('connection' => $name)); |
||
| 213 | |||
| 214 | $container->setDefinition( |
||
| 215 | sprintf('doctrine.dbal.%s_connection.events.mysqlsessioninit', $name), |
||
| 216 | $mysqlSessionInit |
||
| 217 | ); |
||
| 218 | unset($connection['charset']); |
||
| 219 | } |
||
| 220 | } |
||
| 221 | |||
| 222 | $options = $this->getConnectionOptions($connection); |
||
| 223 | |||
| 224 | $def = $container |
||
| 225 | ->setDefinition(sprintf('doctrine.dbal.%s_connection', $name), new DefinitionDecorator('doctrine.dbal.connection')) |
||
| 226 | ->setArguments(array( |
||
| 227 | $options, |
||
| 228 | new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name)), |
||
| 229 | new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name)), |
||
| 230 | $connection['mapping_types'], |
||
| 231 | )) |
||
| 232 | ; |
||
| 233 | |||
| 234 | if (!empty($connection['use_savepoints'])) { |
||
| 235 | $def->addMethodCall('setNestTransactionsWithSavepoints', array($connection['use_savepoints'])); |
||
| 236 | } |
||
| 237 | } |
||
| 238 | |||
| 239 | protected function getConnectionOptions($connection) |
||
| 240 | { |
||
| 241 | $options = $connection; |
||
| 242 | |||
| 243 | if (isset($options['platform_service'])) { |
||
| 244 | $options['platform'] = new Reference($options['platform_service']); |
||
| 245 | unset($options['platform_service']); |
||
| 246 | } |
||
| 247 | unset($options['mapping_types']); |
||
| 248 | |||
| 249 | if (isset($options['shard_choser_service'])) { |
||
| 250 | $options['shard_choser'] = new Reference($options['shard_choser_service']); |
||
| 251 | unset($options['shard_choser_service']); |
||
| 252 | } |
||
| 253 | |||
| 254 | foreach (array( |
||
| 255 | 'options' => 'driverOptions', |
||
| 256 | 'driver_class' => 'driverClass', |
||
| 257 | 'wrapper_class' => 'wrapperClass', |
||
| 258 | 'keep_slave' => 'keepSlave', |
||
| 259 | 'shard_choser' => 'shardChoser', |
||
| 260 | 'server_version' => 'serverVersion', |
||
| 261 | 'default_table_options' => 'defaultTableOptions', |
||
| 262 | ) as $old => $new) { |
||
| 263 | if (isset($options[$old])) { |
||
| 264 | $options[$new] = $options[$old]; |
||
| 265 | unset($options[$old]); |
||
| 266 | } |
||
| 267 | } |
||
| 268 | |||
| 269 | if (!empty($options['slaves']) && !empty($options['shards'])) { |
||
| 270 | throw new InvalidArgumentException('Sharding and master-slave connection cannot be used together'); |
||
| 271 | } |
||
| 272 | |||
| 273 | View Code Duplication | if (!empty($options['slaves'])) { |
|
| 274 | $nonRewrittenKeys = array( |
||
| 275 | 'driver' => true, 'driverOptions' => true, 'driverClass' => true, |
||
| 276 | 'wrapperClass' => true, 'keepSlave' => true, 'shardChoser' => true, |
||
| 277 | 'platform' => true, 'slaves' => true, 'master' => true, 'shards' => true, |
||
| 278 | 'serverVersion' => true, |
||
| 279 | // included by safety but should have been unset already |
||
| 280 | 'logging' => true, 'profiling' => true, 'mapping_types' => true, 'platform_service' => true, |
||
| 281 | ); |
||
| 282 | foreach ($options as $key => $value) { |
||
| 283 | if (isset($nonRewrittenKeys[$key])) { |
||
| 284 | continue; |
||
| 285 | } |
||
| 286 | $options['master'][$key] = $value; |
||
| 287 | unset($options[$key]); |
||
| 288 | } |
||
| 289 | if (empty($options['wrapperClass'])) { |
||
| 290 | // Change the wrapper class only if the user does not already forced using a custom one. |
||
| 291 | $options['wrapperClass'] = 'Doctrine\\DBAL\\Connections\\MasterSlaveConnection'; |
||
| 292 | } |
||
| 293 | } else { |
||
| 294 | unset($options['slaves']); |
||
| 295 | } |
||
| 296 | |||
| 297 | View Code Duplication | if (!empty($options['shards'])) { |
|
| 298 | $nonRewrittenKeys = array( |
||
| 299 | 'driver' => true, 'driverOptions' => true, 'driverClass' => true, |
||
| 300 | 'wrapperClass' => true, 'keepSlave' => true, 'shardChoser' => true, |
||
| 301 | 'platform' => true, 'slaves' => true, 'global' => true, 'shards' => true, |
||
| 302 | // included by safety but should have been unset already |
||
| 303 | 'logging' => true, 'profiling' => true, 'mapping_types' => true, 'platform_service' => true, |
||
| 304 | ); |
||
| 305 | foreach ($options as $key => $value) { |
||
| 306 | if (isset($nonRewrittenKeys[$key])) { |
||
| 307 | continue; |
||
| 308 | } |
||
| 309 | $options['global'][$key] = $value; |
||
| 310 | unset($options[$key]); |
||
| 311 | } |
||
| 312 | if (empty($options['wrapperClass'])) { |
||
| 313 | // Change the wrapper class only if the user does not already forced using a custom one. |
||
| 314 | $options['wrapperClass'] = 'Doctrine\\DBAL\\Sharding\\PoolingShardConnection'; |
||
| 315 | } |
||
| 316 | } else { |
||
| 317 | unset($options['shards']); |
||
| 318 | } |
||
| 319 | |||
| 320 | return $options; |
||
| 321 | } |
||
| 322 | |||
| 323 | /** |
||
| 324 | * Loads the Doctrine ORM configuration. |
||
| 325 | * |
||
| 326 | * Usage example: |
||
| 327 | * |
||
| 328 | * <doctrine:orm id="mydm" connection="myconn" /> |
||
| 329 | * |
||
| 330 | * @param array $config An array of configuration settings |
||
| 331 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
| 332 | */ |
||
| 333 | protected function ormLoad(array $config, ContainerBuilder $container) |
||
| 334 | { |
||
| 335 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
||
| 336 | $loader->load('orm.xml'); |
||
| 337 | |||
| 338 | $this->entityManagers = array(); |
||
| 339 | foreach (array_keys($config['entity_managers']) as $name) { |
||
| 340 | $this->entityManagers[$name] = sprintf('doctrine.orm.%s_entity_manager', $name); |
||
| 341 | } |
||
| 342 | $container->setParameter('doctrine.entity_managers', $this->entityManagers); |
||
| 343 | |||
| 344 | if (empty($config['default_entity_manager'])) { |
||
| 345 | $tmp = array_keys($this->entityManagers); |
||
| 346 | $config['default_entity_manager'] = reset($tmp); |
||
| 347 | } |
||
| 348 | $container->setParameter('doctrine.default_entity_manager', $config['default_entity_manager']); |
||
| 349 | |||
| 350 | $options = array('auto_generate_proxy_classes', 'proxy_dir', 'proxy_namespace'); |
||
| 351 | foreach ($options as $key) { |
||
| 352 | $container->setParameter('doctrine.orm.'.$key, $config[$key]); |
||
| 353 | } |
||
| 354 | |||
| 355 | $container->setAlias('doctrine.orm.entity_manager', sprintf('doctrine.orm.%s_entity_manager', $config['default_entity_manager'])); |
||
| 356 | |||
| 357 | // BC logic to handle DoctrineBridge < 2.6 |
||
| 358 | if (!method_exists($this, 'fixManagersAutoMappings')) { |
||
| 359 | foreach ($config['entity_managers'] as $entityManager) { |
||
| 360 | if ($entityManager['auto_mapping'] && count($config['entity_managers']) > 1) { |
||
| 361 | throw new \LogicException('You cannot enable "auto_mapping" when several entity managers are defined.'); |
||
| 362 | } |
||
| 363 | } |
||
| 364 | } else { |
||
| 365 | $config['entity_managers'] = $this->fixManagersAutoMappings($config['entity_managers'], $container->getParameter('kernel.bundles')); |
||
| 366 | } |
||
| 367 | |||
| 368 | $def = $container->getDefinition('doctrine.orm.entity_manager.abstract'); |
||
| 369 | if (method_exists($def, 'setFactory')) { |
||
| 370 | // to be inlined in dbal.xml when dependency on Symfony DependencyInjection is bumped to 2.6 |
||
| 371 | $def->setFactory(array('%doctrine.orm.entity_manager.class%', 'create')); |
||
| 372 | } else { |
||
| 373 | // to be removed when dependency on Symfony DependencyInjection is bumped to 2.6 |
||
| 374 | $def->setFactoryClass('%doctrine.orm.entity_manager.class%'); |
||
| 375 | $def->setFactoryMethod('create'); |
||
| 376 | } |
||
| 377 | |||
| 378 | foreach ($config['entity_managers'] as $name => $entityManager) { |
||
| 379 | $entityManager['name'] = $name; |
||
| 380 | $this->loadOrmEntityManager($entityManager, $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', array( |
||
| 387 | $name, $implementation, array(), |
||
| 388 | )); |
||
| 389 | } |
||
| 390 | |||
| 391 | // BC: ResolveTargetEntityListener implements the subscriber interface since |
||
| 392 | // v2.5.0-beta1 (Commit 437f812) |
||
|
0 ignored issues
–
show
|
|||
| 393 | if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) { |
||
| 394 | $def->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata')); |
||
| 395 | } else { |
||
| 396 | $def->addTag('doctrine.event_subscriber'); |
||
| 397 | } |
||
| 398 | } |
||
| 399 | } |
||
| 400 | |||
| 401 | /** |
||
| 402 | * Loads a configured ORM entity manager. |
||
| 403 | * |
||
| 404 | * @param array $entityManager A configured ORM entity manager. |
||
| 405 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
| 406 | */ |
||
| 407 | protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $container) |
||
| 408 | { |
||
| 409 | $ormConfigDef = $container->setDefinition(sprintf('doctrine.orm.%s_configuration', $entityManager['name']), new DefinitionDecorator('doctrine.orm.configuration')); |
||
| 410 | |||
| 411 | $this->loadOrmEntityManagerMappingInformation($entityManager, $ormConfigDef, $container); |
||
| 412 | $this->loadOrmCacheDrivers($entityManager, $container); |
||
| 413 | |||
| 414 | if (isset($entityManager['entity_listener_resolver']) && $entityManager['entity_listener_resolver']) { |
||
| 415 | $container->setAlias(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name']), $entityManager['entity_listener_resolver']); |
||
| 416 | } else { |
||
| 417 | $container->setDefinition(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name']), new Definition('%doctrine.orm.entity_listener_resolver.class%')); |
||
| 418 | } |
||
| 419 | |||
| 420 | $methods = array( |
||
| 421 | 'setMetadataCacheImpl' => new Reference(sprintf('doctrine.orm.%s_metadata_cache', $entityManager['name'])), |
||
| 422 | 'setQueryCacheImpl' => new Reference(sprintf('doctrine.orm.%s_query_cache', $entityManager['name'])), |
||
| 423 | 'setResultCacheImpl' => new Reference(sprintf('doctrine.orm.%s_result_cache', $entityManager['name'])), |
||
| 424 | 'setMetadataDriverImpl' => new Reference('doctrine.orm.'.$entityManager['name'].'_metadata_driver'), |
||
| 425 | 'setProxyDir' => '%doctrine.orm.proxy_dir%', |
||
| 426 | 'setProxyNamespace' => '%doctrine.orm.proxy_namespace%', |
||
| 427 | 'setAutoGenerateProxyClasses' => '%doctrine.orm.auto_generate_proxy_classes%', |
||
| 428 | 'setClassMetadataFactoryName' => $entityManager['class_metadata_factory_name'], |
||
| 429 | 'setDefaultRepositoryClassName' => $entityManager['default_repository_class'], |
||
| 430 | ); |
||
| 431 | // check for version to keep BC |
||
| 432 | if (version_compare(Version::VERSION, "2.3.0-DEV") >= 0) { |
||
| 433 | $methods = array_merge($methods, array( |
||
| 434 | 'setNamingStrategy' => new Reference($entityManager['naming_strategy']), |
||
| 435 | 'setQuoteStrategy' => new Reference($entityManager['quote_strategy']), |
||
| 436 | )); |
||
| 437 | } |
||
| 438 | |||
| 439 | if (version_compare(Version::VERSION, "2.4.0-DEV") >= 0) { |
||
| 440 | $methods = array_merge($methods, array( |
||
| 441 | 'setEntityListenerResolver' => new Reference(sprintf('doctrine.orm.%s_entity_listener_resolver', $entityManager['name'])), |
||
| 442 | )); |
||
| 443 | } |
||
| 444 | |||
| 445 | if (version_compare(Version::VERSION, "2.5.0-DEV") >= 0) { |
||
| 446 | $listenerId = sprintf('doctrine.orm.%s_listeners.attach_entity_listeners', $entityManager['name']); |
||
| 447 | $listenerDef = $container->setDefinition($listenerId, new Definition('%doctrine.orm.listeners.attach_entity_listeners.class%')); |
||
| 448 | $listenerDef->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata')); |
||
| 449 | } |
||
| 450 | |||
| 451 | if (isset($entityManager['second_level_cache'])) { |
||
| 452 | $this->loadOrmSecondLevelCache($entityManager, $ormConfigDef, $container); |
||
| 453 | } |
||
| 454 | |||
| 455 | if ($entityManager['repository_factory']) { |
||
| 456 | $methods['setRepositoryFactory'] = new Reference($entityManager['repository_factory']); |
||
| 457 | } |
||
| 458 | |||
| 459 | foreach ($methods as $method => $arg) { |
||
| 460 | $ormConfigDef->addMethodCall($method, array($arg)); |
||
| 461 | } |
||
| 462 | |||
| 463 | foreach ($entityManager['hydrators'] as $name => $class) { |
||
| 464 | $ormConfigDef->addMethodCall('addCustomHydrationMode', array($name, $class)); |
||
| 465 | } |
||
| 466 | |||
| 467 | if (!empty($entityManager['dql'])) { |
||
| 468 | foreach ($entityManager['dql']['string_functions'] as $name => $function) { |
||
| 469 | $ormConfigDef->addMethodCall('addCustomStringFunction', array($name, $function)); |
||
| 470 | } |
||
| 471 | foreach ($entityManager['dql']['numeric_functions'] as $name => $function) { |
||
| 472 | $ormConfigDef->addMethodCall('addCustomNumericFunction', array($name, $function)); |
||
| 473 | } |
||
| 474 | foreach ($entityManager['dql']['datetime_functions'] as $name => $function) { |
||
| 475 | $ormConfigDef->addMethodCall('addCustomDatetimeFunction', array($name, $function)); |
||
| 476 | } |
||
| 477 | } |
||
| 478 | |||
| 479 | $enabledFilters = array(); |
||
| 480 | $filtersParameters = array(); |
||
| 481 | foreach ($entityManager['filters'] as $name => $filter) { |
||
| 482 | $ormConfigDef->addMethodCall('addFilter', array($name, $filter['class'])); |
||
| 483 | if ($filter['enabled']) { |
||
| 484 | $enabledFilters[] = $name; |
||
| 485 | } |
||
| 486 | if ($filter['parameters']) { |
||
| 487 | $filtersParameters[$name] = $filter['parameters']; |
||
| 488 | } |
||
| 489 | } |
||
| 490 | |||
| 491 | $managerConfiguratorName = sprintf('doctrine.orm.%s_manager_configurator', $entityManager['name']); |
||
| 492 | $container |
||
| 493 | ->setDefinition($managerConfiguratorName, new DefinitionDecorator('doctrine.orm.manager_configurator.abstract')) |
||
| 494 | ->replaceArgument(0, $enabledFilters) |
||
| 495 | ->replaceArgument(1, $filtersParameters) |
||
| 496 | ; |
||
| 497 | |||
| 498 | if (!isset($entityManager['connection'])) { |
||
| 499 | $entityManager['connection'] = $this->defaultConnection; |
||
| 500 | } |
||
| 501 | |||
| 502 | $container |
||
| 503 | ->setDefinition(sprintf('doctrine.orm.%s_entity_manager', $entityManager['name']), new DefinitionDecorator('doctrine.orm.entity_manager.abstract')) |
||
| 504 | ->setArguments(array( |
||
| 505 | new Reference(sprintf('doctrine.dbal.%s_connection', $entityManager['connection'])), |
||
| 506 | new Reference(sprintf('doctrine.orm.%s_configuration', $entityManager['name'])), |
||
| 507 | )) |
||
| 508 | ->setConfigurator(array(new Reference($managerConfiguratorName), 'configure')) |
||
| 509 | ; |
||
| 510 | |||
| 511 | $container->setAlias( |
||
| 512 | sprintf('doctrine.orm.%s_entity_manager.event_manager', $entityManager['name']), |
||
| 513 | new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $entityManager['connection']), false) |
||
| 514 | ); |
||
| 515 | |||
| 516 | if (isset($entityManager['entity_listeners'])) { |
||
| 517 | if (!isset($listenerDef)) { |
||
| 518 | throw new InvalidArgumentException('Entity listeners configuration requires doctrine-orm 2.5.0 or newer'); |
||
| 519 | } |
||
| 520 | |||
| 521 | $entities = $entityManager['entity_listeners']['entities']; |
||
| 522 | |||
| 523 | foreach ($entities as $entityListenerClass => $entity) { |
||
| 524 | foreach ($entity['listeners'] as $listenerClass => $listener) { |
||
| 525 | foreach ($listener['events'] as $listenerEvent) { |
||
| 526 | $listenerEventName = $listenerEvent['type']; |
||
| 527 | $listenerMethod = $listenerEvent['method']; |
||
| 528 | |||
| 529 | $listenerDef->addMethodCall('addEntityListener', array( |
||
| 530 | $entityListenerClass, $listenerClass, $listenerEventName, $listenerMethod, |
||
| 531 | )); |
||
| 532 | } |
||
| 533 | } |
||
| 534 | } |
||
| 535 | |||
| 536 | } |
||
| 537 | } |
||
| 538 | |||
| 539 | /** |
||
| 540 | * Loads an ORM entity managers bundle mapping information. |
||
| 541 | * |
||
| 542 | * There are two distinct configuration possibilities for mapping information: |
||
| 543 | * |
||
| 544 | * 1. Specify a bundle and optionally details where the entity and mapping information reside. |
||
| 545 | * 2. Specify an arbitrary mapping location. |
||
| 546 | * |
||
| 547 | * @example |
||
| 548 | * |
||
| 549 | * doctrine.orm: |
||
| 550 | * mappings: |
||
| 551 | * MyBundle1: ~ |
||
| 552 | * MyBundle2: yml |
||
| 553 | * MyBundle3: { type: annotation, dir: Entities/ } |
||
| 554 | * MyBundle4: { type: xml, dir: Resources/config/doctrine/mapping } |
||
| 555 | * MyBundle5: |
||
| 556 | * type: yml |
||
| 557 | * dir: bundle-mappings/ |
||
| 558 | * alias: BundleAlias |
||
| 559 | * arbitrary_key: |
||
| 560 | * type: xml |
||
| 561 | * dir: %kernel.root_dir%/../src/vendor/DoctrineExtensions/lib/DoctrineExtensions/Entities |
||
| 562 | * prefix: DoctrineExtensions\Entities\ |
||
| 563 | * alias: DExt |
||
| 564 | * |
||
| 565 | * In the case of bundles everything is really optional (which leads to autodetection for this bundle) but |
||
| 566 | * in the mappings key everything except alias is a required argument. |
||
| 567 | * |
||
| 568 | * @param array $entityManager A configured ORM entity manager |
||
| 569 | * @param Definition $ormConfigDef A Definition instance |
||
| 570 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
| 571 | */ |
||
| 572 | protected function loadOrmEntityManagerMappingInformation(array $entityManager, Definition $ormConfigDef, ContainerBuilder $container) |
||
| 573 | { |
||
| 574 | // reset state of drivers and alias map. They are only used by this methods and children. |
||
| 575 | $this->drivers = array(); |
||
| 576 | $this->aliasMap = array(); |
||
| 577 | |||
| 578 | $this->loadMappingInformation($entityManager, $container); |
||
| 579 | $this->registerMappingDrivers($entityManager, $container); |
||
| 580 | |||
| 581 | $ormConfigDef->addMethodCall('setEntityNamespaces', array($this->aliasMap)); |
||
| 582 | } |
||
| 583 | |||
| 584 | /** |
||
| 585 | * Loads an ORM second level cache bundle mapping information. |
||
| 586 | * |
||
| 587 | * @example |
||
| 588 | * entity_managers: |
||
| 589 | * default: |
||
| 590 | * second_level_cache: |
||
| 591 | * region_cache_driver: apc |
||
| 592 | * log_enabled: true |
||
| 593 | * regions: |
||
| 594 | * my_service_region: |
||
| 595 | * type: service |
||
| 596 | * service : "my_service_region" |
||
| 597 | * |
||
| 598 | * my_query_region: |
||
| 599 | * lifetime: 300 |
||
| 600 | * cache_driver: array |
||
| 601 | * type: filelock |
||
| 602 | * |
||
| 603 | * my_entity_region: |
||
| 604 | * lifetime: 600 |
||
| 605 | * cache_driver: |
||
| 606 | * type: apc |
||
| 607 | * |
||
| 608 | * @param array $entityManager A configured ORM entity manager |
||
| 609 | * @param Definition $ormConfigDef A Definition instance |
||
| 610 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
| 611 | */ |
||
| 612 | protected function loadOrmSecondLevelCache(array $entityManager, Definition $ormConfigDef, ContainerBuilder $container) |
||
| 613 | { |
||
| 614 | if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) { |
||
| 615 | throw new \InvalidArgumentException('Second-level cache requires doctrine-orm 2.5.0 or newer'); |
||
| 616 | } |
||
| 617 | |||
| 618 | $driverId = null; |
||
| 619 | $enabled = $entityManager['second_level_cache']['enabled']; |
||
| 620 | |||
| 621 | if (isset($entityManager['second_level_cache']['region_cache_driver'])) { |
||
| 622 | $driverName = 'second_level_cache.region_cache_driver'; |
||
| 623 | $driverMap = $entityManager['second_level_cache']['region_cache_driver']; |
||
| 624 | $driverId = $this->loadCacheDriver($driverName, $entityManager['name'], $driverMap, $container); |
||
| 625 | } |
||
| 626 | |||
| 627 | $configId = sprintf('doctrine.orm.%s_second_level_cache.cache_configuration', $entityManager['name']); |
||
| 628 | $regionsId = sprintf('doctrine.orm.%s_second_level_cache.regions_configuration', $entityManager['name']); |
||
| 629 | $driverId = $driverId ?: sprintf('doctrine.orm.%s_second_level_cache.region_cache_driver', $entityManager['name']); |
||
| 630 | $configDef = $container->setDefinition($configId, new Definition('%doctrine.orm.second_level_cache.cache_configuration.class%')); |
||
| 631 | $regionsDef = $container->setDefinition($regionsId, new Definition('%doctrine.orm.second_level_cache.regions_configuration.class%')); |
||
| 632 | |||
| 633 | $slcFactoryId = sprintf('doctrine.orm.%s_second_level_cache.default_cache_factory', $entityManager['name']); |
||
| 634 | $slcFactoryDef = $container |
||
| 635 | ->setDefinition($slcFactoryId, new Definition('%doctrine.orm.second_level_cache.default_cache_factory.class%')) |
||
| 636 | ->setArguments(array(new Reference($regionsId), new Reference($driverId))); |
||
| 637 | |||
| 638 | if (isset($entityManager['second_level_cache']['regions'])) { |
||
| 639 | foreach ($entityManager['second_level_cache']['regions'] as $name => $region) { |
||
| 640 | $regionRef = null; |
||
| 641 | $regionType = $region['type']; |
||
| 642 | |||
| 643 | if ($regionType === 'service') { |
||
| 644 | $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s', $entityManager['name'], $name); |
||
| 645 | $regionRef = new Reference($region['service']); |
||
| 646 | |||
| 647 | $container->setAlias($regionId, new Alias($region['service'], false)); |
||
| 648 | } |
||
| 649 | |||
| 650 | if ($regionType === 'default' || $regionType === 'filelock') { |
||
| 651 | $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s', $entityManager['name'], $name); |
||
| 652 | $driverName = sprintf('second_level_cache.region.%s_driver', $name); |
||
| 653 | $driverMap = $region['cache_driver']; |
||
| 654 | $driverId = $this->loadCacheDriver($driverName, $entityManager['name'], $driverMap, $container); |
||
| 655 | $regionRef = new Reference($regionId); |
||
| 656 | |||
| 657 | $container |
||
| 658 | ->setDefinition($regionId, new Definition('%doctrine.orm.second_level_cache.default_region.class%')) |
||
| 659 | ->setArguments(array($name, new Reference($driverId), $region['lifetime'])); |
||
| 660 | } |
||
| 661 | |||
| 662 | if ($regionType === 'filelock') { |
||
| 663 | $regionId = sprintf('doctrine.orm.%s_second_level_cache.region.%s_filelock', $entityManager['name'], $name); |
||
| 664 | |||
| 665 | $container |
||
| 666 | ->setDefinition($regionId, new Definition('%doctrine.orm.second_level_cache.filelock_region.class%')) |
||
| 667 | ->setArguments(array($regionRef, $region['lock_path'], $region['lock_lifetime'])); |
||
| 668 | |||
| 669 | $regionRef = new Reference($regionId); |
||
| 670 | $regionsDef->addMethodCall('getLockLifetime', array($name, $region['lock_lifetime'])); |
||
| 671 | } |
||
| 672 | |||
| 673 | $regionsDef->addMethodCall('setLifetime', array($name, $region['lifetime'])); |
||
| 674 | $slcFactoryDef->addMethodCall('setRegion', array($regionRef)); |
||
| 675 | } |
||
| 676 | } |
||
| 677 | |||
| 678 | if ($entityManager['second_level_cache']['log_enabled']) { |
||
| 679 | $loggerChainId = sprintf('doctrine.orm.%s_second_level_cache.logger_chain', $entityManager['name']); |
||
| 680 | $loggerStatsId = sprintf('doctrine.orm.%s_second_level_cache.logger_statistics', $entityManager['name']); |
||
| 681 | $loggerChaingDef = $container->setDefinition($loggerChainId, new Definition('%doctrine.orm.second_level_cache.logger_chain.class%')); |
||
| 682 | $loggerStatsDef = $container->setDefinition($loggerStatsId, new Definition('%doctrine.orm.second_level_cache.logger_statistics.class%')); |
||
| 683 | |||
| 684 | $loggerChaingDef->addMethodCall('setLogger', array('statistics', $loggerStatsDef)); |
||
| 685 | $configDef->addMethodCall('setCacheLogger', array($loggerChaingDef)); |
||
| 686 | |||
| 687 | foreach ($entityManager['second_level_cache']['loggers'] as $name => $logger) { |
||
| 688 | $loggerId = sprintf('doctrine.orm.%s_second_level_cache.logger.%s', $entityManager['name'], $name); |
||
| 689 | $loggerRef = new Reference($logger['service']); |
||
| 690 | |||
| 691 | $container->setAlias($loggerId, new Alias($logger['service'], false)); |
||
| 692 | $loggerChaingDef->addMethodCall('setLogger', array($name, $loggerRef)); |
||
| 693 | } |
||
| 694 | } |
||
| 695 | |||
| 696 | $configDef->addMethodCall('setCacheFactory', array($slcFactoryDef)); |
||
| 697 | $configDef->addMethodCall('setRegionsConfiguration', array($regionsDef)); |
||
| 698 | $ormConfigDef->addMethodCall('setSecondLevelCacheEnabled', array($enabled)); |
||
| 699 | $ormConfigDef->addMethodCall('setSecondLevelCacheConfiguration', array($configDef)); |
||
| 700 | } |
||
| 701 | |||
| 702 | /** |
||
| 703 | * {@inheritDoc} |
||
| 704 | */ |
||
| 705 | protected function getObjectManagerElementName($name) |
||
| 706 | { |
||
| 707 | return 'doctrine.orm.'.$name; |
||
| 708 | } |
||
| 709 | |||
| 710 | protected function getMappingObjectDefaultName() |
||
| 711 | { |
||
| 712 | return 'Entity'; |
||
| 713 | } |
||
| 714 | |||
| 715 | /** |
||
| 716 | * {@inheritDoc} |
||
| 717 | */ |
||
| 718 | protected function getMappingResourceConfigDirectory() |
||
| 719 | { |
||
| 720 | return 'Resources/config/doctrine'; |
||
| 721 | } |
||
| 722 | |||
| 723 | /** |
||
| 724 | * {@inheritDoc} |
||
| 725 | */ |
||
| 726 | protected function getMappingResourceExtension() |
||
| 727 | { |
||
| 728 | return 'orm'; |
||
| 729 | } |
||
| 730 | |||
| 731 | /** |
||
| 732 | * {@inheritDoc} |
||
| 733 | */ |
||
| 734 | protected function loadCacheDriver($driverName, $entityManagerName, array $driverMap, ContainerBuilder $container) |
||
| 735 | { |
||
| 736 | if (!empty($driverMap['cache_provider'])) { |
||
| 737 | $aliasId = $this->getObjectManagerElementName(sprintf('%s_%s', $entityManagerName, $driverName)); |
||
| 738 | $serviceId = sprintf('doctrine_cache.providers.%s', $driverMap['cache_provider']); |
||
| 739 | |||
| 740 | $container->setAlias($aliasId, new Alias($serviceId, false)); |
||
| 741 | |||
| 742 | return $aliasId; |
||
| 743 | } |
||
| 744 | |||
| 745 | return $this->adapter->loadCacheDriver($driverName, $entityManagerName, $driverMap, $container); |
||
| 746 | } |
||
| 747 | |||
| 748 | /** |
||
| 749 | * Loads a configured entity managers cache drivers. |
||
| 750 | * |
||
| 751 | * @param array $entityManager A configured ORM entity manager. |
||
| 752 | * @param ContainerBuilder $container A ContainerBuilder instance |
||
| 753 | */ |
||
| 754 | protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $container) |
||
| 755 | { |
||
| 756 | $this->loadCacheDriver('metadata_cache', $entityManager['name'], $entityManager['metadata_cache_driver'], $container); |
||
| 757 | $this->loadCacheDriver('result_cache', $entityManager['name'], $entityManager['result_cache_driver'], $container); |
||
| 758 | $this->loadCacheDriver('query_cache', $entityManager['name'], $entityManager['query_cache_driver'], $container); |
||
| 759 | } |
||
| 760 | |||
| 761 | /** |
||
| 762 | * @param array $objectManager |
||
| 763 | * @param ContainerBuilder $container |
||
| 764 | * @param string $cacheName |
||
| 765 | */ |
||
| 766 | public function loadObjectManagerCacheDriver(array $objectManager, ContainerBuilder $container, $cacheName) |
||
| 767 | { |
||
| 768 | $this->loadCacheDriver($cacheName, $objectManager['name'], $objectManager[$cacheName.'_driver'], $container); |
||
| 769 | } |
||
| 770 | |||
| 771 | /** |
||
| 772 | * {@inheritDoc} |
||
| 773 | */ |
||
| 774 | public function getXsdValidationBasePath() |
||
| 775 | { |
||
| 776 | return __DIR__.'/../Resources/config/schema'; |
||
| 777 | } |
||
| 778 | |||
| 779 | /** |
||
| 780 | * {@inheritDoc} |
||
| 781 | */ |
||
| 782 | public function getNamespace() |
||
| 783 | { |
||
| 784 | return 'http://symfony.com/schema/dic/doctrine'; |
||
| 785 | } |
||
| 786 | |||
| 787 | /** |
||
| 788 | * {@inheritDoc} |
||
| 789 | */ |
||
| 790 | public function getConfiguration(array $config, ContainerBuilder $container) |
||
| 791 | { |
||
| 792 | return new Configuration($container->getParameter('kernel.debug')); |
||
| 793 | } |
||
| 794 | } |
||
| 795 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.