modifs.mineures sans commentaires
This commit is contained in:
		
							parent
							
								
									ad88b16a32
								
							
						
					
					
						commit
						029a16f6de
					
				@ -21,33 +21,47 @@ class Console implements IMessenger {
 | 
			
		||||
    "m" => self::LEVEL_MAJOR,
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  const TYPE_PREFIXES = [
 | 
			
		||||
  protected static function verifix_level($level, bool $debug): int {
 | 
			
		||||
    if ($level === null) $level = $debug? self::LEVEL_DEBUG: self::LEVEL_NORMAL;
 | 
			
		||||
    if (!in_array($level, self::VALID_LEVELS, true)) {
 | 
			
		||||
      $level = cl::get(self::LEVEL_MAP, $level, $level);
 | 
			
		||||
    }
 | 
			
		||||
    if (!in_array($level, self::VALID_LEVELS, true)) {
 | 
			
		||||
      throw new Exception("$level: invalid level");
 | 
			
		||||
    }
 | 
			
		||||
    return $level;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const GENERIC_PREFIXES = [
 | 
			
		||||
    self::LEVEL_MAJOR => [
 | 
			
		||||
      "section" => [true, "SECTION!", "===", "<color @b>= ", " =</color>", "==="],
 | 
			
		||||
      "title" => ["TITLE!", null, "<color @b>T</color><color b> ", "</color>", "---"],
 | 
			
		||||
      "desc" => ["DESC!", "<color @b>></color> ", ""],
 | 
			
		||||
      "error" => ["CRITICAL!", "<color @r>E! ", "</color>"],
 | 
			
		||||
      "warn" => ["ATTENTION!", "<color @y>W! ", "</color>"],
 | 
			
		||||
      "note" => ["IMPORTANT!", "<color @g>N! ", "</color>"],
 | 
			
		||||
      "info" => ["IMPORTANT!", "<color @b>I! ", "</color>"],
 | 
			
		||||
      "section" => [true, "SECTION!", "===", "<color @b>=", "=</color>", "==="],
 | 
			
		||||
      "title" => [false, "TITLE!", null, "<color @b>T</color><color b>", "</color>", "---"],
 | 
			
		||||
      "desc" => ["DESC!", "<color @b>></color>", ""],
 | 
			
		||||
      "error" => ["CRITICAL!", "<color @r>E!", "</color>"],
 | 
			
		||||
      "warn" => ["ATTENTION!", "<color @y>W!", "</color>"],
 | 
			
		||||
      "note" => ["IMPORTANT!", "<color @g>N!", "</color>"],
 | 
			
		||||
      "info" => ["IMPORTANT!", "<color @b>I!", "</color>"],
 | 
			
		||||
      "print" => [null, null, null],
 | 
			
		||||
    ],
 | 
			
		||||
    self::LEVEL_NORMAL => [
 | 
			
		||||
      "section" => [true, "SECTION:", null, "<color @b>>> ", " <<</color>", "---"],
 | 
			
		||||
      "title" => ["TITLE:", null, "<color @b>T</color><color b> ", "</color>", null],
 | 
			
		||||
      "desc" => ["DESC:", "<color @b>></color> ", ""],
 | 
			
		||||
      "error" => ["ERROR:", "<color @r>E</color><color r> ", "</color>"],
 | 
			
		||||
      "warn" => ["WARN:", "<color @y>W</color><color y> ", "</color>"],
 | 
			
		||||
      "note" => ["NOTE:", "<color @g>N</color> ", ""],
 | 
			
		||||
      "info" => ["INFO:", "<color @b>I</color> ", ""],
 | 
			
		||||
      "section" => [true, "SECTION:", "---", "<color @b>-", "-</color>", "---"],
 | 
			
		||||
      "title" => [false, "TITLE:", null, "<color @b>T</color><color b>", "</color>", null],
 | 
			
		||||
      "desc" => ["DESC:", "<color @b>></color>", ""],
 | 
			
		||||
      "error" => ["ERROR:", "<color @r>E</color><color r>", "</color>"],
 | 
			
		||||
      "warn" => ["WARN:", "<color @y>W</color><color y>", "</color>"],
 | 
			
		||||
      "note" => ["NOTE:", "<color @g>N</color>", ""],
 | 
			
		||||
      "info" => ["INFO:", "<color @b>I</color>", ""],
 | 
			
		||||
      "print" => [null, null, null],
 | 
			
		||||
    ],
 | 
			
		||||
    self::LEVEL_DEBUG => [
 | 
			
		||||
      "section" => [false, "s", null, "<color @w>>> ", " <<</color>", null],
 | 
			
		||||
      "title" => ["t", "<color b>t ", "</color>"],
 | 
			
		||||
      "desc" => [">", "<color b>></color> ", ""],
 | 
			
		||||
      "error" => ["e", "<color r>e</color><color -r> ", "</color>"],
 | 
			
		||||
      "warn" => ["w", "<color y>w</color><color -y> ", "</color>"],
 | 
			
		||||
      "note" => ["i", "<color b>i</color> ", ""],
 | 
			
		||||
      "info" => ["D", "<color @w>D</color><color w> ", "</color>"],
 | 
			
		||||
      "section" => [false, "section", null, "<color @w>>>", "<<</color>", null],
 | 
			
		||||
      "title" => [false, "title", null, "<color b>t", "</color>", null],
 | 
			
		||||
      "desc" => [">", "<color b>></color>", ""],
 | 
			
		||||
      "error" => ["e", "<color r>e</color><color -r>", "</color>"],
 | 
			
		||||
      "warn" => ["w", "<color y>w</color><color -y>", "</color>"],
 | 
			
		||||
      "note" => ["i", "<color b>i</color>", ""],
 | 
			
		||||
      "info" => ["D", "<color @w>D</color><color w>", "</color>"],
 | 
			
		||||
      "print" => [null, null, null],
 | 
			
		||||
    ],
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
@ -59,25 +73,24 @@ class Console implements IMessenger {
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  function __construct(?array $params=null) {
 | 
			
		||||
    $color = cl::get($params, "color");
 | 
			
		||||
    $debug = boolval(cl::get($params, "debug"));
 | 
			
		||||
    $minLevel = cl::get($params, "min_level");
 | 
			
		||||
    if ($minLevel === null) $minLevel = $debug? self::LEVEL_DEBUG: self::LEVEL_NORMAL;
 | 
			
		||||
    if (!in_array($minLevel, self::VALID_LEVELS)) {
 | 
			
		||||
      $minLevel = cl::get(self::LEVEL_MAP, $minLevel, $minLevel);
 | 
			
		||||
    }
 | 
			
		||||
    if (!in_array($minLevel, self::VALID_LEVELS)) {
 | 
			
		||||
      throw new Exception("$minLevel: invalid level");
 | 
			
		||||
    }
 | 
			
		||||
    $minLevel = self::verifix_level(cl::get($params, "min_level"), $debug);
 | 
			
		||||
    $defaultLevel = self::verifix_level(cl::get($params, "default_level"), false);
 | 
			
		||||
 | 
			
		||||
    $this->out = new StdOutput(STDOUT);
 | 
			
		||||
    $this->err = new StdOutput(STDERR);
 | 
			
		||||
    $params = [
 | 
			
		||||
      "color" => $color,
 | 
			
		||||
      "indent" => static::INDENT,
 | 
			
		||||
    ];
 | 
			
		||||
    $this->out = new StdOutput(STDOUT, $params);
 | 
			
		||||
    $this->err = new StdOutput(STDERR, $params);
 | 
			
		||||
    $this->minLevel = intval($minLevel);
 | 
			
		||||
    $this->indent = static::INDENT;
 | 
			
		||||
    $this->defaultLevel = intval($defaultLevel);
 | 
			
		||||
    $this->inSection = false;
 | 
			
		||||
    $this->titles = null;
 | 
			
		||||
    $this->currentTitle = null;
 | 
			
		||||
    $this->actions = null;
 | 
			
		||||
    $this->currentAction = null;
 | 
			
		||||
    $this->titles = [];
 | 
			
		||||
    $this->title = null;
 | 
			
		||||
    $this->actions = [];
 | 
			
		||||
    $this->action = null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** @var StdOutput la sortie standard */
 | 
			
		||||
@ -89,25 +102,93 @@ class Console implements IMessenger {
 | 
			
		||||
  /** @var int level minimum que doivent avoir les messages pour être affichés */
 | 
			
		||||
  protected $minLevel;
 | 
			
		||||
 | 
			
		||||
  /** @var string valeur unitaire de l'indentation */
 | 
			
		||||
  protected $indent;
 | 
			
		||||
  /** @var int level par défaut dans lequel les messages sont affichés */
 | 
			
		||||
  protected $defaultLevel;
 | 
			
		||||
 | 
			
		||||
  protected function checkLevel(?int &$level): bool {
 | 
			
		||||
    if ($level === null) $level = $this->defaultLevel;
 | 
			
		||||
    return $level >= $this->minLevel;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function _printTitle(int $level, string $type, $content, int $indentLevel, StdOutput $out): void {
 | 
			
		||||
    $prefixes = self::GENERIC_PREFIXES[$level][$type];
 | 
			
		||||
    if ($prefixes[0]) $out->print();
 | 
			
		||||
    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 = strlen($line);
 | 
			
		||||
        if ($len > $maxlen) $maxlen = $len;
 | 
			
		||||
        $content = [$content, $len];
 | 
			
		||||
      }; unset($content);
 | 
			
		||||
      if ($before !== null) {
 | 
			
		||||
        $out->iprint($indentLevel, $prefix, substr($before, 1), str_repeat($before[0], $maxlen), $suffix);
 | 
			
		||||
      }
 | 
			
		||||
      foreach ($lines as [$content, $len]) {
 | 
			
		||||
        $padding = $len < $maxlen? str_repeat(" ", $maxlen - $len): null;
 | 
			
		||||
        $out->iprint($indentLevel, $prefix2, $content, $padding, $suffix2);
 | 
			
		||||
      }
 | 
			
		||||
      if ($after !== null) {
 | 
			
		||||
        $out->iprint($indentLevel, $prefix, substr($after, 1), str_repeat($after[0], $maxlen), $suffix);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      $prefix = $prefixes[1];
 | 
			
		||||
      if ($prefix !== null) $prefix .= " ";
 | 
			
		||||
      $prefix2 = str_repeat(" ", strlen($prefix));
 | 
			
		||||
      $lines = $out->getLines(false, $content);
 | 
			
		||||
      foreach ($lines as $content) {
 | 
			
		||||
        $out->iprint($indentLevel, $prefix, $content);
 | 
			
		||||
        $prefix = $prefix2;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function _printGeneric(int $level, string $type, $content, int $indentLevel, StdOutput $out): void {
 | 
			
		||||
    $prefixes = self::GENERIC_PREFIXES[$level][$type];
 | 
			
		||||
    if ($out->isColor()) {
 | 
			
		||||
      $prefix = $prefixes[1];
 | 
			
		||||
      $suffix = $prefixes[2];
 | 
			
		||||
    } else {
 | 
			
		||||
      $prefix = $prefixes[0];
 | 
			
		||||
      $suffix = null;
 | 
			
		||||
    }
 | 
			
		||||
    $line = [$prefix];
 | 
			
		||||
    if ($prefix !== null) $line[] = " ";
 | 
			
		||||
    $line[] = $content;
 | 
			
		||||
    $line[] = $suffix;
 | 
			
		||||
    $out->iprint($indentLevel, ...$line);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** @var bool est-on dans une section? */
 | 
			
		||||
  protected $inSection;
 | 
			
		||||
 | 
			
		||||
  /** @var array|string section qui est en attente d'affichage */
 | 
			
		||||
  /** @var array section qui est en attente d'affichage */
 | 
			
		||||
  protected $section;
 | 
			
		||||
 | 
			
		||||
  function section($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
  function section($content, ?int $level=null): void {
 | 
			
		||||
    $this->endSection();
 | 
			
		||||
    $this->inSection = true;
 | 
			
		||||
    if ($level < $this->minLevel) return;
 | 
			
		||||
    $this->section = $content;
 | 
			
		||||
    if (!$this->checkLevel($level)) return;
 | 
			
		||||
    $this->section = [
 | 
			
		||||
      "level" => $level,
 | 
			
		||||
      "content" => $content,
 | 
			
		||||
      "print_content" => true,
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function printSection() {
 | 
			
		||||
    if ($this->section !== null) {
 | 
			
		||||
      $this->section = null;
 | 
			
		||||
    $section =& $this->section;
 | 
			
		||||
    if ($section["print_content"]) {
 | 
			
		||||
      $this->_printTitle($section["level"], "section", $section["content"], 0, $this->err);
 | 
			
		||||
      $section["print_content"] = false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -120,34 +201,57 @@ class Console implements IMessenger {
 | 
			
		||||
  protected $titles;
 | 
			
		||||
 | 
			
		||||
  /** @var array */
 | 
			
		||||
  protected $currentTitle;
 | 
			
		||||
  protected $title;
 | 
			
		||||
 | 
			
		||||
  function title($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
    if ($level < $this->minLevel) return;
 | 
			
		||||
  function title($content, ?int $level=null): void {
 | 
			
		||||
    if (!$this->checkLevel($level)) return;
 | 
			
		||||
    $this->titles[] = [
 | 
			
		||||
      "title" => $content, 
 | 
			
		||||
      "level" => $level,
 | 
			
		||||
      "content" => $content,
 | 
			
		||||
      "print_content" => true,
 | 
			
		||||
      "descs" => [],
 | 
			
		||||
      "print" => true, 
 | 
			
		||||
      "print_descs" => false,
 | 
			
		||||
    ];
 | 
			
		||||
    $this->currentTitle =& $this->titles[count($this->titles) - 1];
 | 
			
		||||
    $this->title =& $this->titles[count($this->titles) - 1];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function desc($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
    if ($level < $this->minLevel) return;
 | 
			
		||||
    $this->currentTitle["descs"][] = $content;
 | 
			
		||||
  function desc($content, ?int $level=null): void {
 | 
			
		||||
    if (!$this->checkLevel($level)) return;
 | 
			
		||||
    $title =& $this->title;
 | 
			
		||||
    $title["descs"][] = [
 | 
			
		||||
      "level" => $level,
 | 
			
		||||
      "content" => $content,
 | 
			
		||||
    ];
 | 
			
		||||
    $title["print_descs"] = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function printTitles(): void {
 | 
			
		||||
    $this->printSection();
 | 
			
		||||
    $out = $this->err;
 | 
			
		||||
    $indentLevel = 0;
 | 
			
		||||
    foreach ($this->titles as &$title) {
 | 
			
		||||
      if ($title["print_content"]) {
 | 
			
		||||
        $this->_printTitle($title["level"], "title", $title["content"], $indentLevel, $out);
 | 
			
		||||
        $title["print_content"] = false;
 | 
			
		||||
      }
 | 
			
		||||
      if ($title["print_descs"]) {
 | 
			
		||||
        foreach ($title["descs"] as $desc) {
 | 
			
		||||
          $this->_printGeneric($desc["level"], "desc", $desc["content"], $indentLevel, $out);
 | 
			
		||||
        }
 | 
			
		||||
        $title["descs"] = [];
 | 
			
		||||
        $title["print_descs"] = false;
 | 
			
		||||
      }
 | 
			
		||||
      $indentLevel++;
 | 
			
		||||
    }; unset($title);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function endTitle(): void {
 | 
			
		||||
    array_pop($this->titles);
 | 
			
		||||
    if ($this->titles) {
 | 
			
		||||
      $this->currentTitle =& $this->titles[count($this->titles) - 1];
 | 
			
		||||
      $this->title =& $this->titles[count($this->titles) - 1];
 | 
			
		||||
    } else {
 | 
			
		||||
      $this->titles = null;
 | 
			
		||||
      unset($this->currentTitle);
 | 
			
		||||
      $this->titles = [];
 | 
			
		||||
      unset($this->title);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -155,9 +259,19 @@ class Console implements IMessenger {
 | 
			
		||||
  protected $actions;
 | 
			
		||||
  
 | 
			
		||||
  /** @var array */
 | 
			
		||||
  protected $currentAction;
 | 
			
		||||
  protected $action;
 | 
			
		||||
 | 
			
		||||
  function action($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
  protected function getIndentLevel(): int {
 | 
			
		||||
    $indentLevel = count($this->titles) - 1;
 | 
			
		||||
    if ($indentLevel < 0) $indentLevel = 0;
 | 
			
		||||
    foreach ($this->actions as $action) {
 | 
			
		||||
      if ($action["level"] < $this->minLevel) continue;
 | 
			
		||||
      $indentLevel++;
 | 
			
		||||
    }
 | 
			
		||||
    return $indentLevel;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function action($content, ?int $level=null): void {
 | 
			
		||||
    $this->actions[] = [
 | 
			
		||||
      "level" => $level,
 | 
			
		||||
      "content" => $content,
 | 
			
		||||
@ -166,77 +280,81 @@ class Console implements IMessenger {
 | 
			
		||||
      "result" => null,
 | 
			
		||||
      "print_result" => true,
 | 
			
		||||
    ];
 | 
			
		||||
    $this->currentAction =& $this->actions[count($this->actions) - 1];
 | 
			
		||||
    $this->action =& $this->actions[count($this->actions) - 1];
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  function printActions(): void {
 | 
			
		||||
  function printActions(bool $willEnd=false): void {
 | 
			
		||||
    $this->printTitles();
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function step($content): void {
 | 
			
		||||
  function step($content, ?int $level=null): void {
 | 
			
		||||
    if (!$this->actions) $this->action(null);
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function success($content=null): void {
 | 
			
		||||
    if (!$this->actions) $this->action(null);
 | 
			
		||||
    $this->currentAction["success"] = true;
 | 
			
		||||
    $this->currentAction["result"] = $content;
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
    $this->action["success"] = true;
 | 
			
		||||
    $this->action["result"] = $content;
 | 
			
		||||
    $this->printActions(true);
 | 
			
		||||
    $this->endAction();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function failure($content=null): void {
 | 
			
		||||
    if (!$this->actions) $this->action(null);
 | 
			
		||||
    $this->currentAction["success"] = false;
 | 
			
		||||
    $this->currentAction["result"] = $content;
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
    $this->action["success"] = false;
 | 
			
		||||
    $this->action["result"] = $content;
 | 
			
		||||
    $this->printActions(true);
 | 
			
		||||
    $this->endAction();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function neutral($content=null): void {
 | 
			
		||||
    if (!$this->actions) $this->action(null);
 | 
			
		||||
    $this->currentAction["success"] = null;
 | 
			
		||||
    $this->currentAction["result"] = $content;
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
    $this->action["success"] = null;
 | 
			
		||||
    $this->action["result"] = $content;
 | 
			
		||||
    $this->printActions(true);
 | 
			
		||||
    $this->endAction();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function endAction(): void {
 | 
			
		||||
    array_pop($this->actions);
 | 
			
		||||
    if ($this->actions) {
 | 
			
		||||
      $this->currentAction =& $this->actions[count($this->actions) - 1];
 | 
			
		||||
      $this->action =& $this->actions[count($this->actions) - 1];
 | 
			
		||||
    } else {
 | 
			
		||||
      $this->actions = null;
 | 
			
		||||
      unset($this->currentAction);
 | 
			
		||||
      $this->actions = [];
 | 
			
		||||
      unset($this->action);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function print($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
    if ($level < $this->minLevel) return;
 | 
			
		||||
  function print($content, ?int $level=null): void {
 | 
			
		||||
    if (!$this->checkLevel($level)) return;
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
    $this->out->print($content);
 | 
			
		||||
    $this->_printGeneric($level, "print", $content, $this->getIndentLevel(), $this->out);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function info($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
    if ($level < $this->minLevel) return;
 | 
			
		||||
  function info($content, ?int $level=null): void {
 | 
			
		||||
    if (!$this->checkLevel($level)) return;
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
    $this->_printGeneric($level, "info", $content, $this->getIndentLevel(), $this->err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function note($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
    if ($level < $this->minLevel) return;
 | 
			
		||||
  function note($content, ?int $level=null): void {
 | 
			
		||||
    if (!$this->checkLevel($level)) return;
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
    $this->_printGeneric($level, "note", $content, $this->getIndentLevel(), $this->err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function warn($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
    if ($level < $this->minLevel) return;
 | 
			
		||||
  function warn($content, ?int $level=null): void {
 | 
			
		||||
    if (!$this->checkLevel($level)) return;
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
    $this->_printGeneric($level, "warn", $content, $this->getIndentLevel(), $this->err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function error($content, int $level=self::LEVEL_NORMAL): void {
 | 
			
		||||
    if ($level < $this->minLevel) return;
 | 
			
		||||
  function error($content, ?int $level=null): void {
 | 
			
		||||
    if (!$this->checkLevel($level)) return;
 | 
			
		||||
    $this->printActions();
 | 
			
		||||
    $this->_printGeneric($level, "error", $content, $this->getIndentLevel(), $this->err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function end(bool $all=false) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								src/output/IContent.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/output/IContent.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\output;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface IContent: un objet capable de produire du contenu à afficher
 | 
			
		||||
 */
 | 
			
		||||
interface IContent {
 | 
			
		||||
  /** retourner le contenu à afficher */
 | 
			
		||||
  function getContent(): iterable;
 | 
			
		||||
}
 | 
			
		||||
@ -13,7 +13,7 @@ interface IMessenger {
 | 
			
		||||
   * flush tous les messages en cours. ne peut être imbriqué. on peut considérer
 | 
			
		||||
   * que c'est une sorte de "reset" de l'objet
 | 
			
		||||
   */
 | 
			
		||||
  function section($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function section($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * commencer un chapitre.
 | 
			
		||||
@ -21,24 +21,24 @@ interface IMessenger {
 | 
			
		||||
   * peut être imbriqué dans un autre chapitre. terminer automatiquement
 | 
			
		||||
   * l'action en cours avec un résultat neutre
 | 
			
		||||
   */
 | 
			
		||||
  function title($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function title($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /** ajouter une description au chapitre courant. */
 | 
			
		||||
  function desc($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function desc($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * comencer une action dans le chapitre courant.
 | 
			
		||||
   *
 | 
			
		||||
   * peut être imbriqué dans une autre action.
 | 
			
		||||
   */
 | 
			
		||||
  function action($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function action($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ajouter une étape à l'action courante.
 | 
			
		||||
   *
 | 
			
		||||
   * démarrer une action le cas échéant (et la terminer aussitôt)
 | 
			
		||||
   */
 | 
			
		||||
  function step($content): void;
 | 
			
		||||
  function step($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * terminer l'action courante avec le résultat "succès"
 | 
			
		||||
@ -62,19 +62,19 @@ interface IMessenger {
 | 
			
		||||
  function neutral($content=null): void;
 | 
			
		||||
 | 
			
		||||
  /** afficher une donnée non structurée */
 | 
			
		||||
  function print($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function print($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /** ajouter un événément "information" */
 | 
			
		||||
  function info($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function info($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /** ajouter un événément "information importante" */
 | 
			
		||||
  function note($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function note($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /** ajouter un événément "avertissement" */
 | 
			
		||||
  function warn($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function warn($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /** ajouter un événément "erreur" */
 | 
			
		||||
  function error($content, int $level=self::LEVEL_NORMAL): void;
 | 
			
		||||
  function error($content, ?int $level=null): void;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * terminer le chapitre en cours. toutes les actions en cours sont terminées
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								src/output/IPrintable.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/output/IPrintable.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace nur\sery\output;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Interface IPrintable: un objet qui peut écrire du contenu sur la sortie
 | 
			
		||||
 * standard
 | 
			
		||||
 */
 | 
			
		||||
interface IPrintable {
 | 
			
		||||
  /** afficher le contenu */
 | 
			
		||||
  function print(): void;
 | 
			
		||||
}
 | 
			
		||||
@ -72,6 +72,7 @@ class StdOutput {
 | 
			
		||||
    if ($output === null) $output = cl::get($params, "output");
 | 
			
		||||
    $color = cl::get($params, "color");
 | 
			
		||||
    $filterTags = cl::get($params, "filter_tags", true);
 | 
			
		||||
    $indent = cl::get($params, "indent", "  ");
 | 
			
		||||
    $flush = cl::get($params, "flush");
 | 
			
		||||
 | 
			
		||||
    if ($output === null) {
 | 
			
		||||
@ -100,6 +101,7 @@ class StdOutput {
 | 
			
		||||
    $this->outf = $outf;
 | 
			
		||||
    $this->color = boolval($color);
 | 
			
		||||
    $this->filterTags = boolval($filterTags);
 | 
			
		||||
    $this->indent = $indent;
 | 
			
		||||
    $this->flush = boolval($flush);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -116,6 +118,9 @@ class StdOutput {
 | 
			
		||||
  /** @var bool faut-il enlever les tags dans la sortie? */
 | 
			
		||||
  protected $filterTags;
 | 
			
		||||
 | 
			
		||||
  /** @var string indentation unitaire */
 | 
			
		||||
  protected $indent;
 | 
			
		||||
 | 
			
		||||
  /** @var bool faut-il flush le fichier après l'écriture de chaque ligne */
 | 
			
		||||
  protected $flush;
 | 
			
		||||
 | 
			
		||||
@ -155,24 +160,82 @@ class StdOutput {
 | 
			
		||||
    }
 | 
			
		||||
    return $text;
 | 
			
		||||
  }
 | 
			
		||||
  protected function filterColors(string $text): string {
 | 
			
		||||
  function filterColors(string $text): string {
 | 
			
		||||
    return preg_replace('/\x1B\[.*?m/', "", $text);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected function fwrite(array $values): void {
 | 
			
		||||
  static function flatten($values, ?array &$dest=null): array {
 | 
			
		||||
    if ($dest === null) $dest = [];
 | 
			
		||||
    if ($values === null) return $dest;
 | 
			
		||||
    if (is_string($values)) {
 | 
			
		||||
      $dest[] = $values;
 | 
			
		||||
      return $dest;
 | 
			
		||||
    } elseif (!is_array($values)) {
 | 
			
		||||
      if ($values instanceof IContent) {
 | 
			
		||||
        $values = $values->getContent();
 | 
			
		||||
      } elseif ($values instanceof IPrintable) {
 | 
			
		||||
        ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
 | 
			
		||||
        $values->print();
 | 
			
		||||
        $dest[] = ob_get_clean();
 | 
			
		||||
        return $dest;
 | 
			
		||||
      } elseif (!is_iterable($values)) {
 | 
			
		||||
        $dest[] = strval($values);
 | 
			
		||||
        return $dest;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    foreach ($values as $value) {
 | 
			
		||||
      self::flatten($value, $dest);
 | 
			
		||||
    }
 | 
			
		||||
    return $dest;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getIndent(int $indentLevel): string {
 | 
			
		||||
    return str_repeat($this->indent, $indentLevel);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function getLines(bool $withNl, ...$values): array {
 | 
			
		||||
    $values = self::flatten($values);
 | 
			
		||||
    $text = implode("", $values);
 | 
			
		||||
    $text = $this->filterContent($text);
 | 
			
		||||
    if (!$this->color) $text = $this->filterColors($text);
 | 
			
		||||
    fwrite($this->outf, $text);
 | 
			
		||||
    if ($this->flush) fflush($this->outf);
 | 
			
		||||
    $lines = explode("\n", $text);
 | 
			
		||||
    $max = count($lines) - 1;
 | 
			
		||||
    if ($withNl) {
 | 
			
		||||
      for ($i = 0; $i < $max; $i++) {
 | 
			
		||||
        $lines[$i] .= "\n";
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if ($lines[$max] === "") unset($lines[$max]);
 | 
			
		||||
    return $lines;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function writeLines($indent, array $lines, bool $addNl=false): void {
 | 
			
		||||
    $outf = $this->outf;
 | 
			
		||||
    foreach ($lines as $line) {
 | 
			
		||||
      if ($indent !== null) fwrite($outf, $indent);
 | 
			
		||||
      fwrite($outf, $line);
 | 
			
		||||
      if ($addNl) fwrite($outf, "\n");
 | 
			
		||||
    }
 | 
			
		||||
    if ($this->flush) fflush($outf);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function write(...$values): void {
 | 
			
		||||
    $this->fwrite($values);
 | 
			
		||||
    $this->writeLines(null, $this->getLines(true, ...$values));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function print(...$values): void {
 | 
			
		||||
    $values[] = "\n";
 | 
			
		||||
    $this->fwrite($values);
 | 
			
		||||
    $this->writeLines(null, $this->getLines(true, ...$values));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function iwrite(int $indentLevel, ...$values): void {
 | 
			
		||||
    $indent = $this->getIndent($indentLevel);
 | 
			
		||||
    $this->writeLines($indent, $this->getLines(true, ...$values));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function iprint(int $indentLevel, ...$values): void {
 | 
			
		||||
    $values[] = "\n";
 | 
			
		||||
    $indent = $this->getIndent($indentLevel);
 | 
			
		||||
    $this->writeLines($indent, $this->getLines(true, ...$values));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										84
									
								
								tbin/test-console.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										84
									
								
								tbin/test-console.php
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,84 @@
 | 
			
		||||
#!/usr/bin/php
 | 
			
		||||
<?php
 | 
			
		||||
require(__DIR__.'/../vendor/autoload.php');
 | 
			
		||||
 | 
			
		||||
use nur\sery\output\Console;
 | 
			
		||||
 | 
			
		||||
$params = [];
 | 
			
		||||
$count = count($argv) - 1;
 | 
			
		||||
for ($i = 1; $i <= $count; $i++) {
 | 
			
		||||
  switch ($argv[$i]) {
 | 
			
		||||
  case "-n":
 | 
			
		||||
    $params["color"] = false;
 | 
			
		||||
    break;
 | 
			
		||||
  case "+n":
 | 
			
		||||
    $params["color"] = true;
 | 
			
		||||
    break;
 | 
			
		||||
  case "-d":
 | 
			
		||||
    $params["debug"] = true;
 | 
			
		||||
    break;
 | 
			
		||||
  case "+d":
 | 
			
		||||
    $params["debug"] = false;
 | 
			
		||||
    break;
 | 
			
		||||
  case "-D":
 | 
			
		||||
    $params["default_level"] = "debug";
 | 
			
		||||
    $params["debug"] = true;
 | 
			
		||||
    break;
 | 
			
		||||
  case "-N":
 | 
			
		||||
    $params["default_level"] = "normal";
 | 
			
		||||
    break;
 | 
			
		||||
  case "-M":
 | 
			
		||||
    $params["default_level"] = "major";
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
$c = new Console($params);
 | 
			
		||||
 | 
			
		||||
$c->section("section");
 | 
			
		||||
 | 
			
		||||
$c->title("title");
 | 
			
		||||
$c->desc("desc");
 | 
			
		||||
$c->print("print");
 | 
			
		||||
 | 
			
		||||
$c->action("action");
 | 
			
		||||
$c->step("step");
 | 
			
		||||
$c->success("action success");
 | 
			
		||||
 | 
			
		||||
$c->action("action");
 | 
			
		||||
$c->step("step");
 | 
			
		||||
$c->failure("action failure");
 | 
			
		||||
 | 
			
		||||
$c->action("action");
 | 
			
		||||
$c->success("action success");
 | 
			
		||||
 | 
			
		||||
$c->action("action");
 | 
			
		||||
$c->failure("action failure");
 | 
			
		||||
 | 
			
		||||
$c->action("action0");
 | 
			
		||||
$c->action("action1");
 | 
			
		||||
$c->action("action2");
 | 
			
		||||
$c->success("action2 success");
 | 
			
		||||
$c->success("action1 success");
 | 
			
		||||
$c->success("action0 success");
 | 
			
		||||
 | 
			
		||||
$c->info("info");
 | 
			
		||||
$c->note("note");
 | 
			
		||||
$c->warn("warn");
 | 
			
		||||
$c->error("error");
 | 
			
		||||
 | 
			
		||||
$c->end();
 | 
			
		||||
 | 
			
		||||
$c->title("title0");
 | 
			
		||||
$c->title("title1");
 | 
			
		||||
$c->print("print under title1");
 | 
			
		||||
$c->end();
 | 
			
		||||
$c->print("print under title0");
 | 
			
		||||
$c->end();
 | 
			
		||||
 | 
			
		||||
$c->end(true);
 | 
			
		||||
 | 
			
		||||
$c->section("multi-line\nsection");
 | 
			
		||||
$c->title("multi-line\ntitle");
 | 
			
		||||
$c->title("another\ntitle");
 | 
			
		||||
$c->print("multi-line\nprint");
 | 
			
		||||
$c->end(true);
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user