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 8086742

Browse filesBrowse files
committed
[Console] Explicitly passed options without value (or empty) should remain empty
1 parent 526d396 commit 8086742
Copy full SHA for 8086742

File tree

8 files changed

+111
-21
lines changed
Filter options

8 files changed

+111
-21
lines changed

‎UPGRADE-3.3.md

Copy file name to clipboardExpand all lines: UPGRADE-3.3.md
+56Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,62 @@ ClassLoader
66

77
* The component is deprecated and will be removed in 4.0. Use Composer instead.
88

9+
Console
10+
-------
11+
12+
* `Input::getOption()` no longer returns the default value for options
13+
with value optional explicitly passed empty.
14+
15+
For:
16+
17+
```php
18+
protected function configure()
19+
{
20+
$this
21+
// ...
22+
->setName('command')
23+
->addOption('foo', null, InputOption::VALUE_OPTIONAL, '', 'default')
24+
;
25+
}
26+
27+
protected function execute(InputInterface $input, OutputInterface $output)
28+
{
29+
var_dump($input->getOption('foo'));
30+
}
31+
```
32+
33+
Before:
34+
35+
```
36+
$ php console.php command
37+
"default"
38+
39+
$ php console.php command --foo
40+
"default"
41+
42+
$ php console.php command --foo ""
43+
"default"
44+
45+
$ php console.php command --foo=
46+
"default"
47+
```
48+
49+
After:
50+
51+
```
52+
$ php console.php command
53+
"default"
54+
55+
$ php console.php command --foo
56+
NULL
57+
58+
$ php console.php command --foo ""
59+
""
60+
61+
$ php console.php command --foo=
62+
""
63+
```
64+
965
Debug
1066
-----
1167

‎src/Symfony/Component/Console/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ CHANGELOG
66

77
* added `ExceptionListener`
88
* added `AddConsoleCommandPass` (originally in FrameworkBundle)
9+
* [BC BREAK] `Input::getOption()` no longer returns the default value for options
10+
with value optional explicitly passed empty
911

1012
3.2.0
1113
------

‎src/Symfony/Component/Console/Input/ArgvInput.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Input/ArgvInput.php
+10-12Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,12 @@ private function parseLongOption($token)
148148

149149
if (false !== $pos = strpos($name, '=')) {
150150
if (0 === strlen($value = substr($name, $pos + 1))) {
151-
array_unshift($this->parsed, null);
151+
// if no value after "=" then substr() returns "" since php7 only, false before
152+
// see http://php.net/manual/fr/migration70.incompatible.php#119151
153+
if (PHP_VERSION_ID < 70000 && false === $value) {
154+
$value = '';
155+
}
156+
array_unshift($this->parsed, $value);
152157
}
153158
$this->addLongOption(substr($name, 0, $pos), $value);
154159
} else {
@@ -221,23 +226,16 @@ private function addLongOption($name, $value)
221226

222227
$option = $this->definition->getOption($name);
223228

224-
// Convert empty values to null
225-
if (!isset($value[0])) {
226-
$value = null;
227-
}
228-
229229
if (null !== $value && !$option->acceptValue()) {
230230
throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
231231
}
232232

233-
if (null === $value && $option->acceptValue() && count($this->parsed)) {
233+
if (in_array($value, array('', null), true) && $option->acceptValue() && count($this->parsed)) {
234234
// if option accepts an optional or mandatory argument
235235
// let's see if there is one provided
236236
$next = array_shift($this->parsed);
237-
if (isset($next[0]) && '-' !== $next[0]) {
237+
if ((isset($next[0]) && '-' !== $next[0]) || in_array($next, array('', null), true)) {
238238
$value = $next;
239-
} elseif (empty($next)) {
240-
$value = null;
241239
} else {
242240
array_unshift($this->parsed, $next);
243241
}
@@ -248,8 +246,8 @@ private function addLongOption($name, $value)
248246
throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
249247
}
250248

251-
if (!$option->isArray()) {
252-
$value = $option->isValueOptional() ? $option->getDefault() : true;
249+
if (!$option->isArray() && !$option->isValueOptional()) {
250+
$value = true;
253251
}
254252
}
255253

‎src/Symfony/Component/Console/Input/ArrayInput.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Input/ArrayInput.php
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,9 @@ private function addLongOption($name, $value)
179179
throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name));
180180
}
181181

182-
$value = $option->isValueOptional() ? $option->getDefault() : true;
182+
if (!$option->isValueOptional()) {
183+
$value = true;
184+
}
183185
}
184186

185187
$this->options[$name] = $value;

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Input/Input.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public function getOption($name)
158158
throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
159159
}
160160

161-
return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
161+
return array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
162162
}
163163

164164
/**

‎src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/Input/ArgvInputTest.php
+24-6Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function testParseOptions($input, $options, $expectedOptions, $message)
4848
$input = new ArgvInput($input);
4949
$input->bind(new InputDefinition($options));
5050

51-
$this->assertEquals($expectedOptions, $input->getOptions(), $message);
51+
$this->assertSame($expectedOptions, $input->getOptions(), $message);
5252
}
5353

5454
public function provideOptions()
@@ -75,14 +75,32 @@ public function provideOptions()
7575
array(
7676
array('cli.php', '--foo='),
7777
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
78-
array('foo' => null),
79-
'->parse() parses long options with optional value which is empty (with a = separator) as null',
78+
array('foo' => ''),
79+
'->parse() parses long options with optional value which is empty (with a = separator) as empty string',
8080
),
8181
array(
8282
array('cli.php', '--foo=', 'bar'),
8383
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)),
84+
array('foo' => ''),
85+
'->parse() parses long options with optional value without value specified or an empty string (with a = separator) followed by an argument as empty string',
86+
),
87+
array(
88+
array('cli.php', 'bar', '--foo'),
89+
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)),
90+
array('foo' => null),
91+
'->parse() parses long options with optional value which is empty (with a = separator) preceded by an argument',
92+
),
93+
array(
94+
array('cli.php', '--foo', '', 'bar'),
95+
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL), new InputArgument('name', InputArgument::REQUIRED)),
96+
array('foo' => ''),
97+
'->parse() parses long options with optional value which is empty as empty string even followed by an argument',
98+
),
99+
array(
100+
array('cli.php', '--foo'),
101+
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL)),
84102
array('foo' => null),
85-
'->parse() parses long options with optional value which is empty (with a = separator) followed by an argument',
103+
'->parse() parses long options with optional value specified with no separator and no value as null',
86104
),
87105
array(
88106
array('cli.php', '-f'),
@@ -252,14 +270,14 @@ public function testParseArrayOption()
252270

253271
$input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name='));
254272
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
255-
$this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');
273+
$this->assertSame(array('name' => array('foo', 'bar', '')), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');
256274

257275
$input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption'));
258276
$input->bind(new InputDefinition(array(
259277
new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
260278
new InputOption('anotherOption', null, InputOption::VALUE_NONE),
261279
)));
262-
$this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)');
280+
$this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options ("--option value" syntax)');
263281
}
264282

265283
public function testParseNegativeNumberAfterDoubleDash()

‎src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/Input/ArrayInputTest.php
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,15 @@ public function provideOptions()
9090
'->parse() parses long options with a default value',
9191
),
9292
array(
93-
array('--foo' => null),
93+
array(),
9494
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
9595
array('foo' => 'default'),
96+
'->parse() uses the default value for long options with value optional which are not passed',
97+
),
98+
array(
99+
array('--foo' => null),
100+
array(new InputOption('foo', 'f', InputOption::VALUE_OPTIONAL, '', 'default')),
101+
array('foo' => null),
96102
'->parse() parses long options with a default value',
97103
),
98104
array(

‎src/Symfony/Component/Console/Tests/Input/InputTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/Input/InputTest.php
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ public function testOptions()
3737
$input = new ArrayInput(array('--name' => 'foo'), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
3838
$this->assertEquals('default', $input->getOption('bar'), '->getOption() returns the default value for optional options');
3939
$this->assertEquals(array('name' => 'foo', 'bar' => 'default'), $input->getOptions(), '->getOptions() returns all option values, even optional ones');
40+
41+
$input = new ArrayInput(array('--name' => 'foo', '--bar' => ''), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
42+
$this->assertEquals('', $input->getOption('bar'), '->getOption() returns null for options explicitly passed without value (or an empty value)');
43+
$this->assertEquals(array('name' => 'foo', 'bar' => ''), $input->getOptions(), '->getOptions() returns all option values.');
44+
45+
$input = new ArrayInput(array('--name' => 'foo', '--bar' => null), new InputDefinition(array(new InputOption('name'), new InputOption('bar', '', InputOption::VALUE_OPTIONAL, '', 'default'))));
46+
$this->assertNull($input->getOption('bar'), '->getOption() returns null for options explicitly passed without value (or an empty value)');
47+
$this->assertEquals(array('name' => 'foo', 'bar' => null), $input->getOptions(), '->getOptions() returns all option values');
4048
}
4149

4250
/**

0 commit comments

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