Add support for multi-value options

Makes it possible to supply options multiple times and to supply the
"--" flag to indicate that there are no options anymore to parse

refs #6092
This commit is contained in:
Johannes Meyer 2014-06-13 09:58:50 +02:00
parent b935cb34fb
commit 561616dca0
1 changed files with 139 additions and 2 deletions

View File

@ -1,21 +1,58 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Cli;
/**
* Params
*
* A class to ease commandline-option and -argument handling.
*/
class Params
{
/**
* The name and path of the executable
*
* @var string
*/
protected $program;
/**
* The arguments
*
* @var array
*/
protected $standalone = array();
/**
* The options
*
* @var array
*/
protected $params = array();
/**
* Parse the given commandline and create a new Params object
*
* @param array $argv The commandline
*/
public function __construct($argv)
{
$noOptionFlag = false;
$this->program = array_shift($argv);
for ($i = 0; $i < count($argv); $i++) {
if (substr($argv[$i], 0, 2) === '--') {
if ($argv[$i] === '--') {
$noOptionFlag = true;
} elseif (!$noOptionFlag && substr($argv[$i], 0, 2) === '--') {
$key = substr($argv[$i], 2);
if (! isset($argv[$i + 1]) || substr($argv[$i + 1], 0, 2) === '--') {
$this->params[$key] = true;
} elseif (array_key_exists($key, $this->params)) {
if (!is_array($this->params[$key])) {
$this->params[$key] = array($this->params[$key]);
}
$this->params[$key][] = $argv[++$i];
} else {
$this->params[$key] = $argv[++$i];
}
@ -25,6 +62,14 @@ class Params
}
}
/**
* Return the value for an argument by position
*
* @param int $pos The position of the argument
* @param mixed $default The default value to return
*
* @return mixed
*/
public function getStandalone($pos = 0, $default = null)
{
if (isset($this->standalone[$pos])) {
@ -33,26 +78,64 @@ class Params
return $default;
}
/**
* Count and return the number of arguments and options
*
* @return int
*/
public function count()
{
return count($this->standalone) + count($this->params);
}
/**
* Return the options
*
* @return array
*/
public function getParams()
{
return $this->params;
}
/**
* Return the arguments
*
* @return array
*/
public function getAllStandalone()
{
return $this->standalone;
}
/**
* @see Params::get()
*/
public function __get($key)
{
return $this->get($key);
}
/**
* Return whether the given option exists
*
* @param string $key The option name to check
*
* @return bool
*/
public function has($key)
{
return array_key_exists($key, $this->params);
}
/**
* Return the value of the given option
*
* @param string $key The option name
* @param mixed $default The default value to return
*
* @return mixed
*/
public function get($key, $default = null)
{
if ($this->has($key)) {
@ -61,12 +144,27 @@ class Params
return $default;
}
/**
* Set a value for the given option
*
* @param string $key The option name
* @param mixed $value The value to set
*
* @return self
*/
public function set($key, $value)
{
$this->params[$key] = $value;
return $this;
}
/**
* Remove a single option or multiple options
*
* @param string|array $keys The option or options to remove
*
* @return self
*/
public function remove($keys = array())
{
if (! is_array($keys)) {
@ -80,12 +178,30 @@ class Params
return $this;
}
/**
* Return a copy of this object with the given options being removed
*
* @param string|array $keys The option or options to remove
*
* @return Params
*/
public function without($keys = array())
{
$params = clone($this);
return $params->remove($keys);
}
/**
* Remove and return the value of the given option
*
* Called multiple times for an option with multiple values returns
* them one by one in case the default is not an array.
*
* @param string $key The option name
* @param mixed $default The default value to return
*
* @return mixed
*/
public function shift($key = null, $default = null)
{
if ($key === null) {
@ -95,16 +211,37 @@ class Params
return $default;
}
$result = $this->get($key, $default);
$this->remove($key);
if (is_array($result) && !is_array($default)) {
$result = array_shift($result) || $default;
if ($result === $default) {
$this->remove($key);
}
} else {
$this->remove($key);
}
return $result;
}
/**
* Put the given value onto the argument stack
*
* @param mixed $key The argument
*
* @return self
*/
public function unshift($key)
{
array_unshift($this->standalone, $key);
return $this;
}
/**
* Parse the given commandline
*
* @param array $argv The commandline to parse
*
* @return Params
*/
public static function parse($argv = null)
{
if ($argv === null) {