modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2024-06-23 21:58:54 +04:00
parent c2c7155f7e
commit c094eea62b
7 changed files with 151 additions and 107 deletions

View File

@ -22,17 +22,22 @@ Les syntaxes possibles sont:
`["class_or_function", $args...]` `["class_or_function", $args...]`
`[["class_or_function"], $args...]` `[["class_or_function"], $args...]`
`[["function", $args0...], $args1...]`
`[["class", null, $args0...], $args1...]`
: instantiation ou appel de fonction : instantiation ou appel de fonction
`["->method", $args...]` `["->method", $args...]`
`[["->method"], $args...]` `[["->method"], $args...]`
`[[null, "method"], $args...]` `[[null, "method"], $args...]`
`[[null, "method", $args0...], $args1...]`
: appel de méthode sur l'objet contexte spécifié lors de la résolution du contenu : appel de méthode sur l'objet contexte spécifié lors de la résolution du contenu
`[[$object, "method"], $args...]` `[[$object, "method"], $args...]`
`[[$object, "method", $args0...], $args1...]`
: appel de méthode sur l'objet spécifié : appel de méthode sur l'objet spécifié
`[["class", "method"], $args...]` `[["class", "method"], $args...]`
`[["class", "method", $args0...], $args1...]`
: appel de méthode statique de la classe spécifiée : appel de méthode statique de la classe spécifiée
Le fait de transformer un contenu en une liste de valeurs statiques s'appelle Le fait de transformer un contenu en une liste de valeurs statiques s'appelle

View File

@ -4,6 +4,7 @@ namespace nur\sery\php;
use Closure; use Closure;
use nur\sery\cl; use nur\sery\cl;
use nur\sery\ref\php\ref_func; use nur\sery\ref\php\ref_func;
use nur\sery\str;
use nur\sery\ValueException; use nur\sery\ValueException;
use ReflectionClass; use ReflectionClass;
use ReflectionFunction; use ReflectionFunction;
@ -11,15 +12,46 @@ use ReflectionMethod;
/** /**
* Class func: outils pour appeler des fonctions et méthodes dynamiquement * Class func: outils pour appeler des fonctions et méthodes dynamiquement
*
* Les formats supportés sont:
* - fonctions globales
* - "func" si function_exists("func")
* - [false, "func", ...]
* - méthodes statiques
* - "::method" méthode à lier à une classe avant l'appel
* - "class::method"
* - ["method"] si !class_exists("method")
* - [null, "method", ...] méthode à lier à une classe avant l'appel
* - ["class", "method", ...]
* - méthodes
* - "->method" méthode à lier à un objet avant l'appel
* - ["method"] si !class_exists("method")
* - [null, "method", ...] méthode à lier à un objet avant l'appel
* - [$object, "method", ...]
* - classes
* - "class" si !function_exists("class")
* - "class::"
* - ["class"] si class_exists("class")
* - ["class", null, ...]
*
* les formes "func" et "class" sont distinguées en vérifiant l'existence de la
* fonction
*
* les formes ["class"] et ["method"] sont distinguées en vérifiant l'existence
* de la classe
*/ */
class func { class func {
/** tester si $value est une chaine non vide */
private static function ne($value): bool {
return is_string($value) && strlen($value) > 0;
}
/** /**
* tester si $func est une chaine de la forme "XXX::method" XXX est une * tester si $func est d'une des formes suivantes:
* chaine quelconque éventuellement vide, ou un tableau de la forme ["method"] * - "::method"
* ou [anything, "method", ...] * - "class::method"
* * - ["method"] si !class_exists("method")
* Avec la forme tableau, "method" ne doit pas contenir le caractère '\', pour * - [anything, "method", ...]
* pouvoir utiliser conjointement {@link is_class()}
*/ */
static final function is_static($func, bool $allowClass=false): bool { static final function is_static($func, bool $allowClass=false): bool {
if (is_string($func)) { if (is_string($func)) {
@ -29,28 +61,21 @@ class func {
} elseif (is_array($func) && array_key_exists(0, $func)) { } elseif (is_array($func) && array_key_exists(0, $func)) {
$count = count($func); $count = count($func);
if ($count == 1) { if ($count == 1) {
if (!is_string($func[0]) || strlen($func[0]) == 0) return false; return self::ne($func[0]) && !class_exists($func[0]);
if (strpos($func[0], "\\") !== false) return false;
return true;
} elseif ($count > 1) { } elseif ($count > 1) {
if (!array_key_exists(1, $func)) return false; return array_key_exists(1, $func) && self::ne($func[1]);
if (!is_string($func[1]) || strlen($func[1]) == 0) return false;
if (strpos($func[1], "\\") !== false) return false;
return true;
} }
} }
return false; return false;
} }
/** /**
* si $func est une chaine de la forme "::method" alors la remplacer par la * en assumant que {@link self::is_static()} retourne true:
* - si $func est une chaine de la forme "::method" alors la remplacer par la
* chaine "$class::method" * chaine "$class::method"
* * - si $func est un tableau de la forme ["method"] ou [null, "method"], alors
* si $func est un tableau de la forme ["method"] ou [null, "method"], alors
* le remplacer par [$class, "method"] * le remplacer par [$class, "method"]
* *
* on assume que {@link is_static()}($func) retourne true
*
* @return bool true si la correction a été faite * @return bool true si la correction a été faite
*/ */
static final function fix_static(&$func, $class): bool { static final function fix_static(&$func, $class): bool {
@ -59,7 +84,7 @@ class func {
if (is_string($func) && substr($func, 0, 2) == "::") { if (is_string($func) && substr($func, 0, 2) == "::") {
$func = "$class$func"; $func = "$class$func";
return true; return true;
} elseif (is_array($func) && array_key_exists(0, $func)) { } else {
$count = count($func); $count = count($func);
if ($count == 1) { if ($count == 1) {
$func = [$class, $func[0]]; $func = [$class, $func[0]];
@ -73,37 +98,41 @@ class func {
} }
/** tester si $method est une chaine de la forme "->method" */ /** tester si $method est une chaine de la forme "->method" */
private static function isam($method): bool { private static function isam(&$method): bool {
return is_string($method) if (is_string($method)) {
&& strlen($method) > 2 if (substr($method, 0, 2) == "->") {
&& substr($method, 0, 2) == "->"; $method = substr($method, 2);
}
return strlen($method) > 0;
}
return false;
} }
/** /**
* tester si $func est une chaine de la forme "->method" ou un tableau de la * tester si $func est d'une des formes suivantes:
* forme ["->method", ...] ou [anything, "->method", ...] * - "->method"
* - ["method"] si !class_exists("method")
* - [anything, "method", ...]
*/ */
static final function is_method($func): bool { static final function is_method($func): bool {
if (is_string($func)) { if (is_string($func)) {
return self::isam($func); return self::isam($func);
} elseif (is_array($func) && array_key_exists(0, $func)) { } elseif (is_array($func) && array_key_exists(0, $func)) {
if (self::isam($func[0])) { $count = count($func);
# ["->method", ...] if ($count == 1) {
return true; return self::isam($func[0]) && !class_exists($func[0]);
} } elseif ($count > 1 && array_key_exists(1, $func)) {
if (array_key_exists(1, $func) && self::isam($func[1])) { return self::isam($func[1]);
# [anything, "->method", ...]
return true;
} }
} }
return false; return false;
} }
/** /**
* si $func est une chaine de la forme "->method" alors la remplacer par le * en assumant que {@link self::is_method()} retourne true:
* - si $func est une chaine de la forme "->method" alors la remplacer par le
* tableau [$object, "method"] * tableau [$object, "method"]
* * - si $func est un tableau de la forme ["method"] ou [anything, "method"],
* si $func est un tableau de la forme ["->method"] ou [anything, "->method"],
* alors le remplacer par [$object, "method"] * alors le remplacer par [$object, "method"]
* *
* @return bool true si la correction a été faite * @return bool true si la correction a été faite
@ -113,14 +142,18 @@ class func {
if (is_string($func)) { if (is_string($func)) {
if (self::isam($func)) { if (self::isam($func)) {
$func = [$object, substr($func, 2)]; $func = [$object, $func];
return true; return true;
} }
} elseif (is_array($func) && array_key_exists(0, $func)) { } else {
if (self::isam($func[0])) $func = array_merge([null], $func); $count = count($func);
if (count($func) > 1 && array_key_exists(1, $func) && self::isam($func[1])) { if ($count == 1) {
self::isam($func[0]);
$func = [$object, $func[0]];
return true;
} else {
$func[0] = $object; $func[0] = $object;
$func[1] = substr($func[1], 2); self::isam($func[1]);
return true; return true;
} }
} }
@ -356,29 +389,28 @@ class func {
} }
/** /**
* tester si $func est une chaine de la forme "XXX" XXX est une classe * tester si $class est d'une des formes suivantes:
* valide, ou un tableau de la forme ["XXX", ...] * - "class" si !function_exists("class")
* * - "class::"
* NB: il est possible d'avoir {@link is_static()} et {@link is_class()} * - ["class"] si class_exists("class")
* vraies pour la même valeur. s'il faut supporter les deux cas, appeler * - ["class", null, ...]
* {@link is_static()} d'abord, mais dans ce cas, on ne supporte que les
* classes qui sont dans un package
*/ */
static final function is_class($class): bool { static final function is_class($class): bool {
if (is_string($class)) { if (is_string($class)) {
return class_exists($class); return str::ends_with("::", $class)
|| !function_exists($class);
} elseif (is_array($class) && array_key_exists(0, $class)) { } elseif (is_array($class) && array_key_exists(0, $class)) {
return class_exists($class[0]); return class_exists($class[0])
|| (array_key_exists(1, $class) && $class[1] === null);
} }
return false; return false;
} }
/** /**
* en assumant que {@link is_class()} est vrai, si $class est un tableau de * si $class est un tableau de plus de 2 éléments, alors déplacer les éléments
* plus de 1 éléments, alors déplacer les éléments supplémentaires au début de * supplémentaires au début de $args. par exemple:
* $args. par exemple:
* ~~~ * ~~~
* $class = ["class", "arg1", "arg2"]; * $class = ["class", null, "arg1", "arg2"];
* $args = ["arg3"]; * $args = ["arg3"];
* func::fix_class_args($class, $args) * func::fix_class_args($class, $args)
* # $class === "class" * # $class === "class"
@ -390,8 +422,8 @@ class func {
static final function fix_class_args(&$class, ?array &$args): bool { static final function fix_class_args(&$class, ?array &$args): bool {
if ($args === null) $args = []; if ($args === null) $args = [];
if (is_array($class)) { if (is_array($class)) {
if (count($class) > 1) { if (count($class) > 2) {
$prefix_args = array_slice($class, 1); $prefix_args = array_slice($class, 2);
$class = array_slice($class, 0, 1)[0]; $class = array_slice($class, 0, 1)[0];
$args = array_merge($prefix_args, $args); $args = array_merge($prefix_args, $args);
} else { } else {

View File

@ -0,0 +1,35 @@
<?php
namespace nur\sery\wip\web\content;
use nur\sery\A;
use nur\sery\php\content\c;
use nur\sery\php\content\IContent;
class Tag implements IContent {
function __construct(string $tag, $content=null) {
$this->tag = $tag;
$content = c::q($content);
$this->content = $content;
}
protected string $tag;
protected iterable $content;
function add($content): self {
if (!is_array($this->content)) {
# si c'est un itérable, l'inclure avec un merge statique, afin de pouvoir
# rajouter des éléments
$this->content = [[[], $this->content]];
}
A::merge($this->content, c::q($content));
return $this;
}
function getContent($object_or_class=null): iterable {
return [
"<$this->tag>",
...c::resolve($this->content, $object_or_class),
"</$this->tag>",
];
}
}

View File

@ -5,4 +5,6 @@ namespace nur\sery\wip\web\content;
* Class v: classe outil pour gérer du contenu pour le web * Class v: classe outil pour gérer du contenu pour le web
*/ */
class v { class v {
static function h1($content): iterable { return (new Tag("h1", $content))->getContent(); }
const h1 = [Tag::class, null, "h1"];
} }

View File

@ -2,6 +2,7 @@
namespace nur\sery\php\content; namespace nur\sery\php\content;
use nur\sery\php\content\impl\html; use nur\sery\php\content\impl\html;
use nur\sery\wip\web\content\v;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class contentTest extends TestCase { class contentTest extends TestCase {
@ -30,5 +31,10 @@ class contentTest extends TestCase {
]], ]],
])); ]));
} }
function testXxx() {
$content = [[v::h1, "hello"]];
self::assertSame("<h1>hello</h1>", c::to_string($content));
}
} }

View File

@ -22,13 +22,14 @@ namespace nur\sery\php {
self::assertFalse(func::is_static("")); self::assertFalse(func::is_static(""));
self::assertFalse(func::is_static("::")); self::assertFalse(func::is_static("::"));
self::assertFalse(func::is_static("xxx::")); self::assertFalse(func::is_static("xxx::"));
self::assertTrue(func::is_static("::xxx"));
self::assertFalse(func::is_static([])); self::assertFalse(func::is_static([]));
self::assertFalse(func::is_static([""])); self::assertFalse(func::is_static([""]));
self::assertTrue(func::is_static(["xxx"]));
self::assertFalse(func::is_static([null, ""])); self::assertFalse(func::is_static([null, ""]));
self::assertTrue(func::is_static([null, "yyy"]));
self::assertFalse(func::is_static(["xxx", ""])); self::assertFalse(func::is_static(["xxx", ""]));
self::assertTrue(func::is_static("::xxx"));
self::assertTrue(func::is_static(["xxx"]));
self::assertTrue(func::is_static([null, "yyy"]));
self::assertTrue(func::is_static(["xxx", "yyy"])); self::assertTrue(func::is_static(["xxx", "yyy"]));
self::assertTrue(func::is_static([null, "yyy", "aaa"])); self::assertTrue(func::is_static([null, "yyy", "aaa"]));
self::assertTrue(func::is_static(["xxx", "yyy", "aaa"])); self::assertTrue(func::is_static(["xxx", "yyy", "aaa"]));
@ -36,33 +37,12 @@ namespace nur\sery\php {
function testFix_static() { function testFix_static() {
$class = "class"; $class = "class";
$func = null;
func::fix_static($func, $class);
self::assertSame(null, $func);
$func = "";
func::fix_static($func, $class);
self::assertSame("", $func);
$func = "::";
func::fix_static($func, $class);
self::assertSame("class::", $func);
$func = "xxx::";
func::fix_static($func, $class);
self::assertSame("xxx::", $func);
$func = "::xxx"; $func = "::xxx";
func::fix_static($func, $class); func::fix_static($func, $class);
self::assertSame("class::xxx", $func); self::assertSame("class::xxx", $func);
$func = [];
func::fix_static($func, $class);
self::assertSame([], $func);
$func = [""];
func::fix_static($func, $class);
self::assertSame(["class", ""], $func);
$func = ["xxx"]; $func = ["xxx"];
func::fix_static($func, $class); func::fix_static($func, $class);
self::assertSame(["class", "xxx"], $func); self::assertSame(["class", "xxx"], $func);
$func = ["xxx", ""];
func::fix_static($func, $class);
self::assertSame(["xxx", ""], $func);
$func = [null, "yyy"]; $func = [null, "yyy"];
func::fix_static($func, $class); func::fix_static($func, $class);
self::assertSame(["class", "yyy"], $func); self::assertSame(["class", "yyy"], $func);
@ -81,14 +61,14 @@ namespace nur\sery\php {
self::assertFalse(func::is_method(null)); self::assertFalse(func::is_method(null));
self::assertFalse(func::is_method("")); self::assertFalse(func::is_method(""));
self::assertFalse(func::is_method("->")); self::assertFalse(func::is_method("->"));
self::assertTrue(func::is_method("->xxx"));
self::assertFalse(func::is_method([])); self::assertFalse(func::is_method([]));
self::assertFalse(func::is_method([""])); self::assertFalse(func::is_method([""]));
self::assertTrue(func::is_method(["->xxx"]));
self::assertTrue(func::is_method(["->xxx", "aaa"]));
self::assertFalse(func::is_method([null, "->"])); self::assertFalse(func::is_method([null, "->"]));
self::assertTrue(func::is_method([null, "->yyy"]));
self::assertFalse(func::is_method(["xxx", "->"])); self::assertFalse(func::is_method(["xxx", "->"]));
self::assertTrue(func::is_method("->xxx"));
self::assertTrue(func::is_method(["->xxx"]));
self::assertTrue(func::is_method([null, "->yyy"]));
self::assertTrue(func::is_method(["xxx", "->yyy"])); self::assertTrue(func::is_method(["xxx", "->yyy"]));
self::assertTrue(func::is_method([null, "->yyy", "aaa"])); self::assertTrue(func::is_method([null, "->yyy", "aaa"]));
self::assertTrue(func::is_method(["xxx", "->yyy", "aaa"])); self::assertTrue(func::is_method(["xxx", "->yyy", "aaa"]));
@ -96,39 +76,15 @@ namespace nur\sery\php {
function testFix_method() { function testFix_method() {
$object = new \stdClass(); $object = new \stdClass();
$func= null;
func::fix_method($func, $object);
self::assertSame(null, $func);
$func= "";
func::fix_method($func, $object);
self::assertSame("", $func);
$func= "->";
func::fix_method($func, $object);
self::assertSame("->", $func);
$func= "->xxx"; $func= "->xxx";
func::fix_method($func, $object); func::fix_method($func, $object);
self::assertSame([$object, "xxx"], $func); self::assertSame([$object, "xxx"], $func);
$func= [];
func::fix_method($func, $object);
self::assertSame([], $func);
$func= [""];
func::fix_method($func, $object);
self::assertSame([""], $func);
$func= ["->xxx"]; $func= ["->xxx"];
func::fix_method($func, $object); func::fix_method($func, $object);
self::assertSame([$object, "xxx"], $func); self::assertSame([$object, "xxx"], $func);
$func= ["->xxx", "aaa"];
func::fix_method($func, $object);
self::assertSame([$object, "xxx", "aaa"], $func);
$func= [null, "->"];
func::fix_method($func, $object);
self::assertSame([null, "->"], $func);
$func= [null, "->yyy"]; $func= [null, "->yyy"];
func::fix_method($func, $object); func::fix_method($func, $object);
self::assertSame([$object, "yyy"], $func); self::assertSame([$object, "yyy"], $func);
$func= ["xxx", "->"];
func::fix_method($func, $object);
self::assertSame(["xxx", "->"], $func);
$func= ["xxx", "->yyy"]; $func= ["xxx", "->yyy"];
func::fix_method($func, $object); func::fix_method($func, $object);
self::assertSame([$object, "yyy"], $func); self::assertSame([$object, "yyy"], $func);

View File

@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase;
class uploadsTest extends TestCase { class uploadsTest extends TestCase {
const _FILES = [ const _FILES = [
# name="simple"
'simple' => [ 'simple' => [
'name' => '', 'name' => '',
'type' => '', 'type' => '',
@ -12,6 +13,7 @@ class uploadsTest extends TestCase {
'error' => 4, 'error' => 4,
'size' => 0, 'size' => 0,
], ],
# name=multiple[], name=multiple[]
'multiple' => [ 'multiple' => [
'name' => [ 'name' => [
0 => '', 0 => '',
@ -34,6 +36,7 @@ class uploadsTest extends TestCase {
1 => 0, 1 => 0,
], ],
], ],
# name=onelevel[a], name=onelevel[b]
'onelevel' => [ 'onelevel' => [
'name' => [ 'name' => [
'a' => '', 'a' => '',
@ -56,6 +59,7 @@ class uploadsTest extends TestCase {
'b' => 0, 'b' => 0,
], ],
], ],
# name=multiplelevel[a][], name=multiplelevel[a][], name=multiplelevel[b][], name=multiplelevel[b][]
'multiplelevel' => [ 'multiplelevel' => [
'name' => [ 'name' => [
'a' => [ 'a' => [
@ -111,6 +115,7 @@ class uploadsTest extends TestCase {
]; ];
const PARSED = [ const PARSED = [
# name="simple"
'simple' => [ 'simple' => [
'name' => '', 'name' => '',
'type' => '', 'type' => '',
@ -118,6 +123,7 @@ class uploadsTest extends TestCase {
'error' => 4, 'error' => 4,
'size' => 0, 'size' => 0,
], ],
# name=multiple[], name=multiple[]
'multiple' => [ 'multiple' => [
0 => [ 0 => [
'name' => '', 'name' => '',
@ -134,6 +140,7 @@ class uploadsTest extends TestCase {
'size' => 0, 'size' => 0,
], ],
], ],
# name=onelevel[a], name=onelevel[b]
'onelevel' => [ 'onelevel' => [
'a' => [ 'a' => [
'name' => '', 'name' => '',
@ -150,6 +157,7 @@ class uploadsTest extends TestCase {
'size' => 0, 'size' => 0,
], ],
], ],
# name=multiplelevel[a][], name=multiplelevel[a][], name=multiplelevel[b][], name=multiplelevel[b][]
'multiplelevel' => [ 'multiplelevel' => [
'a' => [ 'a' => [
0 => [ 0 => [