source: branches/1.2/workflow/inc/engine/src/common/WfRuntime.php @ 1349

Revision 1349, 34.7 KB checked in by niltonneto, 15 years ago (diff)

Ticket #561 - Inclusão do módulo Workflow faltante nessa versão.

  • Property svn:executable set to *
Line 
1<?php
2require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'Base.php');
3
4/**
5 * Can be viewed by the user like an Instance, it is in fact more than an instance
6 * as it handle concurrency and part of the core execution of the instance while avoiding
7 * bad manipulation of the instance
8 *
9 * @package Galaxia
10 * @license http://www.gnu.org/copyleft/gpl.html GPL
11 */
12class WfRuntime extends Base
13
14  /**
15   * @var array processes config values cached for this object life duration, init is done at first use for the only process associated with this runtime object
16   * @access public
17   */
18  var $conf= Array(); 
19  /**
20   * @var object $activity
21   * @access public
22   */
23  var $activity = null;
24  /**
25   * @var object $instance
26   * @access public
27   */
28  var $instance = null;
29  /**
30   * @var int $instance_id
31   * @access public
32   */
33  var $instance_id = 0; 
34  /**
35   * @var int $activity_id
36   * @access public
37   */
38  var $activity_id = 0;
39  /**
40   * @var object $process Retrieve process information
41   * @access public
42   */
43  var $process = null;
44  /**
45   * @var object $workitems  Reference to $instance->workitems
46   * @access public
47   */
48  var $workitems = null;
49  /**
50   * @var object $activities Reference to $instance->activities
51   * @access public
52   */ 
53  var $activities = null;
54  /**
55   * @var object $security Security object
56   * @access public
57   */ 
58  var $security = null;
59  /**
60   * @var bool $transaction_in_progress Transaction state
61   * @access public
62   */ 
63  var $transaction_in_progress = false;
64  /**
65   * @var bool $debug Debug state
66   * @access public
67   */   
68  var $debug=false;
69  /**
70   * @var bool $auto_mode Automatic mode state, non-interactive for instance, big impact on error handling
71   * @access public
72   */ 
73  var $auto_mode=false;
74
75  /**
76   * @var string $activityCompleteMessage Holds a message which is displayed in the activity completion page
77   * @access public
78   */
79  var $activityCompleteMessage = '';
80
81  /**
82   * Constructor
83   *
84   * @param object &$db ADOdb
85   * @return object WfRuntime instance
86   * @access public
87   */
88  function WfRuntime(&$db)
89  {
90    $this->child_name = 'WfRuntime';
91    parent::Base($db);
92    require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'BaseActivity.php');
93    require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'Process.php');
94    require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP.'Instance.php');
95    require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'common'.SEP.'WfSecurity.php');
96   
97    //first the activity is not set
98    $this->activity = null;
99    $this->instance = new Instance($this->db);
100    $this->process = new Process($this->db);
101    $this->security = new WfSecurity($this->db);
102  }
103
104  /**
105   * Collect errors from all linked objects which could have been used by this object
106   * Each child class should instantiate this function with her linked objetcs, calling get_error(true)
107   *
108   * @param bool $debug false by default, if true debug messages can be added to 'normal' messages
109   * @param string $prefix appended to the debug message
110   * @return void
111   * @access private
112   */
113  function collect_errors($debug=false, $prefix = '')
114  {
115    parent::collect_errors($debug, $prefix);
116    if (isset($this->instance) && !!($this->instance)) $this->error[] = $this->instance->get_error(false, $debug, $prefix);
117    if (isset($this->process) && !!($this->process)) $this->error[] = $this->process->get_error(false, $debug, $prefix);
118    if (isset($this->security) && !!($this->security)) $this->error[] = $this->security->get_error(false, $debug, $prefix);
119    if (isset($this->activity) && !!($this->activity)) $this->error[] = $this->activity->get_error(false, $debug, $prefix);
120  }
121
122  /**
123   * Ends-up dying and giving a last message
124   *
125   * @param string $last_message last sentence
126   * @param bool $include_errors false by default, if true we'll include error messages
127   * @param bool $debug false by default, if true you will obtain more messages, if false you could obtain those
128   * @param bool $dying true by default, tells the engine to die or not
129   * messages as well if this object has been placed in debug mode with setDebug(true)
130   * recorded by this runtme object.
131   * @access public
132   * @return void
133   */
134  function fail($last_message, $include_errors = false, $debug=false, $dying=true)
135  {
136    $the_end = '';
137    //see if local objects have been set to enforce it
138    if ($this->debug) $debug = true;
139    if ($this->auto_mode) $dying = false;
140   
141    if ($include_errors)
142    {
143      $the_end = $this->get_error(false, $debug).'<br />';
144    }
145    $the_end .= $last_message;
146    if ($this->transaction_in_progress)
147    {
148      //we had a transaction actually, we mark a fail, this will force Rollback
149      $this->db->FailTrans();
150      $this->db->CompleteTrans();
151    }
152    if ($dying)
153    {
154      //this will make the session die
155      galaxia_show_error($the_end, $dying);
156    }
157    else
158    {
159      //this will NOT BREAK the session!
160      return $the_end;
161    }
162  }
163
164  /**
165   * Loads the config values for the process associated with the runtime
166   * config values are cached while this WfRuntime object stays alive
167   *
168   * @param array $arrayconf Config array with default value, where key is config option name and value is default value
169   * @access private
170   * @return array Values associated with the current process for the asked config options and as well for som WfRuntime internal config options
171   */
172  function &getConfigValues(&$arrayconf)
173  {
174    if (!(isset($this->process)))
175    {
176      $this->loadProcess();
177    }
178    $arrayconf['auto-release_on_leaving_activity'] = 1; 
179    $this->conf =  $this->process->getConfigValues($arrayconf);
180    return $this->conf;
181  }
182
183  /**
184   * Loads instance, the activity and the process, needed by the runtime engine to 'execute' the activity
185   *
186   * @param int $activityId activity id, the activity we will run
187   * @param int $instanceId instance Id, can be empty for a start or standalone activity
188   * @return bool
189   * @access public
190   */
191  function &LoadRuntime($activityId,$instanceId=0)
192  {
193    // load activity
194    if (!($this->loadActivity($activityId, true, true)))
195    {
196      return false;
197    }
198    //interactive or non_interactive?
199    $this->setAuto(!($this->activity->isInteractive()));
200    //load instance
201    if (!($this->loadInstance($instanceId)))
202    {
203      return false;
204    }
205    // load process
206    if (!($this->loadProcess()))
207    {
208      return false;
209    }
210   
211    //ensure the activity is not completed
212    $this->instance->setActivityCompleted(false);
213        $this->instance->activityID = $activityId;
214   
215    //set the workitems and activities links
216    $this->workitems =& $this->instance->workitems;
217    $this->activities =& $this->instance->activities;
218    return true;
219  }
220 
221  /**
222   * Retrieves the process object associated with the activity
223   *
224   * @param int $pId Process id of the process you want, if you do not give it we will try to take it from the activity
225   * @return mixed Process object of the right type or false
226   * @access private
227   */
228  function loadProcess($pId=0)
229  {
230    if ( (!(isset($this->process))) || ($this->process->getProcessId()==0))
231    {
232      if ( (empty($pId)) || (!($pId)) )
233      {
234        $pId = $this->activity->getProcessId();
235        if ( (empty($pId)) || (!($pId)) )
236        {
237          //fail can return in auto mode or die
238          $errors = $this->fail(tra('No Process indicated'),true, $this->debug, !($this->auto_mode));
239          $this->error[] = $errors;
240          return false;
241        }
242      }
243      if ($this->debug) $this->error[] = 'loading process '.$pId;
244      $this->process->getProcess($pId);
245    }
246    return true;
247  }
248 
249  /**
250   * Gets current process instance
251   *
252   * @return object Process instance
253   * @access public
254   */
255  function &getProcess()
256  {
257    return $this->process;
258  }
259
260  /**
261   * Retrieves the activity of the right type from a baseActivity Object
262   *
263   * @param int $activity_id activity_id you want
264   * @param bool $with_roles will load the roles links on the object
265   * @param bool $with_agents will load the agents links on the object
266   * @return mixed Activity object of the right type or false
267   * @access private
268   */
269  function loadActivity($activity_id, $with_roles= true,$with_agents=false)
270  {
271    if ( (empty($activity_id)) || (!($activity_id)) )
272    {
273      //fail can return in auto mode or die
274      $errors = $this->fail(tra('No activity indicated'),true, $this->debug, !($this->auto_mode));
275      $this->error[] = $errors;
276      return false;
277    }
278    $base_activity = new BaseActivity($this->db);
279    $this->activity =& $base_activity->getActivity($activity_id, $with_roles, $with_agents);
280    if (!$this->activity)
281    {
282      $errors = $this->fail(tra('failed to load the activity'),true, $this->debug, !($this->auto_mode));
283      $this->error[] = $errors;
284      return false;
285    }
286    $this->activity_id = $activity_id;
287    $this->error[] =  $base_activity->get_error();
288    if ($this->debug) $this->error[] = 'loading activity '.$activity_id;
289    return true;
290  }
291 
292  /**
293   * Gets current activity instance
294   *
295   * @return object Activity instance
296   * @access public
297   */ 
298  function &getActivity()
299  {
300    return $this->activity;
301  }
302 
303  /**
304   * Gets the instance which could be an empty object
305   *
306   * @param int $instanceId is the instance id
307   * @return mixed Instance object which can be empty or string if something was turning bad
308   * @access public
309   */
310  function loadInstance($instanceId)
311  {
312    $this->instance_id = $instanceId;
313    $this->instance->getInstance($instanceId);
314    if ( ($this->instance->getInstanceId()==0)
315      && (! (($this->activity->getType()=='standalone') || ($this->activity->getType()=='start') )) )
316    {
317      //fail can return in auto mode or die
318      $errors = $this->fail(tra('no instance avaible'), true, $this->debug, !($this->auto_mode));
319      $this->error[] = $errors;
320      return false;
321    }
322    if ($this->debug) $this->error[] = 'loading instance '.$instanceId;
323    return true;
324  }
325 
326  /**
327   * Perform necessary security checks at runtime before running an activity
328   * This will as well lock the tables via the security object
329   * It should be launched in a transaction
330   *
331   * @return bool true if ok, false if the user has no runtime access
332   * @access public
333   */
334  function checkUserRun()
335  {
336    if ($this->activity->getType()=='view')
337    {
338      //on view activities  the run action is a special action
339      $action = 'viewrun';
340    }
341    else
342    {
343      $action = 'run';
344    }
345    //this will test the action rights and lock the necessary rows in tables in case of 'run'
346    $result = $this->security->checkUserAction($this->activity_id,$this->instance_id,$action);
347    $this->error[] =  $this->security->get_error(false, $this->debug);
348    if ($result)
349    {
350      return true;
351    }
352    else
353    {
354      return false;
355    }
356  }
357
358  /**
359   * Perform necessary security checks at runtime
360   * This will as well lock the tables via the security object
361   * It should be launched in a transaction
362   *
363   * @return bool true if ok, false if the user has no runtime access instance and activity are unsetted in case of false check
364   * @access public
365   */
366  function checkUserRelease()
367  {
368    //the first thing to scan if wether or not this process is configured for auto-release
369    if ( (isset($this->conf['auto-release_on_leaving_activity'])) && ($this->conf['auto-release_on_leaving_activity']))
370    {
371      //this will test the release rights and lock the necessary rows in tables in case of 'release'
372      $result = $this->security->checkUserAction($this->activity_id,$this->instance_id,'release');
373      $this->error[] =  $this->security->get_error(false, $this->debug);
374      if ($result)
375      {
376        //we are granted an access to release but there is a special bad case where
377        //we are a user authorized at releasing instances owned by others and where
378        //this instance is owned by another (for some quite complex reasons).
379        //we should not release this new user!!
380        //Then this is auto-release, not a conscious act and so we will release only
381        //if we can still grab this instance (avoiding the bad case)
382       
383        //test grab before release
384        if ($this->checkUserRun())
385        {
386          return true;
387        }
388      }
389    }
390    return false;
391  }
392 
393  /**
394   * Sets/unsets the WfRuntime in debug mode
395   *
396   * @param bool $debug_mode true by default, set it to false to disable debug mode
397   * @access public
398   * @return void
399   */
400  function setDebug($debug_mode=true)
401  {
402    $this->debug = $debug_mode;
403  }
404 
405  /**
406   * Sets/unsets the WfRuntime in automatic mode. i.e : executing
407   * non-interactive or interactive activities. Automatic mode have big impacts
408   * on error handling and on the way activities are executed
409   *
410   * @param bool $auto_mode true by default, set it to false to disable automatic mode
411   * @access public
412   * @return void
413   */
414  function setAuto($auto_mode=true)
415  {
416    $this->auto_mode = $auto_mode;
417  }
418 
419  /**
420   * This function will start a transaction, call it before setActivityUser()
421   *
422   * @access public
423   * @return void
424   */
425  function StartRun()
426  {
427    $this->transaction_in_progress =true;
428    $this->db->StartTrans();
429  }
430 
431  /**
432   * This function ends the transactions started in StartRun()
433   *
434   * @access public
435   * @return void
436   */
437  function EndStartRun()
438  {
439    if ($this->transaction_in_progress)
440    {
441      $this->db->CompleteTrans();
442      $this->transaction_in_progress =false;
443    }
444  }
445 
446  /**
447   * For interactive activities this function will set the current user on the instance-activities table.
448   * This will prevent having several user using the same activity on the same intsance at the same time
449   * But if you want this function to behave well you should call it after a checkUserRun or a checkUserRelease
450   * and inside a transaction. Theses others function will ensure the table will be locked and the user
451   * is really granted the action
452   *
453   * @param bool $grab true by default, if false the user will be set to '*', releasing the instance-activity record
454   * @access public
455   * @return bool
456   */
457  function setActivityUser($grab=true)
458  {
459    if(isset($GLOBALS['user']) && !empty($this->instance->instanceId) && !empty($this->activity_id))
460    {
461      if ($this->activity->isInteractive())
462      {// activity is interactive and we want the form, we'll try to grab the ticket on this instance-activity (or release)
463        if ($grab)
464        {
465          $new_user = $GLOBALS['user'];
466        }
467        else
468        {
469          $new_user= '*';
470        }
471        if (!$this->instance->setActivityUser($this->activity_id,$new_user))
472        {
473           //fail can return in auto mode or die
474           $errors = $this->fail(lang("You do not have the right to run this activity anymore, maybe a concurrent access problem, refresh your datas.", true, $this->debug, !($this->auto_mode)));
475           $this->error[] = $errors;
476           return false;
477        }
478      }// if activity is not interactive there's no need to grab the token
479    }
480    else
481    {
482      //fail can return in auto mode or die
483      $errors= $this->fail(lang("We cannot run this activity, maybe this instance or this activity do not exists anymore.", true, $this->debug, !($this->auto_mode)));
484      $this->error[] = $errors;
485      return false;
486    }   
487  }
488 
489  /**
490   * Tries to give some usefull info about the current runtime
491   *
492   * @return array associative arrays with keys/values which could be usefull
493   * @access public
494   */
495  function &getRuntimeInfo()
496  {
497    $result = Array();
498//    _debug_array($this->instance);
499    if (isset($this->instance))
500    {
501      $result['instance_name'] = $this->instance->getName();
502      $result['instance_owner'] = $this->instance->getOwner();
503    }
504    if (isset($this->activity))
505    {
506      $result['activity_name'] = $this->activity->getName();
507      $result['activity_id'] = $this->activity_id;
508      $result['activity_type'] = $this->activity->getType();
509    }
510    return $result;
511  }
512
513  /**
514   * This part of the runtime will be runned just after the activity code inclusion.
515   * We are in fact after all the "user code" part. We should decide what to do next
516   *
517   * @param bool $debug false by default
518   * @return array an array which must be analysed by the application run class. It contains 2 keys
519   ** 'action' : value is a string is the action the run class should do
520   *    * 'return' should return the result we just returned (in auto mode, to propagate infos)
521   *    * 'loop' should just loop on the form, i.e.: do nothing
522   *    * 'leaving' should show a page for the user leaving the activity (Cancel or Close without completing)
523   *    * 'completed' should show a page for the user having completed the activity
524   ** 'engine_info' : value is an array is an array containing a lot of infos about what was done by the engine
525   *    especially when completing the instance or when executing an automatic activity
526   * @access public
527   */
528  function handle_postUserCode($debug=false)
529  {
530    $result = Array();
531   
532     // re-retrieve instance id which could have been modified by a complete
533     $this->instance_id = $this->instance->getInstanceId();
534     
535     //synchronised instance object with the database
536     $this->instance->sync();
537
538    // for interactive activities in non-auto mode:
539    if (!($this->auto_mode) && $this->activity->isInteractive())
540    {
541      if ($this->instance->getActivityCompleted())
542      {
543        // activity is interactive and completed,
544        // we have to continue the workflow
545        // and send any autorouted activity which could be after this one
546        // this is not done in the $instance->complete() to let
547        // xxx_pos.php code be executed before sending the instance
548
549        $result['engine_info'] =& $this->instance->sendAutorouted($this->activity_id);
550
551        // application should display completed page
552        $result['action']='completed';
553        return $result;
554      }
555      // it hasn't been completed
556      else
557      {
558        if ($GLOBALS['workflow']['__leave_activity'])
559        {
560          // activity is interactive and the activity source set the
561          // $GLOBALS[workflow][__leave_activity] it's a 'cancel' mode.
562          // we redirect the user to the leave activity page
563          $result['action']='leaving';
564          return $result;
565        }
566        else
567        {
568          //the activity is not completed and the user doesn't want to leave
569          // we loop on the form
570          $result['action']='loop';
571          return $result;
572        }
573      }
574    }
575    else
576    {
577      // in auto mode or with non interactive activities we return engine info
578      // and we collect our errors, we do not let them for other objects
579      $this->collect_errors($debug);
580      $result['engine_info']['debug'] = implode('<br />',array_filter($this->error));
581      $result['engine_info']['info'] =& $this->getRuntimeInfo();
582      $result['action'] = 'return';
583      return $result;
584    }
585  }
586
587  /**
588   * Gets the the 'Activity Completed' status
589   *
590   * @access public
591   * @return string
592   */
593  function getActivityCompleted()
594  {
595    return $this->instance->getActivityCompleted();
596  }
597
598 
599  //----------- Instance public function mapping -------------------------------------------
600 
601  /**
602   * Sets the next activity to be executed, if the current activity is
603   * a switch activity the complete() method will use the activity setted
604   * in this method as the next activity for the instance.
605   * Note that this method receives an activity name as argument (Not an Id)
606   * and that it does not need the activityId like the instance method
607   *
608   * @param string $actname name of the next activity
609   * @return bool
610   * @access public
611   */
612  function setNextActivity($actname)
613  {
614    return $this->instance->setNextActivity($this->activity_id,$actname);
615  }
616
617  /**
618   * Sets the user that must perform the next
619   * activity of the process. this effectively "assigns" the instance to
620   * some user
621   *
622   * @param int $user the next user id
623   * @param string $activityName The name of the activity that the user will be able to executed. '*' means the next activity.
624   * @return bool
625   * @access public
626   */
627  function setNextUser($user, $activityName = '*')
628  {
629    if ($activityName != '*')
630                $activityID = $this->getOne('SELECT wf_activity_id FROM ' . GALAXIA_TABLE_PREFIX . 'activities WHERE (wf_name = ?) AND (wf_p_id = ?)', array($activityName, $this->activity->getProcessId()));
631    else
632                $activityID = '*';
633    return $this->instance->setNextUser($user, $activityID);
634  }
635
636  /**
637   * Sets the user role that must perform the next
638   * activity of the process. this effectively "assigns" the instance to
639   * some user
640   *
641   * @param string $roleName the next activity role
642   * @param string $activityName The name of the activity that the role will be able to executed. '*' means the next activity.
643   * @return bool true in case of success or false otherwise
644   * @access public
645   */
646  function setNextRole($roleName, $activityName = '*')
647  {
648    $roleID = $this->getOne('SELECT wf_role_id FROM ' . GALAXIA_TABLE_PREFIX . 'roles WHERE (wf_name = ?) AND (wf_p_id = ?)', array($roleName, $this->activity->getProcessId()));
649    if (is_null($roleID))
650      return false;
651
652    if ($activityName != '*')
653                $activityID = $this->getOne('SELECT wf_activity_id FROM ' . GALAXIA_TABLE_PREFIX . 'activities WHERE (wf_name = ?) AND (wf_p_id = ?)', array($activityName, $this->activity->getProcessId()));
654    else
655                $activityID = '*';
656
657    return $this->instance->setNextRole($roleID, $activityID);
658  }
659
660  /**
661   * Gets the user that must perform the next activity of the process.
662   * This can be empty if no setNextUser() was done before.
663   * It wont return the default user but only the user which was assigned by a setNextUser
664   *
665   * @return int
666   * @access public
667   */
668  function getNextUser()
669  {
670    return $this->instance->getNextUser();
671  }
672 
673  /**
674   * Sets the name of this instance.
675   *
676   * @param string $value new name of the instance
677   * @return bool
678   * @access public
679   */
680  function setName($value)
681  {
682    return $this->instance->setName($value);
683  }
684
685  /**
686   * Gets the name of this instance
687   *
688   * @return string
689   * @access public
690   */
691  function getName() {
692    return $this->instance->getName();
693  }
694
695  /**
696   * Sets the category of this instance
697   *
698   * @param string $value
699   * @return bool
700   * @access public
701   */
702  function setCategory($value)
703  {
704    return $this->instance->setcategory($value);
705  }
706
707  /**
708   * Gets category of this instance
709   *
710   * @return string
711   * @access public
712   */
713  function getCategory()
714  {
715    return $this->instance->getCategory();
716  }
717 
718  /**
719   * Sets a property in this instance. This method is used in activities to
720   * set instance properties.
721   * all property names are normalized for security reasons and to avoid localisation
722   * problems (A->z, digits and _ for spaces). If you have several set to call look
723   * at the setProperties function. Each call to this function has an impact on database
724   *
725   * @param string $name property name (it will be normalized)
726   * @param mixed $value value for this property
727   * @return bool
728   * @access public
729   */
730  function set($name,$value)
731  {
732    return $this->instance->set($name,$value);
733  }
734 
735  /**
736   * Unsets a property in this instance. This method is used in activities to
737   * unset instance properties.
738   * All property names are normalized for security reasons and to avoid localisation
739   * problems (A->z, digits and _ for spaces). Each call to this function has an impact on database
740   *
741   * @param string $name property name (it will be normalized)
742   * @return bool true if it was ok
743   * @access public
744   */
745  function clear($name)
746  {
747    return $this->instance->clear($name);
748  }
749
750  /**
751   * Checks if a property in this instance exists. This method is used in activities to
752   * check the existance of instance properties.
753   * All property names are normalized for security reasons and to avoid localisation
754   * problems (A->z, digits and _ for spaces)
755   *
756   * @param string $name property name (it will be normalized)
757   * @return bool true if it exists and false otherwise
758   * @access public
759   */
760  function exists($name)
761  {
762        return $this->instance->exists($name);
763  }
764
765  /**
766   * Sets several properties in this instance. This method is used in activities to
767   * set instance properties. Use this method if you have several properties to set
768   * as it will avoid
769   * all property names are normalized for security reasons and to avoid localisation
770   * problems (A->z, digits and _ for spaces). If you have several set to call look
771   * at the setProperties function. Each call to this function has an impact on database
772   *
773   * @param array $properties_array associative array containing for each record the
774   * property name as the key and the property value as the value. You do not need the complete
775   * porperty array, you can give only the knew or updated properties.
776   * @return bool true if it was ok
777   * @access public
778   */
779  function setProperties($properties_array)
780  {
781     return $this->instance->setProperties($properties_array);
782  }
783
784  /**
785   * Gets the value of an instance property
786   *
787   * @param string $name name of the instance
788   * @param string $defaultValue
789   * @return bool false if the property was not found, but an error message is stored in the instance object
790   * @access public
791   */
792  function get($name, $defaultValue = "__UNDEF__")
793  {
794    return $this->instance->get($name, $defaultValue);
795  }
796
797  /**
798   * Describes the activities where the instance is present, can be more than one activity if the instance was "splitted"
799   *
800   * @access public
801   * @return array Vector of assocs
802   */
803  function getActivities()
804  {
805    return $this->instance->getActivities();
806  }
807 
808  /**
809   * Gets the instance status can be 'completed', 'active', 'aborted' or 'exception'
810   *
811   * @access public
812   * @return string Instance status
813   */
814  function getStatus()
815  {
816    return $this->instance->getStatus();
817  }
818 
819  /**
820   * Sets the instance status
821   *
822   * @param $status Desired status, it can be: 'completed', 'active', 'aborted' or 'exception'
823   * @return bool
824   * @access public
825   */
826  function setStatus($status)
827  {
828    return $this->instance->setStatus($status);
829  }
830 
831  /**
832   * Gets the instance priority
833   *
834   * @access public
835   * @return int
836   */
837  function getPriority()
838  {
839    return $this->instance->getPriority();
840  }
841
842  /**
843   * Sets the instance priority
844   *
845   * @param int $priority
846   * @access public
847   * @return bool
848   */
849  function setPriority($priority)
850  {
851    return $this->instance->setPriority($priority);
852  }
853   
854  /**
855   * Returns the instance id
856   *
857   * @return int
858   * @access public
859   */
860  function getInstanceId()
861  {
862    return $this->instance->getInstanceId();
863  }
864 
865  /**
866   * Returns the process id for this instance
867   *
868   * @return int
869   * @access public
870   */
871  function getProcessId() {
872    return $this->instance->getProcessId();
873  }
874 
875  /**
876   * Returns the owner of the instance
877   *
878   * @return string
879   * @access public
880   */
881  function getOwner()
882  {
883    return $this->instance->getOwner();
884  }
885 
886  /**
887   * Sets the instance owner
888   *
889   * @param string $user
890   * @access public
891   * @return bool 
892   */
893  function setOwner($user)
894  {
895    return $this->instance->setOwner($user);
896  }
897 
898  /**
899   * Returns the user that must execute or is already executing an activity where the instance is present
900   *
901   * @param int $activityId
902   * @return bool False if the activity was not found for the instance, else return the user id or '*' if no user is defined yet
903   * @access public
904   */ 
905  function getActivityUser($activityId)
906  {
907    return $this->instance->getActivityUser($activityId);
908  }
909 
910  /**
911   * Sets the status of the instance in some activity
912   *
913   * @param int $activityId Activity id
914   * @param string $status New status, it can be 'running' or 'completed'
915   * @return bool False if no activity was found for the instance
916   * @access public
917   */ 
918  function setActivityStatus($activityId,$status)
919  {
920    return $this->instance->setActivityStatus($activityId,$status);
921  }
922 
923 
924  /**
925   * Gets the status of the instance in some activity
926   *
927   * @param int $activityId
928   * @return string 'running' or 'completed'
929   * @access public
930   */
931  function getActivityStatus($activityId)
932  {
933    return $this->instance->getActivityStatus($activityId);
934  }
935 
936  /**
937   * Resets the start time of the activity indicated to the current time
938   *
939   * @param int $activityId
940   * @return bool
941   * @access public
942   */
943  function setActivityStarted($activityId)
944  {
945    return $this->instance->setActivityStarted($activityId);
946  }
947 
948  /**
949   * Gets the Unix timstamp of the starting time for the given activity
950   *
951   * @param int $activityId
952   * @return int
953   * @access public
954   */
955  function getActivityStarted($activityId)
956  {
957    return $this->instance->getActivityStarted($activityId);
958  }
959 
960  /**
961   * Gets the time where the instance was started
962   *
963   * @return int
964   * @access public
965   */
966  function getStarted()
967  {
968    return $this->instance->getStarted();
969  }
970 
971  /**
972   * Gets the end time of the instance (when the process was completed)
973   *
974   * @return int
975   * @access public
976   */
977  function getEnded()
978  {
979    return $this->instance->getEnded();
980  }
981 
982 
983  /**
984   * Completes an activity.
985   * YOU MUST NOT CALL complete() for non-interactive activities since
986   * the engine does automatically complete automatic activities after
987   * executing them
988   *
989   * @return bool True or false, if false it means the complete was not done for some internal reason
990   * consult get_error() for more informations
991   * @access public
992   */
993  function complete()
994  {
995    if (!($this->activity->isInteractive()))
996    {
997      $this->error[] = tra('interactive activities should not call the complete() method');
998      return false;
999    }
1000   
1001    return $this->instance->complete($this->activity_id);
1002  }
1003
1004  /**
1005   * Aborts an activity and terminates the whole instance. We still create a workitem to keep track
1006   * of where in the process the instance was aborted
1007   *
1008   * @return bool
1009   * @access public
1010   */
1011  function abort()
1012  {
1013    return $this->instance->abort();
1014  }
1015 
1016  /**
1017   * Gets a comment for this instance
1018   *
1019   * @param int $cId Comment id
1020   * @return string
1021   * @access public
1022   */
1023  function get_instance_comment($cId)
1024  {
1025    return $this->instance->get_instance_comment($cId);
1026  }
1027 
1028  /**
1029   * Inserts or updates an instance comment
1030   *
1031   * @param int $cId Commend id
1032   * @param int $activityId
1033   * @param object $activity
1034   * @param int $user User id
1035   * @param string $title Comment's title
1036   * @param string $comment Comment's contents
1037   * @return bool
1038   * @access public
1039   */
1040  function replace_instance_comment($cId, $activityId, $activity, $user, $title, $comment)
1041  {
1042    return $this->instance->replace_instance_comment($cId, $activityId, $activity, $user, $title, $comment);
1043  }
1044 
1045  /**
1046   * Removes an instance comment
1047   *
1048   * @param int $cId Comment id
1049   * @return bool
1050   * @access public
1051   */
1052  function remove_instance_comment($cId)
1053  {
1054    return $this->instance->remove_instance_comment($cId);
1055  }
1056 
1057  /**
1058   * Lists instance comments
1059   *
1060   * @return array
1061   * @access public
1062   */
1063  function get_instance_comments()
1064  {
1065    return $this->instance->get_instance_comments();
1066  }
1067
1068  /**
1069   * Creates a child instance from the current one
1070   *
1071   * @param string $activityName The name of the activity of the new instance
1072   * @param mixed $properties Determines the new instance properties. If "true" the properties of the current instance will be inherited by the new instance. If "false" no properties will be set. If an "array" (format: property_name => property_value) every property defined in that array will be available to the new instance. False by default
1073   * @param mixed $user The ID of the user who will own the new instance or '*' (i.e., everyone). '*' by default
1074   * @param bool $parentLock Flag that determines if the parent instance MUST wait for it's children completion before it's own completion ("true") or not ("false"). "true" by default.
1075   * @return int The instance ID of the just created instance
1076   * @access public
1077   */
1078  function createChildInstance($activityName, $properties = false, $user = '*', $parentLock = true)
1079  {
1080    if ((!$this->activity->isInteractive()) && $parentLock)
1081      $this->error[] = "createChildInstance: atividades não interativas não podem executar este método com travamento da instância pai";
1082
1083    $activityID = $this->getOne('SELECT wf_activity_id FROM ' . GALAXIA_TABLE_PREFIX . 'activities WHERE (wf_name = ?) AND (wf_p_id = ?)', array($activityName, $this->activity->getProcessId()));
1084
1085    if ($properties === true)
1086      $properties = $this->instance->properties;
1087    if (!is_array($properties))
1088      $properties = array();
1089
1090    $iid = $_REQUEST['iid'];
1091    $workflow = $GLOBALS['workflow'];
1092    unset($_REQUEST['iid']);
1093    $run_activity = CreateObject('workflow.run_activity');
1094    $run_activity->runtime->instance->parentInstanceId = $this->instance_id;
1095    $run_activity->runtime->instance->parentActivityId = $this->activity_id;
1096    $output = $run_activity->goChildInstance($activityID, $properties, $user, $parentLock);
1097    $_REQUEST['iid'] = $iid;
1098    $GLOBALS['workflow'] = $workflow;
1099
1100    return $output;
1101  }
1102
1103  /**
1104   * Set a message which is displayed in the activity completion page.
1105   *
1106   * @param string $message The message itself.
1107   * @return void
1108   * @access public
1109   */
1110  function setActivityCompleteMessage($message)
1111  {
1112    $this->activityCompleteMessage = $message;
1113  }
1114
1115  /**
1116   * Get the message which is displayed in the activity completion page.
1117   *
1118   * @return string The message which will be shown.
1119   * @access public
1120   */
1121  function getActivityCompleteMessage()
1122  {
1123    return $this->activityCompleteMessage;
1124  }
1125
1126  /**
1127   * Get information about the parent of an instance (if it has one)
1128   *
1129   * @return mixed An array containing the information of the parent or false if the instances does not have a parent
1130   * @access public
1131   */
1132  function getParent()
1133  {
1134    $resultSet = $this->query("SELECT wf_parent_instance_id, wf_parent_activity_id, wf_parent_lock FROM egw_wf_interinstance_relations WHERE (wf_child_instance_id = ?)", array($this->getInstanceId()));
1135    if (($row = $resultSet->fetchRow()))
1136      return array('instance_id' => $row['wf_parent_instance_id'], 'activity_id' => $row['wf_parent_activity_id'], 'lock' => ($row['wf_parent_lock'] == 1));
1137    else
1138      return false;
1139  }
1140
1141  /**
1142   * Unlock the parent of the instance
1143   *
1144   * @return void
1145   * @access public
1146   */
1147  function unlockParent()
1148  {
1149    $this->query("UPDATE egw_wf_interinstance_relations SET wf_parent_lock = 0 WHERE (wf_child_instance_id = ?)", array($this->getInstanceId()));
1150  }
1151}
1152
1153
1154?>
Note: See TracBrowser for help on using the repository browser.