modifs.mineures sans commentaires
This commit is contained in:
		
							parent
							
								
									a70bccbeb8
								
							
						
					
					
						commit
						6435bd0d1d
					
				@ -6,9 +6,10 @@ namespace nur\sery\db;
 | 
				
			|||||||
 * instance de {@link CapacitorStorage}
 | 
					 * instance de {@link CapacitorStorage}
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class Capacitor {
 | 
					class Capacitor {
 | 
				
			||||||
  function __construct(CapacitorStorage $storage, CapacitorChannel $channel) {
 | 
					  function __construct(CapacitorStorage $storage, CapacitorChannel $channel, bool $ensureExists=true) {
 | 
				
			||||||
    $this->storage = $storage;
 | 
					    $this->storage = $storage;
 | 
				
			||||||
    $this->channel = $channel;
 | 
					    $this->channel = $channel;
 | 
				
			||||||
 | 
					    if ($ensureExists) $this->ensureExists();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** @var CapacitorStorage */
 | 
					  /** @var CapacitorStorage */
 | 
				
			||||||
@ -21,14 +22,22 @@ class Capacitor {
 | 
				
			|||||||
    return $this->storage->_exists($this->channel);
 | 
					    return $this->storage->_exists($this->channel);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function ensureExists(): void {
 | 
				
			||||||
 | 
					    $this->storage->_ensureExists($this->channel);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function reset(): void {
 | 
					  function reset(): void {
 | 
				
			||||||
    $this->storage->_reset($this->channel);
 | 
					    $this->storage->_reset($this->channel);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function charge($item, ?callable $func=null, ?array $args=null): bool {
 | 
					  function charge($item, ?callable $func=null, ?array $args=null): int {
 | 
				
			||||||
    return $this->storage->_charge($this->channel, $item, $func, $args);
 | 
					    return $this->storage->_charge($this->channel, $item, $func, $args);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function count($filter=null): int {
 | 
				
			||||||
 | 
					    return $this->storage->_count($this->channel, $filter);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function discharge($filter=null, ?bool $reset=null): iterable {
 | 
					  function discharge($filter=null, ?bool $reset=null): iterable {
 | 
				
			||||||
    return $this->storage->_discharge($this->channel, $filter, $reset);
 | 
					    return $this->storage->_discharge($this->channel, $filter, $reset);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -37,8 +46,8 @@ class Capacitor {
 | 
				
			|||||||
    return $this->storage->_get($this->channel, $filter);
 | 
					    return $this->storage->_get($this->channel, $filter);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function each($filter, ?callable $func=null, ?array $args=null): void {
 | 
					  function each($filter, ?callable $func=null, ?array $args=null): int {
 | 
				
			||||||
    $this->storage->_each($this->channel, $filter, $func, $args);
 | 
					    return $this->storage->_each($this->channel, $filter, $func, $args);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function close(): void {
 | 
					  function close(): void {
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,13 @@ abstract class CapacitorStorage {
 | 
				
			|||||||
    return $this->_exists($this->getChannel($channel));
 | 
					    return $this->_exists($this->getChannel($channel));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  abstract function _ensureExists(CapacitorChannel $channel): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** s'assurer que le canal spécifié existe */
 | 
				
			||||||
 | 
					  function ensureExists(?string $channel): void {
 | 
				
			||||||
 | 
					    $this->_ensureExists($this->getChannel($channel));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  abstract function _reset(CapacitorChannel $channel): void;
 | 
					  abstract function _reset(CapacitorChannel $channel): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** supprimer le canal spécifié */
 | 
					  /** supprimer le canal spécifié */
 | 
				
			||||||
@ -22,7 +29,7 @@ abstract class CapacitorStorage {
 | 
				
			|||||||
    $this->_reset($this->getChannel($channel));
 | 
					    $this->_reset($this->getChannel($channel));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  abstract function _charge(CapacitorChannel $channel, $item, ?callable $func, ?array $args): bool;
 | 
					  abstract function _charge(CapacitorChannel $channel, $item, ?callable $func, ?array $args): int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * charger une valeur dans le canal
 | 
					   * charger une valeur dans le canal
 | 
				
			||||||
@ -33,13 +40,20 @@ abstract class CapacitorStorage {
 | 
				
			|||||||
   * Si la fonction retourne un tableau, il est utilisé pour modifier les valeurs
 | 
					   * Si la fonction retourne un tableau, il est utilisé pour modifier les valeurs
 | 
				
			||||||
   * insérées/mises à jour
 | 
					   * insérées/mises à jour
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * @return true si l'objet a été chargé ou mis à jour, false s'il existait
 | 
					   * @return int 1 si l'objet a été chargé ou mis à jour, 0 s'il existait
 | 
				
			||||||
   * déjà à l'identique dans le canal
 | 
					   * déjà à l'identique dans le canal
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function charge(?string $channel, $item, ?callable $func=null, ?array $args=null): bool {
 | 
					  function charge(?string $channel, $item, ?callable $func=null, ?array $args=null): int {
 | 
				
			||||||
    return $this->_charge($this->getChannel($channel), $item, $func, $args);
 | 
					    return $this->_charge($this->getChannel($channel), $item, $func, $args);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  abstract function _count(CapacitorChannel $channel, $filter): int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** indiquer le nombre d'éléments du canal spécifié */
 | 
				
			||||||
 | 
					  function count(?string $channel, $filter=null): int {
 | 
				
			||||||
 | 
					    return $this->_count($this->getChannel($channel), $filter);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  abstract function _discharge(CapacitorChannel $channel, $filter, ?bool $reset): iterable;
 | 
					  abstract function _discharge(CapacitorChannel $channel, $filter, ?bool $reset): iterable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** décharger les données du canal spécifié */
 | 
					  /** décharger les données du canal spécifié */
 | 
				
			||||||
@ -58,7 +72,7 @@ abstract class CapacitorStorage {
 | 
				
			|||||||
    return $this->_get($this->getChannel($channel), $filter);
 | 
					    return $this->_get($this->getChannel($channel), $filter);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  abstract function _each(CapacitorChannel $channel, $filter, ?callable $func, ?array $args): void;
 | 
					  abstract function _each(CapacitorChannel $channel, $filter, ?callable $func, ?array $args): int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * appeler une fonction pour chaque élément du canal spécifié.
 | 
					   * appeler une fonction pour chaque élément du canal spécifié.
 | 
				
			||||||
@ -67,9 +81,11 @@ abstract class CapacitorStorage {
 | 
				
			|||||||
   *
 | 
					   *
 | 
				
			||||||
   * $func est appelé avec la signature ($item, $row, ...$args). si la fonction
 | 
					   * $func est appelé avec la signature ($item, $row, ...$args). si la fonction
 | 
				
			||||||
   * retourne un tableau, il est utilisé pour mettre à jour la ligne
 | 
					   * retourne un tableau, il est utilisé pour mettre à jour la ligne
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @return int le nombre de lignes parcourues
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  function each(?string $channel, $filter, ?callable $func=null, ?array $args=null): void {
 | 
					  function each(?string $channel, $filter, ?callable $func=null, ?array $args=null): int {
 | 
				
			||||||
    $this->_each($this->getChannel($channel), $filter, $func, $args);
 | 
					    return $this->_each($this->getChannel($channel), $filter, $func, $args);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  abstract function close(): void;
 | 
					  abstract function close(): void;
 | 
				
			||||||
 | 
				
			|||||||
@ -68,6 +68,10 @@ class SqliteCapacitor extends CapacitorStorage {
 | 
				
			|||||||
    return $tableName !== null;
 | 
					    return $tableName !== null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function _ensureExists(CapacitorChannel $channel): void {
 | 
				
			||||||
 | 
					    $this->_create($channel);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function _reset(CapacitorChannel $channel): void {
 | 
					  function _reset(CapacitorChannel $channel): void {
 | 
				
			||||||
    $this->sqlite->exec([
 | 
					    $this->sqlite->exec([
 | 
				
			||||||
      "drop table if exists",
 | 
					      "drop table if exists",
 | 
				
			||||||
@ -76,7 +80,7 @@ class SqliteCapacitor extends CapacitorStorage {
 | 
				
			|||||||
    $channel->setCreated(false);
 | 
					    $channel->setCreated(false);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function _charge(CapacitorChannel $channel, $item, ?callable $func, ?array $args): bool {
 | 
					  function _charge(CapacitorChannel $channel, $item, ?callable $func, ?array $args): int {
 | 
				
			||||||
    $this->_create($channel);
 | 
					    $this->_create($channel);
 | 
				
			||||||
    $now = date("Y-m-d H:i:s");
 | 
					    $now = date("Y-m-d H:i:s");
 | 
				
			||||||
    $_item = serialize($item);
 | 
					    $_item = serialize($item);
 | 
				
			||||||
@ -129,7 +133,7 @@ class SqliteCapacitor extends CapacitorStorage {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if ($insert === null) {
 | 
					    if ($insert === null) {
 | 
				
			||||||
      # aucune modification
 | 
					      # aucune modification
 | 
				
			||||||
      return false;
 | 
					      return 0;
 | 
				
			||||||
    } elseif ($insert) {
 | 
					    } elseif ($insert) {
 | 
				
			||||||
      $this->sqlite->exec([
 | 
					      $this->sqlite->exec([
 | 
				
			||||||
        "insert",
 | 
					        "insert",
 | 
				
			||||||
@ -144,7 +148,16 @@ class SqliteCapacitor extends CapacitorStorage {
 | 
				
			|||||||
        "where" => ["_id" => $id],
 | 
					        "where" => ["_id" => $id],
 | 
				
			||||||
      ]);
 | 
					      ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return true;
 | 
					    return 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function _count(CapacitorChannel $channel, $filter): int {
 | 
				
			||||||
 | 
					    if ($filter !== null && !is_array($filter)) $filter = ["_id" => $filter];
 | 
				
			||||||
 | 
					    return $this->sqlite->get([
 | 
				
			||||||
 | 
					      "select count(*)",
 | 
				
			||||||
 | 
					      "from" => $channel->getTableName(),
 | 
				
			||||||
 | 
					      "where" => $filter,
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function _discharge(CapacitorChannel $channel, $filter, ?bool $reset): iterable {
 | 
					  function _discharge(CapacitorChannel $channel, $filter, ?bool $reset): iterable {
 | 
				
			||||||
@ -174,13 +187,14 @@ class SqliteCapacitor extends CapacitorStorage {
 | 
				
			|||||||
    else return unserialize($row["_item"]);
 | 
					    else return unserialize($row["_item"]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function _each(CapacitorChannel $channel, $filter, ?callable $func, ?array $args): void {
 | 
					  function _each(CapacitorChannel $channel, $filter, ?callable $func, ?array $args): int {
 | 
				
			||||||
    if ($func === null) $func = [$channel, "onEach"];
 | 
					    if ($func === null) $func = [$channel, "onEach"];
 | 
				
			||||||
    $onEach = func::_prepare($func);
 | 
					    $onEach = func::_prepare($func);
 | 
				
			||||||
    if ($filter !== null && !is_array($filter)) $filter = ["_id" => $filter];
 | 
					    if ($filter !== null && !is_array($filter)) $filter = ["_id" => $filter];
 | 
				
			||||||
    $sqlite = $this->sqlite;
 | 
					    $sqlite = $this->sqlite;
 | 
				
			||||||
    $tableName = $channel->getTableName();
 | 
					    $tableName = $channel->getTableName();
 | 
				
			||||||
    $commited = false;
 | 
					    $commited = false;
 | 
				
			||||||
 | 
					    $count = 0;
 | 
				
			||||||
    $sqlite->beginTransaction();
 | 
					    $sqlite->beginTransaction();
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      $rows = $sqlite->all([
 | 
					      $rows = $sqlite->all([
 | 
				
			||||||
@ -203,9 +217,11 @@ class SqliteCapacitor extends CapacitorStorage {
 | 
				
			|||||||
            "where" => ["_id" => $row["_id"]],
 | 
					            "where" => ["_id" => $row["_id"]],
 | 
				
			||||||
          ]);
 | 
					          ]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        $count++;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      $sqlite->commit();
 | 
					      $sqlite->commit();
 | 
				
			||||||
      $commited = true;
 | 
					      $commited = true;
 | 
				
			||||||
 | 
					      return $count;
 | 
				
			||||||
    } finally {
 | 
					    } finally {
 | 
				
			||||||
      if (!$commited) $sqlite->rollback();
 | 
					      if (!$commited) $sqlite->rollback();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -70,6 +70,17 @@ interface IMessenger {
 | 
				
			|||||||
   */
 | 
					   */
 | 
				
			||||||
  function adone($content=null, ?int $overrideLevel=null): void;
 | 
					  function adone($content=null, ?int $overrideLevel=null): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * terminer l'action courante avec le résultat "succès", "échec" ou "neutre"
 | 
				
			||||||
 | 
					   * en fonction de la valeur de $result
 | 
				
			||||||
 | 
					   * - si c'est un booléen, true vaut succès, false vaut échec
 | 
				
			||||||
 | 
					   * - si c'est une exception, c'est un échec et le message est affiché
 | 
				
			||||||
 | 
					   * - sinon, le résultat est neutre et le message est affiché s'il n'est pas null
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * démarrer une action le cas échéant (et la terminer aussitôt)
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function aresult($result=null, ?int $overrideLevel=null): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** afficher une donnée non structurée */
 | 
					  /** afficher une donnée non structurée */
 | 
				
			||||||
  function print($content, ?int $level=null): void;
 | 
					  function print($content, ?int $level=null): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,22 @@
 | 
				
			|||||||
  rotation des logs
 | 
					  rotation des logs
 | 
				
			||||||
  * [ ] lors de la rotation, si l'ouverture du nouveau fichier échoue, continuer
 | 
					  * [ ] lors de la rotation, si l'ouverture du nouveau fichier échoue, continuer
 | 
				
			||||||
    à écrire dans l'ancien fichier
 | 
					    à écrire dans l'ancien fichier
 | 
				
			||||||
 | 
					  * ou alors un moyen pour ré-ouvrir la sortie, afin de pouvoir indiquer à un
 | 
				
			||||||
 | 
					    long running process qu'une rotation a eu lieu
 | 
				
			||||||
* [ ] dans `StdMessenger::resetParams()`, `[output]` peut être une instance de
 | 
					* [ ] dans `StdMessenger::resetParams()`, `[output]` peut être une instance de
 | 
				
			||||||
  StdOutput pour mettre à jour $out ET $err, ou un tableau de deux éléments pour
 | 
					  StdOutput pour mettre à jour $out ET $err, ou un tableau de deux éléments pour
 | 
				
			||||||
  mettre à jour séparément $out et $err
 | 
					  mettre à jour séparément $out et $err
 | 
				
			||||||
 | 
					* [ ] vérifier que la date affichée pour un TITLE est celle à laquelle l'appel
 | 
				
			||||||
 | 
					  a été fait, même si le premier événement en dessous arrive bien plus tard
 | 
				
			||||||
 | 
					* [ ] pareil pour action: sauf si c'est une seule ligne, la date de action est
 | 
				
			||||||
 | 
					  la date du premier appel, alors que la date de $result est celui du result si
 | 
				
			||||||
 | 
					  c'est affiché sur une autre ligne
 | 
				
			||||||
 | 
					* réorganiser pour que msg:: attaque un proxy dans lequel est configuré un
 | 
				
			||||||
 | 
					  ensemble standard de sorties: say, log, debuglog
 | 
				
			||||||
 | 
					  * `--aD, --av, --aq, --asilent` pour les valeurs d'ajustement qui sont un
 | 
				
			||||||
 | 
					    incrément à la valeur courante (+2, +1, -1, -2)
 | 
				
			||||||
 | 
					  * `--yD, --yv, --yq, --ysilent, -D, -v, -q, --silent` pour say
 | 
				
			||||||
 | 
					  * `--lD, --lv, --lq, --lsilent` pour log, `-L:, --L` l'active
 | 
				
			||||||
 | 
					  * `--DD, --Dv, --Dq, --Dsilent` pour debuglog, `--DL:` l'active
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
 | 
					-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary
 | 
				
			||||||
@ -62,6 +62,7 @@ abstract class _messenger {
 | 
				
			|||||||
  static function asuccess($content=null, ?int $override_level=null): void { static::get()->asuccess($content, $override_level); }
 | 
					  static function asuccess($content=null, ?int $override_level=null): void { static::get()->asuccess($content, $override_level); }
 | 
				
			||||||
  static function afailure($content=null, ?int $override_level=null): void { static::get()->afailure($content, $override_level); }
 | 
					  static function afailure($content=null, ?int $override_level=null): void { static::get()->afailure($content, $override_level); }
 | 
				
			||||||
  static function adone($content=null, ?int $override_level=null): void { static::get()->adone($content, $override_level); }
 | 
					  static function adone($content=null, ?int $override_level=null): void { static::get()->adone($content, $override_level); }
 | 
				
			||||||
 | 
					  static function aresult($result=null, ?int $override_level=null): void { static::get()->aresult($result, $override_level); }
 | 
				
			||||||
  static function print($content, ?int $level=null): void { static::get()->print($content, $level); }
 | 
					  static function print($content, ?int $level=null): void { static::get()->print($content, $level); }
 | 
				
			||||||
  static function info($content, ?int $level=null): void { static::get()->info($content, $level); }
 | 
					  static function info($content, ?int $level=null): void { static::get()->info($content, $level); }
 | 
				
			||||||
  static function note($content, ?int $level=null): void { static::get()->note($content, $level); }
 | 
					  static function note($content, ?int $level=null): void { static::get()->note($content, $level); }
 | 
				
			||||||
 | 
				
			|||||||
@ -85,12 +85,11 @@ class ProxyMessenger implements IMessenger {
 | 
				
			|||||||
    if ($useFunc && $func !== null) {
 | 
					    if ($useFunc && $func !== null) {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        $result = $func($this);
 | 
					        $result = $func($this);
 | 
				
			||||||
        if ($result !== null) {
 | 
					 | 
				
			||||||
        /** @var _IMessenger $msg */
 | 
					        /** @var _IMessenger $msg */
 | 
				
			||||||
 | 
					        $index = 0;
 | 
				
			||||||
        foreach ($this->msgs as $msg) {
 | 
					        foreach ($this->msgs as $msg) {
 | 
				
			||||||
            if ($result === true) $msg->asuccess();
 | 
					          if ($msg->_getActionMark() > $untils[$index++]) {
 | 
				
			||||||
            elseif ($result === false) $msg->afailure();
 | 
					            $msg->aresult($result);
 | 
				
			||||||
            else $msg->adone($result);
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } catch (Exception $e) {
 | 
					      } catch (Exception $e) {
 | 
				
			||||||
@ -112,6 +111,7 @@ class ProxyMessenger implements IMessenger {
 | 
				
			|||||||
  function asuccess($content=null, ?int $overrideLevel=null): void { foreach ($this->msgs as $msg) { $msg->asuccess($content, $overrideLevel); } }
 | 
					  function asuccess($content=null, ?int $overrideLevel=null): void { foreach ($this->msgs as $msg) { $msg->asuccess($content, $overrideLevel); } }
 | 
				
			||||||
  function afailure($content=null, ?int $overrideLevel=null): void { foreach ($this->msgs as $msg) { $msg->afailure($content, $overrideLevel); } }
 | 
					  function afailure($content=null, ?int $overrideLevel=null): void { foreach ($this->msgs as $msg) { $msg->afailure($content, $overrideLevel); } }
 | 
				
			||||||
  function adone($content=null, ?int $overrideLevel=null): void { foreach ($this->msgs as $msg) { $msg->adone($content, $overrideLevel); } }
 | 
					  function adone($content=null, ?int $overrideLevel=null): void { foreach ($this->msgs as $msg) { $msg->adone($content, $overrideLevel); } }
 | 
				
			||||||
 | 
					  function aresult($result=null, ?int $overrideLevel=null): void { foreach ($this->msgs as $msg) { $msg->aresult($result, $overrideLevel); } }
 | 
				
			||||||
  function print($content, ?int $level=null): void { foreach ($this->msgs as $msg) { $msg->print($content, $level); } }
 | 
					  function print($content, ?int $level=null): void { foreach ($this->msgs as $msg) { $msg->print($content, $level); } }
 | 
				
			||||||
  function info($content, ?int $level=null): void { foreach ($this->msgs as $msg) { $msg->info($content, $level); } }
 | 
					  function info($content, ?int $level=null): void { foreach ($this->msgs as $msg) { $msg->info($content, $level); } }
 | 
				
			||||||
  function note($content, ?int $level=null): void { foreach ($this->msgs as $msg) { $msg->note($content, $level); } }
 | 
					  function note($content, ?int $level=null): void { foreach ($this->msgs as $msg) { $msg->note($content, $level); } }
 | 
				
			||||||
 | 
				
			|||||||
@ -580,10 +580,8 @@ class StdMessenger implements _IMessenger {
 | 
				
			|||||||
    if ($func !== null) {
 | 
					    if ($func !== null) {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        $result = $func($this);
 | 
					        $result = $func($this);
 | 
				
			||||||
        if ($result !== null) {
 | 
					        if ($this->_getActionMark() > $until) {
 | 
				
			||||||
          if ($result === true) $this->asuccess();
 | 
					          $this->aresult($result);
 | 
				
			||||||
          elseif ($result === false) $this->afailure();
 | 
					 | 
				
			||||||
          else $this->adone($result);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } catch (Exception $e) {
 | 
					      } catch (Exception $e) {
 | 
				
			||||||
        $this->afailure($e);
 | 
					        $this->afailure($e);
 | 
				
			||||||
@ -653,6 +651,14 @@ class StdMessenger implements _IMessenger {
 | 
				
			|||||||
    $this->printActions(true, $overrideLevel);
 | 
					    $this->printActions(true, $overrideLevel);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function aresult($result=null, ?int $overrideLevel=null): void {
 | 
				
			||||||
 | 
					    if (!$this->actions) $this->action(null);
 | 
				
			||||||
 | 
					    if ($result === true) $this->asuccess(null, $overrideLevel);
 | 
				
			||||||
 | 
					    elseif ($result === false) $this->afailure(null, $overrideLevel);
 | 
				
			||||||
 | 
					    elseif ($result instanceof Exception) $this->afailure($result, $overrideLevel);
 | 
				
			||||||
 | 
					    else $this->adone($result, $overrideLevel);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function _endAction(?int $until=null): void {
 | 
					  function _endAction(?int $until=null): void {
 | 
				
			||||||
    if ($until === null) $until = $this->_getActionMark() - 1;
 | 
					    if ($until === null) $until = $this->_getActionMark() - 1;
 | 
				
			||||||
    while (count($this->actions) > $until) {
 | 
					    while (count($this->actions) > $until) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										212
									
								
								src/text/Word.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								src/text/Word.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,212 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nur\sery\text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use nur\b\ValueException;
 | 
				
			||||||
 | 
					use nur\txt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Class Word: accord d'un nom ou d'un adjectif en genre et en nombre
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Pour accorder un nom, construire l'objet avec une spécification de la forme
 | 
				
			||||||
 | 
					 * "GENRE:ARTICLE NOM"
 | 
				
			||||||
 | 
					 * - L'article peut être "l'", "le", "la". Le genre est requis avec "l'"
 | 
				
			||||||
 | 
					 * - Le genre peut être "masculin:" ou "féminin:"
 | 
				
			||||||
 | 
					 * - Le nom est composé d'un ou plusieurs mots qui se terminent par
 | 
				
			||||||
 | 
					 *   - #s pour un pluriel en "s", e.g porte#s
 | 
				
			||||||
 | 
					 *   - #x pour un pluriel en "x", e.g lieu#x
 | 
				
			||||||
 | 
					 *   - rien si le mot est invariable
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Pour accorder un adjectif, la spécification peut se limiter à "ADJECTIF"
 | 
				
			||||||
 | 
					 * - L'adjectif est composé d'un ou plusieurs mots, qui en plus des marques du
 | 
				
			||||||
 | 
					 *   pluriel peuvent se terminent par
 | 
				
			||||||
 | 
					 *   - #e pour indiquer la marque du féminin, e.g "né#e"
 | 
				
			||||||
 | 
					 *   - rien si le mot est invariable
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Chaque mot peut aussi commencer par "^" pour indiquer les caractères qui
 | 
				
			||||||
 | 
					 * peuvent être mis en majuscule par la méthode u(). Par défaut, seule la
 | 
				
			||||||
 | 
					 * première lettre est mise en majuscule
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class Word {
 | 
				
			||||||
 | 
					  /** @var bool le mot est-il féminin? */
 | 
				
			||||||
 | 
					  private $fem;
 | 
				
			||||||
 | 
					  /** @var string article "le", "la", "l'" */
 | 
				
			||||||
 | 
					  private $le;
 | 
				
			||||||
 | 
					  /** @var string article "du", "de la", "de l'" */
 | 
				
			||||||
 | 
					  private $du;
 | 
				
			||||||
 | 
					  /** @var string article "au", "à la", "à l'" */
 | 
				
			||||||
 | 
					  private $au;
 | 
				
			||||||
 | 
					  /** @var string le mot sans article */
 | 
				
			||||||
 | 
					  private $w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function __construct(string $spec, bool $adjective=false) {
 | 
				
			||||||
 | 
					    if (preg_match('/^f([eé]m(inin)?)?\s*:\s*/iu', $spec, $ms)) {
 | 
				
			||||||
 | 
					      $fem = true;
 | 
				
			||||||
 | 
					      $spec = substr($spec, strlen($ms[0]));
 | 
				
			||||||
 | 
					    } elseif (preg_match('/^m(asc(ulin)?)?\s*:\s*/i', $spec, $ms)) {
 | 
				
			||||||
 | 
					      $fem = false;
 | 
				
			||||||
 | 
					      $spec = substr($spec, $ms[0]);
 | 
				
			||||||
 | 
					    } elseif (preg_match('/\s*\|f(?:[eé]m(?:inin)?)?\s*$/iu', $spec, $ms, PREG_OFFSET_CAPTURE)) {
 | 
				
			||||||
 | 
					      $fem = true;
 | 
				
			||||||
 | 
					      $spec = substr($spec, 0, $ms[0][1]);
 | 
				
			||||||
 | 
					    } elseif (preg_match('/\s*\|m(?:asc(?:ulin)?)?\s*$/i', $spec, $ms, PREG_OFFSET_CAPTURE)) {
 | 
				
			||||||
 | 
					      $fem = false;
 | 
				
			||||||
 | 
					      $spec = substr($spec, 0, $ms[0][1]);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $fem = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (preg_match('/^l\'\s*/i', $spec, $ms) && $fem !== null) {
 | 
				
			||||||
 | 
					      $le = "l'";
 | 
				
			||||||
 | 
					      $du = "de l'";
 | 
				
			||||||
 | 
					      $au = "à l'";
 | 
				
			||||||
 | 
					      $spec = substr($spec, strlen($ms[0]));
 | 
				
			||||||
 | 
					    } elseif (preg_match('/^la\s+/i', $spec, $ms)) {
 | 
				
			||||||
 | 
					      $fem = true;
 | 
				
			||||||
 | 
					      $le = "la ";
 | 
				
			||||||
 | 
					      $du = "de la ";
 | 
				
			||||||
 | 
					      $au = "à la ";
 | 
				
			||||||
 | 
					      $spec = substr($spec, strlen($ms[0]));
 | 
				
			||||||
 | 
					    } elseif (preg_match('/^le\s+/i', $spec, $ms)) {
 | 
				
			||||||
 | 
					      $fem = false;
 | 
				
			||||||
 | 
					      $le = "le ";
 | 
				
			||||||
 | 
					      $du = "du ";
 | 
				
			||||||
 | 
					      $au = "au ";
 | 
				
			||||||
 | 
					      $spec = substr($spec, strlen($ms[0]));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $le = null;
 | 
				
			||||||
 | 
					      $du = null;
 | 
				
			||||||
 | 
					      $au = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!$adjective) {
 | 
				
			||||||
 | 
					      # si c'est un nom, il faut l'article et le genre
 | 
				
			||||||
 | 
					      if ($fem === null) {
 | 
				
			||||||
 | 
					        throw new ValueException("Vous devez spécifier le genre du nom");
 | 
				
			||||||
 | 
					      } elseif ($le === null || $du === null || $au === null) {
 | 
				
			||||||
 | 
					        throw new ValueException("Vous devez spécifier l'article du nom");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $this->fem = $fem;
 | 
				
			||||||
 | 
					    $this->le = $le;
 | 
				
			||||||
 | 
					    $this->du = $du;
 | 
				
			||||||
 | 
					    $this->au = $au;
 | 
				
			||||||
 | 
					    $this->w = $spec;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * retourner le mot sans article
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param bool|int $amount nombre du nom, avec l'équivalence false===0 et
 | 
				
			||||||
 | 
					   * true===2. à partir de 2, le mot est ecrit au pluriel
 | 
				
			||||||
 | 
					   * @param bool|string $fem genre du nom avec lequel accorder les adjectifs,
 | 
				
			||||||
 | 
					   * avec l'équivalence false==="M" et true==="F"
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function w($amount=1, bool $upper1=false, $fem=false): string {
 | 
				
			||||||
 | 
					    if ($amount === true) $amount = 2;
 | 
				
			||||||
 | 
					    elseif ($amount === false) $amount = 0;
 | 
				
			||||||
 | 
					    $amount = abs($amount);
 | 
				
			||||||
 | 
					    $w = $this->w;
 | 
				
			||||||
 | 
					    # marque du nombre
 | 
				
			||||||
 | 
					    if ($amount <= 1) {
 | 
				
			||||||
 | 
					      $w = preg_replace('/#[sx]/', "", $w);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      $w = preg_replace('/#([sx])/', "$1", $w);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    # marque du genre
 | 
				
			||||||
 | 
					    if ($fem === "f" || $fem === "F") $fem = true;
 | 
				
			||||||
 | 
					    elseif ($fem === "m" || $fem === "M") $fem = false;
 | 
				
			||||||
 | 
					    $repl = $fem? "$1": "";
 | 
				
			||||||
 | 
					    $w = preg_replace('/#([e])/', $repl, $w);
 | 
				
			||||||
 | 
					    # mise en majuscule
 | 
				
			||||||
 | 
					    if ($upper1) {
 | 
				
			||||||
 | 
					      if (strpos($w, "^") === false) {
 | 
				
			||||||
 | 
					        # uniquement la première lettre
 | 
				
			||||||
 | 
					        $w = txt::upper1($w);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        # toutes les lettres qui suivent les occurences de ^
 | 
				
			||||||
 | 
					        $w = preg_replace_callback('/\^([[:alpha:]])/u', function ($ms) {
 | 
				
			||||||
 | 
					          return mb_strtoupper($ms[1]);
 | 
				
			||||||
 | 
					        }, $w);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $w;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * retourner le mot sans article avec la première lettre en majuscule.
 | 
				
			||||||
 | 
					   * alias pour $this->w($amount, true, $fem)
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param bool|int $amount
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function u($amount=1, $fem=false): string {
 | 
				
			||||||
 | 
					    return $this->w($amount, true, $fem);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * retourner l'adjectif accordé avec le genre spécifié.
 | 
				
			||||||
 | 
					   * alias pour $this->w($amount, false, $fem)
 | 
				
			||||||
 | 
					   *
 | 
				
			||||||
 | 
					   * @param bool|int $amount
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function a($fem=false, $amount=1): string {
 | 
				
			||||||
 | 
					    return $this->w($amount, false, $fem);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** retourner le mot sans article et avec la quantité */
 | 
				
			||||||
 | 
					  function q(int $amount=1, $fem=false): string {
 | 
				
			||||||
 | 
					    return $amount." ".$this->w($amount, $fem);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** retourner le mot sans article et avec la quantité $amount/$max */
 | 
				
			||||||
 | 
					  function r(int $amount, int $max, $fem=false): string {
 | 
				
			||||||
 | 
					    return "$amount/$max ".$this->w($amount, $fem);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** retourner le mot avec l'article indéfini et la quantité */
 | 
				
			||||||
 | 
					  function un(int $amount=1, $fem=false): string {
 | 
				
			||||||
 | 
					    $abs_amount = abs($amount);
 | 
				
			||||||
 | 
					    if ($abs_amount == 0) {
 | 
				
			||||||
 | 
					      $aucun = $this->fem? "aucune ": "aucun ";
 | 
				
			||||||
 | 
					      return $aucun.$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    } elseif ($abs_amount == 1) {
 | 
				
			||||||
 | 
					      $un = $this->fem? "une ": "un ";
 | 
				
			||||||
 | 
					      return $un.$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return "les $amount ".$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function le(int $amount=1, $fem=false): string {
 | 
				
			||||||
 | 
					    $abs_amount = abs($amount);
 | 
				
			||||||
 | 
					    if ($abs_amount == 0) {
 | 
				
			||||||
 | 
					      $le = $this->fem? "la 0 ": "le 0 ";
 | 
				
			||||||
 | 
					      return $le.$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    } elseif ($abs_amount == 1) {
 | 
				
			||||||
 | 
					      return $this->le.$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return "les $amount ".$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function du(int $amount=1, $fem=false): string {
 | 
				
			||||||
 | 
					    $abs_amount = abs($amount);
 | 
				
			||||||
 | 
					    if ($abs_amount == 0) {
 | 
				
			||||||
 | 
					      $du = $this->fem? "de la 0 ": "du 0 ";
 | 
				
			||||||
 | 
					      return $du.$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    } elseif ($abs_amount == 1) {
 | 
				
			||||||
 | 
					      return $this->du.$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return "des $amount ".$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function au(int $amount=1, $fem=false): string {
 | 
				
			||||||
 | 
					    $abs_amount = abs($amount);
 | 
				
			||||||
 | 
					    if ($abs_amount == 0) {
 | 
				
			||||||
 | 
					      $au = $this->fem? "à la 0 ": "au 0 ";
 | 
				
			||||||
 | 
					      return $au.$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    } elseif ($abs_amount == 1) {
 | 
				
			||||||
 | 
					      return $this->au.$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return "aux $amount ".$this->w($amount, $fem);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/text/words.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/text/words.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					namespace nur\sery\text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class words {
 | 
				
			||||||
 | 
					  static function q(int $count, string $spec, bool $adjective=true): string {
 | 
				
			||||||
 | 
					    $word = new Word($spec, $adjective);
 | 
				
			||||||
 | 
					    return $word->q($count);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static function r(int $count, int $max, string $spec, bool $adjective=true): string {
 | 
				
			||||||
 | 
					    $word = new Word($spec, $adjective);
 | 
				
			||||||
 | 
					    return $word->r($count, $max);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -30,5 +30,51 @@ Application::run(new class extends Application {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
      $msg->asuccess();
 | 
					      $msg->asuccess();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  msg::title("auto result");
 | 
				
			||||||
 | 
					  msg::action("sans result 1", function ($msg) {
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  msg::print("hello 1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  msg::action("sans result 2", function ($msg) {
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  msg::print("hello 2");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  msg::action("sans result 3", function ($msg) {
 | 
				
			||||||
 | 
					    return "whatever";
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  msg::print("hello 3");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					  msg::action("sans result 4", function ($msg) {
 | 
				
			||||||
 | 
					    throw new Exception();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  } catch (Exception $e) {}
 | 
				
			||||||
 | 
					  msg::print("hello 4");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  msg::action("avec result 1", function ($msg) {
 | 
				
			||||||
 | 
					    $msg->asuccess();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  msg::print("hello 1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  msg::action("avec result 2", function ($msg) {
 | 
				
			||||||
 | 
					    $msg->afailure();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  msg::print("hello 2");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  msg::action("avec result 3", function ($msg) {
 | 
				
			||||||
 | 
					    $msg->adone();
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  msg::print("hello 3");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					  msg::action("avec result 4", function ($msg) {
 | 
				
			||||||
 | 
					    $msg->aresult(new Exception());
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  } catch (Exception $e) {}
 | 
				
			||||||
 | 
					  msg::print("hello 4");
 | 
				
			||||||
 | 
					  msg::end();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user