getContent(); } elseif ($contents instanceof IPrintable) { ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE); $contents->print(); $dest[] = ob_get_clean(); return $dest; } elseif (is_scalar($contents)) { $dest[] = $contents; return $dest; } elseif (!is_iterable($contents)) { $dest[] = strval($contents); return $dest; } # sinon parcourir $contents foreach ($contents as $value) { if ($value === null) continue; elseif (is_scalar($value)) $dest[] = $value; else self::flatten($value, $dest); } return $dest; } /** * résoudre tout le contenu statique: il ne restera plus qu'une liste de * chaines ou d'instances de IContent, IPrintable ou des objets quelconques */ static function resolve_static($contents, $dest_class=null, bool $quote=true, ?array &$dest=null): array { if ($dest === null) $dest = []; if ($contents === null) return $dest; if (is_string($contents)) { if ($quote) $contents = htmlspecialchars($contents); $dest[] = $contents; return $dest; } elseif ($contents instanceof IStaticContent) { $contents = $contents->getContent(); $dest = cl::merge($dest, self::resolve_static($contents, $dest_class, false)); return $dest; } elseif ($contents instanceof IContent) { $dest[] = $contents; return $dest; } elseif ($contents instanceof IPrintable) { $dest[] = $contents; return $dest; } elseif (!is_iterable($contents)) { $dest[] = $contents; return $dest; } foreach ($contents as $content) { if ($content === null) continue; elseif ($contents instanceof IStaticContent) { $contents = $content->getContent(); $dest = cl::merge($dest, self::resolve_static($contents, $dest_class, false)); } elseif ($contents instanceof IContent) $dest[] = $content; elseif ($contents instanceof IPrintable) $dest[] = $content; elseif (!is_array($content)) $dest[] = $content; else { # ici, $content est soit: # - un appel de fonction ou méthode statique d'une des formes suivantes: # - [class, method, ...args] # - [null, method, ...args] # - [[class, method], ...args] # - [[null, method], ...args] # - ou une définition d'objet d'une des formes suivantes # - [class, ...args] # - [[class], ...args] $func_isa_class = false; if (array_key_exists(0, $content) && is_array($content[0])) { # $content est de la forme [func_or_class, ...args] $func = $content[0]; $args = array_slice($content, 1); if (func::is_static($func)) { func::ensure_func($func, $dest_class, $args); } elseif (func::is_class($func)) { $func_isa_class = true; func::fix_class_args($func, $args); } else { func::ensure_func($func, $dest_class, $args); } } else { # $content est de la forme $func $func = $content; if (func::is_static($func)) { func::ensure_func($func, $dest_class, $args); } elseif (func::is_class($func)) { $func_isa_class = true; func::fix_class_args($func, $args); } else { func::ensure_func($func, $dest_class, $args); } } # chaque argument est un contenu statique foreach ($args as &$arg) { $array = is_array($arg); $arg = self::resolve_static($arg, $dest_class, false); $arg = self::flatten($arg); if ($array) { $arg = [implode("", $arg)]; } else { switch (count($arg)) { case 0: $arg = null; break; case 1: $arg = $arg[0]; break; default: $arg = implode("", $arg); } } }; unset($arg); # puis appeler la fonction if ($func_isa_class) $content = func::cons($func, ...$args); else $content = func::call($func, ...$args); $dest[] = $content; } } return $dest; } static function to_string($contents, $dest_class=null, bool $quote=true): string { return implode("", self::flatten(self::resolve_static($contents, $dest_class, $quote))); } }