612 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			612 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nur\b\ui;
 | |
| 
 | |
| use Exception;
 | |
| use nur\A;
 | |
| use nur\b\ExceptionShadow;
 | |
| use nur\b\io\IWriter;
 | |
| use nur\b\params\Parametrable;
 | |
| use nur\b\params\Tparametrable;
 | |
| use nur\b\UserException;
 | |
| use nur\c;
 | |
| use nur\config;
 | |
| use nur\data\types\md_utils;
 | |
| use nur\data\types\Metadata;
 | |
| use nur\func;
 | |
| use nur\SL;
 | |
| use nur\writer;
 | |
| use Throwable;
 | |
| 
 | |
| abstract class AbstractMessenger extends Parametrable implements IMessenger {
 | |
|   use Tparametrable;
 | |
| 
 | |
|   const PRINT_LEVELS = [
 | |
|     self::KEY_USER => [
 | |
|       self::LEVEL_NORMAL,
 | |
|       config::DEVEL => self::LEVEL_MINOR,
 | |
|     ],
 | |
|     self::KEY_TECH => [
 | |
|       self::LEVEL_NORMAL,
 | |
|       config::DEVEL => self::LEVEL_MINOR,
 | |
|     ],
 | |
|     self::KEY_EXCEPTION => [
 | |
|       self::LEVEL_NEVER,
 | |
|       config::DEVEL => self::LEVEL_MINOR,
 | |
|     ],
 | |
|   ];
 | |
| 
 | |
|   const LOG_LEVELS = [
 | |
|     self::KEY_USER => [
 | |
|       self::LEVEL_NORMAL,
 | |
|       config::DEVEL => self::LEVEL_MINOR,
 | |
|     ],
 | |
|     self::KEY_TECH => [
 | |
|       self::LEVEL_NORMAL,
 | |
|       config::DEVEL => self::LEVEL_MINOR,
 | |
|     ],
 | |
|     self::KEY_EXCEPTION => [
 | |
|       self::LEVEL_NORMAL,
 | |
|       config::DEVEL => self::LEVEL_MINOR,
 | |
|     ],
 | |
|   ];
 | |
| 
 | |
|   const TYPE_LEVELS = [
 | |
|     IMessenger::TYPE_INFO,
 | |
|     config::DEVEL => IMessenger::TYPE_DEBUG,
 | |
|   ];
 | |
| 
 | |
|   const DATE_FORMAT = 'Y-m-d\TH:i:s.u';
 | |
| 
 | |
|   function __construct(?array $params=null) {
 | |
|     self::set_parametrable_params_defaults($params, [
 | |
|       "print_levels" => static::PRINT_LEVELS,
 | |
|       "log_levels" => static::LOG_LEVELS,
 | |
|       "type_levels" => static::TYPE_LEVELS,
 | |
|       "date_format" => static::DATE_FORMAT,
 | |
|     ]);
 | |
|     parent::__construct($params);
 | |
|   }
 | |
| 
 | |
|   const PARAMETRABLE_PARAMS_SCHEMA = [
 | |
|     "print_levels" => ["array", null, "niveaux par défaut pour chaque catégorie de message"],
 | |
|     "log_levels" => ["array", null, "niveaux par défaut pour chaque catégorie de message"],
 | |
|     "type_levels" => ["array", null, "niveaux par défaut des types de message"],
 | |
|     "log_output" => [null, null, "destination des messages de logs"],
 | |
|     "display_log" => ["bool", false, "faut-il afficher les logs?"],
 | |
|     "add_date" => ["?bool", null, "faut-il dater les messages?"],
 | |
|     "date_format" => ["string", null, "format de la date"]
 | |
|   ];
 | |
| 
 | |
|   /** @var array */
 | |
|   protected $ppPrintLevels;
 | |
| 
 | |
|   function pp_setPrintLevels(array $levels): void {
 | |
|     A::merge_nn($this->ppPrintLevels, $levels);
 | |
|   }
 | |
| 
 | |
|   /** @var array */
 | |
|   protected $ppLogLevels;
 | |
| 
 | |
|   function pp_setLogLevels(array $levels): void {
 | |
|     A::merge_nn($this->ppLogLevels, $levels);
 | |
|   }
 | |
| 
 | |
|   /** @var array */
 | |
|   protected $ppTypeLevels;
 | |
| 
 | |
|   /** @var IWriter */
 | |
|   protected $ppLogOutput;
 | |
| 
 | |
|   /** @var bool */
 | |
|   protected $ppDisplayLog;
 | |
| 
 | |
|   /** @var bool */
 | |
|   protected $ppAddDate;
 | |
| 
 | |
|   /** @var ?string */
 | |
|   protected $ppDateFormat;
 | |
| 
 | |
|   /** @var IWriter */
 | |
|   protected $logOutput;
 | |
| 
 | |
|   protected function afterSetParametrableParams(array $modifiedKeys, ?Metadata $md=null): void {
 | |
|     if (self::was_parametrable_param_modified($modifiedKeys, "log_output")) {
 | |
|       $this->logOutput = $this->ppLogOutput !== null? writer::with($this->ppLogOutput): null;
 | |
|       if (!self::was_parametrable_param_modified($modifiedKeys, "add_date")) {
 | |
|         $this->ppAddDate = $this->logOutput !== null;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   function setLevels(?array $printLevels, ?array $logLevels=null, $typeLevels=null): IMessenger {
 | |
|     $this->setParametrableParams(SL::filter_z([
 | |
|       "print_levels" => $printLevels,
 | |
|       "log_levels" => $logLevels,
 | |
|       "type_levels" => $typeLevels,
 | |
|     ]));
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   protected function _getLevel(string $key, array $levels): int {
 | |
|     $level = A::get($levels, $key, self::LEVEL_NORMAL);
 | |
|     if (is_int($level)) return $level;
 | |
| 
 | |
|     $levels = A::with($level);
 | |
|     $level = A::get($levels, config::get_profile());
 | |
|     if ($level === null) $level = A::get($levels, 0);
 | |
|     if ($level === null) return self::LEVEL_NORMAL;
 | |
| 
 | |
|     return $level;
 | |
|   }
 | |
| 
 | |
|   function getPrintLevel(string $key): int {
 | |
|     return $this->_getLevel($key, $this->ppPrintLevels);
 | |
|   }
 | |
| 
 | |
|   function getLogLevel(string $key): int {
 | |
|     return $this->_getLevel($key, $this->ppLogLevels);
 | |
|   }
 | |
| 
 | |
|   function getTypeLevel(): int {
 | |
|     $levels = $this->ppTypeLevels;
 | |
|     $level = A::get($levels, config::get_profile());
 | |
|     if ($level === null) $level = A::get($levels, 0);
 | |
|     if ($level === null) return IMessenger::TYPE_INFO;
 | |
| 
 | |
|     return $level;
 | |
|   }
 | |
| 
 | |
|   function isLogMessage(?string $msg, int $level, string $msgKey): bool {
 | |
|     return $msg !== null && $level >= $this->getLogLevel($msgKey);
 | |
|   }
 | |
| 
 | |
|   function isPrintMessage(?string $msg, int $level, string $msgKey): bool {
 | |
|     return $msg !== null && $level >= $this->getPrintLevel($msgKey);
 | |
|   }
 | |
| 
 | |
|   protected function date() {
 | |
|     return date_create()->format($this->ppDateFormat);
 | |
|   }
 | |
| 
 | |
|   protected function getString($text): string {
 | |
|     return c::string(c::nq($text));
 | |
|   }
 | |
|   protected function filterTags(string $text): string {
 | |
|     return preg_replace('/<[^>]*>/', "", $text);
 | |
|   }
 | |
|   protected function filterColors(string $text): string {
 | |
|     return $text;
 | |
|   }
 | |
|   protected function wnl(IWriter $writer, ?bool $color, string $sep, ...$values): void {
 | |
|     $values = c::flatten($values);
 | |
|     foreach ($values as &$value) {
 | |
|       $value = $this->getString($value);
 | |
|       if (!$value) $value = false;
 | |
|     }; unset($value);
 | |
|     $text = $this->filterTags($writer->toString($sep, $values));
 | |
|     if ($color === null) $color = $writer->isatty();
 | |
|     if (!$color) $text = $this->filterColors($text);
 | |
|     $writer->wnl($text);
 | |
|   }
 | |
| 
 | |
|   protected function fixDest(?int &$type): void {
 | |
|     if ($type === null) $type = 0;
 | |
|     if (($type & self::DEST_MASK) === 0) $type += self::DEST_ALL;
 | |
|   }
 | |
| 
 | |
|   protected function shouldLog(?int $type): bool {
 | |
|     if ($this->logOutput === null) return false;
 | |
|     $this->fixDest($type);
 | |
|     return ($type & self::DEST_LOG) != 0;
 | |
|   }
 | |
| 
 | |
|   protected function shouldPrint(?int $type): bool {
 | |
|     $this->fixDest($type);
 | |
|     return ($type & self::DEST_DISPLAY) != 0 || $this->ppDisplayLog;
 | |
|   }
 | |
| 
 | |
|   #############################################################################
 | |
|   # Sections
 | |
| 
 | |
|   protected function logStartSection($title): void {
 | |
|     $datetime = $this->ppAddDate? $this->date()." ": "\n";
 | |
|     $title = "$datetime>>>> $title <<<<";
 | |
|     $this->wnl($this->logOutput, false, "", $title);
 | |
|   }
 | |
| 
 | |
|   protected function logEndSection(): void {
 | |
|   }
 | |
| 
 | |
|   protected abstract function printStartSection($title, ?int $msgType, ?int $msgLevel): void;
 | |
|   protected abstract function printEndSection(): void;
 | |
| 
 | |
|   /** @var bool */
 | |
|   private $inSection;
 | |
| 
 | |
|   function isInSection(): bool {
 | |
|     return $this->inSection;
 | |
|   }
 | |
| 
 | |
|   function startSection($title, ?int $msgType=null, ?int $msgLevel=null): IMessenger {
 | |
|     if ($this->inSection) $this->endSection();
 | |
|     $allowLog = $msgLevel === null || $msgLevel >= $this->getLogLevel(self::KEY_USER);
 | |
|     $allowPrint = $msgLevel === null || $msgLevel >= $this->getPrintLevel(self::KEY_USER);
 | |
|     if ($allowLog || $allowPrint) {
 | |
|       if ($allowLog && $this->shouldLog($msgType)) $this->logStartSection($title);
 | |
|       if ($allowPrint && $this->shouldPrint($msgType)) $this->printStartSection($title, $msgType, $msgLevel);
 | |
|       $this->inSection = true;
 | |
|     }
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   function endSection(): IMessenger {
 | |
|     if ($this->inSection) {
 | |
|       $this->printEndSection();
 | |
|       $this->inSection = false;
 | |
|     }
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   #############################################################################
 | |
|   # Groupes
 | |
| 
 | |
|   protected function getGroupCount(?array $group): int {
 | |
|     if ($group === null ) return 0;
 | |
|     $count = $group["count"];
 | |
|     return $count !== null? $count: 2;
 | |
|   }
 | |
| 
 | |
|   protected function getGroupIndent(?array $group, ?int $indent=null, int $maxCount=1): string {
 | |
|     if ($group === null) return "";
 | |
|     if ($indent === null) {
 | |
|       $indent = $group["indent"];
 | |
|       $count = $this->getGroupCount($group);
 | |
|       if ($count <= $maxCount) $indent--;
 | |
|     }
 | |
|     return str_repeat("  ", $indent);
 | |
|   }
 | |
| 
 | |
|   protected function getGroupPrefix(?array $group, int $maxCount=1): string {
 | |
|     if ($group === null) return "";
 | |
|     $count = $this->getGroupCount($group);
 | |
|     if ($count > $maxCount) return "";
 | |
|     return $group["prefix"]." :";
 | |
|   }
 | |
| 
 | |
|   protected function logStartGroup(array $group): void {
 | |
|     if ($this->getGroupCount($group) > 1) {
 | |
|       $groupIndent = $this->getGroupIndent($group, $group["indent"] - 1);
 | |
|       if ($this->ppAddDate) $groupIndent = self::date()." $groupIndent";
 | |
|       $this->wnl($this->logOutput, false, " ", $groupIndent.">", $group["prefix"]);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   protected function logEndGroup(array $group): void {
 | |
|   }
 | |
| 
 | |
|   protected abstract function printStartGroup(array $group, ?array $groups): void;
 | |
|   protected abstract function printEndGroup(array $group): void;
 | |
| 
 | |
|   private $groups;
 | |
| 
 | |
|   public function isInGroup(): bool {
 | |
|     return $this->groups !== null;
 | |
|   }
 | |
| 
 | |
|   function startGroup($prefix, int $count=null, ?int $msgType=null, ?int $msgLevel=null): IMessenger {
 | |
|     $allowLog = $msgLevel === null || $msgLevel >= $this->getLogLevel(self::KEY_USER);
 | |
|     $allowPrint = $msgLevel === null || $msgLevel >= $this->getPrintLevel(self::KEY_USER);
 | |
|     if ($allowLog || $allowPrint) {
 | |
|       $indent = 1;
 | |
|       if ($this->groups !== null) {
 | |
|         foreach ($this->groups as $group) {
 | |
|           if ($group !== null) $indent++;
 | |
|         }
 | |
|       }
 | |
|       $group = [
 | |
|         "indent" => $indent,
 | |
|         "prefix" => $prefix,
 | |
|         "count" => $count,
 | |
|         "type" => $msgType,
 | |
|         "level" => $msgLevel,
 | |
|       ];
 | |
|       if ($allowLog && $this->shouldLog($msgType)) $this->logStartGroup($group);
 | |
|       if ($allowPrint && $this->shouldPrint($msgType)) $this->printStartGroup($group, $this->groups);
 | |
|     } else {
 | |
|       $group = false;
 | |
|     }
 | |
|     $this->groups[] = $group;
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   function endGroup(): IMessenger {
 | |
|     $group = array_pop($this->groups);
 | |
|     if ($group) {
 | |
|       $type = $group["type"];
 | |
|       if ($this->shouldLog($type)) $this->logEndGroup($group);
 | |
|       if ($this->shouldPrint($type)) $this->printEndGroup($group);
 | |
|     }
 | |
|     if (!$this->groups) $this->groups = null;
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   function end(bool $all=false): IMessenger {
 | |
|     if ($all) {
 | |
|       while ($this->groups) $this->endGroup();
 | |
|       $this->endSection();
 | |
|     } elseif ($this->groups) $this->endGroup();
 | |
|     else $this->endSection();
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   #############################################################################
 | |
|   # Messages
 | |
| 
 | |
|   const TYPE_PREFIXES = [
 | |
|     # les clés doivent être ordonnées de la plus grande à la plus petite
 | |
|     # la 2ème valeur indique s'il faut garder le préfixe s'il y a un result
 | |
|     self::LEVEL_CRITICAL => [
 | |
|       self::TYPE_ERROR => ["CRITICAL!", true],
 | |
|       self::TYPE_WARNING => ["ATTENTION!", true],
 | |
|       self::TYPE_DEBUG => ["IMPORTANT!", true],
 | |
|     ],
 | |
|     self::LEVEL_MAJOR => [
 | |
|       self::TYPE_ERROR => ["ERROR:", true],
 | |
|       self::TYPE_WARNING => ["WARN:", true],
 | |
|       self::TYPE_INFO => ["INFO:", false],
 | |
|       self::TYPE_DEBUG => ["DEBUG:", true],
 | |
|     ],
 | |
|     self::LEVEL_NORMAL => [
 | |
|       self::TYPE_ERROR => ["E", true],
 | |
|       self::TYPE_WARNING => ["W", true],
 | |
|       self::TYPE_INFO => ["", false],
 | |
|       self::TYPE_DEBUG => ["D", true],
 | |
|     ],
 | |
|     self::LEVEL_MINOR => [
 | |
|       self::TYPE_ERROR => ["e", true],
 | |
|       self::TYPE_WARNING => ["w", true],
 | |
|       self::TYPE_INFO => ["i", false],
 | |
|       self::TYPE_DEBUG => ["d", true],
 | |
|     ],
 | |
|   ];
 | |
|   const RESULT_PREFIXES = [
 | |
|     self::RESULT_FAILURE => "(FAILURE)",
 | |
|     self::RESULT_SUCCESS => "(SUCCESS)",
 | |
|     self::RESULT_NEUTRAL => "*",
 | |
|     self::RESULT_NONE => null,
 | |
|   ];
 | |
| 
 | |
|   protected function getResultPrefix(int $result, bool $color): ?string {
 | |
|     return self::RESULT_PREFIXES[$result];
 | |
|   }
 | |
| 
 | |
|   protected function getTypePrefixSuffix(int $type, int $level, bool $color, bool $haveResultPrefix): array {
 | |
|     $typePrefixSuffix = false;
 | |
|     foreach (self::TYPE_PREFIXES as $prefixLevel => $prefixes) {
 | |
|       if ($level >= $prefixLevel) {
 | |
|         foreach ($prefixes as $prefixType => $prefixValue) {
 | |
|           if ($type >= $prefixType) {
 | |
|             $typePrefixSuffix = $prefixValue;
 | |
|             break;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       if ($typePrefixSuffix !== false) break;
 | |
|     }
 | |
|     if ($typePrefixSuffix === false) return [null, null];
 | |
|     elseif ($haveResultPrefix && !$typePrefixSuffix[1]) return [null, null];
 | |
|     $prefix = $typePrefixSuffix[0];
 | |
|     $suffix = "";
 | |
|     return [$prefix, $suffix];
 | |
|   }
 | |
| 
 | |
|   /** @var Metadata */
 | |
|   private static $message_md;
 | |
| 
 | |
|   protected static function message_md(): Metadata {
 | |
|     return md_utils::ensure_md(self::$message_md
 | |
|       , array_merge(self::MESSAGE_SCHEMA, self::MESSAGE_OPTIONS_SCHEMA));
 | |
|   }
 | |
| 
 | |
|   protected function logMsg(
 | |
|     ?array $groups,
 | |
|     bool $logUser, $userMsg,
 | |
|     bool $logTech, $techMsg,
 | |
|     bool $logException, $exceptionMsg,
 | |
|     int $type, int $level
 | |
|   ): void {
 | |
|     $group = A::last($groups);
 | |
|     if ($group === false) {
 | |
|       # groupe neutralisé
 | |
|       return;
 | |
|     }
 | |
|     $groupIndent = $this->getGroupIndent($group);
 | |
|     $groupPrefix = $this->getGroupPrefix($group);
 | |
|     if ($this->ppAddDate) $groupIndent = self::date()." $groupIndent";
 | |
| 
 | |
|     $color = false;
 | |
|     $result = $type & self::RESULT_MASK;
 | |
|     $type = $type & self::TYPE_MASK;
 | |
|     $resultPrefix = $this->getResultPrefix($result, $color);
 | |
|     [$typePrefix, $typeSuffix] = $this->getTypePrefixSuffix($type, $level, $color, $resultPrefix !== null);
 | |
|     $prefix = $groupIndent.$typePrefix.$resultPrefix;
 | |
| 
 | |
|     $logOutput = $this->logOutput;
 | |
|     if ($logUser) $this->wnl($logOutput, $color, " ", $prefix, $groupPrefix, $userMsg, $typeSuffix);
 | |
|     if ($logTech) $this->wnl($logOutput, $color, " ", $prefix, "TECH:", $techMsg, $typeSuffix);
 | |
|     if ($logException) {
 | |
|       [$summary, $traceback] = $exceptionMsg;
 | |
|       $this->wnl($logOutput, $color, " ", $prefix, "TRACEBACK:", $summary, $typeSuffix);
 | |
|       $this->wnl($logOutput, false, "", $traceback);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   protected abstract function getUserMsg($msg): array;
 | |
|   protected abstract function getTechMsg($msg): array;
 | |
|   protected abstract function getExceptionMsg($exception, $user, $tech, bool $haveTechMsgOrSummary): array;
 | |
|   protected abstract function printMsg(
 | |
|     ?array $groups
 | |
|     , bool $printUser, $userMsg
 | |
|     , bool $printTech, $techMsg
 | |
|     , bool $printException, $exceptionMsg
 | |
|     , int  $type, int $level, array $options
 | |
|   ): void;
 | |
| 
 | |
|   protected function processMsgOptions(array $options): void {
 | |
|   }
 | |
| 
 | |
|   function ensureMessage(&$message): void {
 | |
|     static::message_md()->ensureSchema($message);
 | |
| 
 | |
|     $user =& $message[self::KEY_USER];
 | |
|     $tech =& $message[self::KEY_TECH];
 | |
|     $exception =& $message[self::KEY_EXCEPTION];
 | |
|     if ($exception === null) {
 | |
|       if ($tech instanceof Throwable || $tech instanceof ExceptionShadow) $exception = $tech;
 | |
|       elseif ($user instanceof Throwable || $user instanceof ExceptionShadow) $exception = $user;
 | |
|     }
 | |
|     if ($tech === null) {
 | |
|       if ($user instanceof Throwable || $user instanceof ExceptionShadow) $tech = $user;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   function addMessage($message, int $type, int $level): IMessenger {
 | |
|     $allowType = ($type & self::TYPE_MASK) >= $this->getTypeLevel();
 | |
|     if (!$allowType) return $this;
 | |
| 
 | |
|     $this->fixDest($type);
 | |
|     $this->ensureMessage($message);
 | |
| 
 | |
|     $user = $message[self::KEY_USER];
 | |
|     $logUser = $level >= $this->getLogLevel(self::KEY_USER);
 | |
|     $printUser = $level >= $this->getPrintLevel(self::KEY_USER);
 | |
|     $userMsg = false;
 | |
|     if ($user !== null) {
 | |
|       if ($user instanceof UserException) $msg = $user->getUserMessage();
 | |
|       elseif ($user instanceof Throwable || $user instanceof ExceptionShadow) $msg = $user->getMessage();
 | |
|       else $msg = $user;
 | |
|       if (!$msg) $printUser = false;
 | |
|       else $userMsg = $this->getUserMsg($msg);
 | |
|     }
 | |
|     $logUser &= $userMsg !== false;
 | |
|     $printUser &= $userMsg !== false;
 | |
| 
 | |
|     $tech = $message[self::KEY_TECH];
 | |
|     $logTech = $level >= $this->getLogLevel(self::KEY_TECH);
 | |
|     $printTech = $level >= $this->getPrintLevel(self::KEY_TECH);
 | |
|     $techMsg = false;
 | |
|     $techSummary = false;
 | |
|     $exception = $message[self::KEY_EXCEPTION];
 | |
|     $logException = $exception !== null && $level >= $this->getLogLevel(self::KEY_EXCEPTION);;
 | |
|     $printException = $exception !== null && $level >= $this->getPrintLevel(self::KEY_EXCEPTION);;
 | |
|     $exceptionMsg = false;
 | |
|     if ($tech !== null) {
 | |
|       if ($tech instanceof UserException) {
 | |
|         $msg = $tech->getTechMessage();
 | |
|       } elseif (($tech instanceof Throwable || $tech instanceof ExceptionShadow) && !$printException) {
 | |
|         $techSummary = true;
 | |
|         $msg = UserException::get_summary($tech);
 | |
|       } else {
 | |
|         $msg = $tech;
 | |
|       }
 | |
|       if (!$msg) $printTech = false;
 | |
|       else $techMsg = $this->getTechMsg($msg);
 | |
|     }
 | |
|     $logTech &= $techMsg !== false;
 | |
|     $printTech &= $techMsg !== false;
 | |
| 
 | |
|     if ($exception !== null) {
 | |
|       $exceptionMsg = $this->getExceptionMsg($exception, $user, $tech, $techMsg || $techSummary);
 | |
|     }
 | |
|     $logException &= $exceptionMsg !== false;
 | |
|     $printException &= $exceptionMsg !== false;
 | |
| 
 | |
|     $options = $message;
 | |
|     if ($this->shouldLog($type)) {
 | |
|       $this->logMsg(
 | |
|         $this->groups,
 | |
|         $logUser, $userMsg,
 | |
|         $logTech, $techMsg,
 | |
|         $logException, $exceptionMsg,
 | |
|         $type, $level);
 | |
|     }
 | |
|     if ($this->shouldPrint($type)) {
 | |
|       $this->printMsg(
 | |
|         $this->groups,
 | |
|         $printUser, $userMsg,
 | |
|         $printTech, $techMsg,
 | |
|         $printException, $exceptionMsg,
 | |
|         $type, $level, $options);
 | |
|     }
 | |
|     $this->processMsgOptions($options);
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   function aresult($result, ?array $args=null, $message=null, ?int $type=null): IMessenger {
 | |
|     if ($message !== null) static::message_md()->ensureSchema($message);
 | |
|     if (is_callable($result)) {
 | |
|       if ($args === null) $args = [];
 | |
|       try {
 | |
|         $result = func::call($result, ...$args);
 | |
|         if ($result === null) {
 | |
|           # cas des fonctions void
 | |
|           $result = true;
 | |
|         }
 | |
|       } catch (Exception $e) {
 | |
|         $result = $e;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     $type = ($type?: 0) & self::DEST_MASK;
 | |
|     $level = self::LEVEL_MAJOR;
 | |
|     if ($result instanceof Exception) {
 | |
|       $type += self::TYPE_INFO + self::RESULT_FAILURE;
 | |
|       $message[self::KEY_USER] = $result;
 | |
|     } elseif (is_string($result)) {
 | |
|       $type += self::TYPE_INFO + self::RESULT_SUCCESS;
 | |
|       $message[self::KEY_USER] = $result;
 | |
|     } elseif ($result === null) {
 | |
|       $type += self::TYPE_INFO + self::RESULT_NEUTRAL;
 | |
|       A::replace_z($message, self::KEY_USER, "en cours");
 | |
|     } elseif ($result) {
 | |
|       $type += self::TYPE_INFO + self::RESULT_SUCCESS;
 | |
|       A::replace_z($message, self::KEY_USER, "succès");
 | |
|     } else {
 | |
|       $type += self::TYPE_INFO + self::RESULT_FAILURE;
 | |
|       A::replace_z($message, self::KEY_USER, "échec");
 | |
|     }
 | |
|     $this->addMessage($message, $type, $level);
 | |
|     if ($this->isInGroup()) $this->endGroup();
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   function astep($message=null, ?int $type=null): IMessenger {
 | |
|     $this->aresult(null, null, $message, $type);
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   function asuccess($message=null, ?int $type=null): IMessenger {
 | |
|     $this->aresult(true, null, $message, $type);
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   function afailure($message=null, ?Throwable $e=null, ?int $type=null): IMessenger {
 | |
|     static::message_md()->ensureSchema($message);
 | |
|     if ($message === null) {
 | |
|       $message = $e;
 | |
|     } elseif ($message[self::KEY_USER] === null) {
 | |
|       $message[self::KEY_USER] = $e;
 | |
|     } else {
 | |
|       A::replace_z($message, self::KEY_EXCEPTION, $e);
 | |
|     }
 | |
|     $this->aresult(false, null, $message, $type);
 | |
|     return $this;
 | |
|   }
 | |
| 
 | |
|   function action($message, $result=null, ?array $args=null, ?int $type=null, ?int $level=null): IMessenger {
 | |
|     $this->startGroup($message, 1, $type, $level);
 | |
|     if ($result !== null) $this->aresult($result, $args, null, $type);
 | |
|     return $this;
 | |
|   }
 | |
| }
 |