From 2e30a431d0c38ef1fe774e7cb0be35d98ca6c414 Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Mon, 1 Sep 2014 10:16:24 +0200 Subject: [PATCH] Added some methods to improve the handling of auto_mapping feature --- .../AbstractDoctrineExtension.php | 51 ++++++++ .../DoctrineExtensionTest.php | 122 ++++++++++++++++++ 2 files changed, 173 insertions(+) diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index 458497bc9d..5b1d0eedca 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -396,6 +396,33 @@ abstract class AbstractDoctrineExtension extends Extension return $cacheDriverServiceId; } + /** + * Returns a modified version of $managerConfigs. + * The manager called $autoMappedManager will map all bundles that are not mepped by other managers. + * @param array $managerConfigs + * @param array $bundles + * @return array The modified version of $managerConfigs. + */ + protected function fixManagersAutoMappings(array $managerConfigs, array $bundles) + { + if ($autoMappedManager = $this->validateAutoMapping($managerConfigs)) { + foreach (array_keys($bundles) as $bundle) { + foreach ($managerConfigs as $manager) { + if (isset($manager['mappings'][$bundle])) { + continue 2; + } + } + $managerConfigs[$autoMappedManager]['mappings'][$bundle] = array( + 'mapping' => true, + 'is_bundle' => true, + ); + } + $managerConfigs[$autoMappedManager]['auto_mapping'] = false; + } + + return $managerConfigs; + } + /** * Prefixes the relative dependency injection container path with the object manager prefix. * @@ -429,4 +456,28 @@ abstract class AbstractDoctrineExtension extends Extension * @return string */ abstract protected function getMappingResourceExtension(); + + /** + * Search for a manager that is declared as 'auto_mapping' = true + * @param array $managerConfigs + * @throws \LogicException + * @return null|string The name of the manager. If no one manager is found, returns null. + */ + private function validateAutoMapping(array $managerConfigs) + { + $autoMappedManager = null; + foreach ($managerConfigs as $name => $manager) { + if (!$manager['auto_mapping']) { + continue; + } + + if (null !== $autoMappedManager) { + throw new \LogicException(sprintf('You cannot enable "auto_mapping" on more than one manager at the same time (found in "%s" and %s").', $autoMappedManager, $name)); + } + + $autoMappedManager = $name; + } + + return $autoMappedManager; + } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php index b891f28c8b..3298c2a93c 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -48,6 +48,128 @@ class DoctrineExtensionTest extends \PHPUnit_Framework_TestCase })); } + /** + * @expectedException LogicException + */ + public function testFixManagersAutoMappingsWithTwoAutomappings() + { + $emConfigs = array( + 'em1'=> array( + 'auto_mapping' => true + ), + 'em2'=> array( + 'auto_mapping' => true + ), + ); + + $bundles = array( + 'FristBundle'=> 'My\FristBundle', + 'SecondBundle'=> 'My\SecondBundle', + ); + + $reflection = new \ReflectionClass(get_class($this->extension)); + $method = $reflection->getMethod('fixManagersAutoMappings'); + $method->setAccessible(true); + + $method->invoke($this->extension, $emConfigs, $bundles); + } + + public function getAutomappingData() + { + return array( + array( + array( // no auto mapping on em1 + 'auto_mapping' => false + ), + array( // no auto mapping on em2 + 'auto_mapping' => false + ), + array(), + array() + ), + array( + array( // no auto mapping on em1 + 'auto_mapping' => false + ), + array( // auto mapping enabled on em2 + 'auto_mapping' => true + ), + array(), + array( + 'mappings' => array( + 'FristBundle' => array( + 'mapping' => true, + 'is_bundle' => true + ), + 'SecondBundle' => array( + 'mapping' => true, + 'is_bundle' => true + ) + ) + ) + ), + array( + array( // no auto mapping on em1, but it defines SecondBundle as own + 'auto_mapping' => false, + 'mappings' => array( + 'SecondBundle' => array( + 'mapping' => true, + 'is_bundle' => true + ) + ) + ), + array( // auto mapping enabled on em2 + 'auto_mapping' => true + ), + array( + 'mappings' => array( + 'SecondBundle' => array( + 'mapping' => true, + 'is_bundle' => true + ) + ) + ), + array( + 'mappings' => array( + 'FristBundle' => array( + 'mapping' => true, + 'is_bundle' => true + ) + ) + ) + ) + ); + } + + /** + * @dataProvider getAutomappingData + */ + public function testFixManagersAutoMappings(array $originalEm1, array $originalEm2, array $expectedEm1, array $expectedEm2) + { + $emConfigs = array( + 'em1'=> $originalEm1, + 'em2'=> $originalEm2, + ); + + $bundles = array( + 'FristBundle'=> 'My\FristBundle', + 'SecondBundle'=> 'My\SecondBundle', + ); + + $reflection = new \ReflectionClass(get_class($this->extension)); + $method = $reflection->getMethod('fixManagersAutoMappings'); + $method->setAccessible(true); + + $newEmConfigs = $method->invoke($this->extension, $emConfigs, $bundles); + + $this->assertEquals($newEmConfigs["em1"], array_merge(array( + 'auto_mapping' => false + ), $expectedEm1)); + $this->assertEquals($newEmConfigs["em2"], array_merge(array( + 'auto_mapping' => false + ), $expectedEm2)); + } + public function providerBasicDrivers() { return array(