PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/symfony/src/Symfony/Bundle/DoctrineAbstractBundle/DependencyInjection/AbstractDoctrineExtension.php

https://github.com/casoetan/ServerGroveLiveChat
PHP | 326 lines | 211 code | 23 blank | 92 comment | 29 complexity | 86e7d494fba1c00056bb31e1518d2e2f MD5 | raw file
Possible License(s): LGPL-2.1, LGPL-3.0, ISC, BSD-3-Clause
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\DoctrineAbstractBundle\DependencyInjection;
  11. use Symfony\Component\HttpKernel\DependencyInjection\Extension;
  12. use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
  13. use Symfony\Component\DependencyInjection\ContainerBuilder;
  14. use Symfony\Component\DependencyInjection\Definition;
  15. use Symfony\Component\DependencyInjection\Reference;
  16. use Symfony\Component\DependencyInjection\Resource\FileResource;
  17. /**
  18. * This abstract classes groups common code that Doctrine Object Manager extensions (ORM, MongoDB, CouchDB) need.
  19. */
  20. abstract class AbstractDoctrineExtension extends Extension
  21. {
  22. /**
  23. * Used inside metadata driver method to simplify aggregation of data.
  24. *
  25. * @var array
  26. */
  27. protected $aliasMap = array();
  28. /**
  29. * Used inside metadata driver method to simplify aggregation of data.
  30. *
  31. * @var array
  32. */
  33. protected $drivers = array();
  34. /*
  35. * @param array $entityManager A configured ORM entity manager.
  36. * @param ContainerBuilder $container A ContainerBuilder instance
  37. */
  38. protected function loadMappingInformation(array $objectManager, $container)
  39. {
  40. if (isset($objectManager['mappings'])) {
  41. // fix inconsistency between yaml and xml naming
  42. if (isset($objectManager['mappings']['mapping'])) {
  43. if (isset($objectManager['mappings']['mapping'][0])) {
  44. $objectManager['mappings'] = $objectManager['mappings']['mapping'];
  45. } else {
  46. $objectManager['mappings'] = array($objectManager['mappings']['mapping']);
  47. }
  48. }
  49. foreach ($objectManager['mappings'] as $mappingName => $mappingConfig) {
  50. if (is_string($mappingConfig)) {
  51. $mappingConfig = array('type' => $mappingConfig);
  52. }
  53. if (!isset($mappingConfig['dir'])) {
  54. $mappingConfig['dir'] = false;
  55. }
  56. if (!isset($mappingConfig['type'])) {
  57. $mappingConfig['type'] = false;
  58. }
  59. if (!isset($mappingConfig['prefix'])) {
  60. $mappingConfig['prefix'] = false;
  61. }
  62. $mappingConfig['dir'] = $container->getParameterBag()->resolveValue($mappingConfig['dir']);
  63. // a bundle configuration is detected by realizing that the specified dir is not absolute and existing
  64. if (isset($mappingConfig['is-bundle'])) {
  65. $mappingConfig['is_bundle'] = $mappingConfig['is-bundle'];
  66. }
  67. if (!isset($mappingConfig['is_bundle'])) {
  68. $mappingConfig['is_bundle'] = !file_exists($mappingConfig['dir']);
  69. }
  70. if (isset($mappingConfig['name'])) {
  71. $mappingName = $mappingConfig['name'];
  72. } else if ($mappingConfig === null) {
  73. $mappingConfig = array();
  74. }
  75. if ($mappingConfig['is_bundle']) {
  76. $bundle = null;
  77. foreach ($container->getParameter('kernel.bundles') as $name => $class) {
  78. if ($mappingName === $name) {
  79. $bundle = new \ReflectionClass($class);
  80. break;
  81. }
  82. }
  83. if (null === $bundle) {
  84. throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled.', $mappingName));
  85. }
  86. $mappingConfig = $this->getMappingDriverBundleConfigDefaults($mappingConfig, $bundle, $container);
  87. if (!$mappingConfig) {
  88. continue;
  89. }
  90. }
  91. $this->assertValidMappingConfiguration($mappingConfig, $objectManager['name']);
  92. $this->setMappingDriverConfig($mappingConfig, $mappingName);
  93. $this->setMappingDriverAlias($mappingConfig, $mappingName);
  94. }
  95. }
  96. }
  97. /**
  98. * Register the alias for this mapping driver.
  99. *
  100. * Aliases can be used in the Query languages of all the Doctrine object managers to simplify writing tasks.
  101. *
  102. * @param array $mappingConfig
  103. * @param string $mappingName
  104. * @return void
  105. */
  106. protected function setMappingDriverAlias($mappingConfig, $mappingName)
  107. {
  108. if (isset($mappingConfig['alias'])) {
  109. $this->aliasMap[$mappingConfig['alias']] = $mappingConfig['prefix'];
  110. } else {
  111. $this->aliasMap[$mappingName] = $mappingConfig['prefix'];
  112. }
  113. }
  114. /**
  115. * Registter the mapping driver configuration for later use with the object managers metadata driver chain.
  116. *
  117. * @param array $mappingConfig
  118. * @param string $mappingName
  119. * @return void
  120. */
  121. protected function setMappingDriverConfig(array $mappingConfig, $mappingName)
  122. {
  123. if (is_dir($mappingConfig['dir'])) {
  124. if (!isset($this->drivers[$mappingConfig['type']])) {
  125. $this->drivers[$mappingConfig['type']] = array();
  126. }
  127. $this->drivers[$mappingConfig['type']][$mappingConfig['prefix']] = realpath($mappingConfig['dir']);
  128. } else {
  129. throw new \InvalidArgumentException("Invalid mapping path given. ".
  130. "Cannot load mapping/bundle named '" . $mappingName . "'.");
  131. }
  132. }
  133. /**
  134. * If this is a bundle controlled mapping all the missing information can be autodetected by this method.
  135. *
  136. * Returns false when autodetection failed, an array of the completed information otherwise.
  137. *
  138. * @param array $bundleConfig
  139. * @param \ReflectionClass $bundle
  140. * @param Container $container
  141. *
  142. * @return array|false
  143. */
  144. protected function getMappingDriverBundleConfigDefaults(array $bundleConfig, \ReflectionClass $bundle, $container)
  145. {
  146. $bundleDir = dirname($bundle->getFilename());
  147. if (!$bundleConfig['type']) {
  148. $bundleConfig['type'] = $this->detectMetadataDriver($bundleDir, $container);
  149. }
  150. if (!$bundleConfig['type']) {
  151. // skip this bundle, no mapping information was found.
  152. return false;
  153. }
  154. if (!$bundleConfig['dir']) {
  155. if (in_array($bundleConfig['type'], array('annotation', 'static-php'))) {
  156. $bundleConfig['dir'] = $bundleDir.'/'.$this->getMappingObjectDefaultName();
  157. } else {
  158. $bundleConfig['dir'] = $bundleDir.'/'.$this->getMappingResourceConfigDirectory();
  159. }
  160. } else {
  161. $bundleConfig['dir'] = $bundleDir.'/'.$bundleConfig['dir'];
  162. }
  163. if (!$bundleConfig['prefix']) {
  164. $bundleConfig['prefix'] = $bundle->getNamespaceName().'\\'.$this->getMappingObjectDefaultName();
  165. }
  166. return $bundleConfig;
  167. }
  168. /**
  169. * Register all the collected mapping information with the object manager by registering the appropiate mapping drivers.
  170. *
  171. * @param array $objectManager
  172. * @param Container $container
  173. */
  174. protected function registerMappingDrivers($objectManager, $container)
  175. {
  176. // configure metadata driver for each bundle based on the type of mapping files found
  177. if ($container->hasDefinition($this->getObjectManagerElementName($objectManager['name'] . '_metadata_driver'))) {
  178. $chainDriverDef = $container->getDefinition($this->getObjectManagerElementName($objectManager['name'] . '_metadata_driver'));
  179. } else {
  180. $chainDriverDef = new Definition('%'.$this->getObjectManagerElementName('metadata.driver_chain_class%'));
  181. $chainDriverDef->setPublic(false);
  182. }
  183. foreach ($this->drivers as $driverType => $driverPaths) {
  184. $mappingService = $this->getObjectManagerElementName($objectManager['name'] . '_'.$driverType.'_metadata_driver');
  185. if ($container->hasDefinition($mappingService)) {
  186. $mappingDriverDef = $container->getDefinition($mappingService);
  187. $args = $mappingDriverDef->getArguments();
  188. if ($driverType == 'annotation') {
  189. $args[1] = array_merge($driverPaths, $args[1]);
  190. } else {
  191. $args[0] = array_merge($driverPaths, $args[0]);
  192. }
  193. $mappingDriverDef->setArguments($args);
  194. } else if ($driverType == 'annotation') {
  195. $mappingDriverDef = new Definition('%'.$this->getObjectManagerElementName('metadata.' . $driverType . '_class%'), array(
  196. new Reference($this->getObjectManagerElementName('metadata.annotation_reader')),
  197. array_values($driverPaths)
  198. ));
  199. } else {
  200. $mappingDriverDef = new Definition('%'.$this->getObjectManagerElementName('metadata.' . $driverType . '_class%'), array(
  201. array_values($driverPaths)
  202. ));
  203. }
  204. $mappingDriverDef->setPublic(false);
  205. $container->setDefinition($mappingService, $mappingDriverDef);
  206. foreach ($driverPaths as $prefix => $driverPath) {
  207. $chainDriverDef->addMethodCall('addDriver', array(new Reference($mappingService), $prefix));
  208. }
  209. }
  210. $container->setDefinition($this->getObjectManagerElementName($objectManager['name'] . '_metadata_driver'), $chainDriverDef);
  211. }
  212. /**
  213. * Assertion if the specified mapping information is valid.
  214. *
  215. * @param array $mappingConfig
  216. * @param string $objectManagerName
  217. */
  218. protected function assertValidMappingConfiguration(array $mappingConfig, $objectManagerName)
  219. {
  220. if (!$mappingConfig['type'] || !$mappingConfig['dir'] || !$mappingConfig['prefix']) {
  221. throw new \InvalidArgumentException("Mapping definitions for manager '".$objectManagerName."' ".
  222. "require at least the 'type', 'dir' and 'prefix' options.");
  223. }
  224. if (!file_exists($mappingConfig['dir'])) {
  225. throw new \InvalidArgumentException("Specified non-existing directory '" . $mappingConfig['dir'] . "' as mapping source.");
  226. }
  227. if (!in_array($mappingConfig['type'], array('xml', 'yml', 'annotation', 'php', 'staticphp'))) {
  228. throw new \InvalidArgumentException("Can only configure 'xml', 'yml', 'annotation', 'php' or ".
  229. "'static-php' through the DoctrineBundle. Use your own bundle to configure other metadata drivers. " .
  230. "You can register them by adding a a new driver to the ".
  231. "'" . $this->getObjectManagerElementName($objectManagerName . ".metadata_driver")."' service definition."
  232. );
  233. }
  234. }
  235. /**
  236. * Detects what metadata driver to use for the supplied directory.
  237. *
  238. * @param string $dir A directory path
  239. * @param ContainerBuilder $container A ContainerBuilder configuration
  240. *
  241. * @return string|null A metadata driver short name, if one can be detected
  242. */
  243. protected function detectMetadataDriver($dir, ContainerBuilder $container)
  244. {
  245. // add the closest existing directory as a resource
  246. $configPath = $this->getMappingResourceConfigDirectory();
  247. $resource = $dir.'/'.$configPath;
  248. while (!is_dir($resource)) {
  249. $resource = dirname($resource);
  250. }
  251. $container->addResource(new FileResource($resource));
  252. if (($files = glob($dir.'/'.$configPath.'/*.xml')) && count($files)) {
  253. return 'xml';
  254. } elseif (($files = glob($dir.'/'.$configPath.'/*.yml')) && count($files)) {
  255. return 'yml';
  256. } elseif (($files = glob($dir.'/'.$configPath.'/*.php')) && count($files)) {
  257. return 'php';
  258. }
  259. // add the directory itself as a resource
  260. $container->addResource(new FileResource($dir));
  261. if (is_dir($dir.'/'.$this->getMappingObjectDefaultName())) {
  262. return 'annotation';
  263. }
  264. return null;
  265. }
  266. /**
  267. * Prefixes the relative dependency injenction container path with the object manager prefix.
  268. *
  269. * @example $name is 'entity_manager' then the result would be 'doctrine.orm.entity_manager'
  270. *
  271. * @param string $name
  272. * @return string
  273. */
  274. abstract protected function getObjectManagerElementName($name);
  275. /**
  276. * Noun that describes the mapped objects such as Entity or Document.
  277. *
  278. * Will be used for autodetection of persistent objects directory.
  279. *
  280. * @return string
  281. */
  282. abstract protected function getMappingObjectDefaultName();
  283. /**
  284. * Relative path from the bundle root to the directory where mapping files reside.
  285. *
  286. * @return string
  287. */
  288. abstract protected function getMappingResourceConfigDirectory();
  289. }