Fix default value handling for multi-value options

The default value for array options will be an array, so it is not suitable to use as the default when processing one of many values for a multi-value option. Using null seems appropriate here, as it indicates the absence of a value and also converts nicely to an empty string (as opposed to an empty array).

Fixes #7689
This commit is contained in:
Jeremy Mikola 2013-04-16 18:01:36 -04:00 committed by Fabien Potencier
parent 324686cf25
commit 5abf887180
2 changed files with 24 additions and 2 deletions

View File

@ -215,6 +215,11 @@ class ArgvInput extends Input
$option = $this->definition->getOption($name);
// Convert false values (from a previous call to substr()) to null
if (false === $value) {
$value = null;
}
if (null === $value && $option->acceptValue() && count($this->parsed)) {
// if option accepts an optional or mandatory argument
// let's see if there is one provided
@ -233,7 +238,9 @@ class ArgvInput extends Input
throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
}
$value = $option->isValueOptional() ? $option->getDefault() : true;
if (!$option->isArray()) {
$value = $option->isValueOptional() ? $option->getDefault() : true;
}
}
if ($option->isArray()) {

View File

@ -162,7 +162,22 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
$input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name=baz'));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions());
$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option=value" syntax)');
$input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', 'baz'));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertEquals(array('name' => array('foo', 'bar', 'baz')), $input->getOptions(), '->parse() parses array options ("--option value" syntax)');
$input = new ArgvInput(array('cli.php', '--name=foo', '--name=bar', '--name='));
$input->bind(new InputDefinition(array(new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY))));
$this->assertSame(array('name' => array('foo', 'bar', null)), $input->getOptions(), '->parse() parses empty array options as null ("--option=value" syntax)');
$input = new ArgvInput(array('cli.php', '--name', 'foo', '--name', 'bar', '--name', '--anotherOption'));
$input->bind(new InputDefinition(array(
new InputOption('name', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY),
new InputOption('anotherOption', null, InputOption::VALUE_NONE),
)));
$this->assertSame(array('name' => array('foo', 'bar', null), 'anotherOption' => true), $input->getOptions(), '->parse() parses empty array options as null ("--option value" syntax)');
try {
$input = new ArgvInput(array('cli.php', '-1'));