Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b7c6012

Browse filesBrowse files
committed
[Console] Fix BC break regarding console.command event
1 parent 25a2ce0 commit b7c6012
Copy full SHA for b7c6012

File tree

3 files changed

+177
-3
lines changed
Filter options

3 files changed

+177
-3
lines changed

‎src/Symfony/Component/Console/Application.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Application.php
+19-3Lines changed: 19 additions & 3 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\Event\InputDecorator;
1617
use Symfony\Component\Console\Exception\ExceptionInterface;
1718
use Symfony\Component\Console\Helper\DebugFormatterHelper;
1819
use Symfony\Component\Console\Helper\ProcessHelper;
@@ -859,13 +860,28 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
859860
// ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
860861
}
861862

863+
$event = new ConsoleCommandEvent($command, $eventInput = new InputDecorator($input), $output);
864+
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
865+
866+
// bind again after the console.command event to parse newly added arguments/options
867+
try {
868+
$input->bind($command->getDefinition());
869+
} catch (ExceptionInterface $e) {
870+
// let the command validate the input, as `ignoreValidationErrors()` may have been called on it
871+
}
872+
873+
foreach ($eventInput->getOverriddenArguments() as $k => $v) {
874+
$input->setArgument($k, $v);
875+
}
876+
877+
foreach ($eventInput->getOverriddenOptions() as $k => $v) {
878+
$input->setOption($k, $v);
879+
}
880+
862881
// don't bind the input again as it would override any input argument/option set from the command event in
863882
// addition to being useless
864883
$command->setInputBound(true);
865884

866-
$event = new ConsoleCommandEvent($command, $input, $output);
867-
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
868-
869885
if ($event->commandShouldRun()) {
870886
try {
871887
$e = null;

‎src/Symfony/Component/Console/Event/ConsoleCommandEvent.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Event/ConsoleCommandEvent.php
+107Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111

1212
namespace Symfony\Component\Console\Event;
1313

14+
use Symfony\Component\Console\Input\InputDefinition;
15+
use Symfony\Component\Console\Input\InputInterface;
16+
1417
/**
1518
* Allows to do things before the command is executed, like skipping the command or changing the input.
1619
*
@@ -60,3 +63,107 @@ public function commandShouldRun()
6063
return $this->commandShouldRun;
6164
}
6265
}
66+
67+
/**
68+
* @internal
69+
*/
70+
final class InputDecorator implements InputInterface
71+
{
72+
private $inner;
73+
private $overriddenArguments = array();
74+
private $overriddenOptions = array();
75+
76+
public function __construct(InputInterface $inner)
77+
{
78+
$this->inner = $inner;
79+
}
80+
81+
public function setArgument($key, $value)
82+
{
83+
$this->overriddenArguments[$key] = $value;
84+
85+
return $this->inner->setArgument($key, $value);
86+
}
87+
88+
public function setOption($key, $value)
89+
{
90+
$this->overriddenOptions[$key] = $value;
91+
92+
return $this->inner->setOption($key, $value);
93+
}
94+
95+
public function getOverriddenArguments()
96+
{
97+
return $this->overriddenArguments;
98+
}
99+
100+
public function getOverriddenOptions()
101+
{
102+
return $this->overriddenOptions;
103+
}
104+
105+
public function getFirstArgument()
106+
{
107+
return $this->inner->getFirstArgument();
108+
}
109+
110+
public function hasParameterOption($values)
111+
{
112+
return $this->inner->hasParameterOption($values);
113+
}
114+
115+
public function getParameterOption($values, $default = false)
116+
{
117+
return $this->inner->getParameterOption($values, $default);
118+
}
119+
120+
public function bind(InputDefinition $definition)
121+
{
122+
return $this->inner->bind($definition);
123+
}
124+
125+
public function validate()
126+
{
127+
return $this->inner->validate();
128+
}
129+
130+
public function getArguments()
131+
{
132+
return $this->inner->getArguments();
133+
}
134+
135+
public function getArgument($name)
136+
{
137+
return $this->inner->getArgument($name);
138+
}
139+
140+
public function hasArgument($name)
141+
{
142+
return $this->inner->hasArgument($name);
143+
}
144+
145+
public function getOptions()
146+
{
147+
return $this->inner->getOptions();
148+
}
149+
150+
public function getOption($name)
151+
{
152+
return $this->inner->getOption($name);
153+
}
154+
155+
public function hasOption($name)
156+
{
157+
return $this->inner->hasOption($name);
158+
}
159+
160+
public function isInteractive()
161+
{
162+
return $this->inner->isInteractive();
163+
}
164+
165+
public function setInteractive($interactive)
166+
{
167+
return $this->inner->setInteractive($interactive);
168+
}
169+
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/ApplicationTest.php
+51Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,57 @@ public function testUpdateInputFromConsoleCommandEvent()
11381138
$this->assertEquals('overriden', $tester->getInput()->getOption('extra'));
11391139
}
11401140

1141+
public function testAddArgumentFromConsoleCommandEvent()
1142+
{
1143+
$dispatcher = $this->getDispatcher();
1144+
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) {
1145+
$event->getCommand()->addArgument('extra', InputArgument::REQUIRED);
1146+
});
1147+
1148+
$application = new Application();
1149+
$application->setDispatcher($dispatcher);
1150+
$application->setAutoExit(false);
1151+
1152+
$application
1153+
->register('foo')
1154+
->addOption('extra', null, InputOption::VALUE_REQUIRED)
1155+
->setCode(function (InputInterface $input, OutputInterface $output) {
1156+
$output->write('foo.');
1157+
})
1158+
;
1159+
1160+
$tester = new ApplicationTester($application);
1161+
$tester->run(array('command' => 'foo', 'extra' => 'foo'));
1162+
1163+
$this->assertEquals('foo', $tester->getInput()->getArgument('extra'));
1164+
}
1165+
1166+
public function testAddAndSetArgumentFromConsoleCommandEvent()
1167+
{
1168+
$dispatcher = $this->getDispatcher();
1169+
$dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) {
1170+
$event->getCommand()->addArgument('extra', InputArgument::REQUIRED);
1171+
$event->getInput()->setArgument('extra', 'overridden');
1172+
});
1173+
1174+
$application = new Application();
1175+
$application->setDispatcher($dispatcher);
1176+
$application->setAutoExit(false);
1177+
1178+
$application
1179+
->register('foo')
1180+
->addOption('extra', null, InputOption::VALUE_REQUIRED)
1181+
->setCode(function (InputInterface $input, OutputInterface $output) {
1182+
$output->write('foo.');
1183+
})
1184+
;
1185+
1186+
$tester = new ApplicationTester($application);
1187+
$tester->run(array('command' => 'foo'));
1188+
1189+
$this->assertSame('overridden', $tester->getInput()->getArgument('extra'));
1190+
}
1191+
11411192
public function testTerminalDimensions()
11421193
{
11431194
$application = new Application();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.