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), + "$this->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("