Skip to content

Commit

Permalink
[DoctrineBundle] introduced a Registry class
Browse files Browse the repository at this point in the history
The Registry knows all connections and entity managers declared into a service
container. The Registry is available via the 'doctrine' service.

If can be used to get connections and entity managers by name:

Before:

$em = $this->get('doctrine.orm.entity_manager');
$em = $this->get('doctrine.orm.foobar_entity_manager');

After:

$em = $this->get('doctrine')->getEntityManager();
$em = $this->get('doctrine')->getEntityManager('foobar');

It is better for several reasons:

 * we rely less on naming conventions
 * IDEs will be able to auto-complete methods
  • Loading branch information
fabpot committed May 2, 2011
1 parent 6b74483 commit 6b5438a
Show file tree
Hide file tree
Showing 20 changed files with 276 additions and 98 deletions.
38 changes: 33 additions & 5 deletions UPDATE.md
Expand Up @@ -9,6 +9,39 @@ timeline closely anyway.
beta1 to beta2
--------------

* With the introduction of a new Doctrine Registry class, the following
parameters have been removed (replaced by methods on the `doctrine`
service):

* doctrine.orm.entity_managers
* doctrine.orm.default_entity_manager
* doctrine.dbal.default_connection

Before:

$container->getParameter('doctrine.orm.entity_managers')
$container->getParameter('doctrine.orm.default_entity_manager')
$container->getParameter('doctrine.orm.default_connection')

After:

$container->get('doctrine')->getEntityManagerNames()
$container->get('doctrine')->getDefaultEntityManagerName()
$container->get('doctrine')->getDefaultConnectionName()

But you don't really need to use these methods anymore, as to get an entity
manager, you can now use the registry directly:

Before:

$em = $this->get('doctrine.orm.entity_manager');
$em = $this->get('doctrine.orm.foobar_entity_manager');

After:

$em = $this->get('doctrine')->getEntityManager();
$em = $this->get('doctrine')->getEntityManager('foobar');

* Doctrine event subscribers now use a unique "doctrine.event_subscriber" tag.
Doctrine event listeners also use a unique "doctrine.event_listener" tag. To
specify a connection, use the optional "connection" attribute.
Expand Down Expand Up @@ -39,11 +72,6 @@ beta1 to beta2
- { name: doctrine.event_subscriber } # register for all connections
- { name: doctrine.event_subscriber, connection: default } # only for the default connection

* The `doctrine.orm.entity_managers` is now hash of entity manager names/ids pairs:

Before: array('default', 'foo')
After: array('default' => 'doctrine.orm.default_entity_manager', 'foo' => 'doctrine.orm.foo_entity_manager'))

* Application translations are now stored in the `Resources` directory:

Before:
Expand Down
Expand Up @@ -64,7 +64,7 @@ public function warmUp($cacheDir)
return;
}

foreach ($this->container->getParameter('doctrine.orm.entity_managers') as $id) {
foreach ($this->container->get('doctrine')->getEntityManagerNames() as $id) {
$em = $this->container->get($id);
$classes = $em->getMetadataFactory()->getAllMetadata();
$em->getProxyFactory()->generateProxyClasses($classes);
Expand Down
20 changes: 3 additions & 17 deletions src/Symfony/Bundle/DoctrineBundle/Command/DoctrineCommand.php
Expand Up @@ -42,14 +42,7 @@ protected function getEntityGenerator()

protected function getEntityManager($name)
{
$name = $name ?: $this->container->getParameter('doctrine.orm.default_entity_manager');

$ems = $this->container->getParameter('doctrine.orm.entity_managers');
if (!isset($ems[$name])) {
throw new \InvalidArgumentException(sprintf('Could not find Doctrine EntityManager named "%s"', $name));
}

return $this->container->get($ems[$name]);
return $this->container->get('doctrine')->getEntityManager($name);
}

/**
Expand All @@ -60,21 +53,14 @@ protected function getEntityManager($name)
*/
protected function getDoctrineConnection($name)
{
$name = $name ?: $this->container->getParameter('doctrine.dbal.default_connection');

$connections = $this->container->getParameter('doctrine.dbal.connections');
if (!isset($connections[$name])) {
throw new \InvalidArgumentException(sprintf('<error>Could not find a connection named <comment>%s</comment></error>', $name));
}

return $this->container->get($connections[$name]);
return $this->container->get('doctrine')->getConnection($name);
}

protected function getBundleMetadatas(Bundle $bundle)
{
$namespace = $bundle->getNamespace();
$bundleMetadatas = array();
foreach ($this->container->getParameter('doctrine.orm.entity_managers') as $id) {
foreach ($this->container->get('doctrine')->getEntityManagerNames() as $id) {
$em = $this->container->get($id);
$cmf = new DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
Expand Down
Expand Up @@ -46,7 +46,7 @@ protected function configure()

protected function execute(InputInterface $input, OutputInterface $output)
{
$entityManagerName = $input->getOption('em') ? $input->getOption('em') : $this->container->getParameter('doctrine.orm.default_entity_manager');
$entityManagerName = $input->getOption('em') ? $input->getOption('em') : $this->container->get('doctrine')->getDefaultEntityManagerName();

/* @var $entityManager Doctrine\ORM\EntityManager */
$entityManager = $this->getEntityManager($input->getOption('em'));
Expand Down
Expand Up @@ -30,50 +30,16 @@ abstract class DoctrineCommandHelper
*/
static public function setApplicationEntityManager(Application $application, $emName)
{
$em = self::getEntityManager($application, $emName);
$em = $application->getKernel()->getContainer()->get('doctrine')->getEntityManager($name);
$helperSet = $application->getHelperSet();
$helperSet->set(new ConnectionHelper($em->getConnection()), 'db');
$helperSet->set(new EntityManagerHelper($em), 'em');
}

static public function setApplicationConnection(Application $application, $connName)
{
$connection = self::getDoctrineConnection($application, $connName);
$connection = $application->getKernel()->getContainer()->get('doctrine')->getConnection($name);
$helperSet = $application->getHelperSet();
$helperSet->set(new ConnectionHelper($connection), 'db');
}

static protected function getEntityManager(Application $application, $name)
{
$container = $application->getKernel()->getContainer();

$name = $name ?: $container->getParameter('doctrine.orm.default_entity_manager');

$ems = $container->getParameter('doctrine.orm.entity_managers');
if (!isset($ems[$name])) {
throw new \InvalidArgumentException(sprintf('Could not find Doctrine EntityManager named "%s"', $name));
}

return $container->get($ems[$name]);
}

/**
* Get a doctrine dbal connection by symfony name.
*
* @param string $name
* @return Doctrine\DBAL\Connection
*/
static protected function getDoctrineConnection(Application $application, $name)
{
$container = $application->getKernel()->getContainer();

$name = $name ?: $container->getParameter('doctrine.dbal.default_connection');

$connections = $container->getParameter('doctrine.dbal.connections');
if (!isset($connections[$name])) {
throw new \InvalidArgumentException(sprintf('<error>Could not find a connection named <comment>%s</comment></error>', $name));
}

return $container->get($connections[$name]);
}
}
Expand Up @@ -15,6 +15,7 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\DoctrineBundle\Logger\DbalLogger;
use Symfony\Bundle\DoctrineBundle\Registry;

/**
* DoctrineDataCollector.
Expand All @@ -27,10 +28,10 @@ class DoctrineDataCollector extends DataCollector
private $managers;
private $logger;

public function __construct($connections, $managers, DbalLogger $logger = null)
public function __construct(Registry $registry, DbalLogger $logger = null)
{
$this->connections = $connections;
$this->managers = $managers;
$this->connections = $registry->getConnectionNames();
$this->managers = $registry->getEntityManagerNames();
$this->logger = $logger;
}

Expand Down
Expand Up @@ -16,7 +16,7 @@ class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
public function process(ContainerBuilder $container)
{
$this->container = $container;
$this->connections = $container->getParameter('doctrine.dbal.connections');
$this->connections = $container->getDefinition('doctrine')->getArgument(1);

foreach ($container->findTaggedServiceIds('doctrine.event_subscriber') as $subscriberId => $instances) {
$this->registerSubscriber($subscriberId, $instances);
Expand Down
Expand Up @@ -67,15 +67,15 @@ protected function dbalLoad(array $config, ContainerBuilder $container)

$container->setAlias('database_connection', sprintf('doctrine.dbal.%s_connection', $config['default_connection']));
$container->setAlias('doctrine.dbal.event_manager', new Alias(sprintf('doctrine.dbal.%s_connection.event_manager', $config['default_connection']), false));
$container->setParameter('doctrine.dbal.default_connection', $config['default_connection']);

$container->getDefinition('doctrine.dbal.connection_factory')->replaceArgument(0, $config['types']);

$connections = array();
foreach (array_keys($config['connections']) as $name) {
$connections[$name] = sprintf('doctrine.dbal.%s_connection', $name);
}
$container->setParameter('doctrine.dbal.connections', $connections);
$container->getDefinition('doctrine')->replaceArgument(1, $connections);
$container->getDefinition('doctrine')->replaceArgument(3, $config['default_connection']);

foreach ($config['connections'] as $name => $connection) {
$this->loadDbalConnection($name, $connection, $container);
Expand Down Expand Up @@ -148,18 +148,19 @@ protected function ormLoad(array $config, ContainerBuilder $container)
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('orm.xml');

$entityManagers = array();
$this->entityManagers = array();
foreach (array_keys($config['entity_managers']) as $name) {
$entityManagers[$name] = sprintf('doctrine.orm.%s_entity_manager', $name);
$this->entityManagers[$name] = sprintf('doctrine.orm.%s_entity_manager', $name);
}
$container->setParameter('doctrine.orm.entity_managers', $entityManagers);
$container->getDefinition('doctrine')->replaceArgument(2, $this->entityManagers);

if (empty($config['default_entity_manager'])) {
$tmp = array_keys($entityManagers);
$tmp = array_keys($this->entityManagers);
$config['default_entity_manager'] = reset($tmp);
}
$container->getDefinition('doctrine')->replaceArgument(4, $config['default_entity_manager']);

$options = array('default_entity_manager', 'auto_generate_proxy_classes', 'proxy_dir', 'proxy_namespace');
$options = array('auto_generate_proxy_classes', 'proxy_dir', 'proxy_namespace');
foreach ($options as $key) {
$container->setParameter('doctrine.orm.'.$key, $config[$key]);
}
Expand All @@ -180,7 +181,7 @@ protected function ormLoad(array $config, ContainerBuilder $container)
*/
protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $container)
{
if ($entityManager['auto_mapping'] && count($container->getParameter('doctrine.orm.entity_managers')) > 1) {
if ($entityManager['auto_mapping'] && count($this->entityManagers) > 1) {
throw new \LogicException('You cannot enable "auto_mapping" when several entity managers are defined.');
}

Expand Down Expand Up @@ -227,6 +228,7 @@ protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $
new Reference($connectionId),
new Reference(sprintf('doctrine.orm.%s_configuration', $entityManager['name']))
);

$ormEmDef = new Definition('%doctrine.orm.entity_manager.class%', $ormEmArgs);
$ormEmDef->setFactoryClass('%doctrine.orm.entity_manager.class%');
$ormEmDef->setFactoryMethod('create');
Expand Down
126 changes: 126 additions & 0 deletions src/Symfony/Bundle/DoctrineBundle/Registry.php
@@ -0,0 +1,126 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\DoctrineBundle;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\DBAL\Connection;

/**
* References all Doctrine connections and entity managers in a given Container.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Registry
{
private $container;
private $connections;
private $entityManagers;
private $defaultConnection;
private $defaultEntityManager;

public function __construct(ContainerInterface $container, array $connections, array $entityManagers, $defaultConnection, $defaultEntityManager)
{
$this->container = $container;
$this->connections = $connections;
$this->entityManagers = $entityManagers;

if (!isset($this->connections[$defaultConnection])) {
throw new \LogicException(sprintf('Default connection "%s" is not defined.', $defaultConnection));
}
$this->defaultConnection = $defaultConnection;

if (!isset($this->entityManagers[$defaultEntityManager])) {
throw new \LogicException(sprintf('Default entity manager "%s" is not defined.', $defaultEntityManager));
}
$this->defaultEntityManager = $defaultEntityManager;
}

/**
* Gets the default connection name.
*
* @return string The default connection name
*/
public function getDefaultConnectionName()
{
return $this->defaultConnection;
}

/**
* Gets the named connection.
*
* @param string $name The connection name (null for the default one)
*
* @return Connection
*/
public function getConnection($name = null)
{
if (null === $name) {
return $this->container->get($this->connections[$this->defaultConnection]);
}

if (!isset($this->connections[$name])) {
throw new \InvalidArgumentException(sprintf('Doctrine Connection named "%s" does not exist.', $name));
}

return $this->container->get($this->connections[$name]);
}

/**
* Gets all connection names.
*
* @return array An array of connection names
*/
public function getConnectionNames()
{
return $this->connections;
}

/**
* Gets the default entity manager name.
*
* @return string The default entity manager name
*/
public function getDefaultEntityManagerName()
{
return $this->defaultEntityManager;
}

/**
* Gets the named entity manager.
*
* @param string $name The entity manager name (null for the default one)
*
* @return EntityManager
*/
public function getEntityManager($name = null)
{
if (null === $name) {
return $this->container->get($this->entityManagers[$this->defaultEntityManager]);
}

if (!isset($this->entityManagers[$name])) {
throw new \InvalidArgumentException(sprintf('Doctrine EntityManager named "%s" does not exist.', $name));
}

return $this->container->get($this->entityManagers[$name]);
}

/**
* Gets all connection names.
*
* @return array An array of connection names
*/
public function getEntityManagerNames()
{
return $this->entityManagers;
}
}

2 comments on commit 6b5438a

@igorgolovanov
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's really better.

@michelsalib
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on this one. It will definitely makes sf2 easier to learn and to develop with.

Please sign in to comment.