123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- <?php
- /*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Symfony\Bundle\DoctrineMongoDBBundle\DependencyInjection;
- use Symfony\Component\DependencyInjection\Extension\Extension;
- use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
- use Symfony\Component\DependencyInjection\ContainerBuilder;
- use Symfony\Component\DependencyInjection\Alias;
- use Symfony\Component\DependencyInjection\Reference;
- use Symfony\Component\DependencyInjection\Definition;
- use Symfony\Component\DependencyInjection\Resource\FileResource;
- use Symfony\Bundle\DoctrineAbstractBundle\DependencyInjection\AbstractDoctrineExtension;
- /**
- * Doctrine MongoDB ODM extension.
- *
- * @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
- * @author Kris Wallsmith <kris.wallsmith@symfony-project.com>
- * @author Jonathan H. Wage <jonwage@gmail.com>
- */
- class DoctrineMongoDBExtension extends AbstractDoctrineExtension
- {
- /**
- * Loads the MongoDB ODM configuration.
- *
- * Usage example:
- *
- * <doctrine:mongodb server="mongodb://localhost:27017" />
- *
- * @param array $config An array of configuration settings
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- public function mongodbLoad($config, ContainerBuilder $container)
- {
- $this->loadDefaults($config, $container);
- $this->loadConnections($config, $container);
- $this->loadDocumentManagers($config, $container);
- $this->loadConstraints($config, $container);
- }
- /**
- * Loads the default configuration.
- *
- * @param array $config An array of configuration settings
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- protected function loadDefaults(array $config, ContainerBuilder $container)
- {
- if (!$container->hasDefinition('doctrine.odm.mongodb.metadata.annotation')) {
- // Load DoctrineMongoDBBundle/Resources/config/mongodb.xml
- $loader = new XmlFileLoader($container, __DIR__.'/../Resources/config');
- $loader->load('mongodb.xml');
- }
- // Allow these application configuration options to override the defaults
- $options = array(
- 'default_document_manager',
- 'default_connection',
- 'cache_driver',
- 'metadata_cache_driver',
- 'proxy_namespace',
- 'auto_generate_proxy_classes',
- 'hydrator_namespace',
- 'auto_generate_hydrator_classes',
- 'default_database',
- );
- foreach ($options as $key) {
- if (isset($config[$key])) {
- $container->setParameter('doctrine.odm.mongodb.'.$key, $config[$key]);
- }
- $nKey = str_replace('_', '-', $key);
- if (isset($config[$nKey])) {
- $container->setParameter('doctrine.odm.mongodb.'.$key, $config[$nKey]);
- }
- }
- }
- /**
- * Loads the document managers configuration.
- *
- * @param array $config An array of configuration settings
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- protected function loadDocumentManagers(array $config, ContainerBuilder $container)
- {
- $documentManagers = $this->getDocumentManagers($config, $container);
- foreach ($documentManagers as $name => $documentManager) {
- $documentManager['name'] = $name;
- $this->loadDocumentManager($documentManager, $container);
- }
- }
- /**
- * Loads a document manager configuration.
- *
- * @param array $documentManager A document manager configuration array
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- protected function loadDocumentManager(array $documentManager, ContainerBuilder $container)
- {
- $defaultDocumentManager = $container->getParameter('doctrine.odm.mongodb.default_document_manager');
- $defaultDatabase = isset($documentManager['default_database']) ? $documentManager['default_database'] : $container->getParameter('doctrine.odm.mongodb.default_database');
- $proxyCacheDir = $container->getParameter('kernel.cache_dir').'/doctrine/odm/mongodb/Proxies';
- $hydratorCacheDir = $container->getParameter('kernel.cache_dir').'/doctrine/odm/mongodb/Hydrators';
- $configServiceName = sprintf('doctrine.odm.mongodb.%s_configuration', $documentManager['name']);
- if ($container->hasDefinition($configServiceName)) {
- $odmConfigDef = $container->getDefinition($configServiceName);
- } else {
- $odmConfigDef = new Definition('%doctrine.odm.mongodb.configuration_class%');
- $container->setDefinition($configServiceName, $odmConfigDef);
- }
- $this->loadDocumentManagerBundlesMappingInformation($documentManager, $odmConfigDef, $container);
- $this->loadDocumentManagerMetadataCacheDriver($documentManager, $container);
- $methods = array(
- 'setMetadataCacheImpl' => new Reference(sprintf('doctrine.odm.mongodb.%s_metadata_cache', $documentManager['name'])),
- 'setMetadataDriverImpl' => new Reference(sprintf('doctrine.odm.mongodb.%s_metadata_driver', $documentManager['name'])),
- 'setProxyDir' => $proxyCacheDir,
- 'setProxyNamespace' => $container->getParameter('doctrine.odm.mongodb.proxy_namespace'),
- 'setAutoGenerateProxyClasses' => $container->getParameter('doctrine.odm.mongodb.auto_generate_proxy_classes'),
- 'setHydratorDir' => $hydratorCacheDir,
- 'setHydratorNamespace' => $container->getParameter('doctrine.odm.mongodb.hydrator_namespace'),
- 'setAutoGenerateHydratorClasses' => $container->getParameter('doctrine.odm.mongodb.auto_generate_hydrator_classes'),
- 'setDefaultDB' => $defaultDatabase,
- 'setLoggerCallable' => array(new Reference('doctrine.odm.mongodb.logger'), 'logQuery'),
- );
- foreach ($methods as $method => $arg) {
- if ($odmConfigDef->hasMethodCall($method)) {
- $odmConfigDef->removeMethodCall($method);
- }
- $odmConfigDef->addMethodCall($method, array($arg));
- }
- // event manager
- $eventManagerName = isset($documentManager['event_manager']) ? $documentManager['event_manager'] : $documentManager['name'];
- $eventManagerId = sprintf('doctrine.odm.mongodb.%s_event_manager', $eventManagerName);
- if (!$container->hasDefinition($eventManagerId)) {
- $eventManagerDef = new Definition('%doctrine.odm.mongodb.event_manager_class%');
- $eventManagerDef->addTag('doctrine.odm.mongodb.event_manager');
- $eventManagerDef->setPublic(false);
- $container->setDefinition($eventManagerId, $eventManagerDef);
- }
- $odmDmArgs = array(
- new Reference(sprintf('doctrine.odm.mongodb.%s_connection', isset($documentManager['connection']) ? $documentManager['connection'] : $documentManager['name'])),
- new Reference(sprintf('doctrine.odm.mongodb.%s_configuration', $documentManager['name'])),
- new Reference($eventManagerId),
- );
- $odmDmDef = new Definition('%doctrine.odm.mongodb.document_manager_class%', $odmDmArgs);
- $odmDmDef->setFactoryMethod('create');
- $odmDmDef->addTag('doctrine.odm.mongodb.document_manager');
- $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManager['name']), $odmDmDef);
- if ($documentManager['name'] == $defaultDocumentManager) {
- $container->setAlias(
- 'doctrine.odm.mongodb.document_manager',
- new Alias(sprintf('doctrine.odm.mongodb.%s_document_manager', $documentManager['name']))
- );
- $container->setAlias(
- 'doctrine.odm.mongodb.event_manager',
- new Alias(sprintf('doctrine.odm.mongodb.%s_event_manager', $documentManager['name']))
- );
- }
- }
- /**
- * Gets the configured document managers.
- *
- * @param array $config An array of configuration settings
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- protected function getDocumentManagers(array $config, ContainerBuilder $container)
- {
- $defaultDocumentManager = $container->getParameter('doctrine.odm.mongodb.default_document_manager');
- $documentManagers = array();
- if (isset($config['document-managers'])) {
- $config['document_managers'] = $config['document-managers'];
- }
- if (isset($config['document_managers'])) {
- $configDocumentManagers = $config['document_managers'];
- if (isset($config['document_managers']['document-manager'])) {
- $config['document_managers']['document_manager'] = $config['document_managers']['document-manager'];
- }
- if (isset($config['document_managers']['document_manager']) && isset($config['document_managers']['document_manager'][0])) {
- // Multiple document managers
- $configDocumentManagers = $config['document_managers']['document_manager'];
- }
- foreach ($configDocumentManagers as $name => $documentManager) {
- $documentManagers[isset($documentManager['id']) ? $documentManager['id'] : $name] = $documentManager;
- }
- } else {
- $documentManagers = array($defaultDocumentManager => $config);
- }
- return $documentManagers;
- }
- /**
- * Loads the configured document manager metadata cache driver.
- *
- * @param array $config A configured document manager array
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- protected function loadDocumentManagerMetadataCacheDriver(array $documentManager, ContainerBuilder $container)
- {
- $metadataCacheDriver = $container->getParameter('doctrine.odm.mongodb.metadata_cache_driver');
- $dmMetadataCacheDriver = isset($documentManager['metadata-cache-driver']) ? $documentManager['metadata-cache-driver'] : (isset($documentManager['metadata_cache_driver']) ? $documentManager['metadata_cache_driver'] : $metadataCacheDriver);
- $type = is_array($dmMetadataCacheDriver) && isset($dmMetadataCacheDriver['type']) ? $dmMetadataCacheDriver['type'] : $dmMetadataCacheDriver;
- if ('memcache' === $type) {
- $memcacheClass = isset($dmMetadataCacheDriver['class']) ? $dmMetadataCacheDriver['class'] : sprintf('%%doctrine.odm.mongodb.cache.%s_class%%', $type);
- $cacheDef = new Definition($memcacheClass);
- $memcacheHost = isset($dmMetadataCacheDriver['host']) ? $dmMetadataCacheDriver['host'] : '%doctrine.odm.mongodb.cache.memcache_host%';
- $memcachePort = isset($dmMetadataCacheDriver['port']) ? $dmMetadataCacheDriver['port'] : '%doctrine.odm.mongodb.cache.memcache_port%';
- $memcacheInstanceClass = isset($dmMetadataCacheDriver['instance-class']) ? $dmMetadataCacheDriver['instance-class'] : (isset($dmMetadataCacheDriver['instance_class']) ? $dmMetadataCacheDriver['instance_class'] : '%doctrine.odm.mongodb.cache.memcache_instance_class%');
- $memcacheInstance = new Definition($memcacheInstanceClass);
- $memcacheInstance->addMethodCall('connect', array($memcacheHost, $memcachePort));
- $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_memcache_instance', $documentManager['name']), $memcacheInstance);
- $cacheDef->addMethodCall('setMemcache', array(new Reference(sprintf('doctrine.odm.mongodb.%s_memcache_instance', $documentManager['name']))));
- } else {
- $cacheDef = new Definition(sprintf('%%doctrine.odm.mongodb.cache.%s_class%%', $type));
- }
- $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_metadata_cache', $documentManager['name']), $cacheDef);
- }
- /**
- * Loads the configured connections.
- *
- * @param array $config An array of configuration settings
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- protected function loadConnections(array $config, ContainerBuilder $container)
- {
- $connections = $this->getConnections($config, $container);
- foreach ($connections as $name => $connection) {
- $odmConnArgs = array(
- isset($connection['server']) ? $connection['server'] : null,
- isset($connection['options']) ? $connection['options'] : array(),
- new Reference(sprintf('doctrine.odm.mongodb.%s_configuration', $name))
- );
- $odmConnDef = new Definition('%doctrine.odm.mongodb.connection_class%', $odmConnArgs);
- $container->setDefinition(sprintf('doctrine.odm.mongodb.%s_connection', $name), $odmConnDef);
- }
- }
- /**
- * Gets the configured connections.
- *
- * @param array $config An array of configuration settings
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- protected function getConnections(array $config, ContainerBuilder $container)
- {
- $defaultConnection = $container->getParameter('doctrine.odm.mongodb.default_connection');
- $connections = array();
- if (isset($config['connections'])) {
- $configConnections = $config['connections'];
- if (isset($config['connections']['connection']) && isset($config['connections']['connection'][0])) {
- // Multiple connections
- $configConnections = $config['connections']['connection'];
- }
- foreach ($configConnections as $name => $connection) {
- $connections[isset($connection['id']) ? $connection['id'] : $name] = $connection;
- }
- } else {
- $connections = array($defaultConnection => $config);
- }
- return $connections;
- }
- /**
- * Loads an ODM document managers bundle mapping information.
- *
- * There are two distinct configuration possibilities for mapping information:
- *
- * 1. Specifiy a bundle and optionally details where the entity and mapping information reside.
- * 2. Specifiy an arbitrary mapping location.
- *
- * @example
- *
- * doctrine.orm:
- * mappings:
- * MyBundle1: ~
- * MyBundle2: yml
- * MyBundle3: { type: annotation, dir: Documents/ }
- * MyBundle4: { type: xml, dir: Resources/config/doctrine/mapping }
- * MyBundle5:
- * type: yml
- * dir: [bundle-mappings1/, bundle-mappings2/]
- * alias: BundleAlias
- * arbitrary_key:
- * type: xml
- * dir: %kernel.dir%/../src/vendor/DoctrineExtensions/lib/DoctrineExtensions/Documents
- * prefix: DoctrineExtensions\Documents\
- * alias: DExt
- *
- * In the case of bundles everything is really optional (which leads to autodetection for this bundle) but
- * in the mappings key everything except alias is a required argument.
- *
- * @param array $documentManager A configured ODM entity manager.
- * @param Definition A Definition instance
- * @param ContainerBuilder $container A ContainerBuilder instance
- */
- protected function loadDocumentManagerBundlesMappingInformation(array $documentManager, Definition $odmConfigDef, ContainerBuilder $container)
- {
- // reset state of drivers and alias map. They are only used by this methods and children.
- $this->drivers = array();
- $this->aliasMap = array();
- $this->loadMappingInformation($documentManager, $container);
- $this->registerMappingDrivers($documentManager, $container);
- if ($odmConfigDef->hasMethodCall('setDocumentNamespaces')) {
- // TODO: Can we make a method out of it on Definition? replaceMethodArguments() or something.
- $calls = $odmConfigDef->getMethodCalls();
- foreach ($calls AS $call) {
- if ($call[0] == 'setDocumentNamespaces') {
- $this->aliasMap = array_merge($call[1][0], $this->aliasMap);
- }
- }
- $method = $odmConfigDef->removeMethodCall('setDocumentNamespaces');
- }
- $odmConfigDef->addMethodCall('setDocumentNamespaces', array($this->aliasMap));
- }
- protected function loadConstraints($config, ContainerBuilder $container)
- {
- if ($container->hasParameter('validator.annotations.namespaces')) {
- $container->setParameter('validator.annotations.namespaces', array_merge(
- $container->getParamter('validator.annotations.namespaces'),
- array('Symfony\Bundle\DoctrineMongoDBBundle\Validator\Constraints\\')
- ));
- }
- }
- protected function getObjectManagerElementName($name)
- {
- return 'doctrine.odm.mongodb.' . $name;
- }
- protected function getMappingObjectDefaultName()
- {
- return 'Document';
- }
- protected function getMappingResourceConfigDirectory()
- {
- return 'Resources/config/doctrine/metadata/mongodb';
- }
- /**
- * Returns the namespace to be used for this extension (XML namespace).
- *
- * @return string The XML namespace
- */
- public function getNamespace()
- {
- return 'http://www.symfony-project.org/schema/dic/doctrine/odm/mongodb';
- }
- /**
- * @return string
- */
- public function getXsdValidationBasePath()
- {
- return __DIR__.'/../Resources/config/schema';
- }
- /**
- * Returns the recommended alias to use in XML.
- *
- * This alias is also the mandatory prefix to use when using YAML.
- *
- * @return string The alias
- */
- public function getAlias()
- {
- return 'doctrine_odm';
- }
- }
|