[FrameworkBundle] fixed regression where the command might have the wrong container if the application is reused several times

This commit is contained in:
Fabien Potencier 2013-07-29 19:21:16 +02:00
parent 9d53905b88
commit 1bd45b371e
2 changed files with 33 additions and 4 deletions

View File

@ -11,6 +11,7 @@
namespace Symfony\Bundle\FrameworkBundle\Console; namespace Symfony\Bundle\FrameworkBundle\Console;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Application as BaseApplication; use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
@ -66,13 +67,23 @@ class Application extends BaseApplication
*/ */
public function doRun(InputInterface $input, OutputInterface $output) public function doRun(InputInterface $input, OutputInterface $output)
{ {
$this->kernel->boot();
if (!$this->commandsRegistered) { if (!$this->commandsRegistered) {
$this->registerCommands(); $this->registerCommands();
$this->commandsRegistered = true; $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'))) { if (true === $input->hasParameterOption(array('--shell', '-s'))) {
$shell = new Shell($this); $shell = new Shell($this);
@ -87,8 +98,6 @@ class Application extends BaseApplication
protected function registerCommands() protected function registerCommands()
{ {
$this->kernel->boot();
foreach ($this->kernel->getBundles() as $bundle) { foreach ($this->kernel->getBundles() as $bundle) {
if ($bundle instanceof Bundle) { if ($bundle instanceof Bundle) {
$bundle->registerCommands($this); $bundle->registerCommands($this);

View File

@ -15,6 +15,7 @@ use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\Console\Tester\ApplicationTester;
class ApplicationTest extends TestCase class ApplicationTest extends TestCase
{ {
@ -39,6 +40,25 @@ class ApplicationTest extends TestCase
$application->doRun(new ArrayInput(array('list')), new NullOutput()); $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) private function getKernel(array $bundles)
{ {
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); $dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
@ -49,7 +69,7 @@ class ApplicationTest extends TestCase
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container $container
->expects($this->once()) ->expects($this->atLeastOnce())
->method('get') ->method('get')
->with($this->equalTo('event_dispatcher')) ->with($this->equalTo('event_dispatcher'))
->will($this->returnValue($dispatcher)) ->will($this->returnValue($dispatcher))