8000 feature #15938 [Console] Bind input before executing the COMMAND even… · symfony/symfony@3b3431e · GitHub
[go: up one dir, main page]

Skip to content

Commit 3b3431e

Browse files
committed
feature #15938 [Console] Bind input before executing the COMMAND event (WouterJ)
This PR was merged into the 2.8 branch. Discussion ---------- [Console] Bind input before executing the COMMAND event | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #10695 (problem 1) | License | MIT | Doc PR | - Previously, `$input` wasn't very usefull in the `console.command` event, as the input was not yet bound to the command definition. With this PR, the input is now bound twice: Once before the event is dispatched (to make it usefull in the listeners) and once at the original location in `Command#run()` (to allow changing the input definition in an event listener). Commits ------- 0af1676 Bind input before executing the COMMAND event
2 parents 2f44171 + 0af1676 commit 3b3431e

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

src/Symfony/Component/Console/Application.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Console\Descriptor\TextDescriptor;
1515
use Symfony\Component\Console\Descriptor\XmlDescriptor;
16+
use Symfony\Component\Console\Exception\ExceptionInterface;
1617
use Symfony\Component\Console\Helper\DebugFormatterHelper;
1718
use Symfony\Component\Console\Helper\ProcessHelper;
1819
use Symfony\Component\Console\Helper\QuestionHelper;
@@ -840,6 +841,14 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
840841
return $command->run($input, $output);
841842
}
842843

844+
// bind before the console.command event, so the listeners have access to input options/arguments
845+
try {
846+
$command->mergeApplicationDefinition();
847+
$input->bind($command->getDefinition());
848+
} catch (ExceptionInterface $e) {
849+
// ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
850+
}
851+
843852
$event = new ConsoleCommandEvent($command, $input, $output);
844853
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
845854

src/Symfony/Component/Console/Command/Command.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Console\Descriptor\TextDescriptor;
1515
use Symfony\Component\Console\Descriptor\XmlDescriptor;
16+
use Symfony\Component\Console\Exception\ExceptionInterface;
1617
use Symfony\Component\Console\Input\InputDefinition;
1718
use Symfony\Component\Console\Input\InputOption;
1819
use Symfony\Component\Console\Input\InputArgument;
@@ -221,7 +222,7 @@ public function run(InputInterface $input, OutputInterface $output)
221222
// bind the input against the command specific arguments/options
222223
try {
223224
$input->bind($this->definition);
224-
} catch (\Exception $e) {
225+
} catch (ExceptionInterface $e) {
225226
if (!$this->ignoreValidationErrors) {
226227
throw $e;
227228
}

src/Symfony/Component/Console/Tests/ApplicationTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,63 @@ public function testRunWithDispatcherSkippingCommand()
946946
$this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode);
947947
}
948948

949+
public function testRunWithDispatcherAccessingInputOptions()
950+
{
951+
$noInte 10000 ractionValue = null;
952+
$quietValue = null;
953+
954+
$dispatcher = $this->getDispatcher();
955+
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$noInteractionValue, &$quietValue) {
956+
$input = $event->getInput();
957+
958+
$noInteractionValue = $input->getOption('no-interaction');
959+
$quietValue = $input->getOption('quiet');
960+
});
961+
962+
$application = new Application();
963+
$application->setDispatcher($dispatcher);
964+
$application->setAutoExit(false);
965+
966+
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
967+
$output->write('foo.');
968+
});
969+
970+
$tester = new ApplicationTester($application);
971+
$tester->run(array('command' => 'foo', '--no-interaction' => true));
972+
973+
$this->assertTrue($noInteractionValue);
974+
$this->assertFalse($quietValue);
975+
}
976+
977+
public function testRunWithDispatcherAddingInputOptions()
978+
{
979+
$extraValue = null;
980+
981+
$dispatcher = $this->getDispatcher();
982+
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$extraValue) {
983+
$definition = $event->getCommand()->getDefinition();
984+
$input = $event->getInput();
985+
986+
$definition->addOption(new InputOption('extra', null, InputOption::VALUE_REQUIRED));
987+
$input->bind($definition);
988+
989+
$extraValue = $input->getOption('extra');
990+
});
991+
992+
$application = new Application();
993+
$application->setDispatcher($dispatcher);
994+
$application->setAutoExit(false);
995+
996+
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
997+
$output->write('foo.');
998+
});
999+
1000+
$tester = new ApplicationTester($application);
1001+
$tester->run(array('command' => 'foo', '--extra' => 'some test value'));
1002+
1003+
$this->assertEquals('some test value', $extraValue);
1004+
}
1005+
9491006
public function testTerminalDimensions()
9501007
{
9511008
$application = new Application();

0 commit comments

Comments
 (0)
0