nur-sery/nur_src/b/ui/IMessenger.php

158 lines
6.3 KiB
PHP

<?php
namespace nur\b\ui;
use nur\b\params\IParametrable;
use Throwable;
/**
* Interface IMessenger: interface pour un objet qui centralise des informations
* à afficher à l'utilisateur et/ou à logguer dans un fichier
*/
interface IMessenger extends IParametrable {
# Types et destination de messages
const TYPE_MASK = 0b11;
const TYPE_ERROR = 3, TYPE_WARNING = 2, TYPE_INFO = 1, TYPE_DEBUG = 0;
const RESULT_MASK = 0b1100;
const RESULT_FAILURE = 3 << 2, RESULT_SUCCESS = 2 << 2, RESULT_NEUTRAL = 1 << 2, RESULT_NONE = 0 << 2;
const DEST_MASK = 0b110000;
const DEST_LOG = 2 << 4, DEST_DISPLAY = 1 << 4, DEST_ALL = self::DEST_DISPLAY + self::DEST_LOG;
# Niveaux de messages
const LEVEL_NEVER = PHP_INT_MAX;
const LEVEL_CRITICAL = 100, LEVEL_MAJOR = 90, LEVEL_NORMAL = 30, LEVEL_MINOR = 0;
const LEVEL_ALWAYS = PHP_INT_MIN;
# Composantes d'un message
const KEY_USER = "user", KEY_TECH = "tech", KEY_EXCEPTION = "exception";
const LEVELS_SCHEMA = [
self::KEY_USER => [null, null, "niveau minimum pour afficher des messages utilisateurs"],
self::KEY_TECH => [null, null, "niveau minimum pour afficher des messages techniques"],
self::KEY_EXCEPTION => [null, null, "niveau minimum pour afficher les traces d'exception"],
];
/**
* spécifier les niveaux minimum pour que soient affichés les messages de type
* user, tech et exception.
*
* $levels doit être conforme au schéma {@link LEVELS_SCHEMA}.
* chaque valeur peut être un niveau numérique ou un tableau de la forme
* [$default_level, $profile => $level, ...]
*/
function setLevels(?array $printLevels, ?array $logLevels=null, $typeLevels=null): IMessenger;
/**
* démarrer une nouvelle section dans laquelle ajouter des messages. si une
* section est en cours, la terminer d'abord (il n'est pas prévu de pouvoir
* imbriquer des sections)
*
* @param int|null $msgType le type des messages de cette section. c'est une
* information qui peut être utilisée pour mettre en forme la section
* @param int|null $msgLevel le niveau maximum des messages de cette section.
* c'est une information heuristique pour voir si la section sera affichée ou
* non. si $level===null, la section est toujours affichée
*/
function startSection($title, ?int $msgType=null, ?int $msgLevel=null): IMessenger;
/** retourner true si on est actuellement dans une section */
function isInSection(): bool;
/** terminer explicitement la section démarrée par {@link startSection()} */
function endSection(): IMessenger;
/**
* démarrer un nouveau groupe de messages. contrairement aux sections, les
* groupes peuvent être imbriqués. $count indique le nombre de messages prévus
* dans ce groupe, ou null, si le nombre est inconnu. l'implémentation peut
* choisir d'afficher un groupe différemment en fonction du nombre de ses
* messages
*
* @param int|null $msgType le type des messages de ce groupe. c'est une
* information qui peut être utilisée pour mettre en forme le groupe
* @param int|null $msgLevel le niveau maximum des messages de ce groupe.
* c'est une information heuristique pour voir si le groupe sera affiché ou
* non. si $level===null, le groupe est toujours affiché
*/
function startGroup($prefix, ?int $count=null, ?int $msgType=null, ?int $msgLevel=null): IMessenger;
/** retourner true si on est actuellement dans un groupe */
function isInGroup(): bool;
/** terminer le groupe démarré par {@link startGroup()} */
function endGroup(): IMessenger;
/**
* terminer le groupe ou la section en cours, le cas échéant. si $all==true
* alors terminer tous les groupes en cours, puis terminer le section courante
*/
function end(bool $all=false): IMessenger;
const MESSAGE_SCHEMA = [
self::KEY_USER => [null, null, "message à afficher à l'utilisateur",
# il peut s'agir d'une chaine ou d'une instance de Exception
],
self::KEY_TECH => [null, null, "message technique consultable par l'utilisateur",
# il peut s'agir d'une chaine ou d'une instance de Exception
],
self::KEY_EXCEPTION => [null, null, "instance de Exception qui a provoqué ce message"],
];
# options dépendantes de l'implémentation
const MESSAGE_OPTIONS_SCHEMA = [];
/** normaliser $message pour qu'il soit conforme au schéma */
function ensureMessage(&$message): void;
/**
* ajouter un message de type $type et de niveau $level. le message n'est pris
* en compte que si les niveaux sont suffisants.
*
* C'est à l'implémentation de décider si le message sera affiché de suite ou
* à la fin du groupe ou de la section.
*
* @param array|string|Throwable $message le message à afficher, conforme à
* {@link MESSAGE_SCHEMA} et {@link MESSAGE_OPTIONS_SCHEMA}
* @param int $type le type de message
* @param int $level le niveau du message
*/
function addMessage($message, int $type, int $level): IMessenger;
/**
* méthode de convenance pour démarrer un groupe d'un seul message, puis, si
* le résultat est fourni, le terminer avec le résultat spécifié.
*/
function action($message, $result=null, ?array $args=null, ?int $type=null, ?int $level=null): IMessenger;
/**
* méthode de convenance qui termine le groupe courant avec le résultat
* spécifié
*
* - result peut être booléen: true pour succès, false pour échec
* - si c'est une chaine de caractère, alors c'est un succès
* - si c'est une exception, alors c'est un échec
* - si un callable, alors la fonction est appelée avec les arguments $args et
* le résultat est évalué selon les règles précédentes
*
* $type n'est utilisé que pour spécifier la destination le cas échéant
*/
function aresult($result, ?array $args=null, $message=null, ?int $type=null): IMessenger;
/**
* méthode de convenance qui appelle
* aresult(true, null, $message, $type + NEUTRAL);
*/
function astep($message=null, ?int $type=null): IMessenger;
/**
* méthode de convenance qui appelle
* aresult(true, null, $message, $type);
*/
function asuccess($message=null, ?int $type=null): IMessenger;
/**
* méthode de convenance qui appelle
* aresult(false, null, [...$message, "exception" => $e], $type);
*/
function afailure($message=null, ?Throwable $e=null, ?int $type=null): IMessenger;
}