Déclencheur sur détection de changement dans les données
-
Ce déclencheur automatique permet de déclencher l’exécution d’actions lorsque certaines données de documents changent d’état.
Le paramétrage manuel des actions à déclenchement horodaté pourra se faire via l’URI /ITRocks/Framework/Trigger/Changes. L’interface utilisateur pour la saisie de conditions n’étant pas encore réalisée, pour l’instant on ne peut que générer ces conditions par programmation interne, comme le fait par exemple B-Ticket.
Réglages
- nom : un nom libre pour le déclencheur.
- nom de la classe : la classe document métier dont on va surveiller les modifications.
- condition avant : un ensemble de conditions de type requêtage Func\Where, permettant de valider l’état du document avant sa modification : les actions ne se déclencheront que si cet état antérieur est validé.
- Une condition vide (null) signifie que tous les états antérieurs sont considérés comme valides.
- Une condition Func::isNull() signifie qu’on ne validera la condition que dans le cas d’une création d’un nouveau document.
- Une condition Func::isNotNull() signifie qu’on ne validera la condition que dans le cas d’un document qui était déjà stocké en base avant sa modification, donc condition “ce n’est pas une création”.
- condition après : un ensemble de conditions de type requêtage Func\Where, permettant de valider l’état du document après sa modification : les actions ne se déclencheront que si l’état antérieur et cet état post-modification sont validés.
- Une condition vide (null) signifie que tous les états post-modification sont considérés comme valides.
- Utiliser les conditions Func::isNull() ou Func::isNotNull() n’auraient pas d’intérêt : après modification, l’objet est forcément stocké en base.
- actions : les actions à exécuter si les toutes les conditions sont vérifiées.
- action : l’url d’appel. Peut contenir des éléments remplacés par une référence au document {object} ou {class_name}. Par exemple /Bappli/Ticket/Task/1301/createTicket/{object} portant sur un utilisateur pourra déclencher par exemple une URI /Bappli/Ticket/Task/1301/createTicket/ITRocks/Framework/User/1 lors de la création de l’utilisateur dont l’identifiant est 1.
- en tant qu’utilisateur : on poura forcer ici l’utilisateur authentifié lors de l’exécution de l’action (pas encore implémenté).
- conserve l’utilisateur : si coché, l’utilisateur pour l’exécution de l’action sera celui qui a modifié le document : l’exécution de la fonctionnalité se fera donc avec ses droits (pas encore implémenté).
- dernier : donne l’information de la dernière fois où l’action s’est déclenchée (en lecture seule).
Fonctionnement interne
Pour que le déclencheur automatique fonctionne, il faut installer la fonctionnalité Déclenche des actions lors des modifications aux données et que le serveur d’exécution d’actions déclenchées soit en cours d’exécution.
- Les actions paramétrées sont stockées avec statut static
- Leur date de prochaine exécution est mise à Date_Time::max() : elles ne seront jamais directement exécutées.
- À chaque modification d’un document, le framework cherchera si des actions de modification de données liées au document sont à appliquer.
- Si c’est le cas, une première validation avant écriture a lieu.
- Si le document est dans l’état correspondant à la condition avant, un objet Change\Run est généré pour mémoriser les informations nécessaires à la vérification asynchrone de la condition après et au déclenchement des actions. Notamment la référence au document lui-même est enregistrée ici.
- Aucun autre traitement n’est fait en synchrone, afin que l’utilisateur soit le moins possible ralenti par ce processus. Une action /ITRocks/Framework/Trigger/Change/run est demandée au serveur d’exécution d’actions déclenchées, pour que les prochaines étapes tournent en asynchrone.
- L’exécution asynchrone du contrôle de fin de vérification et d’exécution réalise les prochaines étapes (en asynchrone donc) :
- Les Change\Run en état after sont vérifiées : si le document a alors l’état post-modification attendu, les actions associées sont inscrites pour exécution et l’état passe en pending, sinon le Change\Run est purgé
- Les Change\Run voient leur état évoluer, si partial, pending ou running :
- L’état reste pending si aucune des actions déclenchée n’a encore été lancée par le serveur
- L’état passe en partial si au moins une action déclenchée a été lancée
- L’état passe en running si toutes les actions déclenchées ont été lancées
- L’état passe en complete si toutes les actions déclenchées se sont correctement terminées, sans arreur
- Enfin les Change\Run en état complete sont purgées au bout de 24 heures : ces objets n’ont qu’une valeur temporaire, pour l’exécution des actions, et sont pas destinés à être conservés
- En cas d’erreur d’exécution des actions : erreur, erreur de lancement, les Change\Run restent actifs en état pending, partial ou running, et ne sont jamais purgés. Cela est forcément du à un bogue infrastructure ou logiciel, un traitement manuel s’impose pour s’assurer que toutes les actions post-modifications s’exécutent bien, et une purge de ces objets sera nécessaire.
Création et maintenant d’un déclencheur par modification de données dans le code
Exemple de code qui crée un déclencheur d’une action de création de ticket à partir d’une tâche dès création / modification / enregistrement d’utilisateur :
$trigger = new Change(); $action = new Action(View::link($this->task, Create_Ticket\Controller::FEATURE, '{object}')); $action->next = Date_Time::max(); $action->status = Action\Status::STATIC; $trigger->actions = [$action]; $trigger->after_condition = null; $trigger->before_condition = null; $trigger->class_name = $this->document->class_name; /** @var $feature string @values create, update, write */ switch ($feature) { case 'create': $trigger->before_condition = Func::isNull(); break; case 'update': $trigger->before_condition = Func::isNotNull(); break; } /** @var $document_name string the name of a business document @see Feature_Class */ /** @var $feature string the name of a valid feature that can be applied to the document */ $name = Loc::tr( $document_name . SP . ':feature', [Loc::replace(['feature' => $feature])] ); $trigger->name = $name; Dao::write($trigger);
Structure des classes et de la base de données
- Trigger\Change : change_triggers : listes des déclencheurs
- change_trigger_actions : chaque enregistrement relie une action statique ci-dessous et un déclencheur ci-dessus
- Trigger\Action : trigger_actions : si reliées via change_trigger_actions : liste des actions
- change_trigger_runs_actions : chaque enregistrement relie une action statique ci-dessus et un contrôle de déclencheur ci-dessous
- Trigger\Change\Run : change_trigger_runs : représente un document en cours de contrôle pour un déclencheur