From 1bd45b371ec919185100fe9bcff69b9ba246a3f2 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 29 Jul 2013 19:21:16 +0200 Subject: [PATCH] [FrameworkBundle] fixed regression where the command might have the wrong container if the application is reused several times --- .../FrameworkBundle/Console/Application.php | 15 ++++++++++--- .../Tests/Console/ApplicationTest.php | 22 ++++++++++++++++++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php index 90d19c60e343..aac3928e5d8b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Application.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Application.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Console; +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Application as BaseApplication; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -66,13 +67,23 @@ public function getKernel() */ public function doRun(InputInterface $input, OutputInterface $output) { + $this->kernel->boot(); + if (!$this->commandsRegistered) { $this->registerCommands(); $this->commandsRegistered = true; } - $this->setDispatcher($this->kernel->getContainer()->get('event_dispatcher')); + $container = $this->kernel->getContainer(); + + foreach ($this->all() as $command) { + if ($command instanceof ContainerAwareCommand) { + $command->setContainer($container); + } + } + + $this->setDispatcher($container->get('event_dispatcher')); if (true === $input->hasParameterOption(array('--shell', '-s'))) { $shell = new Shell($this); @@ -87,8 +98,6 @@ public function doRun(InputInterface $input, OutputInterface $output) protected function registerCommands() { - $this->kernel->boot(); - foreach ($this->kernel->getBundles() as $bundle) { if ($bundle instanceof Bundle) { $bundle->registerCommands($this); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php index 6ded6dc5daf8..42fcb6f597dd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Console/ApplicationTest.php @@ -15,6 +15,7 @@ use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\Console\Tester\ApplicationTester; class ApplicationTest extends TestCase { @@ -39,6 +40,25 @@ public function testBundleCommandsAreRegistered() $application->doRun(new ArrayInput(array('list')), new NullOutput()); } + public function testBundleCommandsHaveRightContainer() + { + $command = $this->getMockForAbstractClass('Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand', array('foo'), '', true, true, true, array('setContainer')); + $command->setCode(function () {}); + $command->expects($this->exactly(2))->method('setContainer'); + + $application = new Application($this->getKernel(array())); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->add($command); + $tester = new ApplicationTester($application); + + // set container is called here + $tester->run(array('command' => 'foo')); + + // as the container might have change between two runs, setContainer must called again + $tester->run(array('command' => 'foo')); + } + private function getKernel(array $bundles) { $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); @@ -49,7 +69,7 @@ private function getKernel(array $bundles) $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); $container - ->expects($this->once()) + ->expects($this->atLeastOnce()) ->method('get') ->with($this->equalTo('event_dispatcher')) ->will($this->returnValue($dispatcher))