From c8d364b721e44f8116bcfc7791aa0c4765ed1755 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Thu, 2 Mar 2017 21:19:22 +0100 Subject: [PATCH] [Console] Do not squash input changes made from console.command event --- src/Symfony/Component/Console/Application.php | 4 +++ .../Component/Console/Command/Command.php | 21 ++++++++++++---- .../Console/Tests/ApplicationTest.php | 25 +++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php index bd340d3078..d069da03bc 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -859,6 +859,10 @@ class Application // ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition } + // don't bind the input again as it would override any input argument/option set from the command event in + // addition to being useless + $command->setInputBound(true); + $event = new ConsoleCommandEvent($command, $input, $output); $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event); diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php index 39a1f6e844..fd0376c22d 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -42,6 +42,7 @@ class Command private $ignoreValidationErrors = false; private $applicationDefinitionMerged = false; private $applicationDefinitionMergedWithArgs = false; + private $inputBound = false; private $code; private $synopsis = array(); private $usages = array(); @@ -218,11 +219,13 @@ class Command $this->mergeApplicationDefinition(); // bind the input against the command specific arguments/options - try { - $input->bind($this->definition); - } catch (ExceptionInterface $e) { - if (!$this->ignoreValidationErrors) { - throw $e; + if (!$this->inputBound) { + try { + $input->bind($this->definition); + } catch (ExceptionInterface $e) { + if (!$this->ignoreValidationErrors) { + throw $e; + } } } @@ -678,6 +681,14 @@ class Command return $output->fetch(); } + /** + * @internal + */ + public function setInputBound($inputBound) + { + $this->inputBound = $inputBound; + } + /** * Validates a command name. * diff --git a/src/Symfony/Component/Console/Tests/ApplicationTest.php b/src/Symfony/Component/Console/Tests/ApplicationTest.php index cd52617a5a..3cec084e69 100644 --- a/src/Symfony/Component/Console/Tests/ApplicationTest.php +++ b/src/Symfony/Component/Console/Tests/ApplicationTest.php @@ -1113,6 +1113,31 @@ class ApplicationTest extends TestCase $this->assertEquals('some test value', $extraValue); } + public function testUpdateInputFromConsoleCommandEvent() + { + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) { + $event->getInput()->setOption('extra', 'overriden'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application + ->register('foo') + ->addOption('extra', null, InputOption::VALUE_REQUIRED) + ->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }) + ; + + $tester = new ApplicationTester($application); + $tester->run(array('command' => 'foo', '--extra' => 'original')); + + $this->assertEquals('overriden', $tester->getInput()->getOption('extra')); + } + public function testTerminalDimensions() { $application = new Application();