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

Revision 1349, 48.1 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.'ProcessManager'.SEP.'BaseManager.php');
3/**
4 * Adds, removes, modifies and lists processes.
5 * Most of the methods acts directly in database level, bypassing Project object methods
6 *
7 * @todo Fix multiple non checked fopen ==> infinite loops in case of problems with filesystem
8 * @package Galaxia
9 * @license http://www.gnu.org/copyleft/gpl.html GPL
10 */
11class ProcessManager extends BaseManager {
12 
13  /**
14   * @var resource $parser xml parser
15   * @access public
16   */
17  var $parser;
18 
19  /**
20   * @var array $tree data struture
21   * @access public
22   */
23  var $tree;
24 
25  /**
26   * @var $current current element
27   * @access public
28   */
29  var $current;
30 
31  /**
32   * @var $buffer buffer for data
33   * @access public
34   */
35  var $buffer;
36 
37  /**
38   * @var object $Process Process
39   * @access public
40   */
41  var $Process;
42 
43  /**
44   * @var object $activity_manager Activity Manager
45   * @access public
46   */
47  var $activity_manager;
48
49  /**
50   * @var object $jobManager Job Manager object
51   * @access public
52   */
53  var $jobManager;
54   
55  /**
56   * @var object $role_manager Role Manager
57   * @access public
58   */
59  var $role_manager;
60 
61  /**
62   * Constructor
63   *
64   * @param object &$db ADOdb
65   * @return object ProcessManager
66   * @access public
67   */
68  function ProcessManager(&$db)
69  {
70    parent::BaseManager($db);
71    $this->child_name = 'ProcessManager';
72    require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'ActivityManager.php');
73    require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager'.SEP.'JobManager.php');
74    // $this->activity_manager is not set here to avoid objects loading object A loading object B loading object A, etc
75    //$this->role_manager will only be loaded when needed as well
76  }
77
78  /**
79  * Collect errors from all linked objects which could have been used by this object.
80  * Each child class should instantiate this function with her linked objetcs, calling get_error(true)
81  *
82  * @param bool $debug False by default, if true debug messages can be added to 'normal' messages
83  * @param string $prefix Appended to the debug message
84  * @return void
85  * @access public
86  */
87  function collect_errors($debug=false, $prefix = '')
88  {
89    parent::collect_errors($debug, $prefix);
90    if (isset($this->activity_manager)) $this->error[] = $this->activity_manager->get_error(false, $debug, $prefix);
91    if (isset($this->role_manager)) $this->error[] = $this->role_manager->get_error(false, $debug, $prefix);
92  }
93
94  /**
95   * Activates a process
96   *
97   * @param int $pId Process id
98   * @return void
99   * @access public
100   */
101  function activate_process($pId)
102  {
103    $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_active=? where wf_p_id=?';
104    $this->query($query, array('y',$pId)); 
105    $msg = sprintf(tra('Process %d has been activated'),$pId);
106    $this->notify_all(3,$msg);
107    $this->error[] = $msg;
108  }
109 
110  /**
111   * Deactivates a process
112   *
113   * @param int $pId Process id
114   * @return void
115   * @access public
116   */
117  function deactivate_process($pId)
118  {
119    $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_active=? where wf_p_id=?';
120    $this->query($query, array('n',$pId)); 
121    $msg = sprintf(tra('Process %d has been deactivated'),$pId);
122    $this->notify_all(3,$msg);
123    $this->error[] = $msg;
124  }
125 
126  /**
127   * Creates an XML representation of a process
128   *
129   * @param int $pId Process id
130   * @return string
131   * @access public
132   */ 
133  function serialize_process($pId)
134  {
135    if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db);
136    // <process>
137    $out = '<process>'."\n";
138    //we retrieve config values with the others process data
139    $proc_info =& $this->get_process($pId, true);
140    $wf_procname = $proc_info['wf_normalized_name'];
141    $out.= '  <name>'.htmlspecialchars($proc_info['wf_name']).'</name>'."\n";
142    $out.= '  <isValid>'.htmlspecialchars($proc_info['wf_is_valid']).'</isValid>'."\n";
143    $out.= '  <version>'.htmlspecialchars($proc_info['wf_version']).'</version>'."\n";
144    $out.= '  <isActive>'.htmlspecialchars($proc_info['wf_is_active']).'</isActive>'."\n";
145    $out.='   <description>'.htmlspecialchars($proc_info['wf_description']).'</description>'."\n";
146    $out.= '  <lastModif>'.date("d/m/Y [h:i:s]",$proc_info['wf_last_modif']).'</lastModif>'."\n";
147
148    //Shared code
149    $out.= '  <sharedCode><![CDATA[';
150    $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."shared.php","r");
151    while(!feof($fp)) {
152      $line=fread($fp,8192);
153      $out.=$line;
154    }
155    fclose($fp);
156    $out.= '  ]]></sharedCode>'."\n";
157
158    //Loop on config values
159    $out.='  <configs>'."\n";
160    foreach($proc_info['config'] as $res) {     
161      $name = $res['wf_config_name'];
162      $value_int = $res['wf_config_value_int'];
163      $value = $res['wf_config_value'];
164      $out.='    <config>'."\n";
165      $out.='      <wf_config_name>'.htmlspecialchars($name).'</wf_config_name>'."\n";
166      $out.='      <wf_config_value>'.htmlspecialchars($value).'</wf_config_value>'."\n";
167      $out.='      <wf_config_value_int>'.htmlspecialchars($value_int).'</wf_config_value_int>'."\n";
168      $out.='    </config>'."\n";
169    }
170    $out.='  </configs>'."\n";
171
172    // Now loop over activities
173    $query = "select * from ".GALAXIA_TABLE_PREFIX."activities where wf_p_id=$pId";
174    $result = $this->query($query);
175    $out.='  <activities>'."\n";
176    while($res = $result->fetchRow()) {     
177      $name = $res['wf_normalized_name'];
178      $out.='    <activity>'."\n";
179      $out.='      <name>'.htmlspecialchars($res['wf_name']).'</name>'."\n";
180      $out.='      <type>'.htmlspecialchars($res['wf_type']).'</type>'."\n";
181      $out.='      <description>'.htmlspecialchars($res['wf_description']).'</description>'."\n";
182      $out.='      <lastModif>'.date("d/m/Y [h:i:s]",$res['wf_last_modif']).'</lastModif>'."\n";
183      $out.='      <isInteractive>'.$res['wf_is_interactive'].'</isInteractive>'."\n";
184      $out.='      <isAutoRouted>'.$res['wf_is_autorouted'].'</isAutoRouted>'."\n";
185      $out.='      <roles>'."\n";
186      //loop on activity roles
187      $actid = $res['wf_activity_id'];
188      $roles =& $this->activity_manager->get_activity_roles($actid);
189      foreach($roles as $role) {
190        if ($role['wf_readonly'])
191        {
192          $out.='        <role readonly="true">'.htmlspecialchars($role['wf_name']).'</role>'."\n";
193        }
194        else
195        {
196          $out.='        <role>'.htmlspecialchars($role['wf_name']).'</role>'."\n";
197        }
198      } 
199      $out.='      </roles>'."\n";
200      $out.='      <agents>'."\n";
201      //loop on activity agents
202      $agents =& $this->activity_manager->get_activity_agents($actid);
203      foreach($agents as $agent) {
204        $out.='        <agent>'."\n";
205        $out.='           <agent_type>'.htmlspecialchars($agent['wf_agent_type']).'</agent_type>'."\n";
206        //loop on agent datas
207        $agent_data =& $this->activity_manager->get_activity_agent_data($actid,$agent['wf_agent_type']);
208        $out.='           <agent_datas>'."\n";
209        foreach($agent_data as $key => $value)
210        {
211          if (!($key=='wf_agent_id'))
212          {
213            $out.='               <agent_data>'."\n";
214            $out.='                   <name>'.htmlspecialchars($key).'</name>'."\n";
215            $out.='                   <value>'.htmlspecialchars($value).'</value>'."\n";
216            $out.='               </agent_data>'."\n";
217          }
218        }
219        $out.='           </agent_datas>'."\n";
220        $out.='        </agent>'."\n";
221      } 
222      $out.='      </agents>'."\n";
223
224      //the code
225      $out.='      <code><![CDATA[';
226      $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."activities".SEP."$name.php","r");
227      while(!feof($fp)) {
228        $line=fread($fp,8192);
229        $out.=$line;
230      }
231      fclose($fp);
232      $out.='      ]]></code>';
233      if($res['wf_is_interactive']=='y') {
234        $out.='      <template><![CDATA[';
235        $fp=fopen(GALAXIA_PROCESSES.SEP."$wf_procname".SEP."code".SEP."templates".SEP."$name.tpl","r");
236        while(!feof($fp)) {
237          $line=fread($fp,8192);
238          $out.=$line;
239        }
240        fclose($fp);
241        $out.='      ]]></template>';
242      }
243      $out.='    </activity>'."\n";   
244    }
245    $out.='  </activities>'."\n";
246    $out.='  <transitions>'."\n";
247    //loop on transitions
248    $transitions = $this->activity_manager->get_process_transitions($pId);
249    foreach($transitions as $tran) {
250      $out.='     <transition>'."\n";
251      $out.='       <from>'.htmlspecialchars($tran['wf_act_from_name']).'</from>'."\n";
252      $out.='       <to>'.htmlspecialchars($tran['wf_act_to_name']).'</to>'."\n";
253      $out.='     </transition>'."\n";
254    }     
255    $out.='  </transitions>'."\n";
256    $out.= '</process>'."\n";
257    //$fp = fopen(GALAXIA_PROCESSES."/$wf_procname/$wf_procname.xml","w");
258    //fwrite($fp,$out);
259    //fclose($fp);
260    return $out;
261  }
262 
263  /**
264   * Creates  a process PHP data structure from its XML representation
265   *
266   * @param string &$xml XML document
267   * @return array Process data structure
268   * @access public
269   */
270  function unserialize_process(&$xml)
271  {
272    // Create SAX parser assign this object as base for handlers
273    // handlers are private methods defined below.
274    // keep contexts and parse
275    $this->parser = xml_parser_create();
276    xml_parser_set_option($this->parser,XML_OPTION_CASE_FOLDING,0);
277    //xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE, 1);
278    xml_set_object($this->parser, $this);
279    xml_set_element_handler($this->parser, '_start_element_handler', '_end_element_handler');
280    xml_set_character_data_handler($this->parser, '_data_handler');
281    $aux=Array(
282      'name'=>'root',
283      'children'=>Array(),
284      'parent' => 0,
285      'data'=>'',
286      'attribs' => Array(),
287    );
288    $this->tree[0]=$aux;
289    $this->current=0;
290       
291       
292    if (!xml_parse($this->parser, $xml, true)) {
293       $error = sprintf("XML error: %s at line %d",
294                    xml_error_string(xml_get_error_code($this->parser)),
295                    xml_get_current_line_number($this->parser));
296       trigger_error($error,E_USER_WARNING);
297       $this->error[] = $error;
298    }
299    xml_parser_free($this->parser);   
300    // Now that we have the tree we can do interesting things
301   
302    $process=Array();
303    $activities=Array();
304    $transitions=Array();
305    for($i=0;$i<count($this->tree[1]['children']);$i++) {
306      // Process attributes
307      $z=$this->tree[1]['children'][$i];
308      $name = trim($this->tree[$z]['name']);
309     
310      //config values
311      if ($name=='configs') {
312        for($j=0;$j<count($this->tree[$z]['children']);$j++) {
313          $z2 = $this->tree[$z]['children'][$j];
314          // this is a config $name = $this->tree[$z2]['name'];
315          $aux = Array();
316          if($this->tree[$z2]['name']=='config') {
317            for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
318              $z3 = $this->tree[$z2]['children'][$k];
319              $name = trim($this->tree[$z3]['name']);
320              $value= trim($this->tree[$z3]['data']);
321              $aux[$name]=$value;
322            }
323            $configs[]=$aux;
324          }
325        }     
326      }
327      //activities
328      elseif($name=='activities') {
329        for($j=0;$j<count($this->tree[$z]['children']);$j++) {
330          $z2 = $this->tree[$z]['children'][$j];
331          // this is an activity $name = $this->tree[$z2]['name'];
332          $aux = Array();
333          if($this->tree[$z2]['name']=='activity') {
334            for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
335              $z3 = $this->curre[$z2]['children'][$k];
336              $name = trim($this->tree[$z3]['name']);
337              $value= trim($this->tree[$z3]['data']);
338              if($name=='roles') {
339                $roles=Array();
340                for($l=0;$l<count($this->tree[$z3]['children']);$l++) {
341                  $z4 = $this->tree[$z3]['children'][$l];
342                  $name = trim($this->tree[$z4]['name']);
343                  $data = trim($this->tree[$z4]['data']);
344                  $attribs = $this->tree[$z4]['attribs'];
345                  $readonly = false;
346                  if ( (isset($attribs['readonly'])) && ($attribs['readonly']))
347                  {
348                    //role in read-only
349                    $readonly = true;
350                  }
351                  $roles[]=array(
352                    'name'      => $data,
353                    'readonly'  => $readonly,
354                  );
355                }
356              }
357              elseif ($name=='agents')
358              {
359                $agents=Array();
360                for($l=0;$l<count($this->tree[$z3]['children']);$l++)
361                {
362                  $z4 = $this->tree[$z3]['children'][$l];
363                  //$name is agent
364                  $name = trim($this->tree[$z4]['name']);
365                  if ($name = 'agent')
366                  {
367                    $agent = array();
368                    for($m=0;$m<count($this->tree[$z4]['children']);$m++)
369                    {
370                      $z5 = $this->tree[$z4]['children'][$m];
371                      //$name is agent_type or agent_datas
372                      $name = trim($this->tree[$z5]['name']);
373                      // data will be the agent_type or an array for agent_datas
374                      $data = trim($this->tree[$z5]['data']);
375                      if ($name=='agent_type')
376                      {
377                        $agent['wf_agent_type']=$data;
378                      }
379                      elseif ($name=='agent_datas')
380                      {
381                        for($n=0;$n<count($this->tree[$z5]['children']);$n++)
382                        {
383                          $z6 = $this->tree[$z5]['children'][$n];
384                          //$name is agent_data $val is an array
385                          $name = trim($this->tree[$z6]['name']);
386                          $val = trim($this->tree[$z6]['data']);
387                          if ($name=='agent_data')
388                          {
389                            for($o=0;$o<count($this->tree[$z6]['children']);$o++)
390                            {
391                              $z7 = $this->tree[$z6]['children'][$o];
392                              //$name is agent_data $val is 'name' or 'value'
393                              $name = trim($this->tree[$z7]['name']);
394                              $content = trim($this->tree[$z7]['data']);
395                              //echo "<br>z7 name $name content: $content";
396                              if ($name=='name')
397                              {
398                                $agent_data_name = $content;
399                              }
400                              elseif ($name=='value')
401                              {
402                                $agent_data_value =& $content;
403                              }
404                            }
405                            //echo "<br>associate $agent_data_name to $agent_data_value <hr>";
406                            $agent[$agent_data_name] = $agent_data_value;
407                          }
408                        }
409                      }
410                    }
411                    $agents[]=$agent;
412                  }
413                }
414              } else {
415                $aux[$name]=$value;
416                //print("$name:$value<br/>");
417              }
418            }
419            $aux['agents']=$agents;
420            $aux['roles']=$roles;
421            $activities[]=$aux;
422          }
423        }
424      } elseif($name=='transitions') {
425        for($j=0;$j<count($this->tree[$z]['children']);$j++) {
426          $z2 = $this->tree[$z]['children'][$j];
427          // this is an activity $name = $this->tree[$z2]['name'];
428          $aux=Array();
429          if($this->tree[$z2]['name']=='transition') {
430            for($k=0;$k<count($this->tree[$z2]['children']);$k++) {
431              $z3 = $this->tree[$z2]['children'][$k];
432              $name = trim($this->tree[$z3]['name']);
433              $value= trim($this->tree[$z3]['data']);
434              if($name == 'from' || $name == 'to') {
435                $aux[$name]=$value;
436              }
437            }
438          }
439          $transitions[] = $aux;
440        }
441      } else {
442        $value = trim($this->tree[$z]['data']);
443        //print("$name is $value<br/>");
444        $process[$name]=$value;
445      }
446    }
447    $process['configs']=$configs;
448    $process['activities']=$activities;
449    $process['transitions']=$transitions;
450    return $process;
451  }
452
453  /**
454   * Creates a process from the process data structure, if you want to convert an XML to a process then use first unserialize_process and then this method.
455   *
456   * @access public
457   * @param string &$data
458   * @return bool
459   */
460  function import_process(&$data)
461  {
462    //Now the show begins
463    if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db);
464    if (!(isset($this->role_manager))) $this->role_manager = new RoleManager($this->db);
465    if (!isset($this->jobManager))
466      $this->jobManager = new JobManager($this->db);
467
468    // First create the process. Always inactive and inactive first.
469    $vars = Array(
470      'wf_name' => trim($data['name']),
471      'wf_version' => $data['version'],
472      'wf_description' => $data['description'],
473      'wf_last_modif' => $data['lastModif'],
474      'wf_is_active' => false,
475      'wf_is_valid' => false,
476      'config' => $data['configs'],
477    );
478
479    if (empty($vars['wf_name']))
480    {
481      $msg = tra('invalid name specified');
482      $this->notify_all(2,$msg);
483      $this->error[] = $msg;
484      return false;
485    }
486
487    if (ereg('^[0-9]{1,2}\.[0-9]{1,2}$', $vars['wf_version']) === false)
488    {
489      $msg = tra('invalid version specified');
490      $this->notify_all(2,$msg);
491      $this->error[] = $msg;
492      return false;
493    }
494
495    if ($this->process_name_exists($vars['wf_name'], $vars['wf_version']))
496    {
497      $msg = sprintf(tra('Process %s %s already exists, the import process was aborted'),$vars['wf_name'],$vars['wf_version']);
498      $this->notify_all(2,$msg);
499      $this->error[] = $msg;
500      return false;
501    }
502    $pid = $this->replace_process(0,$vars,false);
503    //Put the shared code
504    $proc_info = $this->get_process($pid);
505    $wf_procname = $proc_info['wf_normalized_name'];
506    $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'shared.php',"w");
507    fwrite($fp, $data['sharedCode']);
508    fclose($fp);
509    $actids = Array();
510   
511    // Foreach activity create activities
512    foreach($data['activities'] as $activity) {
513               
514      $vars = Array(
515        'wf_name' => $activity['name'],
516        'wf_description' => $activity['description'],
517        'wf_type' => $activity['type'],
518        'wf_menu_path' => $activity['menuPath'],
519        'wf_last_modif' => $activity['lastModif'],
520        'wf_is_interactive' => $activity['isInteractive'],
521        'wf_is_autorouted' => $activity['isAutoRouted']
522      );   
523      $actname=$this->activity_manager->_normalize_name($activity['name']);
524      $actid = $this->activity_manager->replace_activity($pid,0,$vars);
525         
526      $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'activities'.SEP.$actname.'.php',"w");
527      fwrite($fp, $activity['code']);
528      fclose($fp);
529      if($activity['isInteractive']=='y') {
530        $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates'.SEP.$actname.'.tpl',"w");
531        fwrite($fp,$activity['template']);
532        fclose($fp);
533      }
534      $actids[$activity['name']] = $this->activity_manager->_get_activity_id_by_name($pid, $activity['name']);
535      $actname = $this->activity_manager->_normalize_name($activity['name']);
536      $now = date("U");
537      //roles
538          if( is_array($activity['roles']) && count($activity['roles']) > 0 )
539          {
540              foreach($activity['roles'] as $role)
541              {
542                $rolename = $role['name'];
543                $vars = Array(
544                  'wf_name' => $rolename,
545                  'wf_description' => $rolename,
546                  'wf_last_modif' => $now,
547                );
548                if(!$this->role_manager->role_name_exists($pid,$rolename)) {
549                  $rid=$this->role_manager->replace_role($pid,0,$vars);
550                } else {
551                  $rid = $this->role_manager->get_role_id($pid,$rolename);
552                }
553                if($actid && $rid) {
554                  $this->activity_manager->add_activity_role($actid,$rid,$role['readonly']);
555                }
556              }
557          }
558      //agents
559      if( is_array($activity['agents']) && count($activity['agents']) > 0 )
560      {
561        foreach($activity['agents'] as $agent)
562        {
563            if (empty($agent['wf_agent_type']))
564            {
565              $this->error[] = lang('empty agent type');
566            }
567            else
568            {
569              //create a new agent of the same type for the new activity
570              $agentid = $this->activity_manager->add_activity_agent($actid,$agent['wf_agent_type']);
571              //save values of this new agent
572              $bindvars = Array();
573              $query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$agent['wf_agent_type'].'
574                        set ';
575              //we wont need the old type anymore
576              unset($agent['wf_agent_type']);
577              $countfields = 0;
578              foreach ($agent as $key => $value)
579              {
580                if ($key)
581                {
582                  $countfields++;
583                  $query .= "$key = ? ,";
584                  $bindvars[] = $value;
585                }
586              }
587              $query = substr($query,'0',-1);
588              $query .= ' where wf_agent_id = ?';
589              $bindvars[] = $agentid;
590              if ($countfields) $this->query($query, $bindvars);
591            }
592        }
593      }
594    }
595    //transitions
596    foreach($data['transitions'] as $tran)
597    {
598      $this->activity_manager->add_transition($pid,$actids[$tran['from']],$actids[$tran['to']]); 
599    }
600
601    foreach ($data['jobs'] as $job)
602    {
603      $this->jobManager->replaceJob($pid, 0, $job);
604    }
605
606    // create a graph for the new process
607    $this->activity_manager->build_process_graph($pid);
608    //Test the final process
609    $this->activity_manager->validate_process_activities($pid);
610
611    $msg = sprintf(tra('Process %s %s imported'),$proc_info['wf_name'],$proc_info['wf_version']);
612    $this->notify_all(2,$msg);
613    $this->error[] = $msg;
614    return true;
615  }
616
617  /**
618   * Creates a new process based on an existing process changing the process version.
619   * By default the process is created as an unactive process and the version is by default a minor version of the process
620   *
621   * @param int $pId Process id
622   * @param bool $minor Process previous version
623   * @return int Process id
624   * @access public
625   */
626  function new_process_version($pId, $minor=true)
627  {
628    if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db);
629    $oldpid = $pId;
630    //retrieve process info with config rows
631    $proc_info = $this->get_process($pId, true);
632    if(!($proc_info) || (count($proc_info)==0)) return false;
633    $name = $proc_info['wf_name'];
634
635    // Now update the version
636    $version = $this->_new_version($proc_info['wf_version'],$minor);
637    while($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_name=? and wf_version=?',array($name,$version)))
638    {
639      $version = $this->_new_version($version,$minor);
640    }
641    $oldname = $proc_info['wf_normalized_name'];
642
643    // Make new versions unactive
644    $proc_info['wf_version'] = $version;
645    $proc_info['wf_is_active'] = 'n';
646    // create a new process, but don't create start/end activities
647    $pid = $this->replace_process(0, $proc_info, false);
648    if (!pid) return false;
649
650    //Since we are copying a process we should copy
651    //the old directory structure to the new directory
652    //oldname was saved a few lines before
653    $newname = $this->_get_normalized_name($pid);
654    $this->_rec_copy(GALAXIA_PROCESSES.SEP.$oldname.SEP.'code',GALAXIA_PROCESSES.SEP.$newname.SEP.'code');
655    // And here copy all the activities & so
656    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?';
657    $result = $this->query($query, array($oldpid));
658    $newaid = array();
659    while($res = $result->fetchRow()) {   
660      $oldaid = $res['wf_activity_id'];
661      // the false tell the am not to create activities source files
662      $newaid[$oldaid] = $this->activity_manager->replace_activity($pid,0,$res, false);
663    }
664    // create transitions
665    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'transitions where wf_p_id=?';
666    $result = $this->query($query, array($oldpid));
667
668    /* create the jobs */
669    $query = "INSERT INTO " . GALAXIA_TABLE_PREFIX . "jobs (wf_process_id, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, active) (SELECT {$pid}, name, description, time_start, interval_value, interval_unity, date_type, week_days, month_offset, FALSE FROM " . GALAXIA_TABLE_PREFIX . "jobs WHERE wf_process_id = ?)";
670    $this->query($query, array($oldpid));
671
672    while($res = $result->fetchRow()) {
673      if (empty($newaid[$res['wf_act_from_id']]) || empty($newaid[$res['wf_act_to_id']])) {
674        continue;
675      }
676      $this->activity_manager->add_transition($pid,$newaid[$res['wf_act_from_id']],$newaid[$res['wf_act_to_id']]);
677    }
678    // create roles
679    if (!(isset($this->role_manager))) $this->role_manager = new RoleManager($this->db);
680    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?';
681    $result = $this->query($query, array($oldpid));
682    $newrid = array();
683    while($res = $result->fetchRow()) {
684      if(!$this->role_manager->role_name_exists($pid,$res['wf_name'])) {
685        $rid=$this->role_manager->replace_role($pid,0,$res);
686      } else {
687        $rid = $this->role_manager->get_role_id($pid,$res['wf_name']);
688      }
689      $newrid[$res['wf_role_id']] = $rid;
690    }
691    // map users to roles
692    if (count($newrid) > 0) {
693      $query = 'select * from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?';
694      $result = $this->query($query, array($oldpid));
695      while($res = $result->fetchRow()) {
696        if (empty($newrid[$res['wf_role_id']])) {
697          continue;
698        }
699        $this->role_manager->map_user_to_role($pid,$res['wf_user'],$newrid[$res['wf_role_id']], $res['wf_account_type']);
700      }
701    }
702    // add roles to activities
703    if (count($newaid) > 0 && count($newrid ) > 0) {
704      $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id in (' . join(', ',array_keys($newaid)) . ')';
705      $result = $this->query($query);
706      while($res = $result->fetchRow()) {
707        if (empty($newaid[$res['wf_activity_id']]) || empty($newrid[$res['wf_role_id']])) {
708          continue;
709        }
710        $this->activity_manager->add_activity_role($newaid[$res['wf_activity_id']],$newrid[$res['wf_role_id']], $res['wf_readonly']);
711      }
712    }
713
714    //create agents
715    //get the list of agents used by the old process
716    $query = 'select gaa.* from '.GALAXIA_TABLE_PREFIX.'activity_agents gaa
717                INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities gac ON gaa.wf_activity_id = gac.wf_activity_id
718                where gac.wf_p_id=?';
719    $result = $this->query($query, array($oldpid));
720    if (!(empty($result)))
721    {
722      while ($res = $result->fetchRow())
723      {
724          //create a new agent of the same type for the new activity
725          $agentid = $this->activity_manager->add_activity_agent($newaid[$res['wf_activity_id']],$res['wf_agent_type']);
726          //save values of this new agents, taking the old ones, we make a simple copy
727          $old_activity_agent_data =& $this->activity_manager->get_activity_agent_data($res['wf_activity_id'],$res['wf_agent_type']);
728          //we wont need the old id and type
729          unset($old_activity_agent_data['wf_agent_id']);
730          unset($old_activity_agent_data['wf_agent_type']);
731          $bindvars = Array();
732          $query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$res['wf_agent_type'].'
733                      set ';
734          $countfields = 0;
735          foreach ($old_activity_agent_data as $key => $value)
736          {
737            if ($key)
738            {
739              $countfields++;
740              $query .= "$key = ? ,";
741              $bindvars[] = $value;
742            }
743          }
744          $query = substr($query,'0',-1);
745          $query .= ' where wf_agent_id = ?';
746          $bindvars[] = $agentid;
747          if ($countfields) $this->query($query, $bindvars);
748      }
749    }
750
751    // create a graph for the new process
752    $this->activity_manager->build_process_graph($pid);
753   
754    return $pid;
755  }
756 
757  /**
758   * This function can be used to check if a process name exists, note that this is NOT used by replace_process since that function can be used to
759   * create new versions of an existing process. The application must use this method to ensure that processes have unique names.
760   *
761   * @param string $name Process name
762   * @param string $version Process version
763   * @return bool
764   * @access public
765  */
766  function process_name_exists($name,$version)
767  {
768    $name = addslashes($this->_normalize_name($name,$version));
769    return $this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_normalized_name=?',array($name));
770  }
771 
772 
773  /**
774   * Gets a process by pId. Fields are returned as an associative array.
775   * If withConfig is set (false by default), the configuration options are returned as well the ['config'] key is then an array containing the config data with type distinction
776   *
777   * @param int $pId Process id
778   * @param bool $withConfig Configuration options
779   * @return bool
780   * @access public
781   */
782  function get_process($pId, $withConfig=false)
783  {
784    $query = 'select * from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?';
785    $result = $this->query($query, array($pId));
786    if((empty($result)) || (!$result->numRows())) return false;
787    $res = $result->fetchRow();
788    if ($withConfig)
789    {
790      // by setting true we force this function to keep type distinction on config values
791      $res['config'] = $this->getConfigValues($res['wf_p_id'], true);
792    }
793    return $res;
794  }
795 
796  /**
797   * Lists all processes
798   *
799   * @param int $offset Resultset starting row
800   * @param int $maxRecords Max number of resulting rows
801   * @param string $sort_mode Sorting mode
802   * @param string $find Search query string
803   * @param string $where Condition query string
804   * @return bool
805   * @access public
806   */
807  function list_processes($offset,$maxRecords,$sort_mode,$find='',$where='')
808  {
809    $sort_mode = $this->convert_sortmode($sort_mode);
810    if($find) {
811      $findesc = '%'.$find.'%';
812      $mid=' where ((wf_name like ?) or (wf_description like ?))';
813      $bindvars = array($findesc,$findesc);
814    } else {
815      $mid='';
816      $bindvars = array();
817    }
818    if($where) {
819      if($mid) {
820        $mid.= " and ($where) ";
821      } else {
822        $mid.= " where ($where) ";
823      }
824    }
825    $query = 'select * from '.GALAXIA_TABLE_PREFIX."processes $mid";
826    $query_cant = 'select count(*) from '.GALAXIA_TABLE_PREFIX."processes $mid";
827    $result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode);
828    $cant = $this->getOne($query_cant,$bindvars);
829    $ret = Array();
830    if (isset($result))
831    {
832      while($res = $result->fetchRow())
833      {
834        $ret[] = $res;
835      }
836    }
837    $retval = Array();
838    $retval['data'] = $ret;
839    $retval['cant'] = $cant;
840    return $retval;
841  }
842 
843  /*!
844   Marks a process as an invalid process
845  */
846  function invalidate_process($pid)
847  {
848    $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_valid=? where wf_p_id=?';
849    $this->query($query, array('n',$pid));
850  }
851 
852  /**
853   * Removes a process by pId
854   *
855   * @param int $pId Process id
856   * @return bool
857   * @access public
858   */
859  function remove_process($pId)
860  {
861    if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db);
862    if (!isset($this->jobManager))
863      $this->jobManager = new JobManager($this->db);
864    $this->deactivate_process($pId);
865    $name = $this->_get_normalized_name($pId);
866   
867    // start a transaction
868    $this->db->StartTrans();
869        $this->jobManager->removeJobsByProcessID($pId);
870   
871    // Remove process activities
872    $query = 'select wf_activity_id from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?';
873    $result = $this->query($query, array($pId));
874    while($res = $result->fetchRow()) {
875      //we add a false parameter to prevent the ActivityManager from opening a new transaction
876      $this->activity_manager->remove_activity($pId,$res['wf_activity_id'], false);
877    }
878
879    // Remove process roles
880    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?';
881    $this->query($query, array($pId));
882    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?';
883    $this->query($query, array($pId));
884
885        // Remove process instances
886        $query = 'delete from '.GALAXIA_TABLE_PREFIX.'instances where wf_p_id=?';
887    $this->query($query, array($pId));
888   
889    // Remove the directory structure
890    if (!empty($name) && is_dir(GALAXIA_PROCESSES.SEP.$name)) {
891      $this->_remove_directory(GALAXIA_PROCESSES.SEP.$name,true);
892    }
893    if (GALAXIA_TEMPLATES && !empty($name) && is_dir(GALAXIA_TEMPLATES.SEP.$name)) {
894      $this->_remove_directory(GALAXIA_TEMPLATES.SEP.$name,true);
895    }
896   
897    // Remove configuration data
898    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?';
899    $this->query($query, array($pId));
900   
901    // And finally remove the proc
902    $query = 'delete from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?';
903    $this->query($query, array($pId));
904    $msg = sprintf(tra('Process %s removed'),$name);
905    $this->notify_all(5,$msg);
906    $this->error[] = $msg;
907   
908    // perform commit (return true) or Rollback (return false)
909    return $this->db->CompleteTrans();
910   
911  }
912 
913  /**
914   * Updates or inserts a new process in the database, $vars is an associative array containing the fields to update or to insert as needed.
915   * Configuration options should be in an array associated with the 'config' key
916   * this config array should contain 'wf_config_name', 'wf_config_value' and 'wf_config_value_int' keys.
917   * $pId is the processI. If $pId is 0 then we create a new process, else we are in edit mode.
918   * if $create is true start and end activities will be created (when importing use $create=false)
919   *
920   * @param int $pId Process id, if 0 then we create a new process, else we are in edit mode
921   * @param array &$vars Associative containing the fields to update or to insert as needed
922   * @param bool $create If true, start and end activities will be created (when importing use $create=false).
923   * @return int Process id
924   * @access public
925   */
926  function replace_process($pId, &$vars, $create = true)
927  {
928    if (!(isset($this->activity_manager)))  $this->activity_manager = new ActivityManager($this->db);
929    $TABLE_NAME = GALAXIA_TABLE_PREFIX.'processes';
930    $now = date("U");
931    $vars['wf_last_modif']=$now;
932    $vars['wf_normalized_name'] = $this->_normalize_name($vars['wf_name'],$vars['wf_version']);
933    $config_array = array();
934       
935    foreach($vars as $key=>$value)
936    {
937      if ($key=='config')
938      {
939        $config_array_init =& $value;
940        // rebuild a nice config_array with type of config and value
941        if( is_array($config_array_init) && count($config_array_init) > 0 )
942        {
943                foreach($config_array_init as $config)
944                {
945                  if (isset($config['wf_config_value_int']) && (!($config['wf_config_value_int']=='')))
946                  {
947                    $config_array[$config['wf_config_name']] = array('int' => $config['wf_config_value_int']);
948                  }
949                  else
950                  {
951                    if (isset($config['wf_config_value']))
952                    {
953                      $config_array[$config['wf_config_name']] = array('text' => $config['wf_config_value']);
954                    }
955                  }
956                }
957        }
958        //no need to keep it in the vars array, this array is used in queries
959        unset($vars['config']);
960      }
961      else // not config, it's just process's fields values
962      {
963        $vars[$key]=addslashes($value);
964      }
965    }
966 
967    if($pId) {
968      // update mode
969      $old_proc = $this->get_process($pId);
970      $first = true;
971      $query ="update $TABLE_NAME set";
972      foreach($vars as $key=>$value) {
973        if(!$first) $query.= ',';
974        if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'";
975        $query.= " $key=$value ";
976        $first = false;
977      }
978      $query .= " where wf_p_id=$pId ";
979      $this->query($query);
980     
981      //set config values
982      $this->setConfigValues($pId,$config_array);
983     
984      // Note that if the name is being changed then
985      // the directory has to be renamed!
986      $oldname = $old_proc['wf_normalized_name'];
987      $newname = $vars['wf_normalized_name'];
988      if ($newname != $oldname) {
989          rename(GALAXIA_PROCESSES.SEP."$oldname",GALAXIA_PROCESSES.SEP."$newname");
990      }
991      $msg = sprintf(tra('Process %s has been updated'),$vars['wf_name']);     
992      $this->notify_all(3,$msg);
993      $this->error[] = $msg;
994    } else {
995      unset($vars['wf_p_id']);
996      // insert mode
997      $name = $this->_normalize_name($vars['wf_name'],$vars['wf_version']);
998      $this->_create_directory_structure($name);
999      $first = true;
1000      $query = "insert into $TABLE_NAME(";
1001      foreach(array_keys($vars) as $key) {
1002        if(!$first) $query.= ',';
1003        $query.= "$key";
1004        $first = false;
1005      }
1006      $query .=") values(";
1007      $first = true;
1008      foreach(array_values($vars) as $value) {
1009        if(!$first) $query.= ',';
1010        if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'";
1011        $query.= "$value";
1012        $first = false;
1013      }
1014      $query .=")";
1015      $this->query($query);
1016      //FIXME: this query seems to be quite sure to get a result, I would prefer something
1017      // more sure to get the right result everytime
1018      $pId = $this->getOne("select max(wf_p_id) from $TABLE_NAME where wf_last_modif=$now");
1019     
1020      //set config values
1021      $this->setConfigValues($pId,$config_array);
1022     
1023      // Now automatically add a start and end activity
1024      // unless importing ($create = false)
1025      if($create) {
1026        $vars1 = Array(
1027          'wf_name' => 'start',
1028          'wf_description' => 'default start activity',
1029          'wf_type' => 'start',
1030          'wf_is_interactive' => 'y',
1031          'wf_is_autorouted' => 'y'
1032        );
1033        $vars2 = Array(
1034          'wf_name' => 'end',
1035          'wf_description' => 'default end activity',
1036          'wf_type' => 'end',
1037          'wf_is_interactive' => 'n',
1038          'wf_is_autorouted' => 'y'
1039        );
1040 
1041        $this->activity_manager->replace_activity($pId,0,$vars1);
1042        $this->activity_manager->replace_activity($pId,0,$vars2);
1043      }
1044    $msg = sprintf(tra('Process %s has been created'),$vars['wf_name']);     
1045    $this->notify_all(4,$msg);
1046    $this->error[] = $msg;
1047    }
1048    // Get the id
1049    return $pId;
1050  }
1051   
1052  /**
1053   * Gets the normalized name of a process by pid
1054   *
1055   * @param int $pId Process id
1056   * @access private
1057   * @return string
1058   */
1059  function _get_normalized_name($pId)
1060  {
1061    $info = $this->get_process($pId);
1062    return $info['wf_normalized_name'];
1063  }
1064   
1065  /**
1066   * Normalizes a process name
1067   *
1068   * @param string $name Process name to be normalized
1069   * @param string $version Process version
1070   * @access private
1071   * @return string Process normalized name
1072   */
1073  function _normalize_name($name, $version)
1074  {
1075    $name = $name.'_'.$version;
1076    $name = str_replace(" ","_",$name);
1077    $name = preg_replace("/[^0-9A-Za-z\_]/",'',$name);
1078    return $name;
1079  }
1080   
1081  /**
1082   * Generates a new minor version number
1083   *
1084   * @param string $version Current process version
1085   * @param bool $minor Generate minor version
1086   * @access private
1087   * @return string
1088   */
1089  function _new_version($version,$minor=true)
1090  {
1091    $parts = explode('.',$version);
1092    if($minor) {
1093      $parts[count($parts)-1]++;
1094    } else {
1095      $parts[0]++;
1096      for ($i = 1; $i < count($parts); $i++) {
1097        $parts[$i] = 0;
1098      }
1099    }
1100    return implode('.',$parts);
1101  }
1102   
1103  /**
1104   * Creates directory structure for process
1105   *
1106   * @param string $name Dir name in process repository
1107   * @access private
1108   * @return bool
1109   */
1110  function _create_directory_structure($name)
1111  {
1112    $path = GALAXIA_PROCESSES.SEP.$name;
1113    if (!file_exists($path)) mkdir($path,0770);
1114    $path = GALAXIA_PROCESSES.SEP.$name.SEP."resources";
1115    if (!file_exists($path)) mkdir($path,0770);
1116    $path = GALAXIA_PROCESSES.SEP.$name.SEP."graph";
1117    if (!file_exists($path)) mkdir($path,0770);
1118    $path = GALAXIA_PROCESSES.SEP.$name.SEP."code";
1119    if (!file_exists($path)) mkdir($path,0770);
1120    $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."activities";
1121    if (!file_exists($path)) mkdir($path,0770);
1122    $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."templates";
1123    if (!file_exists($path)) mkdir($path,0770);
1124    $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."jobs";
1125    if (!file_exists($path)) mkdir($path,0770);
1126    $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty";
1127    if (!file_exists($path)) mkdir($path,0770);
1128    $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."cache";
1129    if (!file_exists($path)) mkdir($path,0770);
1130    $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."compiled";
1131    if (!file_exists($path)) mkdir($path,0770);
1132    if (GALAXIA_TEMPLATES) {
1133      $path = GALAXIA_TEMPLATES.SEP.$name;
1134      if (!file_exists($path)) mkdir($path,0770);
1135    }
1136    // Create shared file
1137    $file = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php";
1138    if (!file_exists($file))
1139    {
1140      $fp = fopen(GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php","w");
1141      if (!fp) return false;
1142      fwrite($fp,'<'.'?'.'php'."\n".'?'.'>');
1143      fclose($fp);
1144    }
1145  }
1146   
1147  /**
1148   * Removes a directory recursively
1149   *
1150   * @param string $dir Dir name to be erased
1151   * @param bool $rec Recursive mode
1152   * @access private
1153   * @return void
1154   */
1155  function _remove_directory($dir,$rec=false)
1156  {
1157    // Prevent a disaster
1158    if(trim($dir) == SEP || trim($dir)=='.' || trim($dir)=='templates' || trim($dir)=='templates'.SEP) return false;
1159    $h = opendir($dir);
1160    while(($file = readdir($h)) != false) {
1161      if(is_file($dir.SEP.$file)) {
1162        @unlink($dir.SEP.$file);
1163      } else {
1164        if($rec && $file != '.' && $file != '..') {
1165          $this->_remove_directory($dir.SEP.$file, true);
1166        }
1167      }
1168    }
1169    closedir($h);   
1170    @rmdir($dir);
1171    @unlink($dir);
1172  }
1173 
1174  /**
1175   * Copies a directory recursively
1176   *
1177   * @param string $dir1 Dir name to be copied
1178   * @param string $dir2 Generated destination dir
1179   * @access private
1180   * @return void
1181   */
1182  function _rec_copy($dir1,$dir2)
1183  {
1184    @mkdir($dir2,0777);
1185    $h = opendir($dir1);
1186    while(($file = readdir($h)) !== false) {
1187      if(is_file($dir1.SEP.$file)) {
1188        copy($dir1.SEP.$file,$dir2.SEP.$file);
1189      } else {
1190        if($file != '.' && $file != '..') {
1191          $this->_rec_copy($dir1.SEP.$file, $dir2.SEP.$file);
1192        }
1193      }
1194    }
1195    closedir($h);   
1196  }
1197
1198  /**
1199   * XML parser start element handler
1200   *
1201   * @param resource $parser Parser handle
1202   * @param string $element XML tag
1203   * @param array $attribs XML tag attributes
1204   * @access private
1205   * @return void
1206   */
1207  function _start_element_handler($parser, $element, $attribs)
1208  {
1209    $aux=Array('name'=>$element,
1210               'data'=>'',
1211               'parent' => $this->current,
1212               'children'=>Array(),
1213               'attribs' => $attribs);
1214                           
1215    $i = count($this->tree);           
1216    $this->tree[$i] = $aux;
1217
1218    $this->tree[$this->current]['children'][]=$i;
1219    $this->current=$i;
1220  }
1221
1222  /**
1223   * XML parser end element handler
1224   *
1225   * @param resource $parser Parser handle
1226   * @param string $element XML tag
1227   * @param array $attribs XML tag attributes
1228   * @access private
1229   * @return void
1230   */
1231  function _end_element_handler($parser, $element)
1232  {
1233    //when a tag ends put text
1234    $this->tree[$this->current]['data']=$this->buffer;           
1235    $this->buffer='';
1236    $this->current=$this->tree[$this->current]['parent'];
1237  }
1238
1239  /**
1240   * XML parser element data handler
1241   *
1242   * @param resource $parser Parser handle
1243   * @param string $element XML tag
1244   * @param string $data XML tag content
1245   * @access private
1246   * @return void
1247   */
1248  function _data_handler($parser, $data)
1249  {
1250          $this->buffer .= $data;
1251  }
1252
1253  /**
1254   * This getConfigValues differs from the Process::getConfigValues because requires only process id.
1255   * This method gets the items defined in process_config table for this process, in fact this admin function bypass
1256   * the process behaviour and is just showing you the basic content of the table.
1257   * All config items are returned as a function result.       
1258   *
1259   * @param int $pId Process id
1260   * @param bool $distinct_types If the distinct_type is set the returned array will follow the format:
1261   * * 0        =>('wf_config_name'=> 'foo')
1262   *            =>('wf_config_value'=>'bar')
1263   *            =>('wf_config_vale_int'=>null)
1264   * * 1        =>('wf_config_name' => 'toto')
1265   *            =>('wf_config_value'=>'')
1266   *            =>('wf_config_vale_int'=>15)
1267   * if set to false (default) the result array will be (note that this is the default result if having just the $pId):
1268   * * 'foo'=>'bar'
1269   * * 'toto'=>15
1270   * @param bool $askProcessObject If the askProcessObject is set to true (false by default) then the ProcessManager will load a process
1271   * object to run directly Process->getConfigValues($config_ask_array) this let you use this ProcessManager
1272   * getConfigValues the same way you would use $process->getConfigValues, with initialisation of default values.
1273   * you should then call this function this way: $conf_result=$pm->getConfigValues($pId,true,true,$my_conf_array)
1274   * @param array $config_array
1275   * @access public
1276   * @return array
1277   */
1278  function getConfigValues($pId, $distinct_types=false, $askProcessObject=false, $config_array=array())
1279  {
1280    if (!$askProcessObject)
1281    {
1282      $query = 'select * from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?';
1283      $result = $this->query($query, array($pId));
1284      $result_array=array();
1285      while($res = $result->fetchRow())
1286      {
1287        if ( (!$distinct_types) )
1288        {// we want a simple array
1289          if ($res['wf_config_value_int']==null)
1290          {
1291            $result_array[$res['wf_config_name']] = $res['wf_config_value'];
1292            }
1293          else
1294          {
1295            $result_array[$res['wf_config_name']] = $res['wf_config_value_int'];
1296          }
1297        }
1298        else
1299        {// build a more complex result array, which is just the table rows
1300          $result_array[] = $res;
1301        }
1302      }
1303    }
1304    else //we'll load a Process object and let him work for us
1305    {
1306      //Warning: this means you have to include the Process.php from the API
1307      $this->Process = new Process($this->db);
1308      $this->Process->getProcess($pId);
1309      $result_array = $this->Process->getConfigValues($config_array);
1310      unset ($this->Process);
1311    }
1312    return $result_array;
1313  }
1314 
1315  /**
1316   * Calls a process object to save his new config values by taking a process Id as first argument and simply call
1317   * this process's setConfigValues method. We let the process define the better way to store the data given as second arg.
1318   *
1319   * @param int $pId Process id
1320   * @param array &$config_array
1321   * @return void
1322   * @access public
1323   */
1324  function setConfigValues($pId, &$config_array)
1325  {
1326    //Warning: this means you have to include the Process.php from the API
1327    $this->Process = new Process($this->db);
1328    $this->Process->getProcess($pId);
1329    $this->Process->setConfigValues($config_array);
1330    unset ($this->Process);
1331  }
1332 
1333  /**
1334   * Gets available agents list
1335   *
1336   * @return array
1337   * @access public
1338   */
1339  function get_agents()
1340  {
1341    return galaxia_get_agents_list();
1342  }
1343
1344  /**
1345   * Gets the view activity id avaible for a given process
1346   *
1347   * @param int $pId Process Id
1348   * @return bool False if no view activity is avaible for the process, return the activity id if there is one
1349   * @access public
1350   */
1351  function get_process_view_activity($pId)
1352  {
1353    $mid = 'where gp.wf_p_id=? and ga.wf_type=?';
1354    $bindvars = array($pId,'view');
1355    $query = 'select ga.wf_activity_id
1356        from '.GALAXIA_TABLE_PREFIX.'processes gp
1357        INNER JOIN '.GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id
1358        $mid";
1359    $result = $this->query($query,$bindvars);
1360    $ret = Array();
1361    $retval = false;
1362    if (!(empty($result)))
1363    {
1364      while($res = $result->fetchRow())
1365      {
1366        $retval = $res['wf_activity_id'];
1367      }
1368    }
1369    return $retval;
1370  }
1371
1372}
1373
1374
1375?>
Note: See TracBrowser for help on using the repository browser.