PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/symfony/2.0.0pr4/src/vendor/symfony/src/Symfony/Bundle/DoctrineMongoDBBundle/DependencyInjection/DoctrineMongoDBExtension.php

http://github.com/pmjones/php-framework-benchmarks
PHP | 403 lines | 260 code | 34 blank | 109 comment | 27 complexity | 4a402cef815b80e339c70f2303148b94 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\DoctrineMongoDBBundle\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\Reference;
  7. use Symfony\Component\DependencyInjection\Definition;
  8. use Symfony\Component\DependencyInjection\Resource\FileResource;
  9. /**
  10. * Doctrine MongoDB ODM extension.
  11. *
  12. * @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
  13. * @author Kris Wallsmith <kris.wallsmith@symfony-project.com>
  14. * @author Jonathan H. Wage <jonwage@gmail.com>
  15. */
  16. class DoctrineMongoDBExtension extends Extension
  17. {
  18. /**
  19. * Loads the MongoDB ODM configuration.
  20. *
  21. * Usage example:
  22. *
  23. * <doctrine:mongodb server="mongodb://localhost:27017" />
  24. *
  25. * @param array $config An array of configuration settings
  26. * @param ContainerBuilder $container A ContainerBuilder instance
  27. */
  28. public function mongodbLoad($config, ContainerBuilder $container)
  29. {
  30. $this->createProxyDirectory($container->getParameter('kernel.cache_dir'));
  31. $this->loadDefaults($config, $container);
  32. $this->loadConnections($config, $container);
  33. $this->loadDocumentManagers($config, $container);
  34. }
  35. /**
  36. * Create the Doctrine MongoDB ODM Document proxy directory
  37. */
  38. protected function createProxyDirectory($tmpDir)
  39. {
  40. // Create document proxy directory
  41. $proxyCacheDir = $tmpDir.'/doctrine/odm/mongodb/Proxies';
  42. if (!is_dir($proxyCacheDir)) {
  43. if (false === @mkdir($proxyCacheDir, 0777, true)) {
  44. die(sprintf('Unable to create the Doctrine Proxy directory (%s)', dirname($proxyCacheDir)));
  45. }
  46. } elseif (!is_writable($proxyCacheDir)) {
  47. die(sprintf('Unable to write in the Doctrine Proxy directory (%s)', $proxyCacheDir));
  48. }
  49. }
  50. /**
  51. * Loads the default configuration.
  52. *
  53. * @param array $config An array of configuration settings
  54. * @param ContainerBuilder $container A ContainerBuilder instance
  55. */
  56. protected function loadDefaults(array $config, ContainerBuilder $container)
  57. {
  58. if (!$container->hasDefinition('doctrine.odm.mongodb.metadata.annotation')) {
  59. // Load DoctrineMongoDBBundle/Resources/config/mongodb.xml
  60. $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config');
  61. $loader->load('mongodb.xml');
  62. }
  63. // Allow these application configuration options to override the defaults
  64. $options = array(
  65. 'default_document_manager',
  66. 'default_connection',
  67. 'cache_driver',
  68. 'metadata_cache_driver',
  69. 'proxy_namespace',
  70. 'auto_generate_proxy_classes',
  71. 'default_database',
  72. );
  73. foreach ($options as $key) {
  74. if (isset($config[$key])) {
  75. $container->setParameter('doctrine.odm.mongodb.'.$key, $config[$key]);
  76. }
  77. }
  78. $container->setParameter('doctrine.odm.mongodb.mapping_dirs', $this->findBundleSubpaths('Resources/config/doctrine/metadata/mongodb', $container));
  79. $container->setParameter('doctrine.odm.mongodb.document_dirs', $this->findBundleSubpaths('Document', $container));
  80. }
  81. /**
  82. * Loads the document managers configuration.
  83. *
  84. * @param array $config An array of configuration settings
  85. * @param ContainerBuilder $container A ContainerBuilder instance
  86. */
  87. protected function loadDocumentManagers(array $config, ContainerBuilder $container)
  88. {
  89. $documentManagers = $this->getDocumentManagers($config, $container);
  90. foreach ($documentManagers as $name => $documentManager) {
  91. $documentManager['name'] = $name;
  92. $this->loadDocumentManager($documentManager, $container);
  93. }
  94. }
  95. /**
  96. * Loads a document manager configuration.
  97. *
  98. * @param array $documentManager A document manager configuration array
  99. * @param ContainerBuilder $container A ContainerBuilder instance
  100. */
  101. protected function loadDocumentManager(array $documentManager, ContainerBuilder $container)
  102. {
  103. $defaultDocumentManager = $container->getParameter('doctrine.odm.mongodb.default_document_manager');
  104. $defaultDatabase = isset($documentManager['default_database']) ? $documentManager['default_database'] : $container->getParameter('doctrine.odm.mongodb.default_database');
  105. $proxyCacheDir = $container->getParameter('kernel.cache_dir').'/doctrine/odm/mongodb/Proxies';
  106. $odmConfigDef = new Definition('%doctrine.odm.mongodb.configuration_class%');
  107. $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_configuration', $documentManager['name']), $odmConfigDef);
  108. $this->loadDocumentManagerBundlesMappingInformation($documentManager, $odmConfigDef, $container);
  109. $this->loadDocumentManagerMetadataCacheDriver($documentManager, $container);
  110. $methods = array(
  111. 'setMetadataCacheImpl' => new Reference(sprintf('doctrine.odm.mongodb.%s_metadata_cache', $documentManager['name'])),
  112. 'setMetadataDriverImpl' => new Reference('doctrine.odm.mongodb.metadata'),
  113. 'setProxyDir' => $proxyCacheDir,
  114. 'setProxyNamespace' => $container->getParameter('doctrine.odm.mongodb.proxy_namespace'),
  115. 'setAutoGenerateProxyClasses' => $container->getParameter('doctrine.odm.mongodb.auto_generate_proxy_classes'),
  116. 'setDefaultDB' => $defaultDatabase,
  117. 'setLoggerCallable' => array(new Reference('doctrine.odm.mongodb.logger'), 'logQuery'),
  118. );
  119. foreach ($methods as $method => $arg) {
  120. $odmConfigDef->addMethodCall($method, array($arg));
  121. }
  122. // event manager
  123. $eventManagerName = isset($documentManager['event_manager']) ? $documentManager['event_manager'] : $documentManager['name'];
  124. $eventManagerId = sprintf('doctrine.odm.mongodb.%s_event_manager', $eventManagerName);
  125. if (!$container->hasDefinition($eventManagerId)) {
  126. $eventManagerDef = new Definition('%doctrine.odm.mongodb.event_manager_class%');
  127. $eventManagerDef->addMethodCall('loadTaggedEventListeners', array(
  128. new Reference('service_container'),
  129. ));
  130. $eventManagerDef->addMethodCall('loadTaggedEventListeners', array(
  131. new Reference('service_container'),
  132. sprintf('doctrine.odm.mongodb.%s_event_listener', $eventManagerName),
  133. ));
  134. $eventManagerDef->addMethodCall('loadTaggedEventSubscribers', array(
  135. new Reference('service_container'),
  136. ));
  137. $eventManagerDef->addMethodCall('loadTaggedEventSubscribers', array(
  138. new Reference('service_container'),
  139. sprintf('doctrine.odm.mongodb.%s_event_subscriber', $eventManagerName),
  140. ));
  141. $container->setDefinition($eventManagerId, $eventManagerDef);
  142. }
  143. $odmDmArgs = array(
  144. new Reference(sprintf('doctrine.odm.mongodb.%s_connection', isset($documentManager['connection']) ? $documentManager['connection'] : $documentManager['name'])),
  145. new Reference(sprintf('doctrine.odm.mongodb.%s_configuration', $documentManager['name'])),
  146. new Reference($eventManagerId),
  147. );
  148. $odmDmDef = new Definition('%doctrine.odm.mongodb.document_manager_class%', $odmDmArgs);
  149. $odmDmDef->setFactoryMethod('create');
  150. $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManager['name']), $odmDmDef);
  151. if ($documentManager['name'] == $defaultDocumentManager) {
  152. $container->setAlias(
  153. 'doctrine.odm.mongodb.document_manager',
  154. sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManager['name'])
  155. );
  156. }
  157. }
  158. /**
  159. * Gets the configured document managers.
  160. *
  161. * @param array $config An array of configuration settings
  162. * @param ContainerBuilder $container A ContainerBuilder instance
  163. */
  164. protected function getDocumentManagers(array $config, ContainerBuilder $container)
  165. {
  166. $defaultDocumentManager = $container->getParameter('doctrine.odm.mongodb.default_document_manager');
  167. $documentManagers = array();
  168. if (isset($config['document_managers'])) {
  169. $configDocumentManagers = $config['document_managers'];
  170. if (isset($config['document_managers']['document_manager']) && isset($config['document_managers']['document_manager'][0])) {
  171. // Multiple document managers
  172. $configDocumentManagers = $config['document_managers']['document_manager'];
  173. }
  174. foreach ($configDocumentManagers as $name => $documentManager) {
  175. $documentManagers[isset($documentManager['id']) ? $documentManager['id'] : $name] = $documentManager;
  176. }
  177. } else {
  178. $documentManagers = array($defaultDocumentManager => $config);
  179. }
  180. return $documentManagers;
  181. }
  182. /**
  183. * Loads a document managers bundles mapping information configuration.
  184. *
  185. * @param array $config An array of configuration settings
  186. * @param ContainerBuilder $container A ContainerBuilder instance
  187. */
  188. protected function loadDocumentManagerBundlesMappingInformation(array $documentManager, Definition $odmConfigDef, ContainerBuilder $container)
  189. {
  190. // configure metadata driver for each bundle based on the type of mapping files found
  191. $mappingDriverDef = new Definition('%doctrine.odm.mongodb.metadata.driver_chain_class%');
  192. $bundleDocumentMappings = array();
  193. $bundleDirs = $container->getParameter('kernel.bundle_dirs');
  194. $aliasMap = array();
  195. foreach ($container->getParameter('kernel.bundles') as $className) {
  196. $tmp = dirname(str_replace('\\', '/', $className));
  197. $namespace = str_replace('/', '\\', dirname($tmp));
  198. $class = basename($tmp);
  199. if (!isset($bundleDirs[$namespace])) {
  200. continue;
  201. }
  202. $type = $this->detectMetadataDriver($bundleDirs[$namespace].'/'.$class, $container);
  203. if (is_dir($dir = $bundleDirs[$namespace].'/'.$class.'/Document')) {
  204. if ($type === null) {
  205. $type = 'annotation';
  206. }
  207. $aliasMap[$class] = $namespace.'\\'.$class.'\\Document';
  208. }
  209. if ($type !== null) {
  210. $mappingDriverDef->addMethodCall('addDriver', array(
  211. new Reference(sprintf('doctrine.odm.mongodb.metadata.%s', $type)),
  212. $namespace.'\\'.$class.'\\Document'
  213. )
  214. );
  215. }
  216. }
  217. $odmConfigDef->addMethodCall('setDocumentNamespaces', array($aliasMap));
  218. $container->setDefinition('doctrine.odm.mongodb.metadata', $mappingDriverDef);
  219. }
  220. /**
  221. * Loads the configured document manager metadata cache driver.
  222. *
  223. * @param array $config A configured document manager array
  224. * @param ContainerBuilder $container A ContainerBuilder instance
  225. */
  226. protected function loadDocumentManagerMetadataCacheDriver(array $documentManager, ContainerBuilder $container)
  227. {
  228. $metadataCacheDriver = $container->getParameter('doctrine.odm.mongodb.metadata_cache_driver');
  229. $dmMetadataCacheDriver = isset($documentManager['metadata_cache_driver']) ? $documentManager['metadata_cache_driver'] : $metadataCacheDriver;
  230. $type = is_array($dmMetadataCacheDriver) && isset($dmMetadataCacheDriver['type']) ? $dmMetadataCacheDriver['type'] : $dmMetadataCacheDriver;
  231. if ($type === 'memcache') {
  232. $memcacheClass = isset($dmMetadataCacheDriver['class']) ? $dmMetadataCacheDriver['class'] : sprintf('%%doctrine.odm.mongodb.cache.%s_class%%', $type);
  233. $cacheDef = new Definition($memcacheClass);
  234. $memcacheHost = isset($dmMetadataCacheDriver['host']) ? $dmMetadataCacheDriver['host'] : '%doctrine.odm.mongodb.cache.memcache_host%';
  235. $memcachePort = isset($dmMetadataCacheDriver['port']) ? $dmMetadataCacheDriver['port'] : '%doctrine.odm.mongodb.cache.memcache_port%';
  236. $memcacheInstanceClass = isset($dmMetadataCacheDriver['instance_class']) ? $dmMetadataCacheDriver['instance_class'] : '%doctrine.odm.mongodb.cache.memcache_instance_class%';
  237. $memcacheInstance = new Definition($memcacheInstanceClass);
  238. $memcacheInstance->addMethodCall('connect', array($memcacheHost, $memcachePort));
  239. $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_memcache_instance', $documentManager['name']), $memcacheInstance);
  240. $cacheDef->addMethodCall('setMemcache', array(new Reference(sprintf('doctrine.odm.mongodb.%s_memcache_instance', $documentManager['name']))));
  241. } else {
  242. $cacheDef = new Definition(sprintf('%%doctrine.odm.mongodb.cache.%s_class%%', $type));
  243. }
  244. $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_metadata_cache', $documentManager['name']), $cacheDef);
  245. }
  246. /**
  247. * Loads the configured connections.
  248. *
  249. * @param array $config An array of configuration settings
  250. * @param ContainerBuilder $container A ContainerBuilder instance
  251. */
  252. protected function loadConnections(array $config, ContainerBuilder $container)
  253. {
  254. $connections = $this->getConnections($config, $container);
  255. foreach ($connections as $name => $connection) {
  256. $odmConnArgs = array(
  257. isset($connection['server']) ? $connection['server'] : null,
  258. isset($connection['options']) ? $connection['options'] : array()
  259. );
  260. $odmConnDef = new Definition('%doctrine.odm.mongodb.connection_class%', $odmConnArgs);
  261. $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_connection', $name), $odmConnDef);
  262. }
  263. }
  264. /**
  265. * Gets the configured connections.
  266. *
  267. * @param array $config An array of configuration settings
  268. * @param ContainerBuilder $container A ContainerBuilder instance
  269. */
  270. protected function getConnections(array $config, ContainerBuilder $container)
  271. {
  272. $defaultConnection = $container->getParameter('doctrine.odm.mongodb.default_connection');
  273. $connections = array();
  274. if (isset($config['connections'])) {
  275. $configConnections = $config['connections'];
  276. if (isset($config['connections']['connection']) && isset($config['connections']['connection'][0])) {
  277. // Multiple connections
  278. $configConnections = $config['connections']['connection'];
  279. }
  280. foreach ($configConnections as $name => $connection) {
  281. $connections[isset($connection['id']) ? $connection['id'] : $name] = $connection;
  282. }
  283. } else {
  284. $connections = array($defaultConnection => $config);
  285. }
  286. return $connections;
  287. }
  288. /**
  289. * Finds existing bundle subpaths.
  290. *
  291. * @param string $path A subpath to check for
  292. * @param ContainerBuilder $container A ContainerBuilder configuration
  293. *
  294. * @return array An array of absolute directory paths
  295. */
  296. protected function findBundleSubpaths($path, ContainerBuilder $container)
  297. {
  298. $dirs = array();
  299. foreach ($container->getParameter('kernel.bundles') as $bundle) {
  300. $reflection = new \ReflectionClass($bundle);
  301. if (is_dir($dir = dirname($reflection->getFilename()).'/'.$path)) {
  302. $dirs[] = $dir;
  303. $container->addResource(new FileResource($dir));
  304. } else {
  305. // add the closest existing parent directory as a file resource
  306. do {
  307. $dir = dirname($dir);
  308. } while (!is_dir($dir));
  309. $container->addResource(new FileResource($dir));
  310. }
  311. }
  312. return $dirs;
  313. }
  314. /**
  315. * Detects what metadata driver to use for the supplied directory.
  316. *
  317. * @param string $dir A directory path
  318. * @param ContainerBuilder $container A ContainerBuilder configuration
  319. *
  320. * @return string|null A metadata driver short name, if one can be detected
  321. */
  322. static protected function detectMetadataDriver($dir, ContainerBuilder $container)
  323. {
  324. // add the closest existing directory as a resource
  325. $resource = $dir.'/Resources/config/doctrine/metadata/mongodb';
  326. while (!is_dir($resource)) {
  327. $resource = dirname($resource);
  328. }
  329. $container->addResource(new FileResource($resource));
  330. if (count(glob($dir.'/Resources/config/doctrine/metadata/mongodb/*.xml'))) {
  331. return 'xml';
  332. } elseif (count(glob($dir.'/Resources/config/doctrine/metadata/mongodb/*.yml'))) {
  333. return 'yml';
  334. }
  335. // add the directory itself as a resource
  336. $container->addResource(new FileResource($dir));
  337. if (is_dir($dir.'/Document')) {
  338. return 'annotation';
  339. }
  340. }
  341. /**
  342. * Returns the namespace to be used for this extension (XML namespace).
  343. *
  344. * @return string The XML namespace
  345. */
  346. public function getNamespace()
  347. {
  348. return 'http://www.symfony-project.org/schema/dic/doctrine/odm/mongodb';
  349. }
  350. /**
  351. * @return string
  352. */
  353. public function getXsdValidationBasePath()
  354. {
  355. return __DIR__.'/../Resources/config/schema';
  356. }
  357. /**
  358. * Returns the recommended alias to use in XML.
  359. *
  360. * This alias is also the mandatory prefix to use when using YAML.
  361. *
  362. * @return string The alias
  363. */
  364. public function getAlias()
  365. {
  366. return 'doctrine_odm';
  367. }
  368. }