247 lines
8.0 KiB
PHP
247 lines
8.0 KiB
PHP
<?php
|
|
namespace nulib\app;
|
|
|
|
use nulib\A;
|
|
use nulib\cl;
|
|
use nulib\cv;
|
|
use nulib\file;
|
|
use nulib\str;
|
|
|
|
class args {
|
|
/**
|
|
* transformer une liste d'argument de la forme
|
|
* - ["myArg" => $value] devient ["--my-arg", "$value"]
|
|
* - ["myOpt" => true] devient ["--my-opt"]
|
|
* - ["myOpt" => false] est omis
|
|
* - les autres valeurs sont transformées en chaines puis ajoutée
|
|
*
|
|
* ainsi, ["myOpt" => "value", "myArg", "myBool" => true]
|
|
* devient ["--my-opt", "value", "myArg", "--my-bool"]
|
|
*/
|
|
static function from_array(?array $array): array {
|
|
$args = [];
|
|
if ($array === null) return $args;
|
|
$index = 0;
|
|
foreach ($array as $arg => $value) {
|
|
if ($value === false) continue;
|
|
if ($arg === $index) {
|
|
$index++;
|
|
} else {
|
|
$arg = str::us2camel($arg);
|
|
$arg = str::camel2us($arg, false, "-");
|
|
$arg = str_replace("_", "-", $arg);
|
|
$args[] = "--$arg";
|
|
if (is_array($value)) $value[] = "--";
|
|
elseif ($value === true) $value = null;
|
|
}
|
|
if (is_array($value)) {
|
|
A::merge($args, array_map("strval", $value));
|
|
} elseif ($value !== null) {
|
|
$args[] = "$value";
|
|
}
|
|
}
|
|
return $args;
|
|
}
|
|
|
|
private static function tint(string $value): int {
|
|
return intval($value);
|
|
}
|
|
|
|
private static function tbool(string $value): bool {
|
|
return boolval($value);
|
|
}
|
|
|
|
private static function tarray(string $value): ?array {
|
|
if ($value === "") return null;
|
|
$tmparray = explode(",", $value);
|
|
$array = null;
|
|
foreach ($tmparray as $tmpvalue) {
|
|
[$tmpkey, $tmpvalue] = str::split_pair($tmpvalue);
|
|
if ($tmpvalue === null) cv::swap($tmpkey, $tmpvalue);
|
|
if ($tmpkey === null) {
|
|
$array[] = $tmpvalue;
|
|
} else {
|
|
if (str::del_suffix($tmpkey, ":int")) {
|
|
$tmpvalue = self::tint($tmpvalue);
|
|
} elseif (str::del_suffix($tmpkey, ":bool")) {
|
|
$tmpvalue = self::tbool($tmpvalue);
|
|
}
|
|
$array[$tmpkey] = $tmpvalue;
|
|
}
|
|
}
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* convertir une liste d'arguments en tableau qui est utilisable comme un
|
|
* filtre de base de données ou des données d'une requête REST. les arguments
|
|
* peuvent être de la forme:
|
|
* - "name=value"
|
|
* qui devient dans le tableau ["name" => "value"]
|
|
* - "+arg" ou "arg"
|
|
* qui devient dans le tableau ["arg" => true]
|
|
* - "-arg" ou "~arg"
|
|
* qui est stocké dans le tableau $query ["arg" => false]
|
|
*
|
|
* si $allow_file == true, les formes d'arguments suivantes sont reconnues
|
|
* aussi:
|
|
* - "name=@file" (1 argument) OU
|
|
* "name=@" "file" (2 arguments)
|
|
* qui deviennent ["name" => new FileReader(file)]
|
|
*/
|
|
static function build_query(?array $args, bool $allow_file=true): ?array {
|
|
$query = null;
|
|
$args ??= [];
|
|
$keys = array_keys($args);
|
|
$index = 0;
|
|
$count = count($keys);
|
|
while ($index < $count) {
|
|
$arg = $args[$keys[$index++]];
|
|
[$name, $value] = str::split_pair($arg, "=");
|
|
$checkType = true;
|
|
if ($value === null) {
|
|
if (str::del_prefix($name, "+")) {
|
|
$value = true;
|
|
} elseif (str::del_prefix($name, "-") || str::del_prefix($name, "~")) {
|
|
$value = false;
|
|
} else {
|
|
$value = true;
|
|
}
|
|
} elseif ($allow_file) {
|
|
if ($value === "@") {
|
|
$value = $args[$keys[$index++]];
|
|
$value = file::reader($value);
|
|
$checkType = false;
|
|
} elseif (substr($value, 0, 1) === "@") {
|
|
$value = substr($value, 1);
|
|
$value = file::reader($value);
|
|
$checkType = false;
|
|
}
|
|
}
|
|
if ($checkType) {
|
|
if (str::del_suffix($name, ":int")) {
|
|
if (str::del_suffix($name, ":array")) {
|
|
$value = array_map([self::class, "tint"], self::tarray($value));
|
|
} else {
|
|
$value = self::tint($value);
|
|
}
|
|
} elseif (str::del_suffix($name, ":bool")) {
|
|
if (str::del_suffix($name, ":array")) {
|
|
$value = array_map([self::class, "tbool"], self::tarray($value));
|
|
} else {
|
|
$value = self::tbool($value);
|
|
}
|
|
} elseif (str::del_suffix($name, ":array")) {
|
|
$value = self::tarray($value);
|
|
if (str::del_suffix($name, ":int")) {
|
|
$value = array_map([self::class, "tint"], $value);
|
|
} elseif (str::del_suffix($name, ":bool")) {
|
|
$value = array_map([self::class, "tbool"], $value);
|
|
}
|
|
}
|
|
}
|
|
if (cl::has($query, $name)) {
|
|
A::ensure_array($query[$name]);
|
|
$query[$name][] = $value;
|
|
} else {
|
|
$query[$name] = $value;
|
|
}
|
|
}
|
|
return $query;
|
|
}
|
|
|
|
/**
|
|
* convertir une liste d'arguments de façon qu'ils soient utilisables pour un
|
|
* appel de méthode. les arguments peuvent être de la forme:
|
|
* - "name=value"
|
|
* qui est stocké dans le tableau $query ["name" => "value"]
|
|
* il est possible de forcer le type de la valeur avec l'un des suffixes
|
|
* :int, :bool ou :array, e.g
|
|
* un entier: "name:int=42"
|
|
* un tableau de chaines: "name:array=a,b,c"
|
|
* un tableau d'entiers: "name:array:int=1,2,3"
|
|
* - "+arg"
|
|
* qui est stocké dans le tableau $query ["arg" => true]
|
|
* - "-arg" ou "~arg"
|
|
* qui est stocké dans le tableau $query ["arg" => false]
|
|
* - "array:sval,key:aval,..."
|
|
* qui devient l'argument ["sval", "key" => "aval", ...]
|
|
* il est possible de forcer le types des éléments avec le préfixe int: ou
|
|
* bool: e.g "array:int:1,2,3"
|
|
* - "int:value"
|
|
* qui devient l'argument intval("value")
|
|
* - "bool:value"
|
|
* qui devient l'argument boolval("value")
|
|
* - "value"
|
|
* qui devient l'argument "value"
|
|
*
|
|
* à la fin, la liste des arguments est retournée [$arguments...]
|
|
* si le tableau $query est renseigné, il est en premier dans la liste des
|
|
* arguments e.g [$query, $arguments...]
|
|
*/
|
|
static function build_method_args(?array $args): ?array {
|
|
$query = null;
|
|
$margs = [];
|
|
$args ??= [];
|
|
foreach ($args as $arg) {
|
|
[$name, $value] = str::split_pair($arg, "=");
|
|
if ($value === null) {
|
|
if (str::del_prefix($name, "+")) {
|
|
$value = true;
|
|
} elseif (str::del_prefix($name, "-") || str::del_prefix($name, "~")) {
|
|
$value = false;
|
|
} elseif (str::del_prefix($name, "int:")) {
|
|
$margs[] = self::tint($name);
|
|
continue;
|
|
} elseif (str::del_prefix($name, "bool:")) {
|
|
$margs[] = self::tbool($name);
|
|
continue;
|
|
} elseif (str::del_prefix($name, "array:")) {
|
|
if (str::del_prefix($name, "int:")) {
|
|
$map = [self::class, "tint"];
|
|
} elseif (str::del_prefix($name, "bool:")) {
|
|
$map = [self::class, "tbool"];
|
|
} else {
|
|
$map = null;
|
|
}
|
|
$value = self::tarray($name);
|
|
if ($map !== null) $value = array_map($map, $value);
|
|
$margs[] = $value;
|
|
continue;
|
|
} else {
|
|
$margs[] = $name;
|
|
continue;
|
|
}
|
|
}
|
|
if (str::del_suffix($name, ":int")) {
|
|
if (str::del_suffix($name, ":array")) {
|
|
$value = array_map([self::class, "tint"], self::tarray($value));
|
|
} else {
|
|
$value = self::tint($value);
|
|
}
|
|
} elseif (str::del_suffix($name, ":bool")) {
|
|
if (str::del_suffix($name, ":array")) {
|
|
$value = array_map([self::class, "tbool"], self::tarray($value));
|
|
} else {
|
|
$value = self::tbool($value);
|
|
}
|
|
} elseif (str::del_suffix($name, ":array")) {
|
|
$value = self::tarray($value);
|
|
if (str::del_suffix($name, ":int")) {
|
|
$value = array_map([self::class, "tint"], $value);
|
|
} elseif (str::del_suffix($name, ":bool")) {
|
|
$value = array_map([self::class, "tbool"], $value);
|
|
}
|
|
}
|
|
if (cl::has($query, $name)) {
|
|
A::ensure_array($query[$name]);
|
|
$query[$name][] = $value;
|
|
} else {
|
|
$query[$name] = $value;
|
|
}
|
|
}
|
|
if ($query !== null) array_unshift($margs, $query);
|
|
return $margs;
|
|
}
|
|
}
|