diff --git a/src/php/content/README.md b/src/php/content/README.md index d7e6b8e..44341ba 100644 --- a/src/php/content/README.md +++ b/src/php/content/README.md @@ -1,8 +1,3 @@ -# TODO - -* [ ] supporter les instances de Closure comme éléments de contenu: elle - retournent du contenu sous forme d'iterable (comme IContent) - # nulib\php\content un contenu est une liste de valeurs, avec une syntaxe pour que certains éléments @@ -15,15 +10,17 @@ le contenu final est résolu selon les règles suivantes: - Sinon, le contenu doit être un tableau, séquentiel ou associatif, ça n'a pas d'incidence - les éléments scalaires ou instance d'objets sont pris tels quels + - les Closure sont appelés dès la résolution, et leur valeur de retour est + considéré comme un contenu statique inséré tel quel dans le flux - les tableaux représentent un traitement dynamique: appel de fonction, - instanciation, etc. + instanciation, etc. le contenu effectif n'est évalué que lors de l'affichage Les syntaxes possibles sont: `[[], $args...]` -: merge littéral: les valeurs $args... sont insérées dans le - flux du contenu sans modification. c'est la seule façon d'insérer un tableau - dans la liste des valeurs +: contenu statique: les valeurs $args... sont insérées dans le flux du contenu + sans modification. c'est la seule façon d'insérer un tableau dans la liste des + valeurs `["class_or_function", $args...]` `[["class_or_function"], $args...]` diff --git a/src/php/content/c.php b/src/php/content/c.php index 351f915..ec18aeb 100644 --- a/src/php/content/c.php +++ b/src/php/content/c.php @@ -1,6 +1,7 @@ $svalue) { + if ($skey === $sindex) { + $sindex++; + if ($seq) { + $dest[] = $svalue; + } else { + # la première sous-clé séquentielle est ajoutée avec la clé du + # merge statique + $dest[$key] = $svalue; + $seq = true; + } + } else { + $dest[$skey] = $svalue; + } + } + + } + /** résoudre le contenu, et retourner la liste des valeurs */ static final function resolve($content, $object_or_class=null, bool $quote=true, ?array &$dest=null): array { if ($dest === null) $dest = []; @@ -37,6 +58,15 @@ class c { } else { $seq = false; } + if ($value instanceof Closure) { + # contenu dynamique: le contenu est la valeur de retour de la fonction + # ce contenu est rajouté à la suite après avoir été quoté avec self::q() + $func = $value; + func::ensure_func($func, $object_or_class, $args); + $values = self::q(func::call($func, ...$args)); + self::add_static_content($dest, $values, $key, $seq); + continue; + } if (is_array($value)) { # contenu dynamique if (count($value) == 0) continue; @@ -44,25 +74,10 @@ class c { $args = array_slice($value, 1); if ($func === []) { # merge statique - $sindex = 0; - foreach ($args as $skey => $arg) { - if ($skey === $sindex) { - $sindex++; - if ($seq) { - $dest[] = $arg; - } else { - # la première sous-clé séquentielle est ajoutée avec la clé du - # merge statique - $dest[$key] = $arg; - $seq = true; - } - } else { - $dest[$skey] = $arg; - } - } + self::add_static_content($dest, $args, $key, $seq); continue; } else { - # chaque argument est aussi un contenu + # chaque argument de la fonction à appeler est aussi un contenu foreach ($args as &$arg) { $array = is_array($arg); $arg = self::resolve($arg, $object_or_class, false); diff --git a/tests/php/content/contentTest.php b/tests/php/content/cTest.php similarity index 97% rename from tests/php/content/contentTest.php rename to tests/php/content/cTest.php index 168c5fc..7ec292e 100644 --- a/tests/php/content/contentTest.php +++ b/tests/php/content/cTest.php @@ -5,7 +5,7 @@ use nur\sery\php\content\impl\html; use nur\sery\wip\web\content\v; use PHPUnit\Framework\TestCase; -class contentTest extends TestCase { +class cTest extends TestCase { function testTo_string() { self::assertSame("", c::to_string(null)); self::assertSame("", c::to_string(false));