source: trunk/workflow/inc/engine/src/common/WfRuntime.php @ 7681

Revision 7681, 34.2 KB checked in by douglasz, 11 years ago (diff)

Ticket #3236 - Correcoes para Best Practice: Short Open Tag e Best Practice: Always Quote Array Keys.

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