From c094eea62b03894d14bd3626b5e5b9d45b1a23f6 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Sun, 23 Jun 2024 21:58:54 +0400 Subject: [PATCH] modifs.mineures sans commentaires --- src/php/content/README.md | 5 ++ src/php/func.php | 142 ++++++++++++++++++------------ src/wip/web/content/Tag.php | 35 ++++++++ src/wip/web/content/v.php | 2 + tests/php/content/contentTest.php | 6 ++ tests/php/funcTest.php | 60 ++----------- tests/web/uploadsTest.php | 8 ++ 7 files changed, 151 insertions(+), 107 deletions(-) create mode 100644 src/wip/web/content/Tag.php diff --git a/src/php/content/README.md b/src/php/content/README.md index f6e7924..f455d35 100644 --- a/src/php/content/README.md +++ b/src/php/content/README.md @@ -22,17 +22,22 @@ Les syntaxes possibles sont: `["class_or_function", $args...]` `[["class_or_function"], $args...]` +`[["function", $args0...], $args1...]` +`[["class", null, $args0...], $args1...]` : instantiation ou appel de fonction `["->method", $args...]` `[["->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 `[[$object, "method"], $args...]` +`[[$object, "method", $args0...], $args1...]` : appel de méthode sur l'objet spécifié `[["class", "method"], $args...]` +`[["class", "method", $args0...], $args1...]` : 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 diff --git a/src/php/func.php b/src/php/func.php index 7a9a305..7b58074 100644 --- a/src/php/func.php +++ b/src/php/func.php @@ -4,6 +4,7 @@ namespace nur\sery\php; use Closure; use nur\sery\cl; use nur\sery\ref\php\ref_func; +use nur\sery\str; use nur\sery\ValueException; use ReflectionClass; use ReflectionFunction; @@ -11,15 +12,46 @@ use ReflectionMethod; /** * 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 { + /** 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" où XXX est une - * chaine quelconque éventuellement vide, ou un tableau de la forme ["method"] - * ou [anything, "method", ...] - * - * Avec la forme tableau, "method" ne doit pas contenir le caractère '\', pour - * pouvoir utiliser conjointement {@link is_class()} + * tester si $func est d'une des formes suivantes: + * - "::method" + * - "class::method" + * - ["method"] si !class_exists("method") + * - [anything, "method", ...] */ static final function is_static($func, bool $allowClass=false): bool { if (is_string($func)) { @@ -29,28 +61,21 @@ class func { } elseif (is_array($func) && array_key_exists(0, $func)) { $count = count($func); if ($count == 1) { - if (!is_string($func[0]) || strlen($func[0]) == 0) return false; - if (strpos($func[0], "\\") !== false) return false; - return true; + return self::ne($func[0]) && !class_exists($func[0]); } elseif ($count > 1) { - if (!array_key_exists(1, $func)) return false; - if (!is_string($func[1]) || strlen($func[1]) == 0) return false; - if (strpos($func[1], "\\") !== false) return false; - return true; + return array_key_exists(1, $func) && self::ne($func[1]); } } 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" - * - * 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"] * - * on assume que {@link is_static()}($func) retourne true - * * @return bool true si la correction a été faite */ static final function fix_static(&$func, $class): bool { @@ -59,7 +84,7 @@ class func { if (is_string($func) && substr($func, 0, 2) == "::") { $func = "$class$func"; return true; - } elseif (is_array($func) && array_key_exists(0, $func)) { + } else { $count = count($func); if ($count == 1) { $func = [$class, $func[0]]; @@ -73,37 +98,41 @@ class func { } /** tester si $method est une chaine de la forme "->method" */ - private static function isam($method): bool { - return is_string($method) - && strlen($method) > 2 - && substr($method, 0, 2) == "->"; + private static function isam(&$method): bool { + if (is_string($method)) { + if (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 - * forme ["->method", ...] ou [anything, "->method", ...] + * tester si $func est d'une des formes suivantes: + * - "->method" + * - ["method"] si !class_exists("method") + * - [anything, "method", ...] */ static final function is_method($func): bool { if (is_string($func)) { return self::isam($func); } elseif (is_array($func) && array_key_exists(0, $func)) { - if (self::isam($func[0])) { - # ["->method", ...] - return true; - } - if (array_key_exists(1, $func) && self::isam($func[1])) { - # [anything, "->method", ...] - return true; + $count = count($func); + if ($count == 1) { + return self::isam($func[0]) && !class_exists($func[0]); + } elseif ($count > 1 && array_key_exists(1, $func)) { + return self::isam($func[1]); } } 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"] - * - * 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"] * * @return bool true si la correction a été faite @@ -113,14 +142,18 @@ class func { if (is_string($func)) { if (self::isam($func)) { - $func = [$object, substr($func, 2)]; + $func = [$object, $func]; return true; } - } elseif (is_array($func) && array_key_exists(0, $func)) { - if (self::isam($func[0])) $func = array_merge([null], $func); - if (count($func) > 1 && array_key_exists(1, $func) && self::isam($func[1])) { + } else { + $count = count($func); + if ($count == 1) { + self::isam($func[0]); + $func = [$object, $func[0]]; + return true; + } else { $func[0] = $object; - $func[1] = substr($func[1], 2); + self::isam($func[1]); return true; } } @@ -356,29 +389,28 @@ class func { } /** - * tester si $func est une chaine de la forme "XXX" où XXX est une classe - * valide, ou un tableau de la forme ["XXX", ...] - * - * NB: il est possible d'avoir {@link is_static()} et {@link is_class()} - * vraies pour la même valeur. s'il faut supporter les deux cas, appeler - * {@link is_static()} d'abord, mais dans ce cas, on ne supporte que les - * classes qui sont dans un package + * tester si $class est d'une des formes suivantes: + * - "class" si !function_exists("class") + * - "class::" + * - ["class"] si class_exists("class") + * - ["class", null, ...] */ static final function is_class($class): bool { 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)) { - return class_exists($class[0]); + return class_exists($class[0]) + || (array_key_exists(1, $class) && $class[1] === null); } return false; } /** - * en assumant que {@link is_class()} est vrai, si $class est un tableau de - * plus de 1 éléments, alors déplacer les éléments supplémentaires au début de - * $args. par exemple: + * si $class est un tableau de plus de 2 éléments, alors déplacer les éléments + * supplémentaires au début de $args. par exemple: * ~~~ - * $class = ["class", "arg1", "arg2"]; + * $class = ["class", null, "arg1", "arg2"]; * $args = ["arg3"]; * func::fix_class_args($class, $args) * # $class === "class" @@ -390,8 +422,8 @@ class func { static final function fix_class_args(&$class, ?array &$args): bool { if ($args === null) $args = []; if (is_array($class)) { - if (count($class) > 1) { - $prefix_args = array_slice($class, 1); + if (count($class) > 2) { + $prefix_args = array_slice($class, 2); $class = array_slice($class, 0, 1)[0]; $args = array_merge($prefix_args, $args); } else { diff --git a/src/wip/web/content/Tag.php b/src/wip/web/content/Tag.php new file mode 100644 index 0000000..d7e8ea6 --- /dev/null +++ b/src/wip/web/content/Tag.php @@ -0,0 +1,35 @@ +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), + "tag>", + ]; + } +} diff --git a/src/wip/web/content/v.php b/src/wip/web/content/v.php index 57d4b83..60f393c 100644 --- a/src/wip/web/content/v.php +++ b/src/wip/web/content/v.php @@ -5,4 +5,6 @@ namespace nur\sery\wip\web\content; * Class v: classe outil pour gérer du contenu pour le web */ class v { + static function h1($content): iterable { return (new Tag("h1", $content))->getContent(); } + const h1 = [Tag::class, null, "h1"]; } diff --git a/tests/php/content/contentTest.php b/tests/php/content/contentTest.php index 4b98387..168c5fc 100644 --- a/tests/php/content/contentTest.php +++ b/tests/php/content/contentTest.php @@ -2,6 +2,7 @@ namespace nur\sery\php\content; use nur\sery\php\content\impl\html; +use nur\sery\wip\web\content\v; use PHPUnit\Framework\TestCase; class contentTest extends TestCase { @@ -30,5 +31,10 @@ class contentTest extends TestCase { ]], ])); } + + function testXxx() { + $content = [[v::h1, "hello"]]; + self::assertSame("

hello

", c::to_string($content)); + } } diff --git a/tests/php/funcTest.php b/tests/php/funcTest.php index 9096a79..3ddf2aa 100644 --- a/tests/php/funcTest.php +++ b/tests/php/funcTest.php @@ -22,13 +22,14 @@ namespace nur\sery\php { self::assertFalse(func::is_static("")); self::assertFalse(func::is_static("::")); self::assertFalse(func::is_static("xxx::")); - self::assertTrue(func::is_static("::xxx")); self::assertFalse(func::is_static([])); self::assertFalse(func::is_static([""])); - self::assertTrue(func::is_static(["xxx"])); self::assertFalse(func::is_static([null, ""])); - self::assertTrue(func::is_static([null, "yyy"])); 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([null, "yyy", "aaa"])); self::assertTrue(func::is_static(["xxx", "yyy", "aaa"])); @@ -36,33 +37,12 @@ namespace nur\sery\php { function testFix_static() { $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::fix_static($func, $class); 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::fix_static($func, $class); self::assertSame(["class", "xxx"], $func); - $func = ["xxx", ""]; - func::fix_static($func, $class); - self::assertSame(["xxx", ""], $func); $func = [null, "yyy"]; func::fix_static($func, $class); self::assertSame(["class", "yyy"], $func); @@ -81,14 +61,14 @@ namespace nur\sery\php { self::assertFalse(func::is_method(null)); 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::assertTrue(func::is_method(["->xxx"])); - self::assertTrue(func::is_method(["->xxx", "aaa"])); self::assertFalse(func::is_method([null, "->"])); - self::assertTrue(func::is_method([null, "->yyy"])); 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([null, "->yyy", "aaa"])); self::assertTrue(func::is_method(["xxx", "->yyy", "aaa"])); @@ -96,39 +76,15 @@ namespace nur\sery\php { function testFix_method() { $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::fix_method($func, $object); 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::fix_method($func, $object); 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::fix_method($func, $object); self::assertSame([$object, "yyy"], $func); - $func= ["xxx", "->"]; - func::fix_method($func, $object); - self::assertSame(["xxx", "->"], $func); $func= ["xxx", "->yyy"]; func::fix_method($func, $object); self::assertSame([$object, "yyy"], $func); diff --git a/tests/web/uploadsTest.php b/tests/web/uploadsTest.php index 52d56f0..73b425b 100644 --- a/tests/web/uploadsTest.php +++ b/tests/web/uploadsTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; class uploadsTest extends TestCase { const _FILES = [ + # name="simple" 'simple' => [ 'name' => '', 'type' => '', @@ -12,6 +13,7 @@ class uploadsTest extends TestCase { 'error' => 4, 'size' => 0, ], + # name=multiple[], name=multiple[] 'multiple' => [ 'name' => [ 0 => '', @@ -34,6 +36,7 @@ class uploadsTest extends TestCase { 1 => 0, ], ], + # name=onelevel[a], name=onelevel[b] 'onelevel' => [ 'name' => [ 'a' => '', @@ -56,6 +59,7 @@ class uploadsTest extends TestCase { 'b' => 0, ], ], + # name=multiplelevel[a][], name=multiplelevel[a][], name=multiplelevel[b][], name=multiplelevel[b][] 'multiplelevel' => [ 'name' => [ 'a' => [ @@ -111,6 +115,7 @@ class uploadsTest extends TestCase { ]; const PARSED = [ + # name="simple" 'simple' => [ 'name' => '', 'type' => '', @@ -118,6 +123,7 @@ class uploadsTest extends TestCase { 'error' => 4, 'size' => 0, ], + # name=multiple[], name=multiple[] 'multiple' => [ 0 => [ 'name' => '', @@ -134,6 +140,7 @@ class uploadsTest extends TestCase { 'size' => 0, ], ], + # name=onelevel[a], name=onelevel[b] 'onelevel' => [ 'a' => [ 'name' => '', @@ -150,6 +157,7 @@ class uploadsTest extends TestCase { 'size' => 0, ], ], + # name=multiplelevel[a][], name=multiplelevel[a][], name=multiplelevel[b][], name=multiplelevel[b][] 'multiplelevel' => [ 'a' => [ 0 => [