source: trunk/workflow/inc/engine/src/ProcessManager/ProcessManager.php @ 7655

Revision 7655, 44.3 KB checked in by douglasz, 11 years ago (diff)

Ticket #3236 - Melhorias de performance no codigo do Expresso.

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