diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterMappingsPass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterMappingsPass.php index e56baa1e48..52bc151ffb 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterMappingsPass.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterMappingsPass.php @@ -69,26 +69,66 @@ abstract class RegisterMappingsPass implements CompilerPassInterface protected $enabledParameter; /** - * @param Definition|Reference $driver driver DI definition or reference - * @param string[] $namespaces list of namespaces handled by $driver - * @param string[] $managerParameters list of container parameters - * that could hold the manager name - * @param string $driverPattern pattern to get the metadata driver service names - * @param string|false $enabledParameter service container parameter that must be - * present to enable the mapping. Set to false - * to not do any check, optional. + * Naming pattern for the configuration service id, for example + * 'doctrine.orm.%s_configuration' + * @var string */ - public function __construct($driver, array $namespaces, array $managerParameters, $driverPattern, $enabledParameter = false) - { + private $configurationPattern; + + /** + * Method name to call on the configuration service. This depends on the + * Doctrine implementation. For example addEntityNamespace + * @var string + */ + private $registerAliasMethodName; + + /** + * Map of alias to namespace. + * @var string[] + */ + private $aliasMap; + + /** + * Constructor. + * + * The $managerParameters is an ordered list of container parameters that could provide the + * name of the manager to register these namespaces and alias on. The first non-empty name + * is used, the others skipped. + * + * The $aliasMap parameter can be used to define bundle namespace shortcuts like the + * DoctrineBundle provides automatically for objects in the default Entity/Document folder. + * + * @param Definition|Reference $driver Driver DI definition or reference. + * @param string[] $namespaces List of namespaces handled by $driver. + * @param string[] $managerParameters List of container parameters that could + * hold the manager name. + * @param string $driverPattern Pattern for the metadata driver service name. + * @param string $enabledParameter Service container parameter that must be + * present to enable the mapping. Set to false + * to not do any check, optional. + * @param string $configurationPattern Pattern for the Configuration service name. + * @param string $registerAliasMethodName Name of Configuration class method to + * register alias. + * @param string[] $aliasMap Map of alias to namespace. + * + * @since Support for bundle alias was added in Symfony 2.6 + */ + public function __construct($driver, array $namespaces, array $managerParameters, $driverPattern, $enabledParameter = false, $configurationPattern = '', $registerAliasMethodName = '', array $aliasMap = array()) { $this->driver = $driver; $this->namespaces = $namespaces; $this->managerParameters = $managerParameters; $this->driverPattern = $driverPattern; $this->enabledParameter = $enabledParameter; + if (count($aliasMap) && (!$configurationPattern || !$registerAliasMethodName)) { + throw new \InvalidArgumentException('configurationPattern and registerAliasMethodName are required to register namespace alias'); + } + $this->configurationPattern = $configurationPattern; + $this->registerAliasMethodName = $registerAliasMethodName; + $this->aliasMap = $aliasMap; } /** - * Register mappings with the metadata drivers. + * Register mappings and alias with the metadata drivers. * * @param ContainerBuilder $container */ @@ -99,39 +139,39 @@ abstract class RegisterMappingsPass implements CompilerPassInterface } $mappingDriverDef = $this->getDriver($container); - $chainDriverDefService = $this->getChainDriverServiceName($container); + // Definition for a Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain $chainDriverDef = $container->getDefinition($chainDriverDefService); foreach ($this->namespaces as $namespace) { $chainDriverDef->addMethodCall('addDriver', array($mappingDriverDef, $namespace)); } + + if (!count($this->aliasMap)) { + return; + } + + $configurationServiceName = $this->getConfigurationServiceName($container); + // Definition of the Doctrine\...\Configuration class specific to the Doctrine flavour. + $configurationServiceDefinition = $container->getDefinition($configurationServiceName); + foreach ($this->aliasMap as $alias => $namespace) { + $configurationServiceDefinition->addMethodCall($this->registerAliasMethodName, array($alias, $namespace)); + } } /** * Get the service name of the metadata chain driver that the mappings - * should be registered with. The default implementation loops over the - * managerParameters and applies the first non-empty parameter it finds to - * the driverPattern. + * should be registered with. * * @param ContainerBuilder $container * - * @return string a service definition name + * @return string The name of the chain driver service * * @throws ParameterNotFoundException if non of the managerParameters has a * non-empty value. */ protected function getChainDriverServiceName(ContainerBuilder $container) { - foreach ($this->managerParameters as $param) { - if ($container->hasParameter($param)) { - $name = $container->getParameter($param); - if ($name) { - return sprintf($this->driverPattern, $name); - } - } - } - - throw new ParameterNotFoundException('None of the managerParameters resulted in a valid name'); + return sprintf($this->driverPattern, $this->getManagerName($container)); } /** @@ -147,6 +187,48 @@ abstract class RegisterMappingsPass implements CompilerPassInterface return $this->driver; } + /** + * Get the service name from the pattern and the configured manager name. + * + * @param ContainerBuilder $container + * + * @return string a service definition name + * + * @throws ParameterNotFoundException if none of the managerParameters has a + * non-empty value. + */ + private function getConfigurationServiceName(ContainerBuilder $container) + { + return sprintf($this->configurationPattern, $this->getManagerName($container)); + } + + /** + * Determine the manager name. + * + * The default implementation loops over the managerParameters and returns + * the first non-empty parameter. + * + * @param ContainerBuilder $container + * + * @return string The name of the active manager. + * + * @throws ParameterNotFoundException If none of the managerParameters is found in the container. + */ + private function getManagerName(ContainerBuilder $container) + { + foreach ($this->managerParameters as $param) { + if ($container->hasParameter($param)) { + $name = $container->getParameter($param); + if ($name) { + return $name; + } + } + } + + throw new ParameterNotFoundException('None of the managerParameters resulted in a valid name'); + + } + /** * Determine whether this mapping should be activated or not. This allows * to take this decision with the container builder available. @@ -156,7 +238,7 @@ abstract class RegisterMappingsPass implements CompilerPassInterface * * @param ContainerBuilder $container * - * @return bool whether this compiler pass really should register the mappings + * @return bool whether this compiler pass really should register the mappings */ protected function enabled(ContainerBuilder $container) {