From a01d99bc6c9a6c8a8ace0012690099dd957ce9b9 Mon Sep 17 00:00:00 2001 From: Anton Minin Date: Mon, 16 Jan 2017 15:01:26 +0300 Subject: [PATCH] Avoid duplication of AttachEntityListeners (#560) * Avoid duplication of AttachEntityListeners * Test AttachEntityListeners are filtered by connections --- DependencyInjection/DoctrineExtension.php | 6 ++- .../AbstractDoctrineExtensionTest.php | 46 +++++++++++++++++++ ...ttach_entity_listeners_two_connections.xml | 20 ++++++++ ...ttach_entity_listeners_two_connections.yml | 16 +++++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 Tests/DependencyInjection/Fixtures/config/xml/orm_attach_entity_listeners_two_connections.xml create mode 100644 Tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listeners_two_connections.yml diff --git a/DependencyInjection/DoctrineExtension.php b/DependencyInjection/DoctrineExtension.php index 6a426da8e..80ec9062a 100644 --- a/DependencyInjection/DoctrineExtension.php +++ b/DependencyInjection/DoctrineExtension.php @@ -474,7 +474,11 @@ protected function loadOrmEntityManager(array $entityManager, ContainerBuilder $ if (version_compare(Version::VERSION, "2.5.0-DEV") >= 0) { $listenerId = sprintf('doctrine.orm.%s_listeners.attach_entity_listeners', $entityManager['name']); $listenerDef = $container->setDefinition($listenerId, new Definition('%doctrine.orm.listeners.attach_entity_listeners.class%')); - $listenerDef->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata')); + $listenerTagParams = array('event' => 'loadClassMetadata'); + if (isset($entityManager['connection'])) { + $listenerTagParams['connection'] = $entityManager['connection']; + } + $listenerDef->addTag('doctrine.event_listener', $listenerTagParams); } if (isset($entityManager['second_level_cache'])) { diff --git a/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php b/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php index 938427525..3da883ce9 100644 --- a/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php +++ b/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php @@ -17,6 +17,7 @@ use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass; use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension; use Doctrine\ORM\Version; +use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterEventListenersAndSubscribersPass; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -808,6 +809,30 @@ public function testAttachEntityListenerTag() $this->assertDICDefinitionMethodCallOnce($attachListener, 'addEntityListener', array('My/Entity2', 'EntityListener2', 'preFlush', 'preFlushHandler')); } + public function testAttachEntityListenersTwoConnections() + { + if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) { + $this->markTestSkipped('Attaching entity listeners by tag requires doctrine-orm 2.5.0 or newer'); + } + + $container = $this->getContainer(['YamlBundle']); + $loader = new DoctrineExtension(); + $container->registerExtension($loader); + $container->addCompilerPass(new RegisterEventListenersAndSubscribersPass('doctrine.connections', 'doctrine.dbal.%s_connection.event_manager', 'doctrine')); + + $this->loadFromFile($container, 'orm_attach_entity_listeners_two_connections'); + + $this->compileContainer($container); + + $defaultEventManager = $container->getDefinition('doctrine.dbal.default_connection.event_manager'); + $this->assertDICDefinitionNoMethodCall($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]); + $this->assertDICDefinitionMethodCallOnce($defaultEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]); + + $foobarEventManager = $container->getDefinition('doctrine.dbal.foobar_connection.event_manager'); + $this->assertDICDefinitionNoMethodCall($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em1_listeners.attach_entity_listeners')]); + $this->assertDICDefinitionMethodCallOnce($foobarEventManager, 'addEventListener', [['loadClassMetadata'], new Reference('doctrine.orm.em2_listeners.attach_entity_listeners')]); + } + public function testAttachLazyEntityListener() { if (version_compare(Version::VERSION, '2.5.0-DEV') < 0) { @@ -1008,6 +1033,27 @@ private function assertDICDefinitionMethodCallCount(Definition $definition, $met $this->assertEquals($nbCalls, $called, sprintf('The method "%s" should be called %d times', $methodName, $nbCalls)); } + /** + * Assertion for the DI Container, check if the given definition does not contain a method call with the given parameters. + * + * @param Definition $definition + * @param string $methodName + * @param array $params + */ + private function assertDICDefinitionNoMethodCall(Definition $definition, $methodName, array $params = null) + { + $calls = $definition->getMethodCalls(); + foreach ($calls as $call) { + if ($call[0] == $methodName) { + if ($params !== null) { + $this->assertNotEquals($params, $call[1], "Method '" . $methodName . "' is not expected to be called with the given parameters."); + } else { + $this->fail("Method '" . $methodName . "' is not expected to be called"); + } + } + } + } + private function compileContainer(ContainerBuilder $container) { $container->getCompilerPassConfig()->setOptimizationPasses(array(new ResolveDefinitionTemplatesPass())); diff --git a/Tests/DependencyInjection/Fixtures/config/xml/orm_attach_entity_listeners_two_connections.xml b/Tests/DependencyInjection/Fixtures/config/xml/orm_attach_entity_listeners_two_connections.xml new file mode 100644 index 000000000..35a705c99 --- /dev/null +++ b/Tests/DependencyInjection/Fixtures/config/xml/orm_attach_entity_listeners_two_connections.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/Tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listeners_two_connections.yml b/Tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listeners_two_connections.yml new file mode 100644 index 000000000..30434719d --- /dev/null +++ b/Tests/DependencyInjection/Fixtures/config/yml/orm_attach_entity_listeners_two_connections.yml @@ -0,0 +1,16 @@ +doctrine: + dbal: + default_connection: default + connections: + default: + dbname: db + foobar: + dbname: foobar + + orm: + default_entity_manager: em1 + entity_managers: + em1: + connection: default + em2: + connection: foobar