$max_level) { throw new Exception("$level: level not allowed here"); } return $level; } /** @var StdOutput la sortie standard */ protected StdOutput $out; /** @var int level par défaut dans lequel les messages sont affichés */ protected int $defaultLevel; /** @var int level minimum que doivent avoir les messages pour être affichés */ protected int $minLevel; /** @var bool faut-il ajouter la date à chaque ligne? */ protected bool $addDate; /** @var string format de la date */ protected string $dateFormat; /** @var bool faut-il afficher les ids (p=id t=id a=id) */ protected bool $showIds; /** @var ?string identifiant de ce messenger, à ajouter à chaque ligne */ protected ?string $id; protected int $lastTitleId = 1; protected abstract function title__getId(): ?int; protected int $lastActionId = 1; protected abstract function action__getId(): ?int; protected function getLinePrefix(): ?string { $linePrefix = null; if ($this->addDate) { $date = date_create()->format($this->dateFormat); $linePrefix .= "$date "; } if ($this->showIds) { if ($this->id !== null) $linePrefix .= "p=$this->id "; $titleId = $this->title__getId(); if ($titleId !== null) $linePrefix .= "t=$titleId "; $actionId = $this->action__getId(); if ($actionId !== null) $linePrefix .= "a=$actionId "; } return $linePrefix; } protected function decrLevel(int $level, int $amount=-1): int { $level += $amount; if ($level < self::MIN_LEVEL) $level = self::MIN_LEVEL; return $level; } protected function checkLevel(?int &$level): bool { if ($level === null) $level = $this->defaultLevel; elseif ($level < 0) $level = $this->decrLevel($this->defaultLevel, $level); return $level >= $this->minLevel; } protected function _printTitle( int $level, string $type, ?string $linePrefix, int $indentLevel, StdOutput $out, $content ): void { $prefixes = self::GENERIC_PREFIXES[$level][$type]; if ($prefixes[0]) $out->print(); $content = cl::with($content); if ($out->isColor()) { $before = $prefixes[2]; $prefix = $prefixes[3]; $prefix2 = $prefix !== null? "$prefix ": null; $suffix = $prefixes[4]; $suffix2 = $suffix !== null? " $suffix": null; $after = $prefixes[5]; $lines = $out->getLines(false, ...$content); $maxlen = 0; foreach ($lines as &$content) { $line = $out->filterColors($content); $len = mb_strlen($line); if ($len > $maxlen) $maxlen = $len; $content = [$content, $len]; }; unset($content); if ($before !== null) { if ($linePrefix !== null) $out->write($linePrefix); $out->iprint($indentLevel, $prefix, substr($before, 1), str_repeat($before[0], $maxlen), $suffix); } foreach ($lines as [$content, $len]) { if ($linePrefix !== null) $out->write($linePrefix); $padding = $len < $maxlen? str_repeat(" ", $maxlen - $len): null; $out->iprint($indentLevel, $prefix2, $content, $padding, $suffix2); } if ($after !== null) { if ($linePrefix !== null) $out->write($linePrefix); $out->iprint($indentLevel, $prefix, substr($after, 1), str_repeat($after[0], $maxlen), $suffix); } } else { $prefix = $prefixes[1]; if ($prefix !== null) $prefix .= " "; $prefix2 = str_repeat(" ", mb_strlen($prefix)); $lines = $out->getLines(false, ...$content); foreach ($lines as $content) { if ($linePrefix !== null) $out->write($linePrefix); $out->iprint($indentLevel, $prefix, $content); $prefix = $prefix2; } } } protected abstract function action__flush(bool $endAction=false, ?int $overrideLevel=null): void; protected function _printAction( int $level, ?string $linePrefix, int $indentLevel, StdOutput $out, bool $printContent, $content, bool $printResult, ?bool $rsuccess, $rcontent ): void { $color = $out->isColor(); if ($rsuccess === true) $type = "success"; elseif ($rsuccess === false) $type = "failure"; else $type = "done"; $rprefixes = self::RESULT_PREFIXES[$type]; if ($color) { $rprefix = $rprefixes[1]; $rprefix2 = null; if ($rprefix !== null) { $rprefix .= " "; $rprefix2 = $out->filterColors($out->filterContent($rprefix)); $rprefix2 = str_repeat(" ", mb_strlen($rprefix2)); } } else { $rprefix = $rprefixes[0]; if ($rprefix !== null) $rprefix .= " "; $rprefix2 = str_repeat(" ", mb_strlen($rprefix)); } if ($printContent && $printResult) { A::ensure_array($content); if ($rcontent) { $content[] = ": "; $content[] = $rcontent; } $lines = $out->getLines(false, ...$content); foreach ($lines as $content) { if ($linePrefix !== null) $out->write($linePrefix); $out->iprint($indentLevel, $rprefix, $content); $rprefix = $rprefix2; } } elseif ($printContent) { $prefixes = self::GENERIC_PREFIXES[$level]["step"]; if ($color) { $prefix = $prefixes[1]; if ($prefix !== null) $prefix .= " "; $prefix2 = $out->filterColors($out->filterContent($prefix)); $prefix2 = str_repeat(" ", mb_strlen($prefix2)); $suffix = $prefixes[2]; } else { $prefix = $prefixes[0]; if ($prefix !== null) $prefix .= " "; $prefix2 = str_repeat(" ", mb_strlen($prefix)); $suffix = null; } A::ensure_array($content); $content[] = ":"; $lines = $out->getLines(false, ...$content); foreach ($lines as $content) { if ($linePrefix !== null) $out->write($linePrefix); $out->iprint($indentLevel, $prefix, $content, $suffix); $prefix = $prefix2; } } elseif ($printResult) { if (!$rcontent) { if ($type === "success") $rcontent = $color? "succès": ""; elseif ($type === "failure") $rcontent = $color? "échec": ""; elseif ($type === "done") $rcontent = "fait"; } $rprefix = " $rprefix"; $rprefix2 = " $rprefix2"; $lines = $out->getLines(false, $rcontent); foreach ($lines as $rcontent) { if ($linePrefix !== null) $out->write($linePrefix); $out->iprint($indentLevel, $rprefix, $rcontent); $rprefix = $rprefix2; } } } protected function _printGeneric( int $level, string $type, ?string $linePrefix, int $indentLevel, StdOutput $out, $content ): void { $prefixes = self::GENERIC_PREFIXES[$level][$type]; $content = cl::with($content); if ($out->isColor()) { $prefix = $prefixes[1]; $prefix2 = null; if ($prefix !== null) { $prefix .= " "; $prefix2 = $out->filterColors($out->filterContent($prefix)); $prefix2 = str_repeat(" ", mb_strlen($prefix2)); } $suffix = $prefixes[2]; $lines = $out->getLines(false, ...$content); foreach ($lines as $content) { if ($linePrefix !== null) $out->write($linePrefix); $out->iprint($indentLevel, $prefix, $content, $suffix); $prefix = $prefix2; } } else { $prefix = $prefixes[0]; if ($prefix !== null) $prefix .= " "; $prefix2 = str_repeat(" ", mb_strlen($prefix)); $lines = $out->getLines(false, ...$content); foreach ($lines as $content) { if ($linePrefix !== null) $out->write($linePrefix); $out->iprint($indentLevel, $prefix, $content); $prefix = $prefix2; } } } protected function _printGenericOrException( ?int $level, string $type, int $indentLevel, StdOutput $out, $content ): void { $linePrefix = $this->getLinePrefix(); # si $content contient des exceptions, les afficher avec un level moindre $exceptions = null; if (is_array($content)) { $valueContent = null; foreach ($content as $value) { if ($value instanceof Throwable || $value instanceof ExceptionShadow) { $exceptions[] = $value; } else { $valueContent[] = $value; } } if ($valueContent === null) $content = null; elseif (count($valueContent) == 1) $content = $valueContent[0]; else $content = $valueContent; } elseif ($content instanceof Throwable || $content instanceof ExceptionShadow) { $exceptions[] = $content; $content = null; } $flushActions = true; $showContent = $this->checkLevel($level); if ($content !== null && $showContent) { $this->action__flush(); $flushActions = false; $this->_printGeneric($level, $type, $linePrefix, $indentLevel, $out, $content); } if ($exceptions !== null) { $level1 = $this->decrLevel($level); $showTraceback = $this->checkLevel($level1); foreach ($exceptions as $exception) { # tout d'abord message $message = exceptions::get_message($exception); if ($showContent) { if ($flushActions) { $this->action__flush(); $flushActions = false; } $this->_printGeneric($level, $type, $linePrefix, $indentLevel, $out, $message); } # puis summary et traceback if ($showTraceback) { if ($flushActions) { $this->action__flush(); $flushActions = false; } $summary = exceptions::get_summary($exception, false); $this->_printGeneric($level1, $type, $linePrefix, $indentLevel, $out, $summary); $traceback = exceptions::get_traceback($exception); $this->_printGeneric($level1, $type, $linePrefix, $indentLevel, $out, $traceback); } } } } }