3 * The ArtifactWorkflow class manages workflow for trackers.
5 * The workflow is attached to custom status field only.
7 * Associated tables are:
8 * - artifact_workflow_event : to track allowed events.
9 * - artifact_workflow_roles : to track roles allowed to perform an event.
10 * - artifact_workflow_notify : to track notification associated to an event (not implemented).
12 * An event is a transition from one value to another.
14 * NOTE: Code should be improved to manage any kind of custom fields not only of type
15 * 'Status' but maybe also for the 'select' also.
17 * 2008 : Alain Peyrat <alain.peyrat@alcatel-lucent.com>
20 * @todo: the getAllowedRoles should be replaced by getRealAllowedRoles code. (to be tested).
21 * @todo: Some code could use a db direct to array func instead of the while.
24 require_once 'common/include/Error.class.php';
26 class ArtifactWorkflow extends Error {
32 function ArtifactWorkflow($artifact, $field_id) {
33 $this->ath = $artifact;
34 $this->artifact_id = (int)$artifact->getID();
35 $this->field_id = (int)$field_id;
39 // Check if the following event is allowed or not.
40 // return true is allowed, false if not.
41 function checkEvent($from, $to) {
46 $res = db_query_params ('SELECT event_id FROM artifact_workflow_event
47 WHERE group_artifact_id=$1
51 array($this->artifact_id,
55 $event_id = db_result($res, 0, 'event_id');
57 // No role based checks for the initial transition.
61 // There is a transition, now check if current role is allowed.
63 $res = db_query_params ('SELECT event_id
64 FROM user_group, artifact_workflow_roles
68 AND user_group.role_id=artifact_workflow_roles.role_id',
70 $this->ath->Group->getID(),
72 return db_result($res, 0, 'event_id') ? true : false;
77 function getNotifyFromWorkFlow() {
82 * When a new element is created, add all the new events in the workflow.
84 function addNode($element_id) {
85 $elearray = $this->ath->getExtraFieldElements($this->field_id);
86 foreach ($elearray as $e) {
87 if ($element_id !== $e['element_id']) {
88 $this->_addEvent($e['element_id'], $element_id);
89 $this->_addEvent($element_id, $e['element_id']);
93 // Allow the new element for the Submit form (Initial values).
94 $this->_addEvent('100', $element_id);
97 // Returns all the possible following nodes (no roles involved).
98 function getNextNodes($from) {
100 $res = db_query_params ('SELECT to_value_id FROM artifact_workflow_event
101 WHERE group_artifact_id=$1
103 AND from_value_id=$3',
104 array($this->artifact_id,
108 while($arr = db_fetch_array($res)) {
109 $values[] = $arr['to_value_id'];
116 function saveNextNodes($from, $nodes) {
118 // Get All possible nodes.
119 $current = $this->getNextNodes($from);
121 // Remove events no longer present.
122 foreach ($current as $node) {
123 if (!in_array($node, $nodes)) {
124 if ($from != $node) {
125 $this->_removeEvent($from, $node);
130 // Add missing events.
131 foreach ($nodes as $node) {
132 if (!in_array($node, $current)) {
133 $this->_addEvent($from, $node);
139 function getAllowedRoles($from, $to) {
140 $values = $this->_getRealAllowedRoles($from, $to);
142 // If no values, then no roles defined, all roles are allowed.
143 if (empty($values)) {
144 $res=db_query_params ('SELECT role_id
145 FROM role WHERE group_id=$1 ORDER BY role_name',
146 array($this->ath->Group->getID()));
147 while($arr = db_fetch_array($res)) {
148 $values[] = $arr['role_id'];
155 function saveAllowedRoles($from, $to, $roles) {
157 $event_id = $this->_getEventId($from, $to);
159 // Get All possible roles.
160 $current = $this->_getRealAllowedRoles($from, $to);
162 // Remove roles no longer present.
163 foreach ($current as $role) {
164 if (!in_array($role, $roles)) {
165 $this->_removeRole($event_id, $role);
169 // Add missing roles.
170 foreach ($roles as $role) {
171 if (!in_array($role, $current)) {
172 $this->_addRole($event_id, $role);
178 function _getEventId($from, $to) {
180 $res = db_query_params ('SELECT event_id FROM artifact_workflow_event
181 WHERE group_artifact_id=$1
185 array($this->artifact_id,
190 $this->setError('Unable to get Event Id ($from, $to): '.db_error());
193 return db_result($res, 0, 'event_id');
198 function _addEvent($from, $to) {
200 $res = db_query_params ('INSERT INTO artifact_workflow_event
201 (group_artifact_id, field_id, from_value_id, to_value_id)
202 VALUES ($1, $2, $3, $4)',
203 array($this->artifact_id,
208 $this->setError('Unable to add Event($from, $to): '.db_error());
212 $event_id = $this->_getEventId($from, $to);
214 // By default, all roles are allowed on a new event.
215 $res=db_query_params ('SELECT role_id
216 FROM role WHERE group_id=$1 ORDER BY role_name',
217 array($this->ath->Group->getID()));
218 while($arr = db_fetch_array($res)) {
219 $this->_addRole($event_id, $arr['role_id']);
227 function _removeEvent($from, $to) {
228 $event_id = $this->_getEventId($from, $to);
231 $res = db_query_params ('DELETE FROM artifact_workflow_event
232 WHERE group_artifact_id=$1
236 array($this->artifact_id,
241 $this->setError('Unable to remove Event($from, $to): '.db_error());
248 function _getRealAllowedRoles($from, $to) {
250 $res = db_query_params ('SELECT role_id
251 FROM artifact_workflow_roles, artifact_workflow_event
252 WHERE artifact_workflow_roles.event_id = artifact_workflow_event.event_id
253 AND group_artifact_id=$1
257 array($this->artifact_id,
262 while($arr = db_fetch_array($res)) {
263 $values[] = $arr['role_id'];
268 function _addRole($event_id, $role_id) {
270 $res = db_query_params ('INSERT INTO artifact_workflow_roles
276 $this->setError('Unable to add Role ($role_id): '.db_error());
283 function _removeRole($event_id, $role_id) {
285 $res = db_query_params ('DELETE FROM artifact_workflow_roles
286 WHERE event_id=$1 AND role_id=$2',
290 $this->setError('Unable to remove Event($from, $to): '.db_error());
300 * Update the required information in the workflow when a new role is created.
301 * In this case, for all the defined events, add the role as allowed.
303 function workflow_add_new_role ($role_id, $group) {
305 $res = db_query_params ('INSERT INTO artifact_workflow_roles
306 SELECT event_id, $1 as role_id
307 FROM artifact_workflow_event, artifact_group_list
308 WHERE artifact_workflow_event.group_artifact_id=artifact_group_list.group_artifact_id
309 AND artifact_group_list.group_id=$2',
313 $this->setError('Unable to register new role in workflows: '.db_error());