diff --git a/src/Symfony/Bridge/Doctrine/ManagerRegistry.php b/src/Symfony/Bridge/Doctrine/ManagerRegistry.php index ff2c598b0577a..3eaf8dbc51188 100644 --- a/src/Symfony/Bridge/Doctrine/ManagerRegistry.php +++ b/src/Symfony/Bridge/Doctrine/ManagerRegistry.php @@ -11,6 +11,8 @@ namespace Symfony\Bridge\Doctrine; +use ProxyManager\Proxy\LazyLoadingInterface; +use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Doctrine\Common\Persistence\AbstractManagerRegistry; @@ -37,6 +39,32 @@ protected function getService($name) */ protected function resetService($name) { - $this->container->set($name, null); + if (!$this->container->initialized($name)) { + return; + } + $manager = $this->container->get($name); + + if (!$manager instanceof LazyLoadingInterface) { + @trigger_error(sprintf('Resetting a non-lazy manager service is deprecated since Symfony 3.2 and will throw an exception in version 4.0. Set the "%s" service as lazy and require "symfony/proxy-manager-bridge" in your composer.json file instead.', $name)); + + $this->container->set($name, null); + + return; + } + $manager->setProxyInitializer(\Closure::bind( + function (&$wrappedInstance, LazyLoadingInterface $manager) use ($name) { + if (isset($this->aliases[$name = strtolower($name)])) { + $name = $this->aliases[$name]; + } + $method = !isset($this->methodMap[$name]) ? 'get'.strtr($name, $this->underscoreMap).'Service' : $this->methodMap[$name]; + $wrappedInstance = $this->{$method}(false); + + $manager->setProxyInitializer(null); + + return true; + }, + $this->container, + Container::class + )); } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php b/src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php new file mode 100644 index 0000000000000..30e3aef900be1 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/ManagerRegistryTest.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests; + +use Symfony\Bridge\Doctrine\ManagerRegistry; +use Symfony\Bridge\ProxyManager\Tests\LazyProxy\Dumper\PhpDumperTest; + +class ManagerRegistryTest extends \PHPUnit_Framework_TestCase +{ + public static function setUpBeforeClass() + { + $test = new PhpDumperTest(); + $test->testDumpContainerWithProxyServiceWillShareProxies(); + } + + public function testResetService() + { + $container = new \LazyServiceProjectServiceContainer(); + + $registry = new TestManagerRegistry('name', array(), array('defaultManager' => 'foo'), 'defaultConnection', 'defaultManager', 'proxyInterfaceName'); + $registry->setContainer($container); + + $foo = $container->get('foo'); + $foo->bar = 123; + $this->assertTrue(isset($foo->bar)); + + $registry->resetManager(); + + $this->assertSame($foo, $container->get('foo')); + $this->assertFalse(isset($foo->bar)); + } +} + +class TestManagerRegistry extends ManagerRegistry +{ + public function getAliasNamespace($alias) + { + return 'Foo'; + } +} diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index aeadc50e8ccdb..e2803b0168cf3 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -27,6 +27,7 @@ "symfony/http-kernel": "~2.8|~3.0", "symfony/property-access": "~2.8|~3.0", "symfony/property-info": "~2.8|3.0", + "symfony/proxy-manager-bridge": "~2.8|~3.0", "symfony/security": "~2.8|~3.0", "symfony/expression-language": "~2.8|~3.0", "symfony/validator": "~2.8|~3.0",