How would one configure symfony/console
to accept a dynamic list of options?
That said - the names for the options aren't known on development step so I need an application to accept everything and expose it using the standard $input->getOption
.
Any chance it can be done easily (without hacking the component in million places)?
My attempts included extending the ArgvInput
and InputDefinition
classes but they failed due to various reasons (they are objective and symfony/console
component implementation-specific). Briefly: the former requires parsing to be invoked multiple times; the latter - is instantiated in multiple places so I just couldn't find a proper way to inject it.
You can create your own ArgvInput that will allow all options.
For example you can see the slightly modified version of ArgvInput here
I have only modified lines : 178
And comment out the lines: 188-199
Then pass instance of your version ArgvInput instead of default one to
$input = new AcceptAllArgvInput();
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);
I have accomplished this in the past using the IS_ARRAY option. Would this not work for your instance as well?
->addArgument('routeParams', InputArgument::IS_ARRAY, "Required Placeholders for route");
My use case was a custom URL generator for a special authentication system. I needed a way to generate URLs for testing. Naturally, each route has a different number of required parameters and I wanted to avoid passing the parameters as a CSV string.
Command examples: Usage: myGenerateToken user route [variables1] ... [variablesN]
php app/console myGenerateToken 1 productHomePage
php app/console myGenerateToken 1 getProduct 1
php app/console myGenerateToken 1 getProductFile 1 changelog
The variables were delivered to the command in the "routeParams" as an array
$params = $input->getArgument('routeParams');
var_dump($params);
array(2) {
[0] =>
string(1) "1"
[1] =>
string(9) "changelog"
}
I noticed that there is also an "Option" version called InputOption::VALUE_IS_ARRAY
, but I did not have success getting it to work. The argument version InputArgument::IS_ARRAY
seems to behave as an option anyways, as it does not error if no arguments are specified.
EDIT:
The author's question is seeking "How do i define variable command line options at run time" where my answer is "How do you provide multiple values for a pre-defined option/argument"
Here is how to implement this on PHP 7+ using symfony/console ^3.0:
abstract class CommandWithDynamicOptions extends Command {
/** @var array The list of dynamic options passed to the command */
protected $dynamicOptions = [];
/**
* @inheritdoc
*/
protected function configure() {
$this->setName('custom:command');
$this->setDefinition(new class($this->getDefinition(), $this->dynamicOptions) extends InputDefinition {
protected $dynamicOptions = [];
public function __construct(InputDefinition $definition, array &$dynamicOptions) {
parent::__construct();
$this->setArguments($definition->getArguments());
$this->setOptions($definition->getOptions());
$this->dynamicOptions =& $dynamicOptions;
}
public function getOption($name) {
if (!parent::hasOption($name)) {
$this->addOption(new InputOption($name, null, InputOption::VALUE_OPTIONAL));
$this->dynamicOptions[] = $name;
}
return parent::getOption($name);
}
public function hasOption($name) {
return TRUE;
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With