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
This commit is contained in:
commit
3b3431e289
@ -13,6 +13,7 @@ namespace Symfony\Component\Console;
|
|||||||
|
|
||||||
use Symfony\Component\Console\Descriptor\TextDescriptor;
|
use Symfony\Component\Console\Descriptor\TextDescriptor;
|
||||||
use Symfony\Component\Console\Descriptor\XmlDescriptor;
|
use Symfony\Component\Console\Descriptor\XmlDescriptor;
|
||||||
|
use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||||
use Symfony\Component\Console\Helper\DebugFormatterHelper;
|
use Symfony\Component\Console\Helper\DebugFormatterHelper;
|
||||||
use Symfony\Component\Console\Helper\ProcessHelper;
|
use Symfony\Component\Console\Helper\ProcessHelper;
|
||||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||||
@ -840,6 +841,14 @@ class Application
|
|||||||
return $command->run($input, $output);
|
return $command->run($input, $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bind before the console.command event, so the listeners have access to input options/arguments
|
||||||
|
try {
|
||||||
|
$command->mergeApplicationDefinition();
|
||||||
|
$input->bind($command->getDefinition());
|
||||||
|
} catch (ExceptionInterface $e) {
|
||||||
|
// ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
|
||||||
|
}
|
||||||
|
|
||||||
$event = new ConsoleCommandEvent($command, $input, $output);
|
$event = new ConsoleCommandEvent($command, $input, $output);
|
||||||
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
|
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Console\Command;
|
|||||||
|
|
||||||
use Symfony\Component\Console\Descriptor\TextDescriptor;
|
use Symfony\Component\Console\Descriptor\TextDescriptor;
|
||||||
use Symfony\Component\Console\Descriptor\XmlDescriptor;
|
use Symfony\Component\Console\Descriptor\XmlDescriptor;
|
||||||
|
use Symfony\Component\Console\Exception\ExceptionInterface;
|
||||||
use Symfony\Component\Console\Input\InputDefinition;
|
use Symfony\Component\Console\Input\InputDefinition;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
@ -221,7 +222,7 @@ class Command
|
|||||||
// bind the input against the command specific arguments/options
|
// bind the input against the command specific arguments/options
|
||||||
try {
|
try {
|
||||||
$input->bind($this->definition);
|
$input->bind($this->definition);
|
||||||
} catch (\Exception $e) {
|
} catch (ExceptionInterface $e) {
|
||||||
if (!$this->ignoreValidationErrors) {
|
if (!$this->ignoreValidationErrors) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
@ -946,6 +946,63 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode);
|
$this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRunWithDispatcherAccessingInputOptions()
|
||||||
|
{
|
||||||
|
$noInteractionValue = null;
|
||||||
|
$quietValue = null;
|
||||||
|
|
||||||
|
$dispatcher = $this->getDispatcher();
|
||||||
|
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$noInteractionValue, &$quietValue) {
|
||||||
|
$input = $event->getInput();
|
||||||
|
|
||||||
|
$noInteractionValue = $input->getOption('no-interaction');
|
||||||
|
$quietValue = $input->getOption('quiet');
|
||||||
|
});
|
||||||
|
|
||||||
|
$application = new Application();
|
||||||
|
$application->setDispatcher($dispatcher);
|
||||||
|
$application->setAutoExit(false);
|
||||||
|
|
||||||
|
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||||
|
$output->write('foo.');
|
||||||
|
});
|
||||||
|
|
||||||
|
$tester = new ApplicationTester($application);
|
||||||
|
$tester->run(array('command' => 'foo', '--no-interaction' => true));
|
||||||
|
|
||||||
|
$this->assertTrue($noInteractionValue);
|
||||||
|
$this->assertFalse($quietValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRunWithDispatcherAddingInputOptions()
|
||||||
|
{
|
||||||
|
$extraValue = null;
|
||||||
|
|
||||||
|
$dispatcher = $this->getDispatcher();
|
||||||
|
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$extraValue) {
|
||||||
|
$definition = $event->getCommand()->getDefinition();
|
||||||
|
$input = $event->getInput();
|
||||||
|
|
||||||
|
$definition->addOption(new InputOption('extra', null, InputOption::VALUE_REQUIRED));
|
||||||
|
$input->bind($definition);
|
||||||
|
|
||||||
|
$extraValue = $input->getOption('extra');
|
||||||
|
});
|
||||||
|
|
||||||
|
$application = new Application();
|
||||||
|
$application->setDispatcher($dispatcher);
|
||||||
|
$application->setAutoExit(false);
|
||||||
|
|
||||||
|
$application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
|
||||||
|
$output->write('foo.');
|
||||||
|
});
|
||||||
|
|
||||||
|
$tester = new ApplicationTester($application);
|
||||||
|
$tester->run(array('command' => 'foo', '--extra' => 'some test value'));
|
||||||
|
|
||||||
|
$this->assertEquals('some test value', $extraValue);
|
||||||
|
}
|
||||||
|
|
||||||
public function testTerminalDimensions()
|
public function testTerminalDimensions()
|
||||||
{
|
{
|
||||||
$application = new Application();
|
$application = new Application();
|
||||||
|
Reference in New Issue
Block a user