PageRenderTime 52ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/symfony/2.0.0pr4/src/vendor/symfony/src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php

http://github.com/pmjones/php-framework-benchmarks
PHP | 530 lines | 322 code | 43 blank | 165 comment | 33 complexity | 8f8145be48e27b0c1dedd5690de78541 MD5 | raw file
Possible License(s): LGPL-3.0, Apache-2.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1
  1. <?php
  2. namespace Symfony\Bundle\DoctrineBundle\DependencyInjection;
  3. use Symfony\Component\DependencyInjection\Extension\Extension;
  4. use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
  5. use Symfony\Component\DependencyInjection\ContainerBuilder;
  6. use Symfony\Component\DependencyInjection\Definition;
  7. use Symfony\Component\DependencyInjection\Reference;
  8. use Symfony\Component\DependencyInjection\Resource\FileResource;
  9. /*
  10. * This file is part of the Symfony framework.
  11. *
  12. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  13. *
  14. * This source file is subject to the MIT license that is bundled
  15. * with this source code in the file LICENSE.
  16. */
  17. /**
  18. * DoctrineExtension is an extension for the Doctrine DBAL and ORM library.
  19. *
  20. * @author Jonathan H. Wage <jonwage@gmail.com>
  21. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  22. */
  23. class DoctrineExtension extends Extension
  24. {
  25. /**
  26. * Loads the DBAL configuration.
  27. *
  28. * Usage example:
  29. *
  30. * <doctrine:dbal id="myconn" dbname="sfweb" user="root" />
  31. *
  32. * @param array $config An array of configuration settings
  33. * @param ContainerBuilder $container A ContainerBuilder instance
  34. */
  35. public function dbalLoad($config, ContainerBuilder $container)
  36. {
  37. $this->loadDbalDefaults($config, $container);
  38. $this->loadDbalConnections($config, $container);
  39. }
  40. /**
  41. * Loads the Doctrine ORM configuration.
  42. *
  43. * Usage example:
  44. *
  45. * <doctrine:orm id="mydm" connection="myconn" />
  46. *
  47. * @param array $config An array of configuration settings
  48. * @param ContainerBuilder $container A ContainerBuilder instance
  49. */
  50. public function ormLoad($config, ContainerBuilder $container)
  51. {
  52. $this->createOrmProxyDirectory($container->getParameter('kernel.cache_dir'));
  53. $this->loadOrmDefaults($config, $container);
  54. $this->loadOrmEntityManagers($config, $container);
  55. }
  56. /**
  57. * Loads the DBAL configuration defaults.
  58. *
  59. * @param array $config An array of configuration settings
  60. * @param ContainerBuilder $container A ContainerBuilder instance
  61. */
  62. protected function loadDbalDefaults(array $config, ContainerBuilder $container)
  63. {
  64. if (!$container->hasDefinition('doctrine.dbal.logger')) {
  65. $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config');
  66. $loader->load('dbal.xml');
  67. }
  68. $defaultConnectionName = isset($config['default_connection']) ? $config['default_connection'] : $container->getParameter('doctrine.dbal.default_connection');
  69. $container->setAlias('database_connection', sprintf('doctrine.dbal.%s_connection', $defaultConnectionName));
  70. $container->setParameter('doctrine.dbal.default_connection', $defaultConnectionName);
  71. }
  72. /**
  73. * Loads the configured DBAL connections.
  74. *
  75. * @param array $config An array of configuration settings
  76. * @param ContainerBuilder $container A ContainerBuilder instance
  77. */
  78. protected function loadDbalConnections(array $config, ContainerBuilder $container)
  79. {
  80. $connections = $this->getDbalConnections($config, $container);
  81. foreach ($connections as $name => $connection) {
  82. $connection['name'] = $name;
  83. $this->loadDbalConnection($connection, $container);
  84. }
  85. }
  86. /**
  87. * Loads a configured DBAL connection.
  88. *
  89. * @param array $connection A dbal connection configuration.
  90. * @param ContainerBuilder $container A ContainerBuilder instance
  91. */
  92. protected function loadDbalConnection(array $connection, ContainerBuilder $container)
  93. {
  94. // previously registered?
  95. if ($container->hasDefinition(sprintf('doctrine.dbal.%s_connection', $connection['name']))) {
  96. $driverDef = $container->getDefinition(sprintf('doctrine.dbal.%s_connection', $connection['name']));
  97. $arguments = $driverDef->getArguments();
  98. $driverOptions = $arguments[0];
  99. } else {
  100. $containerClass = isset($connection['configuration_class']) ? $connection['configuration_class'] : 'Doctrine\DBAL\Configuration';
  101. $containerDef = new Definition($containerClass);
  102. $containerDef->addMethodCall('setSqlLogger', array(new Reference('doctrine.dbal.logger')));
  103. $container->setDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $connection['name']), $containerDef);
  104. $eventManagerDef = new Definition($connection['event_manager_class']);
  105. $container->setDefinition(sprintf('doctrine.dbal.%s_connection.event_manager', $connection['name']), $eventManagerDef);
  106. $driverOptions = array();
  107. $driverDef = new Definition('Doctrine\DBAL\DriverManager');
  108. $driverDef->setFactoryMethod('getConnection');
  109. $container->setDefinition(sprintf('doctrine.dbal.%s_connection', $connection['name']), $driverDef);
  110. }
  111. if (isset($connection['driver'])) {
  112. $driverOptions['driverClass'] = sprintf('Doctrine\\DBAL\\Driver\\%s\\Driver', $connection['driver']);
  113. }
  114. if (isset($connection['wrapper_class'])) {
  115. $driverOptions['wrapperClass'] = $connection['wrapper_class'];
  116. }
  117. if (isset($connection['options'])) {
  118. $driverOptions['driverOptions'] = $connection['options'];
  119. }
  120. foreach (array('dbname', 'host', 'user', 'password', 'path', 'memory', 'port', 'unix_socket', 'charset') as $key) {
  121. if (isset($connection[$key])) {
  122. $driverOptions[$key] = $connection[$key];
  123. }
  124. }
  125. $driverDef->setArguments(array(
  126. $driverOptions,
  127. new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $connection['name'])),
  128. new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $connection['name']))
  129. ));
  130. }
  131. /**
  132. * Gets the configured DBAL connections.
  133. *
  134. * @param array $config An array of configuration settings
  135. * @param ContainerBuilder $container A ContainerBuilder instance
  136. */
  137. protected function getDbalConnections(array $config, ContainerBuilder $container)
  138. {
  139. $defaultConnectionName = $container->getParameter('doctrine.dbal.default_connection');
  140. $defaultConnection = array(
  141. 'driver' => 'PDOMySql',
  142. 'user' => 'root',
  143. 'password' => null,
  144. 'host' => 'localhost',
  145. 'port' => null,
  146. 'event_manager_class' => 'Doctrine\Common\EventManager',
  147. 'configuration_class' => 'Doctrine\DBAL\Configuration',
  148. 'wrapper_class' => null,
  149. 'options' => array()
  150. );
  151. $connections = array();
  152. if (isset($config['connections'])) {
  153. $configConnections = $config['connections'];
  154. if(isset($config['connections']['connection']) && isset($config['connections']['connection'][0])) {
  155. // Multiple connections
  156. $configConnections = $config['connections']['connection'];
  157. }
  158. foreach ($configConnections as $name => $connection) {
  159. $connections[isset($connection['id']) ? $connection['id'] : $name] = array_merge($defaultConnection, $connection);
  160. }
  161. } else {
  162. $connections = array($defaultConnectionName => array_merge($defaultConnection, $config));
  163. }
  164. return $connections;
  165. }
  166. /**
  167. * Create the Doctrine ORM Entity proxy directory
  168. */
  169. protected function createOrmProxyDirectory($tmpDir)
  170. {
  171. // Create entity proxy directory
  172. $proxyCacheDir = $tmpDir.'/doctrine/orm/Proxies';
  173. if (!is_dir($proxyCacheDir)) {
  174. if (false === @mkdir($proxyCacheDir, 0777, true)) {
  175. die(sprintf('Unable to create the Doctrine Proxy directory (%s)', dirname($proxyCacheDir)));
  176. }
  177. } elseif (!is_writable($proxyCacheDir)) {
  178. die(sprintf('Unable to write in the Doctrine Proxy directory (%s)', $proxyCacheDir));
  179. }
  180. }
  181. /**
  182. * Loads the ORM default configuration.
  183. *
  184. * @param array $config An array of configuration settings
  185. * @param ContainerBuilder $container A ContainerBuilder instance
  186. */
  187. protected function loadOrmDefaults(array $config, ContainerBuilder $container)
  188. {
  189. if (!$container->hasDefinition('doctrine.orm.metadata_driver.annotation')) {
  190. $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config');
  191. $loader->load('orm.xml');
  192. }
  193. // Allow these application configuration options to override the defaults
  194. $options = array(
  195. 'default_entity_manager',
  196. 'default_connection',
  197. 'metadata_cache_driver',
  198. 'query_cache_driver',
  199. 'result_cache_driver',
  200. 'proxy_namespace',
  201. 'auto_generate_proxy_classes'
  202. );
  203. foreach ($options as $key) {
  204. if (isset($config[$key])) {
  205. $container->setParameter('doctrine.orm.'.$key, $config[$key]);
  206. }
  207. }
  208. $container->setParameter('doctrine.orm.metadata_driver.mapping_dirs', $this->findBundleSubpaths('Resources/config/doctrine/metadata/orm', $container));
  209. $container->setParameter('doctrine.orm.metadata_driver.entity_dirs', $this->findBundleSubpaths('Entity', $container));
  210. }
  211. /**
  212. * Loads the configured ORM entity managers.
  213. *
  214. * @param array $config An array of configuration settings
  215. * @param ContainerBuilder $container A ContainerBuilder instance
  216. */
  217. protected function loadOrmEntityManagers(array $config, ContainerBuilder $container)
  218. {
  219. $entityManagers = $this->getOrmEntityManagers($config, $container);
  220. foreach ($entityManagers as $name => $entityManager) {
  221. $entityManager['name'] = $name;
  222. $this->loadOrmEntityManager($entityManager, $container);
  223. }
  224. }
  225. /**
  226. * Loads a configured ORM entity manager.
  227. *
  228. * @param array $entityManager A configured ORM entity manager.
  229. * @param ContainerBuilder $container A ContainerBuilder instance
  230. */
  231. protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $container)
  232. {
  233. $defaultEntityManager = $container->getParameter('doctrine.orm.default_entity_manager');
  234. $proxyCacheDir = $container->getParameter('kernel.cache_dir').'/doctrine/orm/Proxies';
  235. $ormConfigDef = new Definition('Doctrine\ORM\Configuration');
  236. $container->setDefinition(sprintf('doctrine.orm.%s_configuration', $entityManager['name']), $ormConfigDef);
  237. $this->loadOrmEntityManagerBundlesMappingInformation($entityManager, $ormConfigDef, $container);
  238. $this->loadOrmCacheDrivers($entityManager, $container);
  239. $methods = array(
  240. 'setMetadataCacheImpl' => new Reference(sprintf('doctrine.orm.%s_metadata_cache', $entityManager['name'])),
  241. 'setQueryCacheImpl' => new Reference(sprintf('doctrine.orm.%s_query_cache', $entityManager['name'])),
  242. 'setResultCacheImpl' => new Reference(sprintf('doctrine.orm.%s_result_cache', $entityManager['name'])),
  243. 'setMetadataDriverImpl' => new Reference('doctrine.orm.metadata_driver'),
  244. 'setProxyDir' => $proxyCacheDir,
  245. 'setProxyNamespace' => $container->getParameter('doctrine.orm.proxy_namespace'),
  246. 'setAutoGenerateProxyClasses' => $container->getParameter('doctrine.orm.auto_generate_proxy_classes')
  247. );
  248. foreach ($methods as $method => $arg) {
  249. $ormConfigDef->addMethodCall($method, array($arg));
  250. }
  251. $ormEmArgs = array(
  252. new Reference(sprintf('doctrine.dbal.%s_connection', isset($entityManager['connection']) ? $entityManager['connection'] : $entityManager['name'])),
  253. new Reference(sprintf('doctrine.orm.%s_configuration', $entityManager['name']))
  254. );
  255. $ormEmDef = new Definition('%doctrine.orm.entity_manager_class%', $ormEmArgs);
  256. $ormEmDef->setFactoryMethod('create');
  257. $container->setDefinition(sprintf('doctrine.orm.%s_entity_manager', $entityManager['name']), $ormEmDef);
  258. if ($entityManager['name'] == $defaultEntityManager) {
  259. $container->setAlias(
  260. 'doctrine.orm.entity_manager',
  261. sprintf('doctrine.orm.%s_entity_manager', $entityManager['name'])
  262. );
  263. }
  264. }
  265. /**
  266. * Gets the configured entity managers.
  267. *
  268. * @param array $config An array of configuration settings
  269. * @param ContainerBuilder $container A ContainerBuilder instance
  270. */
  271. protected function getOrmEntityManagers(array $config, ContainerBuilder $container)
  272. {
  273. $defaultEntityManager = $container->getParameter('doctrine.orm.default_entity_manager');
  274. $entityManagers = array();
  275. if (isset($config['entity_managers'])) {
  276. $configEntityManagers = $config['entity_managers'];
  277. if (isset($config['entity_managers']['entity_manager']) && isset($config['entity_managers']['entity_manager'][0])) {
  278. // Multiple entity managers
  279. $configEntityManagers = $config['entity_managers']['entity_manager'];
  280. }
  281. foreach ($configEntityManagers as $name => $entityManager) {
  282. $entityManagers[isset($entityManager['id']) ? $entityManager['id'] : $name] = $entityManager;
  283. }
  284. } else {
  285. $entityManagers = array($defaultEntityManager => $config);
  286. }
  287. return $entityManagers;
  288. }
  289. /**
  290. * Loads an ORM entity managers bundle mapping information.
  291. *
  292. * @param array $entityManager A configured ORM entity manager.
  293. * @param ContainerBuilder $container A ContainerBuilder instance
  294. */
  295. protected function loadOrmEntityManagerBundlesMappingInformation(array $entityManager, Definition $ormConfigDef, ContainerBuilder $container)
  296. {
  297. // configure metadata driver for each bundle based on the type of mapping files found
  298. $mappingDriverDef = new Definition('%doctrine.orm.metadata.driver_chain_class%');
  299. $bundleEntityMappings = array();
  300. $bundleDirs = $container->getParameter('kernel.bundle_dirs');
  301. $aliasMap = array();
  302. foreach ($container->getParameter('kernel.bundles') as $className) {
  303. $tmp = dirname(str_replace('\\', '/', $className));
  304. $namespace = str_replace('/', '\\', dirname($tmp));
  305. $class = basename($tmp);
  306. if (!isset($bundleDirs[$namespace])) {
  307. continue;
  308. }
  309. $type = $this->detectMetadataDriver($bundleDirs[$namespace].'/'.$class, $container);
  310. if (is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Entity')) {
  311. if ($type === null) {
  312. $type = 'annotation';
  313. }
  314. $aliasMap[$class] = $namespace.'\\'.$class.'\\Entity';
  315. }
  316. if ($type !== null) {
  317. $mappingDriverDef->addMethodCall('addDriver', array(
  318. new Reference(sprintf('doctrine.orm.metadata_driver.%s', $type)),
  319. $namespace.'\\'.$class.'\\Entity'
  320. )
  321. );
  322. }
  323. }
  324. $ormConfigDef->addMethodCall('setEntityNamespaces', array($aliasMap));
  325. $container->setDefinition('doctrine.orm.metadata_driver', $mappingDriverDef);
  326. }
  327. /**
  328. * Loads a configured entity managers cache drivers.
  329. *
  330. * @param array $entityManager A configured ORM entity manager.
  331. * @param ContainerBuilder $container A ContainerBuilder instance
  332. */
  333. protected function loadOrmCacheDrivers(array $entityManager, ContainerBuilder $container)
  334. {
  335. $this->loadOrmEntityManagerMetadataCacheDriver($entityManager, $container);
  336. $this->loadOrmEntityManagerQueryCacheDriver($entityManager, $container);
  337. $this->loadOrmEntityManagerResultCacheDriver($entityManager, $container);
  338. }
  339. /**
  340. * Loads a configured entity managers metadata cache driver.
  341. *
  342. * @param array $entityManager A configured ORM entity manager.
  343. * @param ContainerBuilder $container A ContainerBuilder instance
  344. */
  345. protected function loadOrmEntityManagerMetadataCacheDriver(array $entityManager, ContainerBuilder $container)
  346. {
  347. $cacheDriver = $container->getParameter('doctrine.orm.metadata_cache_driver');
  348. $cacheDriver = isset($entityManager['metadata_cache_driver']) ? $entityManager['metadata_cache_driver'] : $cacheDriver;
  349. $cacheDef = $this->getEntityManagerCacheDefinition($entityManager, $cacheDriver, $container);
  350. $container->setDefinition(sprintf('doctrine.orm.%s_metadata_cache', $entityManager['name']), $cacheDef);
  351. }
  352. /**
  353. * Loads a configured entity managers query cache driver.
  354. *
  355. * @param array $entityManager A configured ORM entity manager.
  356. * @param ContainerBuilder $container A ContainerBuilder instance
  357. */
  358. protected function loadOrmEntityManagerQueryCacheDriver(array $entityManager, ContainerBuilder $container)
  359. {
  360. $cacheDriver = $container->getParameter('doctrine.orm.query_cache_driver');
  361. $cacheDriver = isset($entityManager['query_cache_driver']) ? $entityManager['query_cache_driver'] : $cacheDriver;
  362. $cacheDef = $this->getEntityManagerCacheDefinition($entityManager, $cacheDriver, $container);
  363. $container->setDefinition(sprintf('doctrine.orm.%s_query_cache', $entityManager['name']), $cacheDef);
  364. }
  365. /**
  366. * Loads a configured entity managers result cache driver.
  367. *
  368. * @param array $entityManager A configured ORM entity manager.
  369. * @param ContainerBuilder $container A ContainerBuilder instance
  370. */
  371. protected function loadOrmEntityManagerResultCacheDriver(array $entityManager, ContainerBuilder $container)
  372. {
  373. $cacheDriver = $container->getParameter('doctrine.orm.result_cache_driver');
  374. $cacheDriver = isset($entityManager['result_cache_driver']) ? $entityManager['result_cache_driver'] : $cacheDriver;
  375. $cacheDef = $this->getEntityManagerCacheDefinition($entityManager, $cacheDriver, $container);
  376. $container->setDefinition(sprintf('doctrine.orm.%s_result_cache', $entityManager['name']), $cacheDef);
  377. }
  378. /**
  379. * Gets an entity manager cache driver definition for metadata, query and result caches.
  380. *
  381. * @param array $entityManager
  382. * @param string $cacheDriver
  383. * @param ContainerBuilder $container
  384. * @return Definition $cacheDef
  385. */
  386. protected function getEntityManagerCacheDefinition(array $entityManager, $cacheDriver, ContainerBuilder $container)
  387. {
  388. $type = is_array($cacheDriver) && isset($cacheDriver['type']) ? $cacheDriver['type'] : $cacheDriver;
  389. if ($type === 'memcache') {
  390. $memcacheClass = isset($cacheDriver['class']) ? $cacheDriver['class'] : '%'.sprintf('doctrine.orm.cache.%s_class', $type).'%';
  391. $cacheDef = new Definition($memcacheClass);
  392. $memcacheHost = isset($cacheDriver['host']) ? $cacheDriver['host'] : '%doctrine.orm.cache.memcache_host%';
  393. $memcachePort = isset($cacheDriver['port']) ? $cacheDriver['port'] : '%doctrine.orm.cache.memcache_port%';
  394. $memcacheInstanceClass = isset($cacheDriver['instance_class']) ? $cacheDriver['instance_class'] : '%doctrine.orm.cache.memcache_instance_class%';
  395. $memcacheInstance = new Definition($memcacheInstanceClass);
  396. $memcacheInstance->addMethodCall('connect', array($memcacheHost, $memcachePort));
  397. $container->setDefinition(sprintf('doctrine.orm.%s_memcache_instance', $entityManager['name']), $memcacheInstance);
  398. $cacheDef->addMethodCall('setMemcache', array(new Reference(sprintf('doctrine.orm.%s_memcache_instance', $entityManager['name']))));
  399. } else {
  400. $cacheDef = new Definition('%'.sprintf('doctrine.orm.cache.%s_class', $type).'%');
  401. }
  402. return $cacheDef;
  403. }
  404. /**
  405. * Finds existing bundle subpaths.
  406. *
  407. * @param string $path A subpath to check for
  408. * @param ContainerBuilder $container A ContainerBuilder configuration
  409. *
  410. * @return array An array of absolute directory paths
  411. */
  412. protected function findBundleSubpaths($path, ContainerBuilder $container)
  413. {
  414. $dirs = array();
  415. foreach ($container->getParameter('kernel.bundles') as $bundle) {
  416. $reflection = new \ReflectionClass($bundle);
  417. if (is_dir($dir = dirname($reflection->getFilename()).'/'.$path)) {
  418. $dirs[] = $dir;
  419. $container->addResource(new FileResource($dir));
  420. } else {
  421. // add the closest existing parent directory as a file resource
  422. do {
  423. $dir = dirname($dir);
  424. } while (!is_dir($dir));
  425. $container->addResource(new FileResource($dir));
  426. }
  427. }
  428. return $dirs;
  429. }
  430. /**
  431. * Detects what metadata driver to use for the supplied directory.
  432. *
  433. * @param string $dir A directory path
  434. * @param ContainerBuilder $container A ContainerBuilder configuration
  435. *
  436. * @return string|null A metadata driver short name, if one can be detected
  437. */
  438. static protected function detectMetadataDriver($dir, ContainerBuilder $container)
  439. {
  440. // add the closest existing directory as a resource
  441. $resource = $dir.'/Resources/config/doctrine/metadata/orm';
  442. while (!is_dir($resource)) {
  443. $resource = dirname($resource);
  444. }
  445. $container->addResource(new FileResource($resource));
  446. if (count(glob($dir.'/Resources/config/doctrine/metadata/orm/*.xml'))) {
  447. return 'xml';
  448. } elseif (count(glob($dir.'/Resources/config/doctrine/metadata/orm/*.yml'))) {
  449. return 'yml';
  450. }
  451. // add the directory itself as a resource
  452. $container->addResource(new FileResource($dir));
  453. if (is_dir($dir.'/Entity')) {
  454. return 'annotation';
  455. }
  456. }
  457. /**
  458. * Returns the base path for the XSD files.
  459. *
  460. * @return string The XSD base path
  461. */
  462. public function getXsdValidationBasePath()
  463. {
  464. return __DIR__.'/../Resources/config/schema';
  465. }
  466. /**
  467. * Returns the namespace to be used for this extension (XML namespace).
  468. *
  469. * @return string The XML namespace
  470. */
  471. public function getNamespace()
  472. {
  473. return 'http://www.symfony-project.org/schema/dic/doctrine';
  474. }
  475. /**
  476. * Returns the recommended alias to use in XML.
  477. *
  478. * This alias is also the mandatory prefix to use when using YAML.
  479. *
  480. * @return string The alias
  481. */
  482. public function getAlias()
  483. {
  484. return 'doctrine';
  485. }
  486. }