début réorganisation log

This commit is contained in:
Jephté Clain 2025-10-15 12:13:49 +04:00
parent 51215b42eb
commit 55728059cf
10 changed files with 326 additions and 224 deletions

View File

@ -17,6 +17,21 @@
</DockerContainerSettings> </DockerContainerSettings>
</value> </value>
</entry> </entry>
<entry key="385aa179-8c50-45e2-9ad7-4d9bfba298a3">
<value>
<DockerContainerSettings>
<option name="version" value="1" />
<option name="volumeBindings">
<list>
<DockerVolumeBindingImpl>
<option name="containerPath" value="/opt/project" />
<option name="hostPath" value="$PROJECT_DIR$" />
</DockerVolumeBindingImpl>
</list>
</option>
</DockerContainerSettings>
</value>
</entry>
<entry key="38915385-b3ff-4f4b-8a9a-d5f3ecae559e"> <entry key="38915385-b3ff-4f4b-8a9a-d5f3ecae559e">
<value> <value>
<DockerContainerSettings> <DockerContainerSettings>

4
.idea/php.xml generated
View File

@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="MessDetector"> <component name="MessDetector">
<phpmd_settings> <phpmd_settings>
<phpmd_by_interpreter asDefaultInterpreter="true" interpreter_id="846389f7-9fb5-4173-a868-1dc6b8fbb3fa" timeout="30000" /> <phpmd_by_interpreter asDefaultInterpreter="true" interpreter_id="38915385-b3ff-4f4b-8a9a-d5f3ecae559e" timeout="30000" />
</phpmd_settings> </phpmd_settings>
</component> </component>
<component name="MessDetectorOptionsConfiguration"> <component name="MessDetectorOptionsConfiguration">
@ -17,7 +17,7 @@
</component> </component>
<component name="PhpCodeSniffer"> <component name="PhpCodeSniffer">
<phpcs_settings> <phpcs_settings>
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="846389f7-9fb5-4173-a868-1dc6b8fbb3fa" timeout="30000" /> <phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="38915385-b3ff-4f4b-8a9a-d5f3ecae559e" timeout="30000" />
</phpcs_settings> </phpcs_settings>
</component> </component>
<component name="PhpIncludePathManager"> <component name="PhpIncludePathManager">

View File

@ -11,9 +11,14 @@ trait _TMessenger {
static function set_messenger(IMessenger $msg, bool $replace=false): IMessenger { static function set_messenger(IMessenger $msg, bool $replace=false): IMessenger {
if (self::$msg instanceof NullMessenger) self::$msg = null; if (self::$msg instanceof NullMessenger) self::$msg = null;
if ($replace || self::$msg === null) return self::$msg = $msg; if ($replace || self::$msg === null) {
elseif (self::$msg instanceof ProxyMessenger) self::$msg->addMessenger($msg); return self::$msg = $msg;
else self::$msg = new ProxyMessenger(self::$msg); } elseif (self::$msg instanceof ProxyMessenger) {
self::$msg->addMessenger($msg);
} else {
self::$msg = new ProxyMessenger(self::$msg);
self::$msg->addMessenger($msg);
}
return $msg; return $msg;
} }

View File

@ -49,8 +49,12 @@ abstract class AbstractMessenger implements _IMessenger {
protected int $lastTitleId = 1; protected int $lastTitleId = 1;
protected abstract function title__getId(): ?int;
protected int $lastActionId = 1; protected int $lastActionId = 1;
protected abstract function action__getId(): ?int;
protected function getLinePrefix(): ?string { protected function getLinePrefix(): ?string {
$linePrefix = null; $linePrefix = null;
if ($this->addDate) { if ($this->addDate) {
@ -59,9 +63,9 @@ abstract class AbstractMessenger implements _IMessenger {
} }
if ($this->showIds) { if ($this->showIds) {
if ($this->id !== null) $linePrefix .= "p=$this->id "; if ($this->id !== null) $linePrefix .= "p=$this->id ";
$titleId = $this->_getTitleId(); $titleId = $this->title__getId();
if ($titleId !== null) $linePrefix .= "t=$titleId "; if ($titleId !== null) $linePrefix .= "t=$titleId ";
$actionId = $this->_getActionId(); $actionId = $this->action__getId();
if ($actionId !== null) $linePrefix .= "a=$actionId "; if ($actionId !== null) $linePrefix .= "a=$actionId ";
} }
return $linePrefix; return $linePrefix;
@ -129,7 +133,7 @@ abstract class AbstractMessenger implements _IMessenger {
} }
} }
protected abstract function flushActions(bool $endAction=false, ?int $overrideLevel=null): void; protected abstract function action__flush(bool $endAction=false, ?int $overrideLevel=null): void;
protected function _printAction( protected function _printAction(
?string $linePrefix, int $level, ?string $linePrefix, int $level,
@ -269,7 +273,7 @@ abstract class AbstractMessenger implements _IMessenger {
$flushActions = true; $flushActions = true;
$showContent = $this->checkLevel($level); $showContent = $this->checkLevel($level);
if ($content !== null && $showContent) { if ($content !== null && $showContent) {
$this->flushActions(); $flushActions = false; $this->action__flush(); $flushActions = false;
$this->_printGeneric($linePrefix, $level, $type, $content, $indentLevel, $out); $this->_printGeneric($linePrefix, $level, $type, $content, $indentLevel, $out);
} }
if ($exceptions !== null) { if ($exceptions !== null) {
@ -279,12 +283,12 @@ abstract class AbstractMessenger implements _IMessenger {
# tout d'abord message # tout d'abord message
$message = exceptions::get_message($exception); $message = exceptions::get_message($exception);
if ($showContent) { if ($showContent) {
if ($flushActions) { $this->flushActions(); $flushActions = false; } if ($flushActions) { $this->action__flush(); $flushActions = false; }
$this->_printGeneric($linePrefix, $level, $type, $message, $indentLevel, $out); $this->_printGeneric($linePrefix, $level, $type, $message, $indentLevel, $out);
} }
# puis summary et traceback # puis summary et traceback
if ($showTraceback) { if ($showTraceback) {
if ($flushActions) { $this->flushActions(); $flushActions = false; } if ($flushActions) { $this->action__flush(); $flushActions = false; }
$summary = exceptions::get_summary($exception, false); $summary = exceptions::get_summary($exception, false);
$this->_printGeneric($linePrefix, $level1, $type, $summary, $indentLevel, $out); $this->_printGeneric($linePrefix, $level1, $type, $summary, $indentLevel, $out);
$traceback = exceptions::get_traceback($exception); $traceback = exceptions::get_traceback($exception);

View File

@ -108,8 +108,19 @@ class ConsoleMessenger extends AbstractMessenger {
/** @var array section qui est en attente d'affichage */ /** @var array section qui est en attente d'affichage */
protected ?array $section; protected ?array $section;
protected function section__end(): void {
while ($this->actions) $this->adone();
while ($this->titles) $this->title__end();
$this->inSection = false;
$this->section = null;
}
function section__afterFunc(): void {
$this->section__end();
}
function section($content, ?callable $func=null, ?int $level=null): void { function section($content, ?callable $func=null, ?int $level=null): void {
$this->_endSection(); $this->section__end();
$this->inSection = true; $this->inSection = true;
if (!$this->checkLevel($level)) return; if (!$this->checkLevel($level)) return;
$this->section = [ $this->section = [
@ -122,7 +133,7 @@ class ConsoleMessenger extends AbstractMessenger {
try { try {
$func($this); $func($this);
} finally { } finally {
$this->_endSection(); $this->section__afterFunc();
} }
} }
} }
@ -138,13 +149,6 @@ class ConsoleMessenger extends AbstractMessenger {
} }
} }
function _endSection(): void {
while ($this->actions) $this->adone();
while ($this->titles) $this->_endTitle();
$this->inSection = false;
$this->section = null;
}
protected function getIndentLevel(bool $withActions=true): int { protected function getIndentLevel(bool $withActions=true): int {
$indentLevel = count($this->titles) - 1; $indentLevel = count($this->titles) - 1;
if ($indentLevel < 0) $indentLevel = 0; if ($indentLevel < 0) $indentLevel = 0;
@ -159,63 +163,26 @@ class ConsoleMessenger extends AbstractMessenger {
protected array $titles; protected array $titles;
function _getTitleMark(): int { function title__getMarks(): array {
return count($this->titles); return [count($this->titles)];
} }
function _getTitleId(): ?int { protected function title__getId(): ?int {
return end($this->titles)["id"] ?? null; return end($this->titles)["id"] ?? null;
} }
function title($content, ?callable $func=null, ?int $level=null): void { protected function title__end(?int $until=null): void {
if (!$this->checkLevel($level)) return; $title = $this->titles[array_key_last($this->titles)] ?? null;
$titleLevel = $this->_getTitleMark(); if ($title !== null) {
// faire en deux temps pour linePrefix soit à jour $until ??= $title["max_title_level"];
$this->titles[] = ["id" => $this->lastTitleId++]; $until ??= $this->title__getMarks()[0] - 1;
A::merge($this->titles[array_key_last($this->titles)], [ while (count($this->titles) > $until) {
"title_level" => $titleLevel, array_pop($this->titles);
"max_title_level" => null,
"line_prefix" => $this->getLinePrefix(),
"level" => $level,
"content" => $content,
"print_content" => true,
"descs" => [],
"print_descs" => false,
]);
if ($func !== null) {
try {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = $titleLevel + 1;
$func($this);
} finally {
$title["max_title_level"] = null;
$this->_endTitle($titleLevel);
} }
} }
} }
function desc($content, ?int $level=null): void { protected function title__flush(): void {
if (!$this->checkLevel($level)) return;
$desc = [
"line_prefix" => $this->getLinePrefix(),
"level" => $level,
"content" => $content,
];
$key = array_key_last($this->titles);
if ($key !== null) {
$title =& $this->titles[$key];
$title["descs"][] = $desc;
$title["print_descs"] = true;
} else {
# pas de titre en cours
$this->_printGeneric(
$desc["line_prefix"], $desc["level"],
"desc", $desc["content"],
0, $this->err);
}
}
protected function flushTitles(): void {
$this->printSection(); $this->printSection();
$err = $this->err; $err = $this->err;
$indentLevel = 0; $indentLevel = 0;
@ -241,29 +208,86 @@ class ConsoleMessenger extends AbstractMessenger {
}; unset($title); }; unset($title);
} }
function _endTitle(?int $until=null): void { function title__beforeFunc(array $marks): void {
$title = $this->titles[array_key_last($this->titles)] ?? null; $title =& $this->titles[array_key_last($this->titles)];
if ($title !== null) { $title["max_title_level"] = $marks[0] + 1;
$until ??= $title["max_title_level"]; }
$until ??= $this->_getTitleMark() - 1;
while (count($this->titles) > $until) { function title__afterFunc(array $marks): void {
array_pop($this->titles); $title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = null;
$this->title__end($marks[0]);
}
function title($content, ?callable $func=null, ?int $level=null): void {
if (!$this->checkLevel($level)) return;
$marks = $this->title__getMarks();
// faire en deux temps pour linePrefix soit à jour
$this->titles[] = ["id" => $this->lastTitleId++];
A::merge($this->titles[array_key_last($this->titles)], [
"title_level" => $marks[0],
"max_title_level" => null,
"line_prefix" => $this->getLinePrefix(),
"level" => $level,
"content" => $content,
"print_content" => true,
"descs" => [],
"print_descs" => false,
]);
if ($func !== null) {
try {
$this->title__beforeFunc($marks);
$func($this);
} finally {
$this->title__afterFunc($marks);
} }
} }
} }
function desc($content, ?int $level=null): void {
if (!$this->checkLevel($level)) return;
$desc = [
"line_prefix" => $this->getLinePrefix(),
"level" => $level,
"content" => $content,
];
$key = array_key_last($this->titles);
if ($key !== null) {
$title =& $this->titles[$key];
$title["descs"][] = $desc;
$title["print_descs"] = true;
} else {
# pas de titre en cours
$this->_printGeneric(
$desc["line_prefix"], $desc["level"],
"desc", $desc["content"],
0, $this->err);
}
}
protected array $actions; protected array $actions;
function _getActionMark(): int { function action__getMarks(): array {
return count($this->actions); return [count($this->actions)];
} }
function _getActionId(): ?int { protected function action__getId(): ?int {
return end($this->actions)["id"] ?? null; return end($this->actions)["id"] ?? null;
} }
protected function flushActions(bool $endAction=false, ?int $overrideLevel=null): void { protected function action__end(?int $until=null): void {
$this->flushTitles(); $action = $this->actions[array_key_last($this->actions)] ?? null;
if ($action !== null) {
$until ??= $action["max_action_level"];
$until ??= $this->action__getMarks()[0] - 1;
while (count($this->actions) > $until) {
array_pop($this->actions);
}
}
}
protected function action__flush(bool $endAction=false, ?int $overrideLevel=null): void {
$this->title__flush();
$err = $this->err; $err = $this->err;
$indentLevel = $this->getIndentLevel(false); $indentLevel = $this->getIndentLevel(false);
$lastIndex = array_key_last($this->actions); $lastIndex = array_key_last($this->actions);
@ -311,16 +335,27 @@ class ConsoleMessenger extends AbstractMessenger {
} }
$indentLevel++; $indentLevel++;
}; unset($action); }; unset($action);
if ($endAction) $this->_endAction(); if ($endAction) $this->action__end();
}
function action__beforeFunc(array $marks): void {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = $marks[0] + 1;
}
function action__afterFunc(array $marks): void {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = null;
$this->action__end($marks[0]);
} }
function action($content, ?callable $func=null, ?int $level=null): void { function action($content, ?callable $func=null, ?int $level=null): void {
$this->checkLevel($level); $this->checkLevel($level);
$actionLevel = $this->_getActionMark(); $marks = $this->action__getMarks();
// faire en deux temps pour linePrefix soit à jour // faire en deux temps pour linePrefix soit à jour
$this->actions[] = ["id" => $this->lastActionId++]; $this->actions[] = ["id" => $this->lastActionId++];
A::merge($this->actions[array_key_last($this->actions)], [ A::merge($this->actions[array_key_last($this->actions)], [
"action_level" => $actionLevel, "action_level" => $marks[0],
"max_action_level" => null, "max_action_level" => null,
"timestamp" => time(), "timestamp" => time(),
"line_prefix" => $this->getLinePrefix(), "line_prefix" => $this->getLinePrefix(),
@ -332,18 +367,16 @@ class ConsoleMessenger extends AbstractMessenger {
]); ]);
if ($func !== null) { if ($func !== null) {
try { try {
$action =& $this->actions[array_key_last($this->actions)]; $this->action__beforeFunc($marks);
$action["max_action_level"] = $actionLevel + 1;
$result = $func($this); $result = $func($this);
if ($this->_getActionMark() > $actionLevel) { if ($this->action__getMarks()[0] > $marks[0]) {
$this->aresult($result); $this->aresult($result);
} }
} catch (Exception $e) { } catch (Exception $e) {
$this->afailure($e); $this->afailure($e);
throw $e; throw $e;
} finally { } finally {
$action["max_action_level"] = null; $this->action__afterFunc($marks);
$this->_endAction($actionLevel);
} }
} }
} }
@ -359,7 +392,7 @@ class ConsoleMessenger extends AbstractMessenger {
$action =& $this->actions[array_key_last($this->actions)]; $action =& $this->actions[array_key_last($this->actions)];
$action["result_success"] = true; $action["result_success"] = true;
$action["result_content"] = $content; $action["result_content"] = $content;
$this->flushActions(true, $overrideLevel); $this->action__flush(true, $overrideLevel);
} }
function afailure($content=null, ?int $overrideLevel=null): void { function afailure($content=null, ?int $overrideLevel=null): void {
@ -367,7 +400,7 @@ class ConsoleMessenger extends AbstractMessenger {
$action =& $this->actions[array_key_last($this->actions)]; $action =& $this->actions[array_key_last($this->actions)];
$action["result_success"] = false; $action["result_success"] = false;
$action["result_content"] = $content; $action["result_content"] = $content;
$this->flushActions(true, $overrideLevel); $this->action__flush(true, $overrideLevel);
} }
function adone($content=null, ?int $overrideLevel=null): void { function adone($content=null, ?int $overrideLevel=null): void {
@ -375,7 +408,7 @@ class ConsoleMessenger extends AbstractMessenger {
$action =& $this->actions[array_key_last($this->actions)]; $action =& $this->actions[array_key_last($this->actions)];
$action["result_success"] = null; $action["result_success"] = null;
$action["result_content"] = $content; $action["result_content"] = $content;
$this->flushActions(true, $overrideLevel); $this->action__flush(true, $overrideLevel);
} }
function aresult($result=null, ?int $overrideLevel=null): void { function aresult($result=null, ?int $overrideLevel=null): void {
@ -386,17 +419,6 @@ class ConsoleMessenger extends AbstractMessenger {
else $this->adone($result, $overrideLevel); else $this->adone($result, $overrideLevel);
} }
function _endAction(?int $until=null): void {
$action = $this->actions[array_key_last($this->actions)] ?? null;
if ($action !== null) {
$until ??= $action["max_action_level"];
$until ??= $this->_getActionMark() - 1;
while (count($this->actions) > $until) {
array_pop($this->actions);
}
}
}
function print($content, ?int $level=null): void { function print($content, ?int $level=null): void {
$this->_printGenericOrException( $this->_printGenericOrException(
$level, "print", $content, $level, "print", $content,
@ -428,9 +450,9 @@ class ConsoleMessenger extends AbstractMessenger {
} }
function end(bool $all=false): void { function end(bool $all=false): void {
if ($all) $this->_endSection(); if ($all) $this->section__afterFunc();
elseif ($this->actions) $this->_endAction(); elseif ($this->actions) $this->action__end();
elseif ($this->titles) $this->_endTitle(); elseif ($this->titles) $this->title__end();
else $this->_endSection(); else $this->section__afterFunc();
} }
} }

View File

@ -79,8 +79,16 @@ class LogMessenger extends AbstractMessenger {
return $clone; return $clone;
} }
protected function section__end(): void {
$this->end(true);
}
function section__afterFunc(): void {
$this->section__end();
}
function section($content, ?callable $func=null, ?int $level=null): void { function section($content, ?callable $func=null, ?int $level=null): void {
$this->_endSection(); $this->section__end();
if (!$this->checkLevel($level)) return; if (!$this->checkLevel($level)) return;
$this->_printTitle( $this->_printTitle(
$this->getLinePrefix(), $level, $this->getLinePrefix(), $level,
@ -90,45 +98,61 @@ class LogMessenger extends AbstractMessenger {
try { try {
$func($this); $func($this);
} finally { } finally {
$this->_endSection(); $this->section__afterFunc();
} }
} }
} }
function _endSection(): void {
$this->end(true);
}
protected array $titles; protected array $titles;
function _getTitleMark(): int { function title__getMarks(): array {
return count($this->titles); return [count($this->titles)];
} }
function _getTitleId(): ?int { protected function title__getId(): ?int {
return end($this->titles)["id"] ?? null; return end($this->titles)["id"] ?? null;
} }
protected function title__end(?int $until=null): void {
$title = $this->titles[array_key_last($this->titles)] ?? null;
if ($title !== null) {
$until ??= $title["max_title_level"];
$until ??= $this->title__getMarks()[0] - 1;
while (count($this->titles) > $until) {
array_pop($this->titles);
}
}
}
function title__beforeFunc(array $marks): void {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = $marks[0] + 1;
}
function title__afterFunc(array $marks): void {
$title =& $this->titles[array_key_last($this->titles)];
$title["max_title_level"] = null;
$this->title__end($marks[0]);
}
function title($content, ?callable $func=null, ?int $level=null): void { function title($content, ?callable $func=null, ?int $level=null): void {
if (!$this->checkLevel($level)) return; if (!$this->checkLevel($level)) return;
$titleLevel = $this->_getTitleMark(); $marks = $this->title__getMarks();
$this->titles[] = [ $this->titles[] = [
"id" => $this->lastTitleId++, "id" => $this->lastTitleId++,
"title_level" => $titleLevel, "title_level" => $marks[0],
"max_title_level" => null, "max_title_level" => null,
]; ];
$this->_printTitle( $this->_printTitle(
$this->getLinePrefix(), $level, $this->getLinePrefix(), $level,
"title", $content, "title", $content,
$titleLevel, $this->out); $marks[0], $this->out);
if ($func !== null) { if ($func !== null) {
try { try {
$title =& $this->titles[array_key_last($this->titles)]; $this->title__beforeFunc($marks);
$title["max_title_level"] = $titleLevel + 1;
$func($this); $func($this);
} finally { } finally {
$title["max_title_level"] = null; $this->title__afterFunc($marks);
$this->_endTitle($titleLevel);
} }
} }
} }
@ -143,31 +167,47 @@ class LogMessenger extends AbstractMessenger {
} }
function _endTitle(?int $until=null): void { protected array $actions;
$title = $this->titles[array_key_last($this->titles)];
$until ??= $title["max_title_level"]; function action__getMarks(): array {
$until ??= $this->_getTitleMark() - 1; return [count($this->actions)];
while (count($this->titles) > $until) { }
array_pop($this->titles);
protected function action__getId(): ?int {
return end($this->actions)["id"] ?? null;
}
protected function action__end(?int $until=null): void {
$action = $this->actions[array_key_last($this->actions)] ?? null;
if ($action !== null) {
$until ??= $action["max_action_level"];
$until ??= $this->action__getMarks()[0] - 1;
while (count($this->actions) > $until) {
array_pop($this->actions);
}
} }
} }
protected array $actions; protected function action__flush(bool $endAction=false, ?int $overrideLevel=null): void {
function _getActionMark(): int {
return count($this->actions);
} }
function _getActionId(): ?int { function action__beforeFunc(array $marks): void {
return end($this->actions)["id"] ?? null; $action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = $marks[0] + 1;
}
function action__afterFunc(array $marks): void {
$action =& $this->actions[array_key_last($this->actions)];
$action["max_action_level"] = null;
$this->action__end($marks[0]);
} }
function action($content, ?callable $func=null, ?int $level=null): void { function action($content, ?callable $func=null, ?int $level=null): void {
$this->checkLevel($level); $this->checkLevel($level);
$actionLevel = $this->_getActionMark(); $marks = $this->action__getMarks();
$this->actions[] = [ $this->actions[] = [
"id" => $this->lastActionId++, "id" => $this->lastActionId++,
"action_level" => $actionLevel, "action_level" => $marks[0],
"max_action_level" => null, "max_action_level" => null,
"level" => $level "level" => $level
]; ];
@ -175,28 +215,23 @@ class LogMessenger extends AbstractMessenger {
$this->getLinePrefix(), $level, $this->getLinePrefix(), $level,
true, $content, true, $content,
false, null, null, false, null, null,
$actionLevel, $this->out); $marks[0], $this->out);
if ($func !== null) { if ($func !== null) {
try { try {
$action =& $this->actions[array_key_last($this->actions)]; $this->action__beforeFunc($marks);
$action["max_action_level"] = $actionLevel + 1;
$result = $func($this); $result = $func($this);
if ($this->_getActionMark() > $actionLevel) { if ($this->action__getMarks()[0] > $marks[0]) {
$this->aresult($result); $this->aresult($result);
} }
} catch (Exception $e) { } catch (Exception $e) {
$this->afailure($e); $this->afailure($e);
throw $e; throw $e;
} finally { } finally {
$action["max_action_level"] = null; $this->action__afterFunc($marks);
$this->_endAction($actionLevel);
} }
} }
} }
protected function flushActions(bool $endAction=false, ?int $overrideLevel=null): void {
}
function step($content, ?int $level=null): void { function step($content, ?int $level=null): void {
$this->_printGenericOrException( $this->_printGenericOrException(
$level, "step", $content, $level, "step", $content,
@ -204,7 +239,7 @@ class LogMessenger extends AbstractMessenger {
} }
function asuccess($content=null, ?int $overrideLevel=null): void { function asuccess($content=null, ?int $overrideLevel=null): void {
if ($this->_getActionMark() == 0) $this->action(null); if ($this->action__getMarks()[0] == 0) $this->action(null);
$action = end($this->actions); $action = end($this->actions);
$level = $overrideLevel ?? $action["level"]; $level = $overrideLevel ?? $action["level"];
$this->_printAction( $this->_printAction(
@ -212,11 +247,11 @@ class LogMessenger extends AbstractMessenger {
false, null, false, null,
true, true, $content, true, true, $content,
$action["action_level"], $this->out); $action["action_level"], $this->out);
$this->_endAction(); $this->action__end();
} }
function afailure($content=null, ?int $overrideLevel=null): void { function afailure($content=null, ?int $overrideLevel=null): void {
if ($this->_getActionMark() == 0) $this->action(null); if ($this->action__getMarks()[0] == 0) $this->action(null);
$action = end($this->actions); $action = end($this->actions);
$level = $overrideLevel ?? $action["level"]; $level = $overrideLevel ?? $action["level"];
$this->_printAction( $this->_printAction(
@ -224,11 +259,11 @@ class LogMessenger extends AbstractMessenger {
false, null, false, null,
true, false, $content, true, false, $content,
$action["action_level"], $this->out); $action["action_level"], $this->out);
$this->_endAction(); $this->action__end();
} }
function adone($content=null, ?int $overrideLevel=null): void { function adone($content=null, ?int $overrideLevel=null): void {
if ($this->_getActionMark() == 0) $this->action(null); if ($this->action__getMarks()[0] == 0) $this->action(null);
$action = end($this->actions); $action = end($this->actions);
$level = $overrideLevel ?? $action["level"]; $level = $overrideLevel ?? $action["level"];
$this->_printAction( $this->_printAction(
@ -236,26 +271,17 @@ class LogMessenger extends AbstractMessenger {
false, null, false, null,
true, null, $content, true, null, $content,
$action["action_level"], $this->out); $action["action_level"], $this->out);
$this->_endAction(); $this->action__end();
} }
function aresult($result=null, ?int $overrideLevel=null): void { function aresult($result=null, ?int $overrideLevel=null): void {
if ($this->_getActionMark() == 0) $this->action(null); if ($this->action__getMarks()[0] == 0) $this->action(null);
if ($result === true) $this->asuccess(null, $overrideLevel); if ($result === true) $this->asuccess(null, $overrideLevel);
elseif ($result === false) $this->afailure(null, $overrideLevel); elseif ($result === false) $this->afailure(null, $overrideLevel);
elseif ($result instanceof Exception) $this->afailure($result, $overrideLevel); elseif ($result instanceof Exception) $this->afailure($result, $overrideLevel);
else $this->adone($result, $overrideLevel); else $this->adone($result, $overrideLevel);
} }
function _endAction(?int $until=null): void {
$action = $this->actions[array_key_last($this->actions)];
$until ??= $action["max_action_level"];
$until ??= $this->_getActionMark() - 1;
while (count($this->actions) > $until) {
array_pop($this->actions);
}
}
protected function getIndentLevel(bool $withActions=true): int { protected function getIndentLevel(bool $withActions=true): int {
$indentLevel = count($this->titles) - 1; $indentLevel = count($this->titles) - 1;
if ($indentLevel < 0) $indentLevel = 0; if ($indentLevel < 0) $indentLevel = 0;
@ -296,11 +322,11 @@ class LogMessenger extends AbstractMessenger {
function end(bool $all=false): void { function end(bool $all=false): void {
if ($all) { if ($all) {
while ($this->actions) $this->adone(); while ($this->actions) $this->adone();
while ($this->titles) $this->_endTitle(); while ($this->titles) $this->title__end();
} elseif ($this->actions) { } elseif ($this->actions) {
$this->_endAction(); $this->action__end();
} elseif ($this->titles) { } elseif ($this->titles) {
$this->_endTitle(); $this->title__end();
} }
} }
} }

View File

@ -12,15 +12,18 @@ class NullMessenger implements IMessenger {
} }
function section($content, ?callable $func=null, ?int $level=null): void { function section($content, ?callable $func=null, ?int $level=null): void {
if ($func !== null) $func($this);
} }
function title($content, ?callable $func=null, ?int $level=null): void { function title($content, ?callable $func=null, ?int $level=null): void {
if ($func !== null) $func($this);
} }
function desc($content, ?int $level=null): void { function desc($content, ?int $level=null): void {
} }
function action($content, ?callable $func=null, ?int $level=null): void { function action($content, ?callable $func=null, ?int $level=null): void {
if ($func !== null) $func($this);
} }
function step($content, ?int $level=null): void { function step($content, ?int $level=null): void {

View File

@ -10,14 +10,14 @@ use nulib\output\IMessenger;
* NB: si cette classe est instanciée sans argument, elle agit comme * NB: si cette classe est instanciée sans argument, elle agit comme
* {@link NullMessenger}: elle envoie tous les messages vers /dev/null * {@link NullMessenger}: elle envoie tous les messages vers /dev/null
*/ */
class ProxyMessenger implements IMessenger { class ProxyMessenger implements _IMessenger {
function __construct(?IMessenger ...$msgs) { function __construct(?IMessenger ...$msgs) {
foreach ($msgs as $msg) { foreach ($msgs as $msg) {
if ($msg !== null) $this->msgs[] = $msg; if ($msg !== null) $this->msgs[] = $msg;
} }
} }
/** @var IMessenger[] */ /** @var _IMessenger[] */
protected ?array $msgs = []; protected ?array $msgs = [];
function isEmpty(): bool { function isEmpty(): bool {
@ -43,45 +43,64 @@ class ProxyMessenger implements IMessenger {
return $clone; return $clone;
} }
function section__afterFunc(): void {
foreach ($this->msgs as $msg) {
if ($msg instanceof _IMessenger) {
$msg->section__afterFunc();
}
}
}
function section($content, ?callable $func=null, ?int $level=null): void { function section($content, ?callable $func=null, ?int $level=null): void {
$useFunc = false;
foreach ($this->msgs as $msg) { foreach ($this->msgs as $msg) {
$msg->section($content, null, $level); $msg->section($content, null, $level);
if ($msg instanceof _IMessenger) $useFunc = true;
} }
if ($useFunc && $func !== null) { if ($func !== null) {
try { try {
$func($this); $func($this);
} finally { } finally {
/** @var _IMessenger $msg */ $this->section__afterFunc();
foreach ($this->msgs as $msg) { }
$msg->_endSection(); }
} }
function title__getMarks(): array {
$marks = [];
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$marks[$key] = $msg->title__getMarks();
}
}
return $marks;
}
function title__beforeFunc(array $marks): void {
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$msg->title__beforeFunc($marks[$key]);
}
}
}
function title__afterFunc(array $marks): void {
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$msg->title__afterFunc($marks[$key]);
} }
} }
} }
function title($content, ?callable $func=null, ?int $level=null): void { function title($content, ?callable $func=null, ?int $level=null): void {
$useFunc = false; $marks = $this->title__getMarks();
$untils = [];
foreach ($this->msgs as $msg) { foreach ($this->msgs as $msg) {
if ($msg instanceof _IMessenger) {
$useFunc = true;
$untils[] = $msg->_getTitleMark();
}
$msg->title($content, null, $level); $msg->title($content, null, $level);
} }
if ($useFunc && $func !== null) { if ($func !== null) {
try { try {
$this->title__beforeFunc($marks);
$func($this); $func($this);
} finally { } finally {
/** @var _IMessenger $msg */ $this->title__afterFunc($marks);
$index = 0;
foreach ($this->msgs as $msg) {
if ($msg instanceof _IMessenger) {
$msg->_endTitle($untils[$index++]);
}
}
} }
} }
} }
@ -92,38 +111,43 @@ class ProxyMessenger implements IMessenger {
} }
} }
function action($content, ?callable $func=null, ?int $level=null): void { function action__getMarks(): array {
$useFunc = false; $marks = [];
$untils = []; foreach ($this->msgs as $key => $msg) {
foreach ($this->msgs as $msg) {
if ($msg instanceof _IMessenger) { if ($msg instanceof _IMessenger) {
$useFunc = true; $marks[$key] = $msg->action__getMarks();
$untils[] = $msg->_getActionMark();
} }
}
return $marks;
}
function action__beforeFunc(array $marks): void {
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$msg->action__beforeFunc($marks[$key]);
}
}
}
function action__afterFunc(array $marks): void {
foreach ($this->msgs as $key => $msg) {
if ($msg instanceof _IMessenger) {
$msg->action__afterFunc($marks[$key]);
}
}
}
function action($content, ?callable $func=null, ?int $level=null): void {
$marks = $this->action__getMarks();
foreach ($this->msgs as $msg) {
$msg->action($content, null, $level); $msg->action($content, null, $level);
} }
if ($useFunc && $func !== null) { if ($func !== null) {
try { try {
$result = $func($this); $this->action__beforeFunc($marks);
/** @var _IMessenger $msg */ $func($this);
$index = 0;
foreach ($this->msgs as $msg) {
if ($msg->_getActionMark() > $untils[$index++]) {
$msg->aresult($result);
}
}
} catch (Exception $e) {
/** @var _IMessenger $msg */
foreach ($this->msgs as $msg) {
$msg->afailure($e);
}
throw $e;
} finally { } finally {
/** @var _IMessenger $msg */ $this->action__afterFunc($marks);
$index = 0;
foreach ($this->msgs as $msg) {
$msg->_endAction($untils[$index++]);
}
} }
} }
} }

View File

@ -74,17 +74,19 @@ interface _IMessenger extends IMessenger {
"done" => [null, null], "done" => [null, null],
]; ];
function _endSection(): void; function section__afterFunc(): void;
function _getTitleMark(): int; /** @return int[] */
function title__getMarks(): array;
/** @param int[] $marks */
function title__beforeFunc(array $marks): void;
/** @param int[] $marks */
function title__afterFunc(array $marks): void;
function _getTitleId(): ?int; /** @return int[] */
function action__getMarks(): array;
function _endTitle(?int $until=null): void; /** @param int[] $marks */
function action__beforeFunc(array $marks): void;
function _getActionMark(): int; /** @param int[] $marks */
function action__afterFunc(array $marks): void;
function _getActionId(): ?int;
function _endAction(?int $until=null): void;
} }

1
php/tbin/.gitignore vendored
View File

@ -1,3 +1,4 @@
/devel/
/*.db /*.db
/*.cache /*.cache
/*.log /*.log