Platform  3.1
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Class.WDoc.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
5  * @package FDL
6 */
7 /**
8  * Workflow Class Document
9  *
10  * @author Anakeen 2002
11  * @version $Id: Class.WDoc.php,v 1.63 2009/01/08 17:47:07 eric Exp $
12  * @license http://creativecommons.org/licenses/by-nc-sa/2.0/fr/ Anakeen - licence CC
13  * @package FDL
14  */
15 /**
16  */
17 
18 include_once ('FDL/Class.Doc.php');
19 /**
20  * WorkFlow Class
21  */
22 class WDoc extends Doc
23 {
24  /**
25  * WDoc has its own special access depend on transition
26  * by default the three access are always set
27  *
28  * @var array
29  */
30  var $acls = array(
31  "view",
32  "edit",
33  "delete"
34  );
35 
36  var $usefor = 'W';
37  var $defDoctype = 'W';
38  var $defClassname = 'WDoc';
39  var $attrPrefix = "WF"; // prefix attribute
40  var $stateactivity = array(); // label of states
41  // --------------------------------------------------------------------
42  //---------------------- TRANSITION DEFINITION --------------------
43  var $transitions = array(); // set by childs classes
44  var $cycle = array(); // set by childs classes
45  var $autonext = array(); // set by childs classes
46  var $firstState = ""; // first state in workflow
47  var $viewnext = "list"; // view interface as select list may be (list|button)
48  var $nosave = array(); // states where it is not permitted to save and stay (force next state)
49 
50  /**
51  * document instance
52  * @var Doc
53  */
54  public $doc = null;
55  function __construct($dbaccess = '', $id = '', $res = '', $dbid = 0)
56  {
57  // first construct acl array
58  $ka = POS_WF;
59  foreach ($this->transitions as $k => $trans) {
60  $this->dacls[$k] = array(
61  "pos" => $ka,
62  "description" => _($k)
63  );
64  $this->acls[] = $k;
65  $ka++;
66  }
67  if (isset($this->fromid)) $this->defProfFamId = $this->fromid; // it's a profil itself
68  // don't use Doc constructor because it could call this constructor => infinitive loop
70  }
71  /**
72  * affect document instance
73  * @param Doc $doc
74  */
75  function set(Doc & $doc)
76  {
77  if ((!isset($this->doc)) || ($this->doc->id != $doc->id)) {
78  $this->doc = & $doc;
79  if (($doc->doctype != 'C') && ($doc->state == "")) {
80  $doc->state = $this->getFirstState();
81  $this->changeProfil($doc->state);
82  $this->changeCv($doc->state);
83  }
84  }
85  }
86  function getFirstState()
87  {
88  return $this->firstState;
89  }
90  /**
91  * change profil according to state
92  * @param string $newstate new state of document
93  */
94  function changeProfil($newstate)
95  {
96 
97  if ($newstate != "") {
98  $profid = $this->getValue($this->_Aid("_ID", $newstate));
99  if (!is_numeric($profid)) $profid = getIdFromName($this->dbaccess, $profid);
100  if ($profid > 0) {
101  // change only if new profil
102  $err = $this->doc->setProfil($profid);
103  }
104  }
105  return $err;
106  }
107  /**
108  * change allocate user according to state
109  * @param string $newstate new state of document
110  */
111  function changeAllocateUser($newstate)
112  {
113  $err = "";
114  if ($newstate != "") {
115  $auserref = trim($this->getValue($this->_Aid("_AFFECTREF", $newstate)));
116  if ($auserref) {
117  $uid = $this->getAllocatedUser($newstate);
118  if ($uid) $wuid = $this->getDocValue($uid, "us_whatid");
119  if ($wuid > 0) {
120  $lock = (trim($this->getValue($this->_Aid("_AFFECTLOCK", $newstate))) == "yes");
121  $err = $this->doc->allocate($wuid, "", false, $lock);
122  if ($err == "") {
123  $automail = (trim($this->getValue($this->_Aid("_AFFECTMAIL", $newstate))) == "yes");
124  if ($automail) {
125  include_once ("FDL/mailcard.php");
126  $to = trim($this->getDocValue($uid, "us_mail"));
127  if (!$to) addWarningMsg(sprintf(_("%s has no email address") , $this->getTitle($uid)));
128  else {
129  $subject = sprintf(_("allocation for %s document") , $this->doc->title);
130  $err = sendCard($action, $this->doc->id, $to, "", $subject, "", true, $commentaction, "", "", "htmlnotif");
131  if ($err != "") addWarningMsg($err);
132  }
133  }
134  }
135  }
136  } else $err = $this->doc->unallocate("", false);
137  }
138  return $err;
139  }
140 
141  private function getAllocatedUser($newstate)
142  {
143  $auserref = trim($this->getValue($this->_Aid("_AFFECTREF", $newstate)));
144  $type = trim($this->getValue($this->_Aid("_AFFECTTYPE", $newstate)));
145  if (!$auserref) return false;
146  $wuid = false;
147  $aid = strtok($auserref, " ");
148  switch ($type) {
149  case 'F': // fixed address
150  // $wuid=$this->getDocValue($aid,"us_whatid");
151  $uid = $aid;
152  break;
153 
154  case 'PR': // docid parameter
155  $uid = $this->doc->getparamValue($aid);
156  // if ($uid) $wuid=$this->getDocValue($uid,"us_whatid");
157  break;
158 
159  case 'WPR': // workflow docid parameter
160  $uid = $this->getparamValue($aid);
161  // if ($uid) $wuid=$this->getDocValue($uid,"us_whatid");
162  break;
163 
164  case 'D': // user relations
165  $uid = $this->doc->getRValue($aid);
166  // if ($uid) $wuid=$this->getDocValue($docid,'us_whatid');
167  break;
168 
169  case 'WD': // user relations
170  $uid = $this->getRValue($aid);
171  // if ($uid) $wuid=$this->getDocValue($docid,'us_whatid');
172  break;
173  }
174  return $uid;
175  }
176  /**
177  * change cv according to state
178  * @param string $newstate new state of document
179  */
180  function changeCv($newstate)
181  {
182 
183  if ($newstate != "") {
184  $cvid = ($this->getValue($this->_Aid("_CVID", $newstate)));
185  if (!is_numeric($cvid)) $cvid = getIdFromName($this->dbaccess, $cvid);
186  if ($cvid > 0) {
187  // change only if set
188  $this->doc->cvid = $cvid;
189  } else {
190  $fdoc = $this->doc->getFamDoc();
191  $this->doc->cvid = $fdoc->ccvid;
192  }
193  }
194  }
195 
196  private function _Aid($fix, $state)
197  {
198  return strtolower($this->attrPrefix . $fix . str_replace(":", "_", $state));
199  }
200  /**
201  * get the profile id according to state
202  * @param string $state
203  * @return string
204  */
205  public function getStateProfil($state)
206  {
207  return $this->getValue($this->_Aid("_id", $state));
208  }
209  /**
210  * get the attribute id for profile id according to state
211  * @param string $state
212  * @return string
213  */
215  {
216  return $this->_Aid("_id", $state);
217  }
218  /**
219  * get the mask id according to state
220  * @param string $state
221  * @return string
222  */
223  public function getStateMask($state)
224  {
225  return $this->getValue($this->_Aid("_mskid", $state));
226  }
227  /**
228  * get the view control id according to state
229  * @param string $state
230  * @return string
231  */
232  public function getStateViewControl($state)
233  {
234  return $this->getValue($this->_Aid("_cvid", $state));
235  }
236  /**
237  * get the timers ids according to state
238  * @param string $state
239  * @return string
240  */
241  public function getStateTimers($state)
242  {
243  return $this->getValue($this->_Aid("_tmid", $state));
244  }
245  /**
246  * get the mail templates ids according to state
247  * @param string $state
248  * @return array
249  */
250  public function getStateMailTemplate($state)
251  {
252  return $this->getTValue($this->_Aid("_mtid", $state));
253  }
254  /**
255  * create of parameters attributes of workflow
256  */
258  {
259  if ($this->doctype == 'C') $cid = $this->id;
260  else $cid = $this->fromid;
261 
262  $ordered = 1000;
263  // delete old attributes before
264  $this->exec_query(sprintf("delete from docattr where docid=%d and options ~ 'autocreated=yes'", intval($cid)));
265  $this->getStates();
266  foreach ($this->states as $k => $state) {
267  // --------------------------
268  // frame
269  $aidframe = $this->_Aid("_FR", $state);
270  $oattr = new DocAttr($this->dbaccess, array(
271  $cid,
272  $aidframe
273  ));
274  $oattr->docid = $cid;
275  $oattr->visibility = "W";
276  $oattr->type = "frame";
277  $oattr->id = $aidframe;
278  $oattr->frameid = "wf_tab_states";
279  $oattr->labeltext = sprintf(_("parameters for %s step") , _($state));
280  $oattr->link = "";
281  $oattr->phpfunc = "";
282  $oattr->options = "autocreated=yes";
283  $oattr->ordered = $ordered++;
284  if ($oattr->isAffected()) $oattr->Modify();
285  else $oattr->Add();
286  // --------------------------
287  // profil id
288  $aid = $this->_Aid("_", $state);
289  $aidprofilid = $this->_Aid("_ID", $state); //strtolower($this->attrPrefix."_ID".strtoupper($state));
290  $oattr = new DocAttr($this->dbaccess, array(
291  $cid,
292  $aidprofilid
293  ));
294  $oattr->docid = $cid;
295  $oattr->visibility = "W";
296  $oattr->type = 'docid("PROFIL")';
297  $oattr->id = $aidprofilid;
298  $oattr->labeltext = sprintf(_("%s profile") , _($state));
299  $oattr->link = "";
300  $oattr->frameid = $aidframe;
301  $oattr->options = "autocreated=yes";
302 
303  $oattr->phpfile = "fdl.php";
304  $oattr->phpfunc = "lprofil(D,CT,WF_FAMID):$aidprofilid,CT";
305  $oattr->ordered = $ordered++;
306  if ($oattr->isAffected()) $oattr->Modify();
307  else $oattr->Add();
308  // --------------------------
309  // mask id
310  $aid = $this->_Aid("_MSKID", $state);
311 
312  $oattr = new DocAttr($this->dbaccess, array(
313  $cid,
314  $aid
315  ));
316  $oattr->docid = $cid;
317  $oattr->visibility = "W";
318  $oattr->type = 'docid("MASK")';
319  $oattr->id = $aid;
320  $oattr->labeltext = sprintf(_("%s mask") , _($state));
321  $oattr->link = "";
322  $oattr->frameid = $aidframe;
323  $oattr->phpfile = "fdl.php";
324  $oattr->phpfunc = "lmask(D,CT,WF_FAMID):$aid,CT";
325  $oattr->elink = '';
326  $oattr->options = 'autocreated=yes|creation={autoclose:"yes",msk_famid:wf_famid,ba_title:"' . _($state) . '"}';
327  $oattr->ordered = $ordered++;
328  if ($oattr->isAffected()) $oattr->Modify();
329  else $oattr->Add();
330  // --------------------------
331  // state color
332  $aid = $this->_Aid("_COLOR", $state);
333  $oattr = new DocAttr($this->dbaccess, array(
334  $cid,
335  $aid
336  ));
337  $oattr->docid = $cid;
338  $oattr->visibility = "W";
339  $oattr->type = "color";
340  $oattr->link = "";
341  $oattr->phpfile = "";
342  $oattr->id = $aid;
343  $oattr->frameid = $aidframe;
344  $oattr->ordered = $ordered++;
345  $oattr->phpfunc = "";
346  $oattr->options = "autocreated=yes";
347  $oattr->labeltext = sprintf(_("%s color") , _($state));
348  if ($oattr->isAffected()) $oattr->Modify();
349  else $oattr->Add();
350  // --------------------------
351  // CV link
352  $aid = $this->_Aid("_CVID", $state);
353  $oattr = new DocAttr($this->dbaccess, array(
354  $cid,
355  $aid
356  ));
357  $oattr->docid = $cid;
358  $oattr->visibility = "W";
359  $oattr->type = 'docid("CVDOC")';
360  $oattr->link = "";
361  $oattr->phpfile = "fdl.php";
362  $oattr->phpfunc = "lcvdoc(D,CT,WF_FAMID):$aid,CT";
363  $oattr->elink = '';
364  $oattr->options = 'autocreated=yes|creation={autoclose:"yes",cv_famid:wf_famid,ba_title:"' . _($state) . '"}';
365  $oattr->id = $aid;
366  $oattr->frameid = $aidframe;
367  $oattr->ordered = $ordered++;
368 
369  $oattr->labeltext = sprintf(_("%s cv") , _($state));
370  if ($oattr->isAffected()) $oattr->Modify();
371  else $oattr->Add();
372  // --------------------------
373  // Mail template link
374  $aid = $this->_Aid("_MTID", $state);
375  $oattr = new DocAttr($this->dbaccess, array(
376  $cid,
377  $aid
378  ));
379  $oattr->docid = $cid;
380  $oattr->visibility = "W";
381  $oattr->type = 'docid("MAILTEMPLATE")';
382  $oattr->link = "";
383  $oattr->phpfile = "fdl.php";
384  $oattr->phpfunc = "lmailtemplatedoc(D,CT,WF_FAMID):$aid,CT";
385  $oattr->id = $aid;
386  $oattr->frameid = $aidframe;
387  $oattr->options = "multiple=yes|autocreated=yes";
388 
389  $oattr->elink = '';
390  $oattr->options = 'autocreated=yes|multiple=yes|creation={autoclose:"yes",tmail_family:wf_famid,tmail_workflow:fromid}';
391  $oattr->ordered = $ordered++;
392  $oattr->labeltext = sprintf(_("%s mail template") , _($state));
393  if ($oattr->isAffected()) $oattr->Modify();
394  else $oattr->Add();
395  // --------------------------
396  // Timer link
397  $aid = $this->_Aid("_TMID", $state);
398  $oattr = new DocAttr($this->dbaccess, array(
399  $cid,
400  $aid
401  ));
402  $oattr->docid = $cid;
403  $oattr->visibility = "W";
404  $oattr->type = 'docid("TIMER")';
405  $oattr->link = "";
406  $oattr->phpfile = "fdl.php";
407  $oattr->phpfunc = "ltimerdoc(D,CT,WF_FAMID):$aid,CT";
408  $oattr->id = $aid;
409  $oattr->elink = '';
410  $oattr->options = 'autocreated=yes|creation={autoclose:"yes",tm_family:wf_famid,tm_workflow:fromid,tm_title:"' . _($state) . '"}';
411  $oattr->frameid = $aidframe;
412  $oattr->ordered = $ordered++;
413  $oattr->labeltext = sprintf(_("%s timer") , _($state));
414  if ($oattr->isAffected()) $oattr->Modify();
415  else $oattr->Add();
416  // --------------------------
417  // Ask link
418  $aid = $this->_Aid("_ASKID", $state);
419  $oattr = new DocAttr($this->dbaccess, array(
420  $cid,
421  $aid
422  ));
423  $oattr->docid = $cid;
424  $oattr->visibility = "W";
425  $oattr->type = 'docid("WASK")';
426  $oattr->link = "";
427  $oattr->phpfile = "";
428  $oattr->phpfunc = "";
429  $oattr->id = $aid;
430  $oattr->elink = '';
431  $oattr->options = 'multiple=yes|autocreated=yes|creation={autoclose:"yes"}';
432  $oattr->frameid = $aidframe;
433  $oattr->ordered = $ordered++;
434  $oattr->labeltext = sprintf(_("%s wask") , _($state));
435  if ($oattr->isAffected()) $oattr->Modify();
436  else $oattr->Add();
437  // --------------------------
438  // Label action
439  $aid = $this->_Aid("_ACTIVITYLABEL", $k);
440  $oattr = new DocAttr($this->dbaccess, array(
441  $cid,
442  $aid
443  ));
444  $oattr->docid = $cid;
445 
446  if ($this->stateactivity[$k]) {
447  $oattr->visibility = "S";
448  } else $oattr->visibility = "W";
449  $oattr->type = 'text';
450  $oattr->link = "";
451  $oattr->phpfile = "";
452  $oattr->phpfunc = "";
453  $oattr->id = $aid;
454  $oattr->options = "autocreated=yes";
455  $oattr->frameid = $aidframe;
456  $oattr->ordered = $ordered++;
457 
458  $oattr->labeltext = sprintf(_("%s activity") , _($k));
459  if ($oattr->isAffected()) $oattr->Modify();
460  else $oattr->Add();
461  // --------------------------
462  // Affected user link
463  $aid = $this->_Aid("_T_AFFECT", $state);
464  $afaid = $aid;
465  $oattr = new DocAttr($this->dbaccess, array(
466  $cid,
467  $aid
468  ));
469  $oattr->docid = $cid;
470  $oattr->visibility = "U";
471  $oattr->type = 'array';
472  $oattr->id = $aid;
473  $oattr->frameid = $aidframe;
474  $oattr->options = "vlabel=none|autocreated=yes";
475  $oattr->ordered = $ordered++;
476  $oattr->labeltext = sprintf(_("%s affectation") , _($state));
477  if ($oattr->isAffected()) $oattr->Modify();
478  else $oattr->Add();
479 
480  $aid = $this->_Aid("_AFFECTTYPE", $state);
481  $aidtype = $aid;
482  $oattr = new DocAttr($this->dbaccess, array(
483  $cid,
484  $aid
485  ));
486  $oattr->docid = $cid;
487  $oattr->visibility = "W";
488  $oattr->type = 'enum';
489  $oattr->options = "autocreated=yes";
490  $oattr->phpfunc = "F|" . _("Utilisateur fixe") . ",D|" . _("Attribut relation") . ",PR|" . _("Relation parametre") . ",WD|" . _("Relation cycle") . ",WPR|" . _("Parametre cycle");
491  $oattr->id = $aid;
492  $oattr->frameid = $afaid;
493  $oattr->ordered = $ordered++;
494  $oattr->labeltext = sprintf(_("%s affectation type") , _($state));
495  if ($oattr->isAffected()) $oattr->Modify();
496  else $oattr->Add();
497 
498  $aid = $this->_Aid("_AFFECTREF", $state);
499  $oattr = new DocAttr($this->dbaccess, array(
500  $cid,
501  $aid
502  ));
503  $oattr->docid = $cid;
504  $oattr->visibility = "W";
505  $oattr->type = 'text';
506  $oattr->link = "";
507  $oattr->options = "cwidth=160px|autocreated=yes";
508  $oattr->phpfile = "fdl.php";
509  $oattr->phpfunc = "tpluser(D,$aidtype,WF_FAMID,FROMID,$aid):$aid";
510  $oattr->id = $aid;
511  $oattr->frameid = $afaid;
512  $oattr->ordered = $ordered++;
513  $oattr->labeltext = sprintf(_("%s affected user") , _($state));
514  if ($oattr->isAffected()) $oattr->Modify();
515  else $oattr->Add();
516 
517  $aid = $this->_Aid("_AFFECTLOCK", $state);
518  $oattr = new DocAttr($this->dbaccess, array(
519  $cid,
520  $aid
521  ));
522  $oattr->docid = $cid;
523  $oattr->visibility = "W";
524  $oattr->type = 'enum';
525  $oattr->link = "";
526  $oattr->options = "eformat=bool|autocreated=yes";
527  $oattr->phpfunc = "no|" . _("affect no lock") . ",yes|" . _("affect auto lock");
528  $oattr->id = $aid;
529  $oattr->frameid = $afaid;
530  $oattr->ordered = $ordered++;
531  $oattr->labeltext = sprintf(_("%s autolock") , _($state));
532  if ($oattr->isAffected()) $oattr->Modify();
533  else $oattr->Add();
534 
535  $aid = $this->_Aid("_AFFECTMAIL", $state);
536  $oattr = new DocAttr($this->dbaccess, array(
537  $cid,
538  $aid
539  ));
540  $oattr->docid = $cid;
541  $oattr->visibility = "W";
542  $oattr->type = 'enum';
543  $oattr->link = "";
544  $oattr->options = "eformat=bool|autocreated=yes";
545  $oattr->phpfunc = "no|" . _("affect no mail") . ",yes|" . _("affect auto mail");
546  $oattr->id = $aid;
547  $oattr->frameid = $afaid;
548  $oattr->ordered = $ordered++;
549  $oattr->labeltext = sprintf(_("%s automail") , _($state));
550  if ($oattr->isAffected()) $oattr->Modify();
551  else $oattr->Add();
552  }
553 
554  foreach ($this->transitions as $k => $trans) {
555  // --------------------------
556  // frame
557  $aidframe = $this->_Aid("_TRANS_FR", $k);
558  $oattr = new DocAttr($this->dbaccess, array(
559  $cid,
560  $aidframe
561  ));
562  $oattr->docid = $cid;
563  $oattr->visibility = "W";
564  $oattr->type = "frame";
565  $oattr->id = $aidframe;
566  $oattr->frameid = "wf_tab_transitions";
567  $oattr->labeltext = sprintf(_("parameters for %s transition") , _($k));
568  $oattr->link = "";
569  $oattr->phpfunc = "";
570  $oattr->options = "autocreated=yes";
571  $oattr->ordered = $ordered++;
572  if ($oattr->isAffected()) $oattr->Modify();
573  else $oattr->Add();
574  // --------------------------
575  // Mail template link
576  $aid = $this->_Aid("_TRANS_MTID", $k);
577  $oattr = new DocAttr($this->dbaccess, array(
578  $cid,
579  $aid
580  ));
581  $oattr->docid = $cid;
582  $oattr->visibility = "W";
583  $oattr->type = 'docid("MAILTEMPLATE")';
584  $oattr->link = "";
585  $oattr->phpfile = "fdl.php";
586  $oattr->phpfunc = "lmailtemplatedoc(D,CT,WF_FAMID):$aid,CT";
587  $oattr->elink = "";
588  $oattr->id = $aid;
589  $oattr->frameid = $aidframe;
590  $oattr->ordered = $ordered++;
591  $oattr->options = 'autocreated=yes|multiple=yes|creation={autoclose:"yes",tmail_family:wf_famid,tmail_workflow:fromid}';
592 
593  $oattr->labeltext = sprintf(_("%s mail template") , _($k));
594  if ($oattr->isAffected()) $oattr->Modify();
595  else $oattr->Add();
596  // --------------------------
597  // Timer link
598  $aid = $this->_Aid("_TRANS_TMID", $k);
599  $oattr = new DocAttr($this->dbaccess, array(
600  $cid,
601  $aid
602  ));
603  $oattr->docid = $cid;
604  $oattr->visibility = "W";
605  $oattr->type = 'docid("TIMER")';
606  $oattr->link = "";
607  $oattr->phpfile = "fdl.php";
608  $oattr->phpfunc = "ltimerdoc(D,CT,WF_FAMID):$aid,CT";
609  $oattr->elink = "";
610  $oattr->options = 'autocreated=yes|creation={autoclose:"yes",tm_family:wf_famid,tm_workflow:fromid,tm_title:"' . _($state) . '"}';
611 
612  $oattr->id = $aid;
613  $oattr->frameid = $aidframe;
614  $oattr->ordered = $ordered++;
615  $oattr->labeltext = sprintf(_("%s timer") , _($k));
616  if ($oattr->isAffected()) $oattr->Modify();
617  else $oattr->Add();
618  // --------------------------
619  // Persistent Attach Timer link
620  $aid = $this->_Aid("_TRANS_PA_TMID", $k);
621  $oattr = new DocAttr($this->dbaccess, array(
622  $cid,
623  $aid
624  ));
625  $oattr->docid = $cid;
626  $oattr->visibility = "W";
627  $oattr->type = 'docid("TIMER")';
628  $oattr->link = "";
629  $oattr->phpfile = "fdl.php";
630  $oattr->phpfunc = "ltimerdoc(D,CT,WF_FAMID):$aid,CT";
631  $oattr->elink = "";
632  $oattr->options = 'multiple=yes|autocreated=yes|creation={autoclose:"yes",tm_family:wf_famid,tm_workflow:fromid,tm_title:"' . _($state) . '"}';
633 
634  $oattr->id = $aid;
635  $oattr->frameid = $aidframe;
636  $oattr->ordered = $ordered++;
637  $oattr->labeltext = sprintf(_("%s persistent timer") , _($k));
638  if ($oattr->isAffected()) $oattr->Modify();
639  else $oattr->Add();
640  // --------------------------
641  // Persistent UnAttach Timer link
642  $aid = $this->_Aid("_TRANS_PU_TMID", $k);
643  $oattr = new DocAttr($this->dbaccess, array(
644  $cid,
645  $aid
646  ));
647  $oattr->docid = $cid;
648  $oattr->visibility = "W";
649  $oattr->type = 'docid("TIMER")';
650  $oattr->link = "";
651  $oattr->phpfile = "fdl.php";
652  $oattr->phpfunc = "ltimerdoc(D,CT,WF_FAMID):$aid,CT";
653  $oattr->elink = "";
654  $oattr->id = $aid;
655  $oattr->options = "multiple=yes|autocreated=yes";
656  $oattr->frameid = $aidframe;
657  $oattr->ordered = $ordered++;
658  $oattr->labeltext = sprintf(_("%s unattach timer") , _($k));
659  if ($oattr->isAffected()) $oattr->Modify();
660  else $oattr->Add();
661  }
662  refreshPhpPgDoc($this->dbaccess, $cid);
663  }
664  /**
665  * change state of a document
666  * the method {@link set()} must be call before
667  * @param string $newstate the next state
668  * @param string $comment comment to be set in history (describe why change state)
669  * @param bool $force is true when it is the second passage (without interactivity)
670  * @param bool $withcontrol set to false if you want to not verify control permission ot transition
671  * @param bool $wm1 set to false if you want to not apply m1 methods
672  * @param bool $wm2 set to false if you want to not apply m2 methods
673  * @param bool $need set to false if you want to not verify needed attribute are set
674  * @return string error message, if no error empty string
675  */
676  function changeState($newstate, $addcomment = "", $force = false, $withcontrol = true, $wm1 = true, $wm2 = true, $wneed = true)
677  {
678  // if ($this->doc->state == $newstate) return ""; // no change => no action
679  // search if possible change in concordance with transition array
680  $foundFrom = false;
681  $foundTo = false;
682  reset($this->cycle);
683  while (list($k, $trans) = each($this->cycle)) {
684  if (($this->doc->state == $trans["e1"])) {
685  // from state OK
686  $foundFrom = true;
687  if ($newstate == $trans["e2"]) {
688  $foundTo = true;
689  $tr = $this->transitions[$trans["t"]];
690  $tname = $trans["t"];
691  }
692  }
693  }
694 
695  if ($this->userid != 1) { // admin can go to any states
696  if (!$foundTo) return (sprintf(_("ChangeState :: the new state '%s' is not known or is not allowed from %s") , _($newstate) , _($this->doc->state)));
697  if (!$foundFrom) return (sprintf(_("ChangeState :: the initial state '%s' is not known") , _($this->doc->state)));
698  }
699  // verify if completed doc
700  if ($wneed) {
701  $err = $this->doc->isCompleteNeeded();
702  if ($err != "") return $err;
703  }
704  // verify if privilege granted
705  if ($withcontrol) $err = $this->control($tname);
706  if ($err != "") return $err;
707 
708  if ($wm1 && ($tr["m1"] != "")) {
709  // apply first method (condition for the change)
710  if (!method_exists($this, $tr["m1"])) return (sprintf(_("the method '%s' is not known for the object class %s") , $tr["m1"], get_class($this)));
711 
712  $err = call_user_func(array(
713  $this,
714  $tr["m1"]
715  ) , $newstate, $this->doc->state, $addcomment);
716 
717  if ($err == "->") {
718  if ($force) {
719  $err = ""; // it is the return of the report
720  SetHttpVar("redirect_app", ""); // override the redirect
721  SetHttpVar("redirect_act", "");
722  } else {
723  if ($addcomment != "") $this->doc->AddComment($addcomment); // add comment now because it will be lost
724  return ""; //it is not a real error, but don't change state (reported)
725 
726  }
727  }
728  if ($err != "") {
729  $this->doc->unlock(true);
730  return (sprintf(_("The change state to %s has been aborted.\n%s") , _($newstate) , $err));
731  }
732  }
733  // change the state
734  $oldstate = $this->doc->state == "" ? " " : $this->doc->state;
735  $this->doc->state = $newstate;
736  $this->changeProfil($newstate);
737  $this->changeCv($newstate);
738  $this->doc->disableEditControl();
739  $err = $this->doc->Modify(); // don't control edit permission
740  if ($err != "") return $err;
741 
742  $revcomment = sprintf(_("change state : %s to %s") , _($oldstate) , _($newstate));
743  if ($addcomment != "") $this->doc->AddComment($addcomment);
744  if (isset($tr["ask"])) {
745  foreach ($tr["ask"] as $vpid) {
746  $pv = $this->getValue($vpid);
747  if ($pv != "") {
748  $oa = $this->getAttribute($vpid);
749  $revcomment.= "\n-" . $oa->getLabel() . ":" . $pv;
750  }
751  }
752  }
753 
754  $err = $this->doc->AddRevision($revcomment);
755  if ($err != "") {
756  $this->doc->disableEditControl(); // restore old states
757  $this->doc->state = $oldstate;
758  $this->changeProfil($oldstate);
759  $this->changeCv($oldstate);
760  $err2 = $this->doc->Modify(); // don't control edit permission
761  $this->doc->enableEditControl();
762 
763  return $err . $err2;
764  }
765  AddLogMsg(sprintf(_("%s new state %s") , $this->doc->title, _($newstate)));
766 
767  $this->doc->enableEditControl();
768  // post action
769  if ($wm2 && ($tr["m2"] != "")) {
770  if (!method_exists($this, $tr["m2"])) return (sprintf(_("the method '%s' is not known for the object class %s") , $tr["m2"], get_class($this)));
771  $err = call_user_func(array(
772  $this,
773  $tr["m2"]
774  ) , $newstate, $oldstate, $addcomment);
775 
776  if ($err == "->") $err = ""; //it is not a real error
777  if ($err != "") $err = sprintf(_("The change state to %s has been realized. But the following warning is appeared.\n%s") , _($newstate) , $err);
778  }
779  $this->doc->addLog("state", array(
780  "id" => $this->id,
781  "initid" => $this->initid,
782  "revision" => $this->revision,
783  "title" => $this->title,
784  "state" => $this->state,
785  "message" => $err
786  ));
787  $this->doc->disableEditControl();
788  if (!$this->doc->domainid) $this->doc->unlock(false, true);
789  $this->workflowSendMailTemplate($newstate, $addcomment, $tname);
790  $this->workflowAttachTimer($newstate, $tname);
791  $err.= $this->changeAllocateUser($newstate);
792  $this->doc->enableEditControl();
793  return $err;
794  }
795  // --------------------------------------------------------------------
796  function getFollowingStates($noVerifyDomain=false)
797  {
798  // search if following states in concordance with transition array
799  if ($this->doc->locked == - 1) return array(); // no next state for revised document
800  if (($this->doc->locked > 0) && ($this->doc->locked != $this->doc->userid)) return array(); // no next state if locked by another person
801 
802  if ((!$noVerifyDomain) && ($this->doc->lockdomainid > 0)) return array(); // no next state if locked in a domain
803  $fstate = array();
804  if ($this->doc->state == "") $this->doc->state = $this->getFirstState();
805 
806  if ($this->userid == 1) return $this->getStates(); // only admin can go to any states from anystates
807  reset($this->cycle);
808  while (list($k, $tr) = each($this->cycle)) {
809  if ($this->doc->state == $tr["e1"]) {
810  // from state OK
811  if ($this->control($tr["t"]) == "") $fstate[] = $tr["e2"];
812  }
813  }
814  return $fstate;
815  }
816 
817  function getStates()
818  {
819  if (!isset($this->states)) {
820  $this->states = array();
821  reset($this->cycle);
822  while (list($k, $tr) = each($this->cycle)) {
823  if ($tr["e1"] != "") $this->states[$tr["e1"]] = $tr["e1"];
824  if ($tr["e2"] != "") $this->states[$tr["e2"]] = $tr["e2"];
825  }
826  }
827  return $this->states;
828  }
829  /**
830  * get associated color of a state
831  * @param string $state the state
832  * @return string the color (#RGB)
833  */
834  function getColor($state, $def = "")
835  {
836  //$acolor=$this->attrPrefix."_COLOR".($state);
837  $acolor = $this->_Aid("_COLOR", $state);
838  return $this->getValue($acolor, $def);
839  }
840  /**
841  * get activity (localized language)
842  * @param string $state the state
843  * @return string the text of action
844  */
845  function getActivity($state, $def = "")
846  {
847  //$acolor=$this->attrPrefix."_ACTIVITYLABEL".($state);
848  $acolor = $this->_Aid("_ACTIVITYLABEL", $state);
849  $v = $this->getValue($acolor);
850  if ($v) return _($v);
851  return $def;
852  }
853  /**
854  * get action (localized language)
855  * @deprecated
856  * @param string $state the state
857  * @return string the text of action
858  */
859  function getAction($state, $def = "")
860  {
862  return $this->getActivity($state, $def);
863  }
864  /**
865  * get askes for a document
866  * searcj all WASK document which current user can see for a specific state
867  * @param string $state the state
868  * @param bool $control set to false to not control ask access
869  * @return string the text of action
870  */
871  function getDocumentWasks($state, $control = true)
872  {
873  $aask = $this->_Aid("_ASKID", $state);
874  $vasks = $this->getTValue($aask);
875  if ($control) {
876  $cask = array();
877  foreach ($vasks as $askid) {
878  $ask = new_doc($this->dbaccess, $askid);
879  $ask->set($this->doc);
880  if ($ask->isAlive() && ($ask->control('answer') == "")) $cask[] = $ask->id;
881  }
882  return $cask;
883  } else {
884  return $vasks;
885  }
886  }
887  /**
888  * verify if askes are defined
889  *
890  * @return bool true if at least one ask is set in workflow
891  */
892  function hasWasks()
893  {
894  $states = $this->getStates();
895  foreach ($states as $state) {
896  $aask = $this->_Aid("_ASKID", $state);
897  if ($this->getValue($aask)) return true;
898  }
899  return false;
900  }
901  /**
902  * send associated mail of a state
903  * @param string $state the state
904  * @param string $comment reason of change state
905  * @param array $tname transition name
906  * @return Doc
907  */
908  function workflowSendMailTemplate($state, $comment = "", $tname = "")
909  {
910  $tmtid = $this->getTValue($this->_Aid("_TRANS_MTID", $tname));
911 
912  $tr = $this->transitions[$tname];
913  if ($tmtid && (count($tmtid) > 0)) {
914  foreach ($tmtid as $mtid) {
915  $keys = array();
916  $mt = new_doc($this->dbaccess, $mtid);
917  if ($mt->isAlive()) {
918  $keys["WCOMMENT"] = nl2br($comment);
919  if (isset($tr["ask"])) {
920  foreach ($tr["ask"] as $vpid) {
921  $keys["V_" . strtoupper($vpid) ] = $this->getHtmlAttrValue($vpid);
922  $keys[strtoupper($vpid) ] = $this->getValue($vpid);
923  }
924  }
925  $err = $mt->sendDocument($this->doc, $keys);
926  }
927  }
928  }
929 
930  $tmtid = $this->getTValue($this->_Aid("_MTID", $state));
931  if ($tmtid && (count($tmtid) > 0)) {
932  foreach ($tmtid as $mtid) {
933  $keys = array();
934  $mt = new_doc($this->dbaccess, $mtid);
935  if ($mt->isAlive()) {
936  $keys["WCOMMENT"] = nl2br($comment);
937  if (isset($tr["ask"])) {
938  foreach ($tr["ask"] as $vpid) {
939  $keys["V_" . strtoupper($vpid) ] = $this->getHtmlAttrValue($vpid);
940  $keys[strtoupper($vpid) ] = $this->getValue($vpid);
941  }
942  }
943  $err = $mt->sendDocument($this->doc, $keys);
944  }
945  }
946  }
947  return $err;
948  }
949  /**
950  * attach timer to a document
951  * @param string $state the state
952  * @param array $tname transition name
953  * @return Doc
954  */
955  function workflowAttachTimer($state, $tname = "")
956  {
957  $mtid = $this->getValue($this->_Aid("_TRANS_TMID", $tname));
958 
959  $this->doc->unattachAllTimers($this);
960  $tr = $this->transitions[$tname];
961  if ($mtid) {
962  $mt = new_doc($this->dbaccess, $mtid);
963  if ($mt->isAlive()) {
964  $err = $this->doc->attachTimer($mt, $this);
965  }
966  }
967  // unattach persistent
968  $tmtid = $this->getTValue($this->_Aid("_TRANS_PU_TMID", $tname));
969  if ($tmtid && (count($tmtid) > 0)) {
970  foreach ($tmtid as $mtid) {
971  $mt = new_doc($this->dbaccess, $mtid);
972  if ($mt->isAlive()) {
973  $err.= $this->doc->unattachTimer($mt);
974  }
975  }
976  }
977 
978  $mtid = $this->getValue($this->_Aid("_TMID", $state));
979  if ($mtid) {
980  $mt = new_doc($this->dbaccess, $mtid);
981  if ($mt->isAlive()) {
982  $err.= $this->doc->attachTimer($mt, $this);
983  }
984  }
985  // attach persistent
986  $tmtid = $this->getTValue($this->_Aid("_TRANS_PA_TMID", $tname));
987  if ($tmtid && (count($tmtid) > 0)) {
988  foreach ($tmtid as $mtid) {
989  $mt = new_doc($this->dbaccess, $mtid);
990  if ($mt->isAlive()) {
991  $err.= $this->doc->attachTimer($mt);
992  }
993  }
994  }
995  return $err;
996  }
997 
998  function changeStateOfDocid($docid, $newstate, $comment = "")
999  {
1000  $cmd = new_Doc($this->dbaccess, $docid);
1001  $cmdid = $cmd->latestId(); // get the latest
1002  $cmd = new_Doc($this->dbaccess, $cmdid);
1003 
1004  if ($cmd->wid > 0) {
1005  $wdoc = new_Doc($this->dbaccess, $cmd->wid);
1006 
1007  if (!$wdoc) $err = sprintf(_("cannot change state of document #%d to %s") , $cmd->wid, $newstate);
1008  if ($err != "") return $err;
1009  $wdoc->Set($cmd);
1010  $err = $wdoc->ChangeState($newstate, sprintf(_("automaticaly by change state of %s\n%s") , $this->doc->title, $comment));
1011  if ($err != "") return $err;
1012  }
1013  }
1014  /**
1015  * get transition array for the transition between $to and $from states
1016  * @param string $to first state
1017  * @param string $from next state
1018  * @return array transition array (false if not found)
1019  */
1021  {
1022  foreach ($this->cycle as $v) {
1023  if (($v["e1"] == $from) && ($v["e2"] == $to)) {
1024  $t = $this->transitions[$v["t"]];
1025  $t["id"] = $v["t"];
1026  return $t;
1027  }
1028  }
1029  return false;
1030  }
1031 
1032  function DocControl($aclname)
1033  {
1034  return Doc::Control($aclname);
1035  }
1036  /**
1037  * Special control in case of dynamic controlled profil
1038  */
1039  function Control($aclname)
1040  {
1041  $err = Doc::Control($aclname);
1042  if ($err == "") return $err; // normal case
1043  if ($this->getValue("DPDOC_FAMID") > 0) {
1044  // special control for dynamic users
1045  if (!isset($this->pdoc)) {
1046  $pdoc = createDoc($this->dbaccess, $this->fromid, false);
1047  $pdoc->doctype = "T"; // temporary
1048  // $pdoc->setValue("DPDOC_FAMID",$this->getValue("DPDOC_FAMID"));
1049  $err = $pdoc->Add();
1050  if ($err != "") return "WDoc::Control:" . $err; // can't create profil
1051  $pdoc->setProfil($this->profid, $this->doc);
1052 
1053  $this->pdoc = & $pdoc;
1054  }
1055  $err = $this->pdoc->DocControl($aclname);
1056  }
1057  return $err;
1058  }
1059  /**
1060  * affect action label
1061  */
1062  function postModify()
1063  {
1064  foreach ($this->stateactivity as $k => $v) {
1065  $this->setValue($this->_Aid("_ACTIVITYLABEL", $k) , $v);
1066  }
1067  $this->getStates();
1068  foreach ($this->states as $k => $state) {
1069  $allo = trim($this->getValue($this->_Aid("_AFFECTREF", $state)));
1070  if (!$allo) $this->removeArrayRow($this->_Aid("_T_AFFECT", $state) , 0);
1071  }
1072 
1073  if ($this->isChanged()) $this->modify();
1074  }
1075  /**
1076  * get value of instanced document
1077  * @param string $attrid attribute identificator
1078  * @return string return the value, false if attribute not exist or document not set
1079  */
1080  function getInstanceValue($attrid, $def = false)
1081  {
1082  if ($this->doc) {
1083  return $this->doc->getValue($attrid, $def);
1084  }
1085  return $def;
1086  }
1087 }
1088 ?>
← centre documentaire © anakeen - published under CC License - Dynacase