Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8086742

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

File tree

8 files changed

+111
-21
lines changed

8 files changed

+111
-21
lines changed

UPGRADE-3.3.md

Lines 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

Lines 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

Lines 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

Lines 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

Lines 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

Lines 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

Lines 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

Lines 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)