10.3.1 La famille de Workflow
La famille de workflow permet de spécifier :
- le graphe du cycle ainsi que les attributs spécifiques au cycle,
- les paramètres de familles qui seront utilisables lors des traitements spécifiques liés aux cycles.
10.3.1.1 Définition de la famille
Au même titre que les autres familles, une famille de workflow est caractérisée par :
son code dans un fichier php
sa définition dans un fichier csv.
Cette famille doit :
- Hériter de la famille
WDOC
, - être liée à une classe définissant les états et transitions du cycle.
La propriété USEFOR
est SW
par défaut, cela indique que
la famille est :
- Système (
S
), - utilisable comme workflow (
W
).
10.3.1.1.1 Exemple
Famille parente | Libellé | / | / | Nom logique | |
---|---|---|---|---|---|
BEGIN | WDOC | Cycle Demo | WFL_DEMO | ||
CLASS | Demo\WflDemo | ||||
END |
10.3.1.2 La classe de workflow
La classe correspondante à un workflow doit définir la structure de ce workflow.
Cette structure s'exprime sous la forme d'un graphe, exprimé notamment au moyen
des propriétés de classe $cycle
et $transitions
.
10.3.1.2.1 $cycle
La propriété $cycle
définit le graphe à proprement parler. C'est une liste
d'éléments de la forme :
array( "e1" => "<état de départ>", "e2" => "<état d'arrivée>", "t" => "<transition à utiliser>" )
où
-
e1
est l'identifiant de l'état de départ, -
e2
est l'identifiant de l'état d'arrivée, -
t
est l'identifiant de la transition à utiliser pour passer de l'état de départ à l'état d'arrivée.
Exemple :
public $cycle = array( array( "e1" => "<état de départ 1>", "e2" => "<état d'arrivée 1>", "t" => "<transition à utiliser 1>" ), …, array( "e1" => "<état de départ N>", "e2" => "<état d'arrivée N>", "t" => "<transition à utiliser N>" ) );
10.3.1.2.2 $transitions
La propriété $transitions
définit l'ensemble des types de transitions
utilisables. C'est un tableau associatif dont la clé est le nom de la
transition, et la valeur est un élément de la forme :
array( "nr" => true, "m0" => "myFirstCondition", "m1" => "mySecondCondition", "m2" => "myFirstProcess", "m3" => "myLastProcess", "ask" => array("askId1", …) )
où
-
nr
est un booléen indiquant qu'il ne faut pas demander de raison au passage de transition (nr pour No Reason).
La valeur par défaut est àfalse
; dans ce cas, une popup demande à l'utilisateur de préciser la raison du passage de transition. -
m0
,m1
,m2
,m3
sont chacune le nom d'une méthode de la classe de workflow. -
ask
est un tableau d'identifiants de paramètres ou d'attributs du workflow, qui seront utilisés pour générer la demande des paramètres de transition.
Exemple :
public $transitions = array( "<transition à utiliser 1>" => array( "nr" => true, "m0" => "myFirstCondition_1", … ), …, "<transition à utiliser N>" => array( "nr" => true, "m0" => "myFirstCondition_N", … ) );
10.3.1.2.3 $firstState
La propriété $firstState
définit l'état initial des documents liés à ce cycle
de vie. Elle désigne l'identifiant d'un état.
10.3.1.2.4 $attrPrefix
Lors de la génération d'un cycle de vie, Dynacase génère un grand nombre
d'attributs pour paramétrer finement chaque état et chaque transition. ces
attributs sont préfixés par $attrPrefix
pour éviter les éventuelles collisions
en base de données.
10.3.1.2.5 $stateactivity
La propriété $stateactivity
définit l'ensemble des activités. C'est un tableau
associatif ; la clé est l'identifiant de l'état et la valeur est le libellé
de l'activité.
10.3.1.2.6 Les méthodes de transition
Les méthodes appelées lors des transitions en m0
, m1
, m2
, m3
sont des
méthodes de la famille de workflow.
- Les méthodes appelées en
m0
doivent être en visibilitépublic
; - les méthodes appelées en
m1
,m2
, etm3
peuvent être en visibilitéprotected
oupublic
mais elles ne peuvent pas êtreprivate
.
10.3.1.2.6.1 Définition méthode m0
La méthode appelée en m0
est de la forme :
m0 ( $nextStep, $currentStep, $confirmationMessage)
où :
-
$nextStep
est l'identifiant de la prochaine étape, (étape d'arrivée) -
$currentStep
est l'identifiant de l'étape actuelle, (étape de départ) -
$confirmationMessage
est le message de confirmation (si la méthode est exécuté pour l'affichage des menus, le message est vide)
Si elle retourne une chaîne vide, alors la transition peut être effectuée. dans le cas contraire, elle doit retourner un message localisé qui indiquera à l'utilisateur la raison pour laquelle la transition ne peut pas être effectuée.
Le message retourné par la méthode est présenté dans un "tooltip" lors du
survol de l'entrée de l'étape dans le menu Étapes
, ou dans un "popover" lors
du clic sur l'entrée de l'étape.
Note : Cette méthode est aussi appelée lors de l'affichage de la liste des transitions accessibles. Cela permet notamment de signaler à l'utilisateur les transitions qu'il a le droit d'effectuer, mais pour lesquelles il doit faire des modifications sur le document. De fait, cette méthode ne doit pas modifier le document.
10.3.1.2.6.2 Définition méthode m1
La méthode appelée en m1
est de la forme :
m1 ( $nextStep, $currentStep, $confirmationMessage)
où :
-
$nextStep
est l'identifiant de la prochaine étape, (étape d'arrivée) -
$currentStep
est l'identifiant de l'étape actuelle, (étape de départ) -
$confirmationMessage
est le message de confirmation
Si elle retourne une chaîne vide, alors la transition peut être effectuée. dans le cas contraire, elle doit retourner un message localisé qui indiquera à l'utilisateur la raison pour laquelle la transition ne peut pas être effectuée.
10.3.1.2.6.3 Définition méthode m2
La méthode appelée en m2
est de la forme :
m2 ( $currentStep, $previousStep, $confirmationMessage)
où :
-
$currentStep
est l'identifiant de l'étape actuelle, (étape d'arrivée) -
$previousStep
est l'identifiant de l'ancienne étape, (étape de départ) -
$confirmationMessage
est le message de confirmation
Si elle retourne une chaîne non vide, cette chaîne est considérée comme un message d'erreur qui sera affiché à l'utilisateur à l'issue de la transition (Cette méthode n'est pas bloquante).
10.3.1.2.6.4 Définition méthode m3
La méthode appelée en m3
est de la forme :
m3 ( $currentStep, $previousStep, $confirmationMessage)
où :
-
$currentStep
est l'identifiant de l'étape actuelle, (étape d'arrivée) -
$previousStep
est l'identifiant de l'ancienne étape, (étape de départ) -
$confirmationMessage
est le message de confirmation
Si elle retourne une chaîne non vide, cette chaîne est considérée comme un message d'erreur qui sera affiché à l'utilisateur à l'issue de la transition (Cette méthode n'est pas bloquante).
10.3.1.2.6.5 Utilisation des paramètres de transition ask
Les paramètres de transition sont envoyés lors de la requête de transition effectuée par l'interface web.
Les valeurs présentées sur l'interface sont les valeurs des paramètres ou des attributs référencés au moment de la demande de transition.
Les valeurs des paramètres de transition utilisées sont enregistrés dans l'historique du document.
Si le paramètre référencé est obligatoire, l'interface exigera que le paramètre soit complété. Cette contrainte n'est pas testée lorsqu'il s'agit de passer une transition par programmation. Elle est prise en compte que par l'interface web. De même, les valeurs des paramètres de transition ne sont remplies que lors d'une transition effectuée par l'interface.
Attention : Contrairement aux paramètres de famille ordinaires, les contraintes ne sont pas prises en compte dans les paramètres de transition.
Dans les méthodes m0
, m1
, m2
, m3
, la récupération des valeurs des
paramètres de transition s'effectuent au moyen de la méthode
WDoc::getValue()
(bien que ces valeurs soient utilisées dans des paramètres,
ce n'est pas la méthode getParameterValue
qui est utilisée).
Lors de la recherche des transitions
accessibles, La méthode m0
ne peut accèder aux paramètres de transition (ils
ne sont pas encore demandés).
10.3.1.2.7 Exemple
Considérons le workflow de l'introduction. La classe le définissant contiendra :
namespace Demo; class WflDemo extends \Dcp\Family\WDoc { public $attrPrefix = "DEMO"; public $firstState = self::etat_created; public $viewlist = "none"; //region States const etat_created = "myapp_demo_e1"; const etat_redacted = "myapp_demo_e2"; const etat_verified = "myapp_demo_e3"; const etat_diffused = "myapp_demo_e4"; const etat_archived = "myapp_demo_e5"; const etat_abandonned = "myapp_demo_e6"; //endregion //region Transitions const transition_created_redacted = "myapp_demo_t1"; const transition_redacted_created = "myapp_demo_t2"; const transition_redacted_verified = "myapp_demo_t3"; const transition_verified_created = "myapp_demo_t4"; const transition_verified_diffused = "myapp_demo_t5"; const transition_diffused_archived = "myapp_demo_t6"; const transition_created_abandonned = "myapp_demo_t7"; const transition_redacted_abandonned = "myapp_demo_t8"; const transition_verified_abandonned = "myapp_demo_t9"; //endregion public $stateactivity = array( self::etat_created => "demo:activity:etat_created", self::etat_redacted => "demo:activity:etat_redacted", self::etat_verified => "demo:activity:etat_verified", self::etat_diffused => "demo:activity:etat_diffused", self::etat_archived => "demo:activity:etat_archived", self::etat_abandonned => "demo:activity:etat_abandonned" ); public $transitions = array( self::transition_created_redacted =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "ask" => array(\Dcp\Family\AttributeIdentifiers\MyDemo::wdemo_deadline_date), "nr" => true ), self::transition_redacted_created =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "nr" => true ), self::transition_redacted_verified =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "nr" => true ), self::transition_verified_created =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "nr" => true ), self::transition_verified_diffused =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "nr" => true ), self::transition_diffused_archived =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "nr" => true ), self::transition_created_abandonned =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "nr" => true ), self::transition_redacted_abandonned =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "nr" => true ), self::transition_verified_abandonned =>array( "m0" => "", "m1" => "", "m2" => "", "m3" => "", "nr" => true ) ); public $cycle = array( array( "e1" => self::etat_created, "e2" => self::etat_redacted, "t" => self::transition_created_redacted ), array( "e1" => self::etat_redacted, "e2" => self::etat_created, "t" => self::transition_redacted_created ), array( "e1" => self::etat_redacted, "e2" => self::etat_verified, "t" => self::transition_redacted_verified ), array( "e1" => self::etat_verified, "e2" => self::etat_created, "t" => self::transition_verified_created ), array( "e1" => self::etat_verified, "e2" => self::etat_diffused, "t" => self::transition_verified_diffused ), array( "e1" => self::etat_diffused, "e2" => self::etat_archived, "t" => self::transition_diffused_archived ), array( "e1" => self::etat_created, "e2" => self::etat_abandonned, "t" => self::transition_created_abandonned ), array( "e1" => self::etat_redacted, "e2" => self::etat_abandonned, "t" => self::transition_redacted_abandonned ), array( "e1" => self::etat_verified, "e2" => self::etat_abandonned, "t" => self::transition_verified_abandonned ) ); }
Quelques remarques sur ce code :
-
Toutes les activités et tous les états ont été définis au moyen de constantes.
Cela n'est en aucun cas obligatoire, mais permet d'éviter les erreurs de copier-coller ; en effet, les identifiants des états, ainsi que les noms des transitions sont utilisés à de nombreux endroits.
-
Les noms des états et des transitions ont été anonymisés, et seules les constantes ont des labels intelligibles.
Puisque les états et transitions vont générer des attributs, ils vont également générer des colonnes en base de données. Ces colonnes sont nommées à partir des identifiants de l'état ou de la transition. Aussi, si demain il est nécessaire de renommer l'état archivé en classé, il faudra soit accepter que le nom affiché et le nom stocké soient différents, soit renommer des colonnes en base de données et mettre à jour des fichiers de paramétrage. Aucun de ces 2 choix n'est pérenne ou dénué de risque.
Avec des constantes anonymisées, il n'y a rien à changer en base de données, ni dans les fichiers de paramétrage, il suffit de changer la traduction de ce libellé. Accessoirement, on peut renommer la constante en bénéficiant de l'assistance d'outils de refactoring.
10.3.1.3 Internationalisation
Dans un workflow, les éléments qui peuvent être internationalisés sont :
- le nom des états
- le nom des activités
- le nom des transitions
Pour être internationalisés, ces éléments doivent être ajoutés aux catalogues de traduction.