Core  3.2
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
wdoc_graphviz.php
Go to the documentation of this file.
1 <?php
2 /*
3  * Generate worflow graph
4  * @author Anakeen
5  * @package FDL
6 */
7 /**
8  * @global string $id Http var : document id to affect
9  * @global string $type Http var : type of graph
10  * @global string $orient Http var :orientation TB (TopBottom) or LR (LeftRight)
11  * @global string $size Http var : global size of graph
12  */
13 // refreah for a classname
14 // use this only if you have changed title attributes
15 include_once ("FDL/Lib.Attr.php");
16 include_once ("FDL/Class.DocFam.php");
17 /**
18  * generate doc text for workflow to be used by graphviz
19  * @class DotWorkflow
20  */
22 {
23  /**
24  * @var array
25  */
26  private $lines = array();
27  /**
28  * @var WDoc
29  */
30  private $wdoc;
31  private $ratio = 'auto';
32  private $orient = 'LR';
33  private $size;
34  private $type = 'simple';
35  private $statefontsize;
36  private $conditionfontsize;
37  private $labelfontsize;
38  private $fontsize;
39  private $memoTr = array();
40  private $clusters = array();
41  private $clusterProps = array();
42  public $style = array(
43  'autonext-color' => '#006400', // darkgreen
44  'arrow-label-font-color' => '#555555', // dark grey
45  'arrow-color' => '#00008b', // darkblue
46  'ask-color' => '#00008b', // darkblue
47  'condition-color0' => '#6df8ab', // green
48  'condition-color1' => '#ffff00', // yellow
49  'action-color2' => '#ffa500', // orange
50  'action-color3' => '#74c0ec', // light blue
51  'mail-color' => '#a264d2', // light violet
52  'timer-color' => '#64a2d2', // light blue
53  'start-color' => '#00ff00', // green
54  'end-color' => '#ff0000', // red
55 
56  );
57  /**
58  * Generate dot text
59  * @return string dot text
60  */
61  public function generate()
62  {
63  if (!$this->wdoc) {
64  throw new Dcp\Exception('need workflow');
65  }
66  $ft = $this->wdoc->firstState;
67 
68  switch ($this->type) {
69  case 'cluster':
70  case 'complet':
71 
72  $ft = "D";
73  $this->setActivity();
74  $this->setStartPoint();
75  $this->setEndPoint();
76  $this->setTransitionLines();
77  if ($this->type == 'cluster') $this->drawCluster();
78  break;
79 
80  case 'simple':
81  $this->setStates();
82  $this->setTransitionLines();
83  $this->lines[] = sprintf('%s [shape=doublecircle]', $this->wdoc->firstState);
84  break;
85 
86  case 'justactivity':
87  $this->setActivities();
88  $this->setTransitionLines();
89  $this->lines[] = sprintf('%s [penwidth=2]', $this->wdoc->firstState);
90  break;
91 
92  case 'activity':
93  $this->setStates();
94  $this->setActivity();
95  $this->setTransitionLines();
96  $this->lines[] = sprintf('%s [shape=doublecircle]', $this->wdoc->firstState);
97  break;
98  }
99  //if ($this->ratio=="auto") $this->size='';
100  $dot = "digraph \"" . $this->wdoc->getHtmlTitle() . "\" {
101  ratio=\"{$this->ratio}\";
102  rankdir={$this->orient};
103  {$this->size}
104  bgcolor=\"white\";
105  {rank=1; \"$ft\";}
106  splines=true; fontsize={$this->conditionfontsize}; fontname=sans;
107  node [shape = circle, style=filled, fixedsize=true,fontsize={$this->fontsize},fontname=sans];
108  edge [shape = circle, style=filled, fixedsize=true,fontsize={$this->conditionfontsize},fontname=sans];\n";
109 
110  $dot.= implode($this->lines, "\n");
111  $dot.= "\n}";
112  return $dot;
113  }
114 
115  private function setTransitionLines()
116  {
117  foreach ($this->wdoc->cycle as $k => $v) {
118  switch ($this->type) {
119  case 'cluster':
120  case 'complet':
121  $this->setCompleteTransitionLine($k, $v);
122  break;
123 
124  case 'justactivity':
125  case 'simple':
126  $this->setSimpleTransitionLine($k, $v);
127  break;
128 
129  case 'activity':
130  $this->setActivityTransitionLine($k, $v);
131  break;
132  }
133  }
134  }
135  /**
136  * search attach point to activity
137  * the node which are branch to activity
138  * @param $startPoint
139  * @param $end
140  */
141  private function setAttachStart($startPoint, $end, $limitIndex = - 1)
142  {
143  $transitionLink = array();
144 
145  foreach ($this->wdoc->cycle as $k => $v) {
146  if ($v["e2"] == $startPoint) {
147  $t = $this->wdoc->transitions[$v["t"]];
148  $kt = $v["t"];
149  if (!empty($t["m3"])) $start = "m3" . $k;
150  else {
151  $tmids = $this->wdoc->getTransitionTimers($v["t"]);
152  if ($tmids) $start = "tm" . $k;
153  else {
154  $tmid = $this->wdoc->getStateTimers($v["e2"]);
155 
156  if ($tmid) $start = "tmf" . $k;
157  else {
158  $tmid = $this->wdoc->getTransitionMailTemplates($v["t"]);
159 
160  if ($tmid) $start = "mt" . $k;
161  else {
162  $tmid = $this->wdoc->getStateMailTemplate($v["e2"]);
163 
164  if ($tmid) $start = "mtf" . $k;
165  else {
166 
167  if (!empty($t["m2"])) $start = "m2" . $k;
168  else $start = $v["e2"] . $k;
169  }
170  }
171  }
172  }
173  }
174  if ($start && (($limitIndex == - 1) || (empty($transitionLink[$v["t"] . $v["e2"]])))) {
175  $transitionLink[$v["t"] . $v["e2"]] = true;
176  if (empty($this->memoTr[$start][$end]) && empty($transitionLink[$kt])) {
177  $transitionLink[$kt] = true;
178  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans, label="%s"];', $start, $end, $this->style['arrow-label-font-color'], $this->style['arrow-color'], "");
179 
180  $this->memoTr[$start][$end] = true;
181  }
182  }
183  }
184  }
185  }
186  /**
187  * add node for state (one per transition)
188  * @param $e1
189  * @param $index
190  */
191  private function setTransitionState($e1, $index)
192  {
193  $color = $this->wdoc->getColor($e1);
194  $saction = $this->getActivityLabel($e1);
195  $tt = sprintf('label="%s"', $this->_n($e1));
196  $tt.= ',shape = circle, style=filled, fixedsize=true,width=1.0, fontname=sans';
197  if ($saction) $tt.= ', tooltip="' . $e1 . '"';
198 
199  if ($color) $tt.= ',fillcolor="' . $color . '"';
200 
201  $this->lines[] = '"' . $e1 . $index . '" [' . $tt . '];';
202 
203  $this->clusters[$index][] = $e1 . $index;
204  $this->clusterProps[$index] = sprintf('color="%s";fillcolor="blue:yellow";label="%s";', $color, $index);
205  }
206 
207  private function existsTransition($e1, $e2, $t)
208  {
209  foreach ($this->wdoc->cycle as $k => $v) {
210  if (($v["e1"] == $e1) && ($v["e2"] == $e2) && ($v["t"] == $t)) return true;
211  }
212  return false;
213  }
214  private function linkSameTransition($tr, $index)
215  {
216  foreach ($this->wdoc->cycle as $k => $v) {
217  if (($k < $index) && ($v["e2"] == $tr["e2"]) && ($v["t"] == $tr["t"])) {
218  $e2 = $v["e2"] . $k;
219  $t = $this->wdoc->transitions[$tr["t"]];
220  if (!empty($t["m0"])) $e2 = "m0" . $k;
221  elseif (!empty($t["m1"])) $e2 = "m1" . $k;
222  $e1 = $this->getActivityId($tr["e1"]);
223  if ($this->existsTransition($tr["e2"], $tr["e1"], $tr["t"])) continue;
224 
225  $this->lines[] = sprintf('"%s" -> "%s" [labelfontsize=6,color="%s" ,labelfontname=sans, label="%s"];', $e1, $e2, $this->style['arrow-color'], $this->_n($tr["t"]));
226  return true;
227  }
228  }
229  return false;
230  }
231  /**
232  * analyze a transition e1 - e2
233  * @param $index
234  * @param array $tr
235  */
236  public function setCompleteTransitionLine($index, $tr)
237  {
238  $this->lines[] = sprintf('# complete %d %s %s->%s', $index, $tr["t"], $tr["e1"], $tr["e2"]);
239  $e1 = $tr["e1"];
240  $e2 = $tr["e2"];
241  $t = $this->wdoc->transitions[$tr["t"]];
242  $m0 = isset($t["m0"]) ? $t["m0"] : null;
243  $m1 = isset($t["m1"]) ? $t["m1"] : null;
244  $m2 = isset($t["m2"]) ? $t["m2"] : null;
245  $m3 = isset($t["m3"]) ? $t["m3"] : null;
246  $ask = isset($t["ask"]) ? $t["ask"] : null;
247  $act = $this->getActivityId($e1);
248 
249  if ($this->linkSameTransition($tr, $index)) {
250 
251  $this->setAttachStart($e1, $act);
252  return;
253  }
254 
255  $this->setTransitionState($e2, $index);
256  $this->setM0M3($t, $index);
257  $tmain = '';
258  if (isset($this->wdoc->autonext[$tr["e1"]]) && ($this->wdoc->autonext[$e1] == $e2)) {
259  $tmain = sprintf('color="%s",style="setlinewidth(3)",arrowsize=1.0', $this->style['autonext-color']);
260  }
261  $startedPoint = false;
262  if ($act) {
263  $this->setAttachStart($e1, $act);
264  $startedPoint = true;
265 
266  $e1 = $act;
267  }
268 
269  if ($ask) {
270  $mi = "ask" . $index;
271  if (!$startedPoint) {
272  $this->setAttachStart($e1, $mi);
273  $startedPoint = true;
274  }
275  $this->lines[] = '#ASK';
276  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans, label="%s"];', $e1, $mi, $this->style['arrow-label-font-color'], $this->style['arrow-color'], _($tr["t"]));
277  $e1 = $mi;
278  }
279  if ($m0) {
280  $mi = "m0" . $index;
281  if (!$startedPoint) {
282  $this->setAttachStart($e1, $mi);
283  $startedPoint = true;
284  }
285  $this->lines[] = '#M0';
286  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans, label="%s"];', $e1, $mi, $this->style['arrow-label-font-color'], $this->style['arrow-color'], _($tr["t"]));
287  $e1 = $mi;
288  }
289 
290  if ($m1) {
291  $mi = "m1" . $index;
292  if (!$startedPoint) {
293  $this->setAttachStart($e1, $mi);
294  $startedPoint = true;
295  }
296  $this->lines[] = '#M1';
297  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans, label="%s"];', $e1, $mi, $this->style['arrow-label-font-color'], $this->style['arrow-color'], _($tr["t"]));
298  $e1 = $mi;
299  }
300  $e2p = $e2 . $index;
301  if (empty($this->memoTr[$e1][$e2p])) {
302 
303  if (!$startedPoint) {
304  $this->setAttachStart($e1, $e2);
305  $startedPoint = true;
306  }
307  $this->lines[] = sprintf('"%s" -> "%s" [labelfontsize=6,color="%s" %s,labelfontname=sans, label="%s"];', $e1, $e2p, $this->style['arrow-color'], $tmain, _($tr["t"]));
308  $this->memoTr[$e1][$e2p] = true;
309  }
310  $e2 = $e2p;
311  if ($m2) {
312  $mi = "m2" . $index;
313  $this->lines[] = '#M2';
314  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans, label="%s"];', $e2, $mi, $this->style['arrow-label-font-color'], $this->style['arrow-color'], _($tr["t"]));
315  $e2 = $mi;
316  }
317  $e2 = $this->setTransitionMail($e2, $tr, $index);
318  $e2 = $this->setStateMail($e2, $tr, $index);
319  $e2 = $this->setTransitionTimer($e2, $tr, $index);
320  $e2 = $this->setStateTimer($e2, $tr, $index);
321  if ($m3) {
322  $mi = "m3" . $index;
323  $this->lines[] = '#M3';
324  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans, label="%s"];', $e2, $mi, $this->style['arrow-label-font-color'], $this->style['arrow-color'], _($tr["t"]));
325  $e2 = $mi;
326  }
327  $this->lines[] = sprintf('# end complete %d %s %s->%s', $index, $tr["t"], $tr["e1"], $tr["e2"]);
328  }
329  /**
330  * declare end state and add red node to see it
331  */
332  private function setEndPoint()
333  {
334 
335  $end = $start = array();
336  foreach ($this->wdoc->cycle as $k => $t) {
337  $start[] = $t["e1"];
338  $end[] = $t["e2"];
339  }
340  $end = array_unique($end);
341  $start = array_unique($start);
342  $endState = array_diff(($end) , ($start));
343  //print_r2($endState);
344  $see = array();
345  $ends = array();
346  foreach ($endState as $e) {
347  foreach ($this->wdoc->cycle as $k => $t) {
348  if ($t["e2"] == $e && (empty($see[$e])) && (empty($see[$t["t"] . $t["e2"]]))) {
349  $end = 'E' . $e . $k;
350  $this->lines[] = '"' . $end . '" [shape = square,style=filled, width=0.3,label="", fixedsize=true,fontname=sans,color="' . $this->style['end-color'] . '"];';
351  $see[$e] = true;
352  $see[$t["t"] . $t["e2"]] = true;
353 
354  $ends[] = $end;
355  $this->setAttachStart($t["e2"], $end, $k);
356  }
357  }
358  }
359  if (count($ends) > 0) {
360  // $this->lines[] = sprintf('{rank=max; %s}', implode(',',$ends));
361 
362  }
363  }
364  /**
365  * draw cluster around transition
366  */
367  private function drawCluster()
368  {
369  foreach ($this->clusters as $kc => $aCluster) {
370  $sCluster = sprintf('subgraph cluster_%d {
371  style="rounded"; %s label="%s"', $kc, $this->clusterProps[$kc], $kc);
372  $sCluster.= '"' . implode('";"', $aCluster) . '"';
373  $sCluster.= '}';
374  $this->lines[] = $sCluster;
375  }
376  }
377  /**
378  * define starting of workflow
379  */
380  private function setStartPoint()
381  {
382 
383  $aid = strtolower($this->wdoc->attrPrefix . "_TMID" . $this->wdoc->firstState);
384  $tm = $this->wdoc->getMultipleRawValues($aid);
385  $aid = strtolower($this->wdoc->attrPrefix . "_MTID" . $this->wdoc->firstState);
386  $mt = $this->wdoc->getMultipleRawValues($aid);
387  $e1 = "D";
388 
389  $this->lines[] = '"' . $e1 . '" [shape = point,style=filled, width=0.3, fixedsize=true,fontname=sans,color="' . $this->style['start-color'] . '"];';;
390 
391  if (count($tm) == 0 && count($mt) == 0) {
392  $e2 = $this->getActivityId($this->wdoc->firstState);
393  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans];', $e1, $e2, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
394  } else {
395 
396  $e2 = 'D' . $this->wdoc->firstState;
397  $this->lines[] = sprintf('"%s" [label="%s",shape = doublecircle, style=filled, width=1.0, fixedsize=true,fontname=sans,fillcolor="%s"];', $e2, $this->_n($this->wdoc->firstState) , $this->wdoc->getColor($this->wdoc->firstState));
398  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans];', $e1, $e2, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
399  $e1 = $e2;
400 
401  if (count($tm) > 0) {
402  $e2 = 'tmfirst';
403 
404  $tmlabel = $this->quoteLabel($this->wdoc->getHtmlValue($this->wdoc->getAttribute($this->wdoc->attrPrefix . "_TMID" . $this->wdoc->firstState) , $this->wdoc->arrayToRawValue($tm) , '_self', false));
405  $timgt = ' image="' . DEFAULT_PUBDIR . '/Images/timer.png"';
406  $this->lines[] = '"' . str_replace(" ", "\\n", $e2) . '" [ label="' . $tmlabel . '",fixedsize=false,style=bold,shape=octagon,color="' . $this->style['timer-color'] . '", fontsize=' . $this->conditionfontsize . $timgt . ' ];';
407  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans];', $e1, $e2, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
408  $e1 = $e2;
409  }
410  if (count($mt) > 0) {
411  $e2 = 'mtfirst';
412  $tmlabel = $this->quoteLabel($this->wdoc->getHtmlValue($this->wdoc->getAttribute($this->wdoc->attrPrefix . "_MTID" . $this->wdoc->firstState) , $this->wdoc->arrayToRawValue($mt) , '_self', false));
413  $timgt = ' image="' . DEFAULT_PUBDIR . '/Images/tmail.png"';
414  $this->lines[] = '"' . $e2 . '" [ label="' . $tmlabel . '",fixedsize=false,style=bold,shape=house,color="' . $this->style['mail-color'] . '", fontsize=' . $this->conditionfontsize . $timgt . ' ];';
415  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans];', $e1, $e2, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
416  $e1 = $e2;
417  }
418 
419  if ($e1 != 'D') {
420  //attach to first state
421  $e2 = $this->getActivityId($this->wdoc->firstState);
422  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans];', $e1, $e2, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
423  }
424  }
425  }
426 
427  private function quoteLabel($s)
428  {
429  return str_replace(array(
430  "\n",
431  ' ',
432  '"',
433  '<BR>',
434  ) , array(
435  "\\n,",
436  "\\n",
437  "&quot;",
438  ",\\n"
439  ) , $s);
440  }
441  /**
442  * define mail node
443  * @param string $e2 state
444  * @param array $t transition
445  * @param int $index index
446  * @return string new node id
447  */
448  private function setTransitionMail($e2, $t, $index)
449  {
450  $ttrans = array();
451  $tm = $this->wdoc->getStateMailTemplate($t["t"]);
452  if ($tm) $ttrans[] = $tm;
453  $mtrans = $this->wdoc->getTransitionMailTemplates($t["t"]);
454 
455  if (count($mtrans) > 0) {
456  $ex = 'mt' . $index;
457  $tmlabel = "mail";
458 
459  $tmlabel = $this->quoteLabel($this->wdoc->getHtmlValue($this->wdoc->getAttribute($this->wdoc->attrPrefix . "_TRANS_MTID" . $t["t"]) , $this->wdoc->arrayToRawValue($mtrans) , '_self', false));
460  $timgt = ' image="' . DEFAULT_PUBDIR . '/Images/tmail.png"';
461 
462  $this->lines[] = '"' . $ex . '" [ label="' . $tmlabel . '",fixedsize=false, tooltip="mail",style=bold,shape=house,color="' . $this->style['mail-color'] . '"' . $timgt . ' ];';
463  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false,color="%s",labelfontname=sans];', $e2, $ex, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
464  $this->clusters[$index][] = $ex;
465  $e2 = $ex;
466  }
467 
468  return $e2;
469  }
470  /**
471  * define mail node
472  * @param string $e2 state
473  * @param array $t transition
474  * @param int $index index
475  * @return string new node id
476  */
477  private function setStateMail($e2, $t, $index)
478  {
479  $mt = $this->wdoc->getStateMailTemplate($t["e2"]);
480  if (count($mt) > 0) {
481  $ex = 'mtf' . $index;
482 
483  $tmlabel = $this->quoteLabel($this->wdoc->getHtmlValue($this->wdoc->getAttribute($this->wdoc->attrPrefix . "_MTID" . $t["e2"]) , $this->wdoc->arrayToRawValue($mt) , '_self', false));
484  $timgt = ' image="' . DEFAULT_PUBDIR . '/Images/tmail.png"';
485  $this->lines[] = '"' . $ex . '" [ label="' . $tmlabel . '",fixedsize=false,tooltip="mail",style=bold,shape=house,color="' . $this->style['mail-color'] . '"' . $timgt . ' ];';
486  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans];', $e2, $ex, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
487 
488  $this->clusters[$index][] = $ex;
489  $e2 = $ex;
490  }
491 
492  return $e2;
493  }
494  /**
495  * define timer node
496  * @param string $e2 state
497  * @param array $t transition
498  * @param int $index index
499  * @return string new node id
500  */
501  private function setStateTimer($e2, $t, $index)
502  {
503  $aid = strtolower($this->wdoc->attrPrefix . "_TMID" . $t["e2"]);
504  $mt = $this->wdoc->getMultipleRawValues($aid);
505  if (count($mt) > 0) {
506  $ex = 'tmf' . $index;
507 
508  $tmlabel = $this->quoteLabel($this->wdoc->getHtmlValue($this->wdoc->getAttribute($this->wdoc->attrPrefix . "_TMID" . $t["e2"]) , $this->wdoc->arrayToRawValue($mt) , '_self', false));
509  $timgt = ' image="' . DEFAULT_PUBDIR . '/Images/timer.png"';
510  $this->lines[] = '"' . $ex . '" [ label="' . $tmlabel . '",fixedsize=false,tooltip="timer",style=bold,shape=octagon,color="' . $this->style['mail-color'] . '"' . $timgt . ' ];';
511  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans];', $e2, $ex, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
512  $this->clusters[$index][] = $ex;
513  $e2 = $ex;
514  }
515 
516  return $e2;
517  }
518  /**
519  * define timer node
520  * @param string $e2 state
521  * @param array $t transition
522  * @param int $index index
523  * @return string new node id
524  */
525  private function setTransitionTimer($e2, $t, $index)
526  {
527  $ttrans = array();
528  $tm = $this->wdoc->getRawValue($this->wdoc->attrPrefix . "_TRANS_TMID" . $t["t"]);
529  if ($tm) $ttrans[] = $tm;
530  $ttrans = array_merge($ttrans, $this->wdoc->getMultipleRawValues($this->wdoc->attrPrefix . "_TRANS_PA_TMID" . $t["t"]));
531 
532  if (count($ttrans) > 0) {
533  $ex = 'tm' . $index;
534  $tmlabel = $this->quoteLabel($this->wdoc->getHtmlValue($this->wdoc->getAttribute($this->wdoc->attrPrefix . "_TRANS_MTID" . $t["t"]) , $this->wdoc->arrayToRawValue($ttrans) , '_self', false));
535  $timgt = ' image="' . DEFAULT_PUBDIR . '/Images/timer.png"';
536  $this->lines[] = '"' . $ex . '" [ label="' . $tmlabel . '",fixedsize=false,style=bold,tooltip="timer",shape=octagon,color="' . $this->style['timer-color'] . '"' . $timgt . ' ];';
537  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s",labelfontname=sans];', $e2, $ex, $this->style['arrow-label-font-color'], $this->style['arrow-color']);
538  $this->clusters[$index][] = $ex;
539  $e2 = $ex;
540  }
541 
542  return $e2;
543  }
544 
545  private function setSimpleTransitionLine($index, $tr)
546  {
547  $this->lines[] = sprintf('# simple %d %s %s->%s', $index, $tr["t"], $tr["e1"], $tr["e2"]);
548  $e1 = $tr["e1"];
549  $e2 = $tr["e2"];
550 
551  $tmain = '';
552  if (isset($this->wdoc->autonext[$tr["e1"]]) && ($this->wdoc->autonext[$tr["e1"]] == $tr["e2"])) {
553  $tmain = sprintf('color="%s",style="setlinewidth(3)",arrowsize=1.0', $this->style['autonext-color']);
554  }
555  $this->lines[] = sprintf('"%s" -> "%s" [labelfontsize=6,color="%s" %s,labelfontname=sans, label="%s"];', $e1, $e2, $this->style['arrow-color'], $tmain, _($tr["t"]));
556  }
557 
558  private function getActivityLabel($e)
559  {
560  $act = $this->wdoc->getActivity($e);
561  if (!$act) {
562  $act = sprintf(_("activity for %s") , _($e));
563  }
564  return str_replace('_', ' ', $act);
565  }
566 
567  private function setActivityTransitionLine($index, $tr)
568  {
569  $this->lines[] = sprintf('# activity %d %s %s->%s', $index, $tr["t"], $tr["e1"], $tr["e2"]);
570 
571  $e1 = $tr["e1"];
572  $e2 = $tr["e2"];
573  $act = $this->getActivityId($e1);
574  $tmain = '';
575  if (isset($this->wdoc->autonext[$tr["e1"]]) && ($this->wdoc->autonext[$e1] == $e2)) {
576  $tmain = sprintf('color="%s",style="setlinewidth(3)",arrowsize=1.0', $this->style['autonext-color']);
577  }
578  if ($act) {
579  if (empty($this->memoTr[$e1][$act])) {
580  $this->lines[] = sprintf('"%s" -> "%s" [labelfontcolor="%s",decorate=false, color="%s", labelfontname=sans, label="%s"];', $e1, $act, $this->style['arrow-label-font-color'], $this->style['arrow-color'], "");
581 
582  $this->memoTr[$e1][$act] = true;
583  }
584  $e1 = $act;
585  }
586 
587  if (empty($this->memoTr[$e1][$e2])) {
588  $this->lines[] = sprintf('"%s" -> "%s" [labelfontsize=6,color="%s" %s,labelfontname=sans, label="%s"];', $e1, $e2, $this->style['arrow-color'], $tmain, _($tr["t"]));
589  $this->memoTr[$e1][$e2] = true;
590  }
591  }
592 
593  private function setStates()
594  {
595  $states = $this->wdoc->getStates();
596  foreach ($states as $k => $v) {
597  $color = $this->wdoc->getColor($v);
598  $saction = $this->getActivityLabel($v);
599  $tt = sprintf('label="%s"', $this->_n($v));
600  $tt.= ',shape = circle, style=filled, fixedsize=true,width=1.0, fontname=sans';
601  if ($saction) $tt.= ', tooltip="' . $v . '"';
602 
603  if ($color) $tt.= ',fillcolor="' . $color . '"';
604 
605  $this->lines[] = '"' . $v . '" [' . $tt . '];';
606  }
607  }
608 
609  private function setActivities()
610  {
611  $states = $this->wdoc->getStates();
612  foreach ($states as $k => $v) {
613  $color = $this->wdoc->getColor($v);
614  $activity = $this->wdoc->getActivity($v);
615 
616  if (!$activity) {
617  $activity = $v;
618  $shape = "circle";
619  } else {
620  $shape = "box";
621  }
622 
623  $tt = sprintf('label="%s"', $this->_n($activity));
624  $tt.= ',shape = ' . $shape . ', style=filled, fixedsize=false,width=1.0, fontname=sans';
625  if ($v) $tt.= ', tooltip="' . $v . '"';
626 
627  if ($color) $tt.= ',fillcolor="' . $color . '"';
628 
629  $this->lines[] = '"' . $v . '" [' . $tt . '];';
630  }
631  }
632  private function setActivity()
633  {
634  $states = $this->wdoc->getStates();
635  foreach ($states as $k => $v) {
636  $color = $this->wdoc->getColor($v);
637  $sact = $this->getActivityLabel($v);
638  if (!$sact) {
639  //$sact = "activity $v";
640 
641  }
642  if ($this->wdoc->getActivity($v) || (!$this->isEndState($v))) {
643  $tt = 'shape = box, style=filled, fixedsize=false,width=1.0, fontname=sans';
644  if ($sact) $tt.= sprintf(',label="%s"', $this->_n($sact));
645 
646  if ($color) $tt.= ',fillcolor="' . $color . '"';
647 
648  $this->lines[] = '"' . $this->getActivityId($v) . '" [' . $tt . '];';
649  }
650  }
651  }
652 
653  private function getActivityId($state)
654  {
655  return "act_" . $state;
656  }
657 
658  private function isEndState($e)
659  {
660  foreach ($this->wdoc->cycle as $t) {
661  if ($t["e1"] == $e) return false;
662  }
663  return true;
664  }
665 
666  private function setM0M3($tr, $k)
667  {
668 
669  $tt = sprintf('fixedsize=false,fontsize="%s"', $this->conditionfontsize);
670  if (!empty($tr["m0"])) {
671  $mi = "m0" . $k;
672  $this->lines[] = sprintf('"%s" [%s,label="%s", shape=Mdiamond,tooltip="m0",color="%s"];', $mi, $tt, $this->_n($tr["m0"]) , $this->style['condition-color0']);
673 
674  $this->clusters[$k][] = $mi;
675  }
676  if (!empty($tr["m1"])) {
677  $mi = "m1" . $k;
678  $this->lines[] = sprintf('"%s" [%s,label="%s", tooltip="m1",shape=diamond,color="%s"];', $mi, $tt, $this->_n($tr["m1"]) , $this->style['condition-color1']);
679  $this->clusters[$k][] = $mi;
680  }
681  if (!empty($tr["m2"])) {
682  $mi = "m2" . $k;
683  $this->lines[] = sprintf('"%s" [%s,label="%s",tooltip="m2",shape=box,color="%s"];', $mi, $tt, $this->_n($tr["m2"]) , $this->style['action-color2']);
684  $this->clusters[$k][] = $mi;
685  }
686  if (!empty($tr["m3"])) {
687  $mi = "m3" . $k;
688  $this->lines[] = sprintf('"%s" [%s,label="%s",tooltip="m3",shape=box,color="%s"];', $mi, $tt, $this->_n($tr["m3"]) , $this->style['action-color3']);
689  $this->clusters[$k][] = $mi;
690  }
691  if (!empty($tr["ask"]) && count($tr["ask"]) > 0) {
692  $mi = "ask" . $k;
693  $askLabel = array();
694  foreach ($tr["ask"] as $aAsk) {
695  $oa = $this->wdoc->getAttribute($aAsk);
696  if ($oa) $askLabel[] = $oa->getLabel();
697  }
698  $this->lines[] = sprintf('"%s" [%s,label="%s", style="rounded",tooltip="ask",shape=egg,color="%s", image="%s"];', $mi, $tt, implode('\\n', $askLabel) , $this->style['ask-color'], DEFAULT_PUBDIR . '/Images/wask.png');
699  $this->clusters[$k][] = $mi;
700  }
701  }
702 
703  public function _n($s)
704  {
705  if ($s) return str_replace(array(
706  " ",
707  '"',
708  "_"
709  ) , array(
710  "\\n",
711  "&quot;",
712  "\\n"
713  ) , _($s));
714  return '';
715  }
716 
717  public function setWorkflow(WDoc & $doc)
718  {
719  $this->wdoc = $doc;
720  }
721 
722  public function setRatio($ratio)
723  {
724  $this->ratio = $ratio;
725  }
726 
727  public function setType($type)
728  {
729  $this->type = $type;
730  }
731 
732  public function setOrient($orient)
733  {
734  $this->orient = $orient;
735  }
736 
737  public function setSize($isize)
738  {
739  $this->fontsize = 13;
740  if ($isize == "auto") $this->size = "";
741  else {
742  if ($isize == "A4") {
743  $this->fontsize = 20;
744  $this->size = "size=\"7.6,11!\";"; // A4 whith 1.5cm margin
745 
746  } else {
747  if (preg_match("/([0-9\.]+),([0-9\.]+)/", $isize, $reg)) {
748  $this->fontsize = intval(min($reg[1], $reg[2]) / 1);
749  $this->fontsize = 12;
750  $this->size = sprintf("size=\"%.2f,%.2f!\";", floatval($reg[1]) / 2.55, floatval($reg[2]) / 2.55);
751  } else {
752  $isize = sprintf("%.2f", floatval($isize) / 2.55);
753  $this->size = "size=\"$isize,$isize!\";";
754  }
755  }
756  }
757 
758  $this->statefontsize = $this->fontsize;
759  $this->conditionfontsize = intval($this->fontsize * 10 / 13);
760  $this->labelfontsize = intval($this->fontsize * 11 / 13);
761  }
762 }
763 /*
764  * @var Application $appl
765  */
766 $dbaccess = $appl->dbaccess;
767 if ($dbaccess == "") {
768  print "Database not found : appl->dbaccess";
769  exit;
770 }
771 
772 $usage = new ApiUsage();
773 $usage->setDefinitionText("Create graph image for workflow");
774 $docid = $usage->addRequiredParameter("docid", "workflow identificator");
775 $orient = $usage->addOptionalParameter("orient", "orientation", array(
776  "LR",
777  "TB",
778  "BT",
779  "RL"
780 ) , "LR");
781 
782 $ratio = $usage->addOptionalParameter("ratio", "ratio", array(
783  "auto",
784  "fill",
785  "compress",
786  "expand"
787 ) , "auto");
788 $isize = $usage->addOptionalParameter("size", "image size", array() , "10");
789 
790 $type = $usage->addOptionalParameter("type", "type of output", array(
791  "complet",
792  "activity",
793  "justactivity",
794  "simple",
795  "cluster"
796 ) , "complet");
797 $usage->verify();
798 /*
799  * @var WDoc $doc
800  */
801 $doc = new_doc($dbaccess, $docid);
802 
803 $dw = new DotWorkflow();
804 $dw->setOrient($orient);
805 $dw->setRatio($ratio);
806 $dw->setSize($isize);
807 $dw->setType($type);
808 $dw->setWorkflow($doc);
809 print $dw->generate();
global $appl
Definition: checkVault.php:9
$s type
Definition: dav.php:73
if($_POST["login"]=="")
Definition: chgpasswd.php:19
setRatio($ratio)
if($dbaccess=="") $usage
Exception class use exceptionCode to identifiy correctly exception.
Definition: exceptions.php:19
print t
Definition: cleanFamily.php:92
if($famId) $s
if($app->id > 0) return false
const DEFAULT_PUBDIR
Definition: Lib.Prefix.php:28
setSize($isize)
setWorkflow(WDoc &$doc)
setCompleteTransitionLine($index, $tr)
$dbaccess
print
Definition: checklist.php:49
switch($command) exit
Definition: checkVault.php:46
$docid
setOrient($orient)
$isize
Verify arguments for wsh programs.
← centre documentaire © anakeen