Suppression support PHP 5 (min PHP 7.4)

+ Typage du code
master 2.0.0
Julien Rosset 4 years ago
parent 08a5e0b552
commit 0f44062269

@ -3,24 +3,24 @@
require_once '../vendor/autoload.php';
use jrosset\CommandLine\Argument\Option\Flag;
use jrosset\CommandLine\Argument\Option\Value;
use jrosset\CommandLine\Argument\Option\Value as OptionValue;
use jrosset\CommandLine\Argument\Parser\IntegerParser;
use jrosset\CommandLine\Argument\Parser\PathParser;
use jrosset\CommandLine\Argument\Value\Value;
use jrosset\CommandLine\CommandLine;
$cmdline = new CommandLine('Test', 'Programme de test', 'php test.php');
$cmdline->addDefaultArguments();
$cmdline->addOption(new Flag('array_form', false, 'Sous la forme d\'un tableau ?' . "\n" . 'Ou pas'));
$cmdline->addOption((new Value('days', 'Nombre jour', new IntegerParser(0, 365)))->setDefault(3));
$cmdline->addOption((new Value('years', 'Nombre d\'années', new IntegerParser(0)))->setDefault(5));
$cmdline->addValue((new \jrosset\CommandLine\Argument\Value\Value('path', 'Chemin sauvegarde images', new PathParser(), true)));
$cmdline->addOption((new OptionValue('days', 'Nombre jour', new IntegerParser(0, 365)))->setDefault(3));
$cmdline->addOption((new OptionValue('years', 'Nombre d\'années', new IntegerParser(0)))->setDefault(5));
$cmdline->addValue((new Value('path', 'Chemin sauvegarde images', new PathParser(false), true)));
$cmdline->addExitCode(0, 'OK');
$cmdline->addExitCode(255, 'Unexpected error' . "\n" . 'Unknown error');
$args = $cmdline->parse();
$args = $cmdline->parseNoExcept(255);
$cmdline->treatDefaultArguments($args, false);
echo "\n";
var_dump($args);
var_dump((string)$args->path);

@ -5,7 +5,7 @@
"minimum-stability": "dev",
"require": {
"php": ">= 7.2"
"php": ">= 7.4"
},
"autoload": {
"psr-4": {

4
composer.lock generated

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "c4ba533c1f0324fb3d0f3a361f9b5cf8",
"content-hash": "48ff5bfcbd629a4e01b1a44b581763f5",
"packages": [ ],
"packages-dev": [ ],
"aliases": [ ],
@ -13,7 +13,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">= 7.2"
"php": ">= 7.4"
},
"platform-dev": [ ],
"plugin-api-version": "2.1.0"

@ -14,15 +14,15 @@ abstract class ArgumentAbstract implements IArgument {
/**
* @var string Le nom de la variable de retour de l'argument.
*/
protected $_varName;
protected string $varName;
/**
* @var string Le nom de l'argument.
*/
protected $_name;
protected string $name;
/**
* @var string|null La description de l'argument.
*/
protected $_description;
protected ?string $description;
/**
* @var mixed|null La valeur par défaut. Null si aucune.
@ -35,16 +35,16 @@ abstract class ArgumentAbstract implements IArgument {
* @param string $name Le nom de l'argument
* @param string|null $description La description de l'argument
*/
protected function __construct ($name, $description) {
$this->setName($name, true);
protected function __construct (string $name, ?string $description) {
$this->setName($name);
$this->setDescription($description);
}
/**
* @inheritDoc
*/
public function getVarName() {
return $this->_varName;
public function getVarName (): string {
return $this->varName;
}
/**
* Définit le nom de la variable de retour de l'argument.
@ -53,18 +53,18 @@ abstract class ArgumentAbstract implements IArgument {
*
* @return $this
*
* @see $_name
* @see $name
*/
public function setVarName($varName) {
$this->_varName = $varName;
public function setVarName (string $varName): self {
$this->varName = $varName;
return $this;
}
/**
* @inheritDoc
*/
public function getName() {
return $this->_name;
public function getName (): string {
return $this->name;
}
/**
* Définit le nom de l'argument.
@ -74,20 +74,21 @@ abstract class ArgumentAbstract implements IArgument {
*
* @return $this
*
* @see $_name
* @see $name
*/
public function setName($name, $replaceVarName = true) {
$this->_name = $name;
if($replaceVarName)
public function setName (string $name, bool $replaceVarName = true): self {
$this->name = $name;
if ($replaceVarName) {
$this->setVarName($name);
}
return $this;
}
/**
* @inheritDoc
*/
public function getDescription() {
return $this->_description;
public function getDescription (): ?string {
return $this->description;
}
/**
* Définit la description de l'argument.
@ -96,10 +97,10 @@ abstract class ArgumentAbstract implements IArgument {
*
* @return $this
*
* @see $_description
* @see $description
*/
public function setDescription($description) {
$this->_description = $description;
public function setDescription (?string $description): self {
$this->description = $description;
return $this;
}
@ -118,7 +119,7 @@ abstract class ArgumentAbstract implements IArgument {
*
* @see $_default
*/
public function setDefault($default = null) {
public function setDefault ($default = null): self {
$this->_default = $default;
return $this;
}

@ -17,13 +17,13 @@ interface IArgument {
*
* @return string Le nom
*/
public function getVarName();
public function getVarName (): string;
/**
* Le nom de l'argument
*
* @return string Le nom
*/
public function getName();
public function getName (): string;
/**
* La valeur par défaut de l'argument. Null si pas de valeur par défaut
*
@ -36,7 +36,7 @@ interface IArgument {
*
* @return string|null La description
*/
public function getDescription();
public function getDescription (): ?string;
/**
* Parse les arguments.
@ -46,5 +46,5 @@ interface IArgument {
* @return ParseResult|null Le résultat du parsage. Null si rien parsé
* @throws IncorrectParse Echec du parsage de l'argument
*/
public function parse($args);
public function parse (array $args): ?ParseResult;
}

@ -15,5 +15,5 @@ interface IArgumentValueDescription {
*
* @return string La description.
*/
public function getValueDescription();
public function getValueDescription (): string;
}

@ -2,6 +2,7 @@
/**
* Déclare la classe CommandLine\Argument\Option\Flag.
*/
namespace jrosset\CommandLine\Argument\Option;
use InvalidArgumentException;
@ -21,12 +22,12 @@ class Flag extends OptionAbstract {
* Crée un nouvel argument de type option
*
* @param string $name Le nom
* @param boolean $default La valeur par défaut
* @param bool $default La valeur par défaut
* @param string|null $description La description
* @param string|null $tagLong Le tag long
* @param string|null $tagShort Le tag court
*/
public function __construct ($name, $default, $description, $tagLong = null, $tagShort = null) {
public function __construct (string $name, bool $default, ?string $description, ?string $tagLong = null, ?string $tagShort = null) {
parent::__construct($name, $description, $tagLong, $tagShort);
$this->setDefault($default);
}
@ -34,23 +35,25 @@ class Flag extends OptionAbstract {
/**
* @inheritDoc
*/
public function parse ($args) {
if($this->_parseTag($args[0]))
public function parse (array $args): ?ParseResult {
if ($this->_parseTag($args[0])) {
return new ParseResult(true, 1);
}
return null;
}
/**
* Définit le valeur par défaut
* Définit la valeur par défaut
*
* @param boolean $default La valeur par défaut.
*
* @return $this
*/
public function setDefault ($default = null) {
if(is_null($default) || !is_bool($default))
public function setDefault ($default = null): self {
if (!is_bool($default)) {
throw new InvalidArgumentException('La valeur par défaut DOIT être un booléen');
}
parent::setDefault($default);
return $this;

@ -2,6 +2,7 @@
/**
* Déclare la classe CommandLine\Argument\Option\OptionFlagWithReverse.
*/
namespace jrosset\CommandLine\Argument\Option;
/**
@ -18,25 +19,31 @@ namespace jrosset\CommandLine\Argument\Option;
* @package CommandLine\Argument\Option
*/
class FlagWithReverse extends Flag implements IArgumentOptionSecondary {
public function getOthersOptions () {
public function getOthersOptions (): array {
$tagShort = null;
if ($this->hasTagShort()) {
if(substr($this->getTagShort(), 0, 1) == 'n')
if (substr($this->getTagShort(), 0, 1) == 'n') {
$tagShort = substr($this->getTagShort(), 1);
else
}
else {
$tagShort = 'n' . $this->getTagShort();
}
}
if(substr($this->getTagLong(), 0, 3) == 'no-')
if (substr($this->getTagLong(), 0, 3) == 'no-') {
$tagLong = substr($this->getTagLong(), 3);
else
}
else {
$tagLong = 'no-' . $this->getTagLong();
}
$name = $this->getName();
if(substr($name, 0, 3) == 'no')
if (substr($name, 0, 3) == 'no') {
$name = strtolower(substr($name, 2, 1)) . substr($name, 3);
else
}
else {
$name = 'no' . strtoupper(substr($name, 0, 1)) . substr($name, 1);
}
$description = '[INVERSE] ' . $this->getDescription();

@ -19,7 +19,7 @@ interface IArgumentOption extends IArgument {
*
* @see $_tagShort
*/
public function getTagShort();
public function getTagShort (): ?string;
/**
* Le tag long.
*
@ -27,14 +27,14 @@ interface IArgumentOption extends IArgument {
*
* @see $_tagLong
*/
public function getTagLong();
public function getTagLong (): string;
/**
* Est-ce que l'argument est autorisé plusieurs fois ?
*
* @return boolean True si l'argument est autorisé plusieurs fois, sinon False
*/
public function allowMultiple();
public function allowMultiple (): bool;
/**
* Est-ce que l'argument met fin au parsage ?
*
@ -42,5 +42,5 @@ interface IArgumentOption extends IArgument {
*
* @return boolean True si la présence de l'argument mat fin au parsage, sinon False.
*/
public function isStoppingParse();
public function isStoppingParse (): bool;
}

@ -15,5 +15,5 @@ interface IArgumentOptionSecondary {
*
* @return IArgumentOption[] La liste des arguments
*/
public function getOthersOptions();
public function getOthersOptions (): array;
}

@ -2,6 +2,7 @@
/**
* Déclaration de la classe CommandLine\Argument\Option\OptionAbstract.
*/
namespace jrosset\CommandLine\Argument\Option;
use InvalidArgumentException;
@ -16,20 +17,20 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
/**
* @var string|null L'argument court (cas d'un seul "-"). Null si aucun.
*/
protected $_tagShort;
protected ?string $tagShort;
/**
* @var string L'argument long (cas d'un "--").
*/
protected $_tagLong;
protected string $tagLong;
/**
* @var boolean Est-ce que l'argument est autorisé plusieurs fois ?
*/
protected $_multiple = false;
protected bool $multiple = false;
/**
* @var boolean Est-ce que l'argument met fin au parsage ?
*/
protected $_isStoppingParse = false;
protected bool $isStoppingParse = false;
/**
* Crée un nouvel argument de type option.
@ -39,7 +40,7 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
* @param string|null $tagLong Le tag long.
* @param string|null $tagShort Le tag court.
*/
public function __construct ($name, $description, $tagLong = null, $tagShort = null) {
public function __construct (string $name, ?string $description, ?string $tagLong = null, ?string $tagShort = null) {
parent::__construct($name, $description);
$this->setTagLong($tagLong);
@ -55,11 +56,12 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
*
* @return boolean True si le tag correspond, sinon False.
*/
protected function _parseTag($arg) {
protected function _parseTag (string $arg): bool {
if ($this->hasTagShort()) {
if ($arg == '-'.$this->getTagShort())
if ($arg == '-' . $this->getTagShort()) {
return true;
}
}
return $arg == '--' . $this->getTagLong();
}
@ -71,18 +73,18 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
*
* @return string|false La valeur qui une option au False si aucune correspondance
*/
public static function containsOption($args) {
public static function containsOption (array $args) {
foreach ($args as $arg) {
if (preg_match('@^--?[a-zA-Z0-9_-]+@', $arg)) {
return (string)$arg;
return $arg;
}
}
return false;
}
public function getTagShort() {
return $this->_tagShort;
public function getTagShort (): ?string {
return $this->tagShort;
}
/**
* Définit le tag court.
@ -91,10 +93,10 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
*
* @return $this
*
* @see $_tagShort
* @see $tagShort
*/
public function setTagShort($tagShort = null) {
$this->_tagShort = $tagShort;
public function setTagShort (string $tagShort = null): self {
$this->tagShort = $tagShort;
return $this;
}
/**
@ -102,17 +104,17 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
*
* @return boolean True si existe en forme courte, sinon False.
*/
public function hasTagShort() {
return !is_null($this->_tagShort);
public function hasTagShort (): bool {
return !is_null($this->tagShort);
}
public function getTagLong() {
return $this->_tagLong;
public function getTagLong (): string {
return $this->tagLong;
}
/**
* Définit le tag long.
*
* Si non fourni, est déduit du {@see $_name nom de l'argument} :
* Si non fourni, est déduit du {@see $name nom de l'argument} :
* - Les "_" sont remplacés par "-"
* - Les lettres majuscules sont remplacées par "-" suivit de la lettre en minuscule
*
@ -120,29 +122,32 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
*
* @return $this
*
* @see $_tagLong
* @see $tagLong
*/
public function setTagLong($tagLong = null) {
$this->_tagLong = $tagLong;
if(is_null($this->_tagLong)) {
$this->_tagLong = preg_replace_callback(
public function setTagLong (string $tagLong = null): self {
if (is_null($tagLong)) {
$this->tagLong = preg_replace_callback(
'/[A-Z_]/',
function ($matches) {
if($matches[0] == '_')
if ($matches[0] == '_') {
return '-';
else
}
else {
return '-' . strtolower($matches[0]);
}
},
$this->getName()
);
}
else {
$this->tagLong = $tagLong;
}
return $this;
}
public function allowMultiple() {
return $this->_multiple;
public function allowMultiple (): bool {
return $this->multiple;
}
/**
* Définit si l'argument est autorisé plusieurs fois ou non.
@ -152,16 +157,17 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
* @return $this
* @see $_optional
*/
public function setMultiple($multiple) {
if (!is_bool($multiple))
public function setMultiple (bool $multiple): self {
if (!is_bool($multiple)) {
throw new InvalidArgumentException('La multiplicité n\'est pas un booléen');
}
$this->_multiple = $multiple;
$this->multiple = $multiple;
return $this;
}
public function isStoppingParse() {
return $this->_isStoppingParse;
public function isStoppingParse (): bool {
return $this->isStoppingParse;
}
/**
* Définit si l'argument met fin au parsage ou non.
@ -171,11 +177,12 @@ abstract class OptionAbstract extends ArgumentAbstract implements IArgumentOptio
* @return $this
* @see $_optional
*/
public function setStoppingParse($stoppingParse) {
if (!is_bool($stoppingParse))
public function setStoppingParse (bool $stoppingParse): self {
if (!is_bool($stoppingParse)) {
throw new InvalidArgumentException('La stoppabilité n\'est pas un booléen');
}
$this->_isStoppingParse = $stoppingParse;
$this->isStoppingParse = $stoppingParse;
return $this;
}
}

@ -1,4 +1,5 @@
<?php
/**
* Déclaration de la classe CommandLine\Argument\Option\Value
*/
@ -19,7 +20,7 @@ class Value extends OptionAbstract implements IArgumentValueDescription {
/**
* @var IValueParser Parseur pour la valeur
*/
protected $_valueParser;
protected IValueParser $valueParser;
/**
* Crée un nouvel argument de type option
@ -30,7 +31,7 @@ class Value extends OptionAbstract implements IArgumentValueDescription {
* @param string|null $tagLong Le tag long
* @param string|null $tagShort Le tag court
*/
public function __construct ($name, $description, IValueParser $valueParser, $tagLong = null, $tagShort = null) {
public function __construct (string $name, ?string $description, IValueParser $valueParser, ?string $tagLong = null, ?string $tagShort = null) {
parent::__construct($name, $description, $tagLong, $tagShort);
$this->setValueParser($valueParser);
}
@ -38,15 +39,17 @@ class Value extends OptionAbstract implements IArgumentValueDescription {
/**
* @inheritDoc
*/
public function parse ($args) {
public function parse (array $args): ?ParseResult {
try {
if(!$this->_parseTag($args[0]))
if (!$this->_parseTag($args[0])) {
return null;
}
if(count($args) < 2 || is_null($args[1]))
if (count($args) < 2 || is_null($args[1])) {
throw new IncorrectParse('La seconde valeur de l\'argument manquante');
}
return new ParseResult($this->_valueParser->parseValue($args[1]), 2);
return new ParseResult($this->valueParser->parseValue($args[1]), 2);
}
catch (RuntimeException $e) {
throw new IncorrectParse('Échec du parsage de la valeur "' . $args[0] . '"', 0, $e);
@ -56,8 +59,8 @@ class Value extends OptionAbstract implements IArgumentValueDescription {
/**
* @inheritDoc
*/
public function getValueDescription () {
return $this->_valueParser->getValueDescription();
public function getValueDescription (): string {
return $this->valueParser->getValueDescription();
}
/**
@ -65,10 +68,12 @@ class Value extends OptionAbstract implements IArgumentValueDescription {
*
* @return IValueParser Le parseur.
*
* @see $_valueParser
* @see $valueParser
*
* @noinspection PhpUnused
*/
public function getValueParser() {
return $this->_valueParser;
public function getValueParser (): IValueParser {
return $this->valueParser;
}
/**
* Définit le parseur de valeur
@ -77,10 +82,10 @@ class Value extends OptionAbstract implements IArgumentValueDescription {
*
* @return $this
*
* @see $_valueParser
* @see $valueParser
*/
public function setValueParser(IValueParser $valueParser) {
$this->_valueParser = $valueParser;
public function setValueParser (IValueParser $valueParser): self {
$this->valueParser = $valueParser;
return $this;
}
}

@ -13,11 +13,11 @@ class ParseResult {
/**
* @var int Le nombre d'argument consumé.
*/
protected $_consume;
protected int $consume;
/**
* @var mixed La valeur.
*/
protected $_value;
protected $value;
/**
* ArgumentParseResult constructor.
@ -25,7 +25,7 @@ class ParseResult {
* @param mixed $value La valeur.
* @param int $consume Le nombre d'argument consumé.
*/
public function __construct ($value, $consume = 1) {
public function __construct ($value, int $consume = 1) {
$this->setValue($value);
$this->setConsume($consume);
}
@ -35,10 +35,10 @@ class ParseResult {
*
* @return int Le nombre d'argument consumé.
*
* @see $_consume
* @see $consume
*/
public function getConsume() {
return $this->_consume;
public function getConsume (): int {
return $this->consume;
}
/**
* Définit le nombre d'argument consumé.
@ -47,10 +47,10 @@ class ParseResult {
*
* @return $this
*
* @see $_consume
* @see $consume
*/
public function setConsume($consume) {
$this->_consume = $consume;
public function setConsume (int $consume): self {
$this->consume = $consume;
return $this;
}
@ -59,10 +59,10 @@ class ParseResult {
*
* @return mixed La valeur.
*
* @see $_value
* @see $value
*/
public function getValue() {
return $this->_value;
return $this->value;
}
/**
* Définit les valeurs définies.
@ -71,10 +71,10 @@ class ParseResult {
*
* @return $this
*
* @see $_value
* @see $value
*/
public function setValue($value) {
$this->_value = $value;
public function setValue ($value): self {
$this->value = $value;
return $this;
}
}

@ -19,20 +19,27 @@ class BooleanParser implements IValueParser {
/**
* @inheritDoc
*/
public function parseValue ($arg) {
if(!in_array($arg, array(
'true' , '1', 'oui', 'vrai',
'false', '0', 'non', 'faux',
)))
throw new RangeException('La valeur n\'est pas un booléen valide : '.$arg);
public function parseValue (string $val) {
if (!in_array($val, array(
'true',
'1',
'oui',
'vrai',
'false',
'0',
'non',
'faux',
))) {
throw new RangeException('La valeur n\'est pas un booléen valide : ' . $val);
}
return in_array($arg, array('true' , '1', 'oui', 'vrai'));
return in_array($val, array('true', '1', 'oui', 'vrai'));
}
/**
* @inheritDoc
*/
public function getValueDescription () {
public function getValueDescription (): string {
return 'boolean';
}
}

@ -11,16 +11,18 @@ use RangeException;
* Parseur vers un réel
*
* @package CommandLine\Argument\Parser
*
* @noinspection PhpUnused
*/
class DecimalParser implements IValueParser {
/**
* @var double|null La valeur minimum autorisée. Null si pas de limite.
*/
protected $_valueMin = null;
protected ?float $valueMin = null;
/**
* @var double|null La valeur maximum autorisée. Null si pas de limite
*/
protected $_valueMax = null;
protected ?float $valueMax = null;
/**
* Crée un nouveau parseur
@ -28,7 +30,7 @@ class DecimalParser implements IValueParser {
* @param double|null $valueMin La valeur minimum autorisée
* @param double|null $valueMax La valeur maximum autorisée
*/
public function __construct ($valueMin = null, $valueMax = null) {
public function __construct (?float $valueMin = null, ?float $valueMax = null) {
$this->setValueMin($valueMin);
$this->setValueMax($valueMax);
}
@ -36,30 +38,36 @@ class DecimalParser implements IValueParser {
/**
* @inheritDoc
*/
public function parseValue ($arg) {
if (!$this->_isDecimal($arg))
throw new RangeException('La valeur n\'est pas un réel valide : ' . $arg);
public function parseValue (string $val) {
if (!$this->isDecimal($val)) {
throw new RangeException('La valeur n\'est pas un réel valide : ' . $val);
}
$int = (int)$arg;
$int = (int)$val;
if ($this->hasValueMin()) {
if ($int < $this->getValueMin())
throw new RangeException('La valeur est inférieure au minimum (' . $this->getValueMin().') : ' . $arg);
if ($int < $this->getValueMin()) {
throw new RangeException('La valeur est inférieure au minimum (' . $this->getValueMin() . ') : ' . $val);
}
}
if ($this->hasValueMax()) {
if ($int > $this->getValueMax())
throw new RangeException($int, 'La valeur est supérieur au maximum (' . $this->getValueMax() . ') : ' . $arg);
if ($int > $this->getValueMax()) {
throw new RangeException($int, 'La valeur est supérieur au maximum (' . $this->getValueMax() . ') : ' . $val);
}
}
return $int;
}
/**
* @inheritDoc
* Vérifie si la valeur est bien un nombre réel ?
*
* @return bool Est-ce que la valeur est bien un nombre réel ?
*/
protected function _isDecimal($val) {
if(!is_numeric($val))
protected function isDecimal ($val): bool {
if (!is_numeric($val)) {
return false;
}
return true;
}
@ -67,7 +75,7 @@ class DecimalParser implements IValueParser {
/**
* @inheritDoc
*/
public function getValueDescription () {
public function getValueDescription (): string {
return ($this->hasValueMin() ? $this->getValueMin() . ' <= ' : '') . 'decimal' . ($this->hasValueMax() ? ' <= ' . $this->getValueMax() : '');
}
@ -76,10 +84,10 @@ class DecimalParser implements IValueParser {
*
* @return double|null La valeur minimum.
*
* @see $_valueMin
* @see $valueMin
*/
public function getValueMin() {
return $this->_valueMin;
public function getValueMin (): ?float {
return $this->valueMin;
}
/**
* Définit la valeur minimum autorisée.
@ -88,15 +96,14 @@ class DecimalParser implements IValueParser {
*
* @return $this
*/
public function setValueMin($valueMin = null) {
public function setValueMin (?float $valueMin = null): self {
if (!is_null($valueMin)) {
if (!$this->_isDecimal($valueMin)) {
if (!$this->isDecimal($valueMin)) {
throw new InvalidArgumentException('Le minimum n\'est pas un entier ou null : ' . $valueMin);
}
$valueMin = (double)$valueMin;
}
$this->_valueMin = $valueMin;
$this->valueMin = $valueMin;
return $this;
}
/**
@ -104,7 +111,7 @@ class DecimalParser implements IValueParser {
*
* @return boolean True s'il existe une limite, sinon False
*/
public function hasValueMin() {
public function hasValueMin (): bool {
return !is_null($this->getValueMin());
}
@ -113,10 +120,10 @@ class DecimalParser implements IValueParser {
*
* @return double|null La valeur maximum.
*
* @see $_valueMax
* @see $valueMax
*/
public function getValueMax() {
return $this->_valueMax;
public function getValueMax (): ?float {
return $this->valueMax;
}
/**
* Définit la valeur maximum autorisée.
@ -125,15 +132,14 @@ class DecimalParser implements IValueParser {
*
* @return $this
*/
public function setValueMax($valueMax = null) {
public function setValueMax (?float $valueMax = null): self {
if (!is_null($valueMax)) {
if (!$this->_isDecimal($valueMax)) {
if (!$this->isDecimal($valueMax)) {
throw new InvalidArgumentException('Le maximum n\'est pas un entier ou null : ' . $valueMax);
}
$valueMax = (double)$valueMax;
}
$this->_valueMax = $valueMax;
$this->valueMax = $valueMax;
return $this;
}
/**
@ -141,7 +147,7 @@ class DecimalParser implements IValueParser {
*
* @return boolean True s'il existe une limite, sinon False
*/
public function hasValueMax() {
public function hasValueMax (): bool {
return !is_null($this->getValueMax());
}
}

@ -11,36 +11,39 @@ use RangeException;
* Parseur vers une liste de valeurs possible (chaine de caractère).
*
* @package CommandLine\Argument\Parser
*
* @noinspection PhpUnused
*/
class EnumParser implements IValueParser {
/**
* @var string[] Liste des valeurs autorisées
*/
protected $_values;
protected array $values;
/**
* Crée un nouveau parseur
*
* @param string[] $values La liste des valeurs autorisées
*/
public function __construct ($values) {
public function __construct (array $values) {
$this->setValues($values);
}
/**
* @inheritDoc
*/
public function parseValue ($arg) {
if(!in_array($arg, $this->_values))
throw new RangeException('La valeur ne fait partie de liste des valeurs autorisées (' . implode(', ', $this->getValues()) . ') : ' . $arg);
public function parseValue (string $val) {
if (!in_array($val, $this->values)) {
throw new RangeException('La valeur ne fait partie de liste des valeurs autorisées (' . implode(', ', $this->getValues()) . ') : ' . $val);
}
return $arg;
return $val;
}
/**
* @inheritDoc
*/
public function getValueDescription () {
public function getValueDescription (): string {
return 'enum(' . implode(',', $this->getValues()) . ')';
}
@ -49,10 +52,10 @@ class EnumParser implements IValueParser {
*
* @return string[] La liste des valeurs
*
* @see $_values
* @see $values
*/
public function getValues() {
return $this->_values;
public function getValues (): array {
return $this->values;
}
/**
* Définit la liste des valeurs autorisées.
@ -60,16 +63,18 @@ class EnumParser implements IValueParser {
* @param string[] $values La liste des valeurs
*
* @return $this
* @see $_values
* @see $values
*/
public function setValues($values) {
if(!is_array($values))
public function setValues (array $values): self {
if (!is_array($values)) {
throw new InvalidArgumentException('La liste de valeurs n\'est pas un tableau');
}
if(count($values) == 0)
if (count($values) == 0) {
throw new InvalidArgumentException('La liste de valeurs doit avoir au moins un élément');
}
$this->_values = $values;
$this->values = $values;
return $this;
}
}

@ -17,12 +17,12 @@ interface IValueParser {
*
* @return mixed La valeur transformée.
*/
public function parseValue($val);
public function parseValue (string $val);
/**
* La description des contraintes de la valeur.
*
* @return string La description.
*/
public function getValueDescription();
public function getValueDescription (): string;
}

@ -2,6 +2,7 @@
/**
* Déclaration de la classe CommandLine\Argument\Parser\IntegerParser
*/
namespace jrosset\CommandLine\Argument\Parser;
use InvalidArgumentException;
@ -16,11 +17,11 @@ class IntegerParser implements IValueParser {
/**
* @var int|null La valeur minimum autorisée. Null si pas de limite.
*/
protected $_valueMin = null;
protected ?int $valueMin = null;
/**
* @var int|null La valeur maximum autorisée. Null si pas de limite
*/
protected $_valueMax = null;
protected ?int $valueMax = null;
/**
* Crée un nouveau parseur
@ -28,7 +29,7 @@ class IntegerParser implements IValueParser {
* @param int|null $valueMin La valeur minimum autorisée
* @param int|null $valueMax La valeur maximum autorisée
*/
public function __construct ($valueMin = null, $valueMax = null) {
public function __construct (?int $valueMin = null, ?int $valueMax = null) {
$this->setValueMin($valueMin);
$this->setValueMax($valueMax);
}
@ -36,33 +37,40 @@ class IntegerParser implements IValueParser {
/**
* @inheritDoc
*/
public function parseValue ($arg) {
if(!$this->_isInt($arg))
throw new RangeException('La valeur n\'est pas un entier valide : ' . $arg);
public function parseValue (string $val) {
if (!$this->isInt($val)) {
throw new RangeException('La valeur n\'est pas un entier valide : ' . $val);
}
$int = (int)$arg;
$int = (int)$val;
if ($this->hasValueMin()) {
if($int < $this->getValueMin())
if ($int < $this->getValueMin()) {
throw new RangeException('La valeur est inférieure au minimum (' . $this->getValueMin() . ') :' . $int);
}
}
if ($this->hasValueMax()) {
if($int > $this->getValueMax())
if ($int > $this->getValueMax()) {
throw new RangeException('La valeur est supérieur au maximum (' . $this->getValueMax() . ') : ' . $int);
}
}
return $int;
}
/**
* @inheritDoc
* Vérifie si la valeur est bien un nombre entier ?
*
* @return bool Est-ce que la valeur est bien un nombre entier ?
*/
protected function _isInt($val) {
if(!is_numeric($val))
protected function isInt ($val): bool {
if (!is_numeric($val)) {
return false;
}
if(floor($val) != $val)
if (floor($val) != $val) {
return false;
}
return true;
}
@ -70,7 +78,7 @@ class IntegerParser implements IValueParser {
/**
* @inheritDoc
*/
public function getValueDescription () {
public function getValueDescription (): string {
return ($this->hasValueMin() ? $this->getValueMin() . ' <= ' : '') . 'integer' . ($this->hasValueMax() ? ' <= ' . $this->getValueMax() : '');
}
@ -79,10 +87,10 @@ class IntegerParser implements IValueParser {
*
* @return int|null La valeur minimum.
*
* @see $_valueMin
* @see $valueMin
*/
public function getValueMin() {
return $this->_valueMin;
public function getValueMin (): ?int {
return $this->valueMin;
}
/**
* Définit la valeur minimum autorisée.
@ -91,15 +99,14 @@ class IntegerParser implements IValueParser {
*
* @return $this
*/
public function setValueMin($valueMin = null) {
public function setValueMin (?int $valueMin = null): self {
if (!is_null($valueMin)) {
if (!$this->_isInt($valueMin)) {
if (!$this->isInt($valueMin)) {
throw new InvalidArgumentException('Le minimum n\'est pas un entier ou null : ' . $valueMin);
}
$valueMin = (int)$valueMin;
}
$this->_valueMin = $valueMin;
$this->valueMin = $valueMin;
return $this;
}
/**
@ -107,7 +114,7 @@ class IntegerParser implements IValueParser {
*
* @return boolean True s'il existe une limite, sinon False
*/
public function hasValueMin() {
public function hasValueMin (): bool {
return !is_null($this->getValueMin());
}
@ -116,10 +123,10 @@ class IntegerParser implements IValueParser {
*
* @return int|null La valeur maximum.
*
* @see $_valueMax
* @see $valueMax
*/
public function getValueMax() {
return $this->_valueMax;
public function getValueMax (): ?int {
return $this->valueMax;
}
/**
* Définit la valeur maximum autorisée.
@ -128,15 +135,14 @@ class IntegerParser implements IValueParser {
*
* @return $this
*/
public function setValueMax($valueMax = null) {
public function setValueMax (?int $valueMax = null): self {
if (!is_null($valueMax)) {
if (!$this->_isInt($valueMax)) {
if (!$this->isInt($valueMax)) {
throw new InvalidArgumentException('Le maximum n\'est pas un entier ou null : ' . $valueMax);
}
$valueMax = (int)$valueMax;
}
$this->_valueMax = $valueMax;
$this->valueMax = $valueMax;
return $this;
}
/**
@ -144,7 +150,7 @@ class IntegerParser implements IValueParser {
*
* @return boolean True s'il existe une limite, sinon False
*/
public function hasValueMax() {
public function hasValueMax (): bool {
return !is_null($this->getValueMax());
}
}

@ -34,42 +34,25 @@ class PathParser implements IValueParser {
/**
* @var bool Est-ce que le fichier doit exister ?
*/
protected $_mustExist;
protected bool $mustExist;
/**
* Crée un nouveau parseur
*
* @param bool $mustExists Est-ce que le chemin doit exister ?
*/
public function __construct ($mustExists = false) {
public function __construct (bool $mustExists) {
$this->setMustExists($mustExists);
}
/**
* Spécifie si le chemin doit exister ou non
*
* @param bool $mustExists True si le chemin doit exister, sinon False
*
* @return $this
*
* @see $_mustExists
*/
public function setMustExists ($mustExists = false) {
if (!is_bool($mustExists)) {
throw new InvalidArgumentException('Le contrôle si le chemin doit exister ou non n\'est pas booléen : ' . $mustExists);
}
$this->_mustExist = $mustExists;
return $this;
}
/**
* @inheritDoc
*/
public function parseValue ($arg) {
public function parseValue (string $val) {
foreach (self::REGEX_PATH as $regex) {
if (preg_match($regex, $arg, $matches, PREG_UNMATCHED_AS_NULL)) {
if ($this->_mustExist && !file_exists($matches[0])) {
throw new UnexpectedValueException('Le chemin n\'existe pas : ' . $arg);
if (preg_match($regex, $val, $matches, PREG_UNMATCHED_AS_NULL)) {
if ($this->mustExist && !file_exists($matches[0])) {
throw new UnexpectedValueException('Le chemin n\'existe pas : ' . $val);
}
$out = new stdStringClass('fullpath');
@ -83,13 +66,13 @@ class PathParser implements IValueParser {
}
}
throw new UnexpectedValueException('La valeur n\'est pas un chemin valide : ' . $arg);
throw new UnexpectedValueException('La valeur n\'est pas un chemin valide : ' . $val);
}
/**
* @inheritDoc
*/
public function getValueDescription () {
public function getValueDescription (): string {
return 'path';
}
@ -99,8 +82,27 @@ class PathParser implements IValueParser {
* @return bool True si le chemin doit exister, sinon False
*
* @see $_mustExists
*
* @noinspection PhpUnused
*/
public function getMustExist () {
return $this->_mustExist;
public function getMustExist (): bool {
return $this->mustExist;
}
/**
* Spécifie si le chemin doit exister ou non
*
* @param bool $mustExists True si le chemin doit exister, sinon False
*
* @return $this
*
* @see $_mustExists
*/
public function setMustExists (bool $mustExists): self {
if (!is_bool($mustExists)) {
throw new InvalidArgumentException('Le contrôle si le chemin doit exister ou non n\'est pas booléen : ' . $mustExists);
}
$this->mustExist = $mustExists;
return $this;
}
}

@ -12,16 +12,18 @@ use RangeException;
* Renvoie la liste des groupes capturants
*
* @package CommandLine\Argument\Parser
*
* @noinspection PhpUnused
*/
class RegexParser implements IValueParser {
/**
* @var string La regex à respecter
*/
protected $_regex = '';
protected string $regex = '';
/**
* @var string|null Le format affiché dans la description
*/
protected $_format = '';
protected ?string $format = '';
/**
* Crée un nouveau parseur
@ -29,7 +31,7 @@ class RegexParser implements IValueParser {
* @param string $regex Le motif à respecter
* @param string|null $format Le format à afficher
*/
public function __construct ($regex, $format = null) {
public function __construct (string $regex, ?string $format = null) {
$this->setRegex($regex);
$this->setFormat($format);
}
@ -37,9 +39,10 @@ class RegexParser implements IValueParser {
/**
* @inheritDoc
*/
public function parseValue ($arg) {
if(!preg_match($this->_regex, $arg, $matches))
throw new RangeException('La valeur ne correspond pas au motif attendu : ' . $arg);
public function parseValue (string $val) {
if (!preg_match($this->regex, $val, $matches)) {
throw new RangeException('La valeur ne correspond pas au motif attendu : ' . $val);
}
return $matches;
}
@ -47,7 +50,7 @@ class RegexParser implements IValueParser {
/**
* @inheritDoc
*/
public function getValueDescription () {
public function getValueDescription (): string {
return is_null($this->getFormat()) ? $this->getRegex() : $this->getFormat();
}
@ -56,10 +59,10 @@ class RegexParser implements IValueParser {
*
* @return string Le motif
*
* @see $_regex
* @see $regex
*/
public function getRegex() {
return $this->_regex;
public function getRegex (): string {
return $this->regex;
}
/**
* Modifie le motif à respecter
@ -68,8 +71,8 @@ class RegexParser implements IValueParser {
*
* @return $this
*/
public function setRegex($regex) {
$this->_regex = $regex;
public function setRegex (string $regex): self {
$this->regex = $regex;
return $this;
}
@ -78,10 +81,10 @@ class RegexParser implements IValueParser {
*
* @return string|null Le format
*
* @see $_format
* @see $format
*/
public function getFormat() {
return $this->_format;
public function getFormat (): ?string {
return $this->format;
}
/**
* Modifie le format à afficher
@ -90,8 +93,8 @@ class RegexParser implements IValueParser {
*
* @return $this
*/
public function setFormat($format = null) {
$this->_format = $format;
public function setFormat (?string $format = null): self {
$this->format = $format;
return $this;
}
}

@ -8,19 +8,21 @@ namespace jrosset\CommandLine\Argument\Parser;
* Parseur vers une chaine de caractères
*
* @package CommandLine\Argument\Parser
*
* @noinspection PhpUnused
*/
class StringParser implements IValueParser {
/**
* @inheritDoc
*/
public function parseValue ($arg) {
return $arg;
public function parseValue (string $val) {
return $val;
}
/**
* @inheritDoc
*/
public function getValueDescription () {
public function getValueDescription (): string {
return 'string';
}
}

@ -15,15 +15,15 @@ class stdStringClass extends stdClass {
/**
* @var string Le nom de la propriété
*/
private $_property;
private string $property;
/**
* Crée une nouvelle instance
*
* @param string $property Le nom de la propriété
*/
public function __construct ($property) {
$this->_property = $property;
public function __construct (string $property) {
$this->property = $property;
}
/**
@ -32,6 +32,6 @@ class stdStringClass extends stdClass {
* @return string La valeur de l'attribut choisi (convertion forcé en chaine de caractères)
*/
public function __toString () {
return (string)$this->{$this->_property};
return (string)$this->{$this->property};
}
}

@ -11,12 +11,14 @@ use jrosset\CommandLine\Argument\ParseResult;
* Argument devant correspondre une valeur fixe
*
* @package CommandLine\Argument
*
* @noinspection PhpUnused
*/
class FixedValue extends ValueAbstract implements IArgumentValueDescription {
/**
* @var string La valeur que doit avoir l'argument
*/
protected $_value;
protected string $value;
/**
* Crée un nouvel argument de type valeur
@ -26,7 +28,7 @@ class FixedValue extends ValueAbstract implements IArgumentValueDescription {
* @param string|null $description La description
* @param boolean $optional Valeur optionnelle ?
*/
public function __construct ($varName, $value, $description, $optional = false) {
public function __construct (string $varName, string $value, ?string $description, bool $optional) {
parent::__construct($value, $description, $optional);
$this->setVarName($varName);
$this->setValue($value);
@ -35,9 +37,10 @@ class FixedValue extends ValueAbstract implements IArgumentValueDescription {
/**
* @inheritDoc
*/
public function parse ($args) {
if($args[0] == $this->getValue())
public function parse (array $args): ?ParseResult {
if ($args[0] == $this->getValue()) {
return new ParseResult($this->getValue(), 1);
}
return null;
}
@ -45,7 +48,7 @@ class FixedValue extends ValueAbstract implements IArgumentValueDescription {
/**
* @inheritDoc
*/
public function getValueDescription () {
public function getValueDescription (): string {
return '"' . $this->getValue() . '"';
}
@ -54,10 +57,10 @@ class FixedValue extends ValueAbstract implements IArgumentValueDescription {
*
* @return string La valeur.
*
* @see $_value
* @see $value
*/
public function getValue() {
return $this->_value;
public function getValue (): string {
return $this->value;
}
/**
* Définit la valeur
@ -65,10 +68,10 @@ class FixedValue extends ValueAbstract implements IArgumentValueDescription {
* @param string $value La valeur
*
* @return $this
* @see $_value
* @see $value
*/
public function setValue($value) {
$this->_value = $value;
public function setValue (string $value): self {
$this->value = $value;
return $this;
}
}

@ -19,7 +19,7 @@ interface IArgumentValue extends IArgument {
*
* @return int Le nombre minimum d'occurence
*/
public function getOccurMin();
public function getOccurMin (): int;
/**
* Le nombre maximum d'occurence.
*
@ -27,5 +27,5 @@ interface IArgumentValue extends IArgument {
*
* @return int|null Le nombre maximum d'occurence
*/
public function getOccurMax();
public function getOccurMax (): ?int;
}

@ -19,7 +19,7 @@ class Value extends ValueAbstract implements IArgumentValueDescription {
/**
* @var IValueParser Parseur pour la valeur
*/
protected $_valueParser;
protected IValueParser $valueParser;
/**
* Crée un nouvel argument de type valeur
@ -29,7 +29,7 @@ class Value extends ValueAbstract implements IArgumentValueDescription {
* @param IValueParser $valueParser Le parseur de valeur.
* @param boolean $optional Valeur optionnelle ?
*/
public function __construct ($name, $description, IValueParser $valueParser, $optional = false) {
public function __construct (string $name, ?string $description, IValueParser $valueParser, bool $optional) {
parent::__construct($name, $description, $optional);
$this->setValueParser($valueParser);
@ -38,9 +38,9 @@ class Value extends ValueAbstract implements IArgumentValueDescription {
/**
* @inheritDoc
*/
public function parse ($args) {
public function parse (array $args): ?ParseResult {
try {
return new ParseResult($this->_valueParser->parseValue($args[0]), 1);
return new ParseResult($this->valueParser->parseValue($args[0]), 1);
}
catch (RangeException $e) {
throw new IncorrectParse('Échec du parsage de la valeur "' . $args[0] . '"', 0, $e);
@ -50,8 +50,8 @@ class Value extends ValueAbstract implements IArgumentValueDescription {
/**
* @inheritDoc
*/
public function getValueDescription () {
return $this->_valueParser->getValueDescription();
public function getValueDescription (): string {
return $this->valueParser->getValueDescription();
}
/**
@ -59,10 +59,12 @@ class Value extends ValueAbstract implements IArgumentValueDescription {
*
* @return IValueParser Le parseur.
*
* @see $_valueParser
* @see $valueParser
*
* @noinspection PhpUnused
*/
public function getValueParser() {
return $this->_valueParser;
public function getValueParser (): IValueParser {
return $this->valueParser;
}
/**
* Définit le parseur de valeur
@ -71,10 +73,10 @@ class Value extends ValueAbstract implements IArgumentValueDescription {
*
* @return $this
*
* @see $_valueParser
* @see $valueParser
*/
public function setValueParser(IValueParser $valueParser) {
$this->_valueParser = $valueParser;
public function setValueParser (IValueParser $valueParser): self {
$this->valueParser = $valueParser;
return $this;
}
}

@ -18,11 +18,11 @@ abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue
/**
* @var int Le nombre minimum d'occurence.
*/
protected $_occurMin = 1;
protected int $occurMin = 1;
/**
* @var int|null Le nombre maximum d'occurence.
*/
protected $_occurMax = 1;
protected ?int $occurMax = 1;
/**
* Crée un nouvel argument.
@ -31,11 +31,22 @@ abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue
* @param string|null $description La description de l'argument
* @param boolean $optional Argument optionel ?
*/
protected function __construct ($name, $description, $optional = false) {
protected function __construct (string $name, ?string $description, bool $optional) {
parent::__construct($name, $description);
$this->setOptional($optional);
}
/**
* Est-ce que l'argument est facultatif ?
*
* @return bool Est-ce que l'argument est facultatif ?
*
* @noinspection PhpUnused
*/
public function isOptional (): bool {
return $this->getOccurMin() === 0;
}
/**
* Définit si l'argument est facultatif ou non.
*
@ -43,7 +54,7 @@ abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue
*
* @return $this
*/
public function setOptional ($optional = false) {
public function setOptional (bool $optional): self {
$this->setOccurMin($optional ? 0 : 1);
return $this;
}
@ -51,8 +62,8 @@ abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue
/**
* @inheritDoc
*/
public function getOccurMin () {
return $this->_occurMin;
public function getOccurMin (): int {
return $this->occurMin;
}
/**
* Définit le nombre minimum d'occurence.
@ -60,9 +71,9 @@ abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue
* @param int $occurMin Le nombre minimum
*
* @return $this
* @see $_occurMin
* @see $occurMin
*/
public function setOccurMin ($occurMin) {
public function setOccurMin (int $occurMin): self {
if (!is_numeric($occurMin)) {
throw new InvalidArgumentException('Le nombre minimum d\'ocurrence n\'est pas un entier');
}
@ -76,15 +87,15 @@ abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue
throw new InvalidArgumentException('Le nombre minimum d\'ocurrence n\'est pas un entier positif');
}
$this->_occurMin = $int;
$this->occurMin = $int;
return $this;
}
/**
* @inheritDoc
*/
public function getOccurMax () {
return $this->_occurMax;
public function getOccurMax (): int {
return $this->occurMax;
}
/**
* Définit le nombre mawimum d'occurence.
@ -92,9 +103,9 @@ abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue
* @param int|null $occurMax Le nombre maximum
*
* @return $this
* @see $_occurMax
* @see $occurMax
*/
public function setOccurMax ($occurMax) {
public function setOccurMax (?int $occurMax): self {
if (!is_null($occurMax)) {
if (!is_numeric($occurMax)) {
throw new InvalidArgumentException('Le nombre maximum d\'ocurrence n\'est pas un entier');
@ -110,7 +121,7 @@ abstract class ValueAbstract extends ArgumentAbstract implements IArgumentValue
}
}
$this->_occurMax = $occurMax;
$this->occurMax = $occurMax;
return $this;
}
}

@ -19,6 +19,7 @@ use jrosset\CommandLine\Exception\TooMuchValues;
use ReflectionClass;
use ReflectionException;
use stdClass;
use Throwable;
/**
* Une ligne de commande (description, arguments, etc.)
@ -60,33 +61,33 @@ class CommandLine {
/**
* @var string|null La commande de lancement du script (si non fourni, égal au {@see CommandeLine::_programName nom du programme})
*/
protected $_command;
protected ?string $command;
/**
* @var string Le nom du programme
*/
protected $_programName;
protected string $programName;
/**
* @var string Description du programme
*/
protected $_description;
protected string $description;
/**
* @var string|null La version du programme.
*/
protected $_version;
protected ?string $version;
/**
* @var IArgumentOption[] Liste des options de la ligne de commande
*/
protected $_arguments_options = array();
protected array $argumentsOptions = array();
/**
* @var IArgumentValue[] Liste _ordonnée_ des arguments "valeur" de la ligne de commande
*/
protected $_arguments_values = array();
protected array $argumentsValues = array();
/**
* @var string[] Liste des codes de retour avec leur descriptif
*/
protected $_exitCodes = array();
protected array $exitCodes = array();
/**
* Crée un ligne de commande
@ -98,7 +99,7 @@ class CommandLine {
*
* @throws InvalidArgumentException
*/
public function __construct ($programName, $mainDescription, $command = null, $version = null) {
public function __construct (string $programName, string $mainDescription, ?string $command = null, ?string $version = null) {
$this->setProgramName($programName);
$this->setDescription($mainDescription);
$this->setCommand($command);
@ -108,13 +109,13 @@ class CommandLine {
/**
* La commande de lancement du programme
*
* NULL = {@see CommandLine::$_programName Nom du programme}
* NULL = {@see CommandLine::$programName Nom du programme}
*
* @return string|null La commande
* @see CommandLine::$_command
* @see CommandLine::$command
*/
public function getCommand () {
return $this->_command;
public function getCommand (): ?string {
return $this->command;
}
/**
* Modifie la commande de lancement du programme
@ -122,10 +123,10 @@ class CommandLine {
* @param string|null $command La nouvelle commande
*
* @return $this
* @see CommandLine::$_command
* @see CommandLine::$command
*/
public function setCommand ($command) {
$this->_command = $command;
public function setCommand (?string $command): self {
$this->command = $command;
return $this;
}
@ -133,10 +134,10 @@ class CommandLine {
* Le nom du programme.
*
* @return string Le nom.
* @see CommandLine::$_programName
* @see CommandLine::$programName
*/
public function getProgramName () {
return $this->_programName;
public function getProgramName (): string {
return $this->programName;
}
/**
* Modifie le nom du programme.
@ -144,10 +145,10 @@ class CommandLine {
* @param string $programName Le nouveau nom
*
* @return $this
* @see CommandLine::$_programName
* @see CommandLine::$programName
*/
public function setProgramName ($programName) {
$this->_programName = $programName;
public function setProgramName (string $programName): self {
$this->programName = $programName;
return $this;
}
@ -155,10 +156,10 @@ class CommandLine {
* La description du programme
*
* @return string La description
* @see CommandLine::$_description
* @see CommandLine::$description
*/
public function getDescription () {
return $this->_description;
public function getDescription (): string {
return $this->description;
}
/**
* Modifie la description du programme.
@ -166,10 +167,10 @@ class CommandLine {
* @param string $description La nouvelle description.
*
* @return $this
* @see CommandLine::$_description
* @see CommandLine::$description
*/
public function setDescription ($description) {
$this->_description = $description;
public function setDescription (string $description): self {
$this->description = $description;
return $this;
}
@ -177,10 +178,10 @@ class CommandLine {
* La version du programme
*
* @return string|null La version
* @see CommandLine::$_version
* @see CommandLine::$version
*/
public function getVersion () {
return $this->_version;
public function getVersion (): ?string {
return $this->version;
}
/**
* Modifie la version du programme.
@ -188,10 +189,10 @@ class CommandLine {
* @param string|null $version La nouvelle version.
*
* @return $this
* @see CommandLine::$_version
* @see CommandLine::$version
*/
public function setVersion ($version) {
$this->_version = $version;
public function setVersion (?string $version): self {
$this->version = $version;
return $this;
}
@ -199,10 +200,10 @@ class CommandLine {
* La liste des arguments "value"
*
* @return IArgumentValue[] La liste des valeurs
* @see CommandLine::$_arguments_values
* @see CommandLine::$argumentsValues
*/
public function getValues () {
return $this->_arguments_values;
public function getValues (): array {
return $this->argumentsValues;
}
/**
* Modifie la liste des arguments "value"
@ -213,12 +214,12 @@ class CommandLine {
* @param IArgumentValue[] $values La nouvelle liste de valeurs
*
* @return $this
* @see CommandLine::$_arguments_values
* @see CommandLine::$argumentsValues
*/
public function setValues ($values) {
public function setValues (array $values): self {
self::_checkValueList($values);
$this->_arguments_values = $values;
$this->argumentsValues = $values;
return $this;
}
/**
@ -229,15 +230,15 @@ class CommandLine {
* @param IArgumentValue[]|IArgumentValue $values La liste des valeurs à ajouter
*
* @return $this
* @see CommandLine::$_arguments_values
* @see CommandLine::$argumentsValues
*/
public function addValues ($values) {
public function addValues ($values): self {
if (!is_array($values) && $values instanceof IArgumentValue) {
$values = array($values);
}
self::_checkValueList($values);
$this->_arguments_values = array_merge($this->_arguments_values, $values);
$this->argumentsValues = array_merge($this->argumentsValues, $values);
return $this;
}
/**
@ -248,9 +249,9 @@ class CommandLine {
* @param IArgumentValue $value La valeur à ajouter
*
* @return $this
* @see CommandLine::$_arguments_values
* @see CommandLine::$argumentsValues
*/
public function addValue ($value) {
public function addValue (IArgumentValue $value): self {
return $this->addValues(array($value));
}
/**
@ -260,8 +261,8 @@ class CommandLine {
*
* @return bool True si la valeur existe déjà, sinon False
*/
public function existsValue ($valueName) {
foreach ($this->_arguments_values as $option) {
public function existsValue (string $valueName): bool {
foreach ($this->argumentsValues as $option) {
if ($option->getName() == $valueName) {
return true;
}
@ -276,7 +277,7 @@ class CommandLine {
*
* @return bool True si c'est bien un argument "value", sinon False
*/
public static function isValue ($argument) {
public static function isValue ($argument): bool {
return $argument instanceof IArgumentValue;
}
/**
@ -286,7 +287,7 @@ class CommandLine {
*
* @param IArgumentValue[] $values Les valeurs à vérifier
*/
protected static function _checkValueList ($values) {
protected static function _checkValueList (array $values) {
if (!is_array($values)) {
throw new InvalidArgumentException('La liste des valeurs n\'est pas un tableau');
}
@ -301,10 +302,10 @@ class CommandLine {
* La liste des arguments "option"
*
* @return IArgumentOption[] La liste des options
* @see CommandLine::$_arguments_options
* @see CommandLine::$argumentsOptions
*/
public function getOptions () {
return $this->_arguments_options;
public function getOptions (): array {
return $this->argumentsOptions;
}
/**
* Modifie la liste des arguments "option"
@ -315,12 +316,12 @@ class CommandLine {
* @param IArgumentOption[] $options La nouvelle liste d'options
*
* @return $this
* @see CommandLine::$_arguments_options
* @see CommandLine::$argumentsOptions
*/
public function setOptions ($options) {
public function setOptions (array $options): self {
self::_checkOptionList($options);
$this->_arguments_options = $options;
$this->argumentsOptions = $options;
return $this;
}
/**
@ -331,15 +332,15 @@ class CommandLine {
* @param IArgumentOption[]|IArgumentOption $options La liste d'options à ajouter
*
* @return $this
* @see CommandLine::$_arguments_options
* @see CommandLine::$argumentsOptions
*/
public function addOptions ($options) {
public function addOptions ($options): self {
if (!is_array($options) && $options instanceof IArgumentOption) {
$options = array($options);
}
self::_checkOptionList($options);
$this->_arguments_options = array_merge($this->_arguments_options, $options);
$this->argumentsOptions = array_merge($this->argumentsOptions, $options);
return $this;
}
/**
@ -350,9 +351,9 @@ class CommandLine {
* @param IArgumentOption $option L'options à ajouter
*
* @return $this
* @see CommandLine::$_arguments_options
* @see CommandLine::$argumentsOptions
*/
public function addOption ($option) {
public function addOption (IArgumentOption $option): self {
return $this->addOptions(array($option));
}
/**
@ -362,8 +363,8 @@ class CommandLine {
*
* @return bool True si l'option existe déjà, sinon False
*/
public function existsOption ($optionName) {
foreach ($this->_arguments_options as $option) {
public function existsOption (string $optionName): bool {
foreach ($this->argumentsOptions as $option) {
if ($option->getName() == $optionName) {
return true;
}
@ -378,7 +379,7 @@ class CommandLine {
*
* @return bool True si c'est bien un argument "option", sinon False
*/
public static function isOption ($argument) {
public static function isOption ($argument): bool {
return $argument instanceof IArgumentOption;
}
/**
@ -388,7 +389,7 @@ class CommandLine {
*
* @param IArgumentOption[] $options Les options à vérifier
*/
protected static function _checkOptionList ($options) {
protected static function _checkOptionList (array $options) {
if (!is_array($options)) {
throw new InvalidArgumentException('La liste des options n\'est pas un tableau');
}
@ -404,7 +405,7 @@ class CommandLine {
*
* @return IArgument[] La liste des arguments
*/
public function getArguments () {
public function getArguments (): array {
return array_merge($this->getValues(), $this->getOptions());
}
/**
@ -417,7 +418,7 @@ class CommandLine {
*
* @return $this
*/
public function setArguments ($arguments) {
public function setArguments (array $arguments): self {
$this->setOptions(array());
$this->setValues(array());
@ -432,7 +433,7 @@ class CommandLine {
*
* @return $this
*/
public function addArguments ($arguments) {
public function addArguments ($arguments): self {
if (!is_array($arguments) && $arguments instanceof IArgumentValue) {
$arguments = array($arguments);
}
@ -453,7 +454,7 @@ class CommandLine {
*
* @return $this
*/
public function addArgument ($argument) {
public function addArgument (IArgument $argument): self {
if (!self::isArgument($argument)) {
throw new InvalidArgumentException('L\'argument n\'est pas valide (n\'implémente pas IArgument)');
}
@ -477,6 +478,7 @@ class CommandLine {
}
}
}
/** @noinspection PhpRedundantCatchClauseInspection */
catch (ReflectionException $e) {
$type = /** @lang text */
'<inconnu>';
@ -493,8 +495,10 @@ class CommandLine {
* @param string $argumentName Le nom de l'argument
*
* @return bool True si l'argument existe déjà, sinon False
*
* @noinspection PhpUnused
*/
public function existsArgument ($argumentName) {
public function existsArgument (string $argumentName): bool {
$arguments = $this->getArguments();
foreach ($arguments as $argument) {
if ($argument->getName() == $argumentName) {
@ -511,7 +515,7 @@ class CommandLine {
*
* @return bool True si c'est bien un argument, sinon False
*/
public static function isArgument ($argument) {
public static function isArgument ($argument): bool {
return $argument instanceof IArgument;
}
/**
@ -520,8 +524,10 @@ class CommandLine {
* Doit être un tableau et chaque élément doit implémenter {@see IArgument}
*
* @param IArgument[] $arguments Les arguments à vérifier
*
* @noinspection PhpUnused
*/
protected static function _checkArgumentList ($arguments) {
protected static function _checkArgumentList (array $arguments) {
if (!is_array($arguments)) {
throw new InvalidArgumentException('La liste des arguments n\'est pas un tableau');
}
@ -537,8 +543,8 @@ class CommandLine {
*
* @return string[] La liste des codes de retour avec leur descriptifs
*/
public function getExitCodes () {
return $this->_exitCodes;
public function getExitCodes (): array {
return $this->exitCodes;
}
/**
* La description de l'un de code de retour
@ -549,11 +555,11 @@ class CommandLine {
*
* @throws InvalidArgumentException Si le code de retour n'est pas un entier
*/
public function getExitCodeDescription ($code) {
public function getExitCodeDescription (int $code): ?string {
if (filter_var($code, FILTER_VALIDATE_INT) === false) {
throw new InvalidArgumentException('Le code de retour "' . $code . '" n\'est pas un entier');
}
return $this->_exitCodes[(int)$code];
return $this->exitCodes[$code];
}
/**
* Remplace la liste des codes de retour avec leur descriptif
@ -565,8 +571,8 @@ class CommandLine {
* @throws InvalidArgumentException Si la clé du tableaux (les codes) ne sont pas des entiers ou
* que la valeur (description) n'est pas convertible en chaine de caractères
*/
public function setExitCodes ($exitCodes = array()) {
$this->_exitCodes = array();
public function setExitCodes (array $exitCodes = array()): self {
$this->exitCodes = array();
return $this->addExitCodes($exitCodes);
}
/**
@ -579,7 +585,7 @@ class CommandLine {
* @throws InvalidArgumentException Si la clé du tableaux (les codes) ne sont pas des entiers ou
* que la valeur (description) n'est pas convertible en chaine de caractères
*/
public function addExitCodes ($exitCodes) {
public function addExitCodes (array $exitCodes): self {
foreach ($exitCodes as $code => $description) {
$this->addExitCode($code, $description);
}
@ -597,7 +603,7 @@ class CommandLine {
* @throws InvalidArgumentException Si le code n'est pas un entier ou
* que la description n'est pas convertible en chaine de caractères
*/
public function addExitCode ($code, $description = null) {
public function addExitCode (int $code, ?string $description = null): self {
if (filter_var($code, FILTER_VALIDATE_INT) === false) {
throw new InvalidArgumentException('Le code de retour "' . $code . '" n\'est pas un entier');
}
@ -610,7 +616,7 @@ class CommandLine {
throw new InvalidArgumentException('La description "' . $code . '" n\'est pas convertible en chaine de caractères');
}
$this->_exitCodes[(int)$code] = (string)$description;
$this->exitCodes[$code] = (string)$description;
return $this;
}
/**
@ -622,11 +628,11 @@ class CommandLine {
*
* @throws InvalidArgumentException Si le code de retour n'est pas un entier
*/
public function existsExitCode ($code) {
public function existsExitCode (int $code): bool {
if (filter_var($code, FILTER_VALIDATE_INT) === false) {
throw new InvalidArgumentException('Le code de retour "' . $code . '" n\'est pas un entier');
}
return array_key_exists((int)$code, $this->_exitCodes);
return array_key_exists($code, $this->exitCodes);
}
/**
@ -640,7 +646,7 @@ class CommandLine {
*
* @return $this
*/
public function addDefaultArguments ($shortForVersion = true) {
public function addDefaultArguments (bool $shortForVersion = true): self {
if (!$this->existsOption(self::ARGUMENT_OPTION_HELP)) {
$this->addOption(
(new Argument\Option\Flag(self::ARGUMENT_OPTION_HELP, false, 'Affiche cette aide', 'help', 'h'))
@ -663,7 +669,7 @@ class CommandLine {
* @param stdClass $values Les valeurs du parsage
* @param boolean $exitAtEnd Terminer le script à la fin de la fonction correspondante ?
*/
public function treatDefaultArguments ($values, $exitAtEnd = true) {
public function treatDefaultArguments (stdClass $values, bool $exitAtEnd = true) {
if (isset($values->{self::ARGUMENT_OPTION_HELP}) && $values->{self::ARGUMENT_OPTION_HELP} === true) {
$this->showHelp($exitAtEnd);
}
@ -680,7 +686,7 @@ class CommandLine {
*
* @see CommandLine::getVersion()
*/
public function showVersion ($exitAtEnd = true) {
public function showVersion (bool $exitAtEnd = true) {
echo $this->getVersion() . "\n";
if ($exitAtEnd) {
@ -694,7 +700,7 @@ class CommandLine {
*
* @see CommandLine::generateHelp()
*/
public function showHelp ($exitAtEnd = true) {
public function showHelp (bool $exitAtEnd = true) {
echo $this->generateHelp() . "\n";
if ($exitAtEnd) {
@ -708,7 +714,7 @@ class CommandLine {
*
* @see CommandLine::showHelp()
*/
public function generateHelp () {
public function generateHelp (): string {
$help = array();
$help[] = $this->getProgramName() . (is_null($this->getVersion()) ? '' : ', version ' . $this->getVersion());
@ -719,21 +725,21 @@ class CommandLine {
empty($this->getCommand()) ? $this->getProgramName() : $this->getCommand(),
count($this->getOptions()) > 0 ? '[OPTIONS]' : '',
);
$syntax = array_merge($syntax, array_map(array(__CLASS__, '_getSyntaxOfValue'), $this->getValues()));
$syntax = array_merge($syntax, array_map(array(__CLASS__, 'getSyntaxOfValue'), $this->getValues()));
$help[] = implode(' ', $syntax);
$help[] = 'Arguments :';
$help = array_merge($help, self::_getValuesListing($this->getValues()));
$help = array_merge($help, self::getValuesListing($this->getValues()));
$help[] = '';
$help[] = 'Options :';
$help = array_merge($help, self::_getOptionsListing($this->getOptions()));
$help = array_merge($help, self::getOptionsListing($this->getOptions()));
$help[] = '';
if (count($this->getExitCodes()) > 0) {
$help[] = 'Exit codes :';
$help = array_merge($help, self::_getExitCodesListing($this->getExitCodes()));
$help = array_merge($help, self::getExitCodesListing($this->getExitCodes()));
$help[] = '';
}
@ -748,7 +754,7 @@ class CommandLine {
* @return string La syntax de l'argument
* @see generateHelp()
*/
protected static function _getSyntaxOfValue (IArgumentValue $value) {
protected static function getSyntaxOfValue (IArgumentValue $value): string {
$syntax = '';
$min = $value->getOccurMin();
@ -781,13 +787,13 @@ class CommandLine {
return $syntax;
}
/**
* Genère l'aide d'une liste d'arguments "value"
* Génère l'aide d'une liste d'arguments "value"
*
* @param IArgumentValue[] $values La liste des valeurs
*
* @return string[] L'aide de chaque valeur
*/
protected static function _getValuesListing ($values) {
protected static function getValuesListing (array $values): array {
/*
* Calcul des différents padding
*/
@ -814,13 +820,13 @@ class CommandLine {
}
$spaces = array();
$spaces[] = str_pad('', $pads->name, ' ');
$spaces[] = str_pad('', $pads->occurMin + 4 + $pads->occurMax, ' ');
$spaces[] = str_pad('', $pads->name);
$spaces[] = str_pad('', $pads->occurMin + 4 + $pads->occurMax);
if ($pads->valueDescription > 0) {
$spaces[] = str_pad('', $pads->valueDescription, ' ');
$spaces[] = str_pad('', $pads->valueDescription);
}
if ($pads->default > 0) {
$spaces[] = str_pad('', $pads->default, ' ');
$spaces[] = str_pad('', $pads->default);
}
$spaces[] = '';
@ -834,8 +840,7 @@ class CommandLine {
$max = $value->getOccurMax();
$occur = '';
$occur .= str_pad($value->getOccurMin(), $pads->occurMin, ' ', STR_PAD_LEFT);
$occur = str_pad($value->getOccurMin(), $pads->occurMin, ' ', STR_PAD_LEFT);
$occur .= ' => ';
$occur .= str_pad(is_null($max) ? 'N' : $max, $pads->occurMax, ' ', STR_PAD_RIGHT);
$entry[] = $occur;
@ -864,13 +869,13 @@ class CommandLine {
return $entries;
}
/**
* Genère l'aide d'une liste d'arguments "option"
* Génère l'aide d'une liste d'arguments "option"
*
* @param IArgumentOption[] $options La liste des options
*
* @return string[] L'aide de chaque option
*/
protected static function _getOptionsListing ($options) {
protected static function getOptionsListing (array $options): array {
/*
* Calcul des différents padding
*/
@ -900,12 +905,12 @@ class CommandLine {
$pads->tagLong += 2;
$spaces = array();
$spaces[] = str_pad('', $pads->tagShort + 1 + $pads->tagLong + 2, ' ');
$spaces[] = str_pad('', $pads->tagShort + 1 + $pads->tagLong + 2);
if ($pads->valueDescription > 0) {
$spaces[] = str_pad('', $pads->valueDescription, ' ');
$spaces[] = str_pad('', $pads->valueDescription);
}
if ($pads->default > 0) {
$spaces[] = str_pad('', $pads->default, ' ');
$spaces[] = str_pad('', $pads->default);
}
$spaces[] = '';
@ -918,8 +923,7 @@ class CommandLine {
$short = $option->getTagShort();
$label = '';
$label .= str_pad(is_null($short) ? '' : '-' . $short, $pads->tagShort, ' ', STR_PAD_RIGHT);
$label = str_pad(is_null($short) ? '' : '-' . $short, $pads->tagShort, ' ', STR_PAD_RIGHT);
$label .= ' ';
$label .= str_pad('--' . $option->getTagLong(), $pads->tagLong, ' ', STR_PAD_RIGHT);
$label .= $option->allowMultiple() ? ' *' : ($option->isStoppingParse() ? ' X' : ' ');
@ -956,7 +960,7 @@ class CommandLine {
*
* @return string[] L'aide de chaque code de retour
*/
protected static function _getExitCodesListing ($exitCodes) {
protected static function getExitCodesListing (array $exitCodes): array {
/*
* Calcul des différents padding
*/
@ -969,8 +973,6 @@ class CommandLine {
$pads->codes = max($pads->codes, strlen($code));
}
$spaces[] = str_pad('', $pads->tagShort + 1 + $pads->tagLong + 2, ' ');
/*
* Génération des descriptifs
*/
@ -997,17 +999,45 @@ class CommandLine {
* Revient à appeler {@see CommandLine::parseExplicit()} avec les arguments du script {@link https://www.php.net/manual/en/reserved.variables.argv.php $_SERVER['argv']}
*
* @return stdClass Les valeurs extraites
*
* @throws MissingArgument Quand un argument de la liste est manquant ou en quantité insuffisante
* @throws TooMuchValues Quand il reste des valeurs supplémentaires après le traitement de la liste d'arguments
*/
public function parse () {
public function parse (): stdClass {
$argv = $_SERVER['argv'];
array_shift($argv); // Supprime le 1er paramètre : le nom du script PHP
return $this->parseExplicit($argv);
}
/**
* Traite une liste d'arguments.
* Traite les arguments du script
*
* Le lève pas d'exceptions : le message d'erreur est redirigé vers $file
*
* @param int|null $exitCode Null si n'arrête pas l'exécution, sinon le code retour (exit)
* @param resource $file Le fichier dans lequel écrire l'erreur
*
* @return stdClass|null Les valeurs extraites (Null si erreur)
*
* @see CommandLine::parse()
*
* @noinspection PhpMissingParamTypeInspection
*/
public function parseNoExcept (?int $exitCode = null, $file = STDERR): ?stdClass {
try {
return $this->parse();
}
catch (Throwable $e) {
fwrite($file, $e->getMessage());
if ($exitCode !== null) {
exit($exitCode);
}
return null;
}
}
/**
* Traite une liste d'arguments
*
* 1/ Vérifie que la liste d'arguments correspond à la syntaxe de la ligne de commande
* 2/ Extrait les valeurs voulues de la liste d'arguments
@ -1018,7 +1048,7 @@ class CommandLine {
* @throws MissingArgument Quand un argument de la liste est manquant ou en quantité insuffisante
* @throws TooMuchValues Quand il reste des valeurs supplémentaires après le traitement de la liste d'arguments
*/
public function parseExplicit ($argv) {
public function parseExplicit (array $argv): stdClass {
$stop = false;
$nb_args = count($argv);
@ -1072,6 +1102,36 @@ class CommandLine {
return $out;
}
/**
* Traite une liste d'arguments
*
* Le lève pas d'exceptions : le message d'erreur est redirigé vers $file
*
* @param string[] $argv La liste d'arguments
* @param int|null $exitCode Null si n'arrête pas l'exécution, sinon le code retour (exit)
* @param resource $file Le fichier dans lequel écrire l'erreur
*
* @return stdClass|null Les valeurs extraites (Null si erreur)
*
* @see CommandLine::parseExplicit()
*
* @noinspection PhpUnused
* @noinspection PhpMissingParamTypeInspection
*/
public function parseExplicitNoExcept (array $argv, ?int $exitCode = null, $file = STDERR): ?stdClass {
try {
return $this->parseExplicit($argv);
}
catch (Throwable $e) {
fwrite($file, $e->getMessage());
if ($exitCode !== null) {
exit($exitCode);
}
return null;
}
}
/**
* Calcule le nombre d'argument "value" restant à honorer.
*
@ -1079,7 +1139,7 @@ class CommandLine {
*
* @return int Le nombre de valeurs restantes à traiter, ou -1 si un nombre "illimité"
*/
protected function _getNbArgumentRestant ($ordre_start) {
protected function _getNbArgumentRestant (int $ordre_start): int {
$nb = 0;
/**
* @var int $ordre
@ -1110,7 +1170,7 @@ class CommandLine {
* @return stdClass Les options extraites
* @throws IncorrectParse Si le parsage d'une des options échoue
*/
protected static function _parseOptions (&$argv, $options, &$stop) {
protected static function _parseOptions (array &$argv, array $options, bool &$stop): stdClass {
$values = new stdClass();
$stop = false;
@ -1158,7 +1218,7 @@ class CommandLine {
* @throws MissingArgument Si l'argument n'est pas en quantité suffisante
* @throws IncorrectParse Si l'argument échoue à se parser
*/
protected static function _parseXTimes (&$argv, &$out, $value, $xTimes, $offset = 0) {
protected static function _parseXTimes (array &$argv, stdClass $out, IArgumentValue $value, int $xTimes, int $offset = 0) {
if ($xTimes > count($argv)) {
throw new MissingArgument('L\'argument ' . $value->getName() . ' est en quantité insuffisante (' . count($argv) . ' / ' . $xTimes . ')');
}
@ -1181,7 +1241,7 @@ class CommandLine {
* @param ParseResult $result Le résultat du parsage de l'argument
* @param int|null $max Le nombre maximum de valeur autorisé
*/
protected static function _setValue (&$out, $argument, $result, $max) {
protected static function _setValue (stdClass $out, IArgument $argument, ParseResult $result, ?int $max) {
if (is_null($max) || $max > 1) {
if (!isset($out->{$argument->getVarName()})) {
$out->{$argument->getVarName()} = array();

Loading…
Cancel
Save