Changeset 3167 for branches/2.2/workflow/inc/engine/src/ProcessManager
- Timestamp:
- 08/17/10 16:17:12 (14 years ago)
- Location:
- branches/2.2/workflow/inc/engine/src/ProcessManager
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2/workflow/inc/engine/src/ProcessManager/ActivityManager.php
r795 r3167 26 26 * @access public 27 27 */ 28 function ActivityManager( &$db)29 { 30 parent::BaseManager( $db);28 function ActivityManager() 29 { 30 parent::BaseManager(); 31 31 $this->child_name = 'ActivityManager'; 32 32 require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'ProcessManager' .SEP . 'ProcessManager.php'); … … 370 370 function build_process_graph($pId) 371 371 { 372 if (!(isset($this->process_manager))) $this->process_manager = new ProcessManager($this->db);372 if (!(isset($this->process_manager))) $this->process_manager = &Factory::newInstance('ProcessManager'); 373 373 $attributes = Array( 374 374 375 375 ); 376 $graph = new Process_GraphViz(true,$attributes);376 $graph = &Factory::newInstance('Process_GraphViz', true, $attributes); 377 377 $name = $this->process_manager->_get_normalized_name($pId); 378 378 $graph->set_pid($name); … … 747 747 { 748 748 require_once(GALAXIA_LIBRARY.SEP.'src'.SEP.'API'.SEP . 'BaseActivity.php'); 749 $act = new BaseActivity($this->db);749 $act = &Factory::newInstance('BaseActivity'); 750 750 //Warning, we now use the BaseActivity object for it, interactivity and autorouting is now true/fales, not y/n 751 751 return ($act->getActivity($activityId,false,true, true)); … … 825 825 function remove_activity($pId, $activityId, $transaction = true) 826 826 { 827 if (!(isset($this->process_manager))) $this->process_manager = new ProcessManager($this->db);827 if (!(isset($this->process_manager))) $this->process_manager = &Factory::newInstance('ProcessManager'); 828 828 $proc_info = $this->process_manager->get_process($pId); 829 829 $actname = $this->_get_normalized_name($activityId); … … 888 888 function replace_activity($pId, $activityId, $vars, $create_files=true) 889 889 { 890 if (!(isset($this->process_manager))) $this->process_manager = new ProcessManager($this->db);890 if (!(isset($this->process_manager))) $this->process_manager = &Factory::newInstance('ProcessManager'); 891 891 $TABLE_NAME = GALAXIA_TABLE_PREFIX.'activities'; 892 892 $now = date("U"); … … 1195 1195 elseif ( (!($result=='*')) && $performAccessCheck) 1196 1196 { 1197 $wf_security = new WfSecurity($this->db);1197 $wf_security = &Factory::getInstance('WfSecurity'); 1198 1198 // perform the check 1199 1199 if (!($wf_security->checkUserAccess($result,$activityId))) -
branches/2.2/workflow/inc/engine/src/ProcessManager/BaseManager.php
r795 r3167 4 4 /** 5 5 * This class is derived by all the API classes so they get the 6 * database connection , database methods and the Observable interface6 * database connection and the database methods. 7 7 * 8 8 * @package Galaxia … … 18 18 * @access public 19 19 */ 20 function BaseManager( &$db)20 function BaseManager() 21 21 { 22 22 $this->child_name = 'BaseManager'; 23 parent::Base( $db);23 parent::Base(); 24 24 } 25 25 -
branches/2.2/workflow/inc/engine/src/ProcessManager/InstanceManager.php
r795 r3167 16 16 * @access public 17 17 */ 18 function InstanceManager( &$db)19 { 20 parent::BaseManager( $db);18 function InstanceManager() 19 { 20 parent::BaseManager(); 21 21 $this->child_name = 'InstanceManager'; 22 22 } -
branches/2.2/workflow/inc/engine/src/ProcessManager/JobManager.php
r795 r3167 76 76 * @access public 77 77 */ 78 public function JobManager( &$db)79 { 80 parent::BaseManager( $db);78 public function JobManager() 79 { 80 parent::BaseManager(); 81 81 $this->child_name = 'JobManager'; 82 82 83 83 $this->jobTable = GALAXIA_TABLE_PREFIX . 'jobs'; 84 84 $this->logTable = GALAXIA_TABLE_PREFIX . 'job_logs'; 85 $this->processManager = new ProcessManager($this->db);85 $this->processManager = &Factory::newInstance('ProcessManager'); 86 86 } 87 87 -
branches/2.2/workflow/inc/engine/src/ProcessManager/ProcessManager.php
r795 r3167 4 4 * Adds, removes, modifies and lists processes. 5 5 * Most of the methods acts directly in database level, bypassing Project object methods 6 * 6 * 7 7 * @todo Fix multiple non checked fopen ==> infinite loops in case of problems with filesystem 8 8 * @package Galaxia 9 * @license http://www.gnu.org/copyleft/gpl.html GPL 9 * @license http://www.gnu.org/copyleft/gpl.html GPL 10 10 */ 11 11 class 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 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 for($i=0;$i<count($this->tree[1]['children']);$i++) { 302 // Process attributes 303 $z=$this->tree[1]['children'][$i]; 304 $name = trim($this->tree[$z]['name']); 305 306 //config values 307 if ($name=='configs') { 308 for($j=0;$j<count($this->tree[$z]['children']);$j++) { 309 $z2 = $this->tree[$z]['children'][$j]; 310 // this is a config $name = $this->tree[$z2]['name']; 311 $aux = Array(); 312 if($this->tree[$z2]['name']=='config') { 313 for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 314 $z3 = $this->tree[$z2]['children'][$k]; 315 $name = trim($this->tree[$z3]['name']); 316 $value= trim($this->tree[$z3]['data']); 317 $aux[$name]=$value; 318 } 319 $configs[]=$aux; 320 } 321 } 322 } 323 //activities 324 elseif($name=='activities') { 325 for($j=0;$j<count($this->tree[$z]['children']);$j++) { 326 $z2 = $this->tree[$z]['children'][$j]; 327 // this is an activity $name = $this->tree[$z2]['name']; 328 $aux = Array(); 329 if($this->tree[$z2]['name']=='activity') { 330 for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 331 $z3 = $this->curre[$z2]['children'][$k]; 332 $name = trim($this->tree[$z3]['name']); 333 $value= trim($this->tree[$z3]['data']); 334 if($name=='roles') { 335 $roles=Array(); 336 for($l=0;$l<count($this->tree[$z3]['children']);$l++) { 337 $z4 = $this->tree[$z3]['children'][$l]; 338 $name = trim($this->tree[$z4]['name']); 339 $data = trim($this->tree[$z4]['data']); 340 $attribs = $this->tree[$z4]['attribs']; 341 $readonly = false; 342 if ( (isset($attribs['readonly'])) && ($attribs['readonly'])) 343 { 344 //role in read-only 345 $readonly = true; 346 } 347 $roles[]=array( 348 'name' => $data, 349 'readonly' => $readonly, 350 ); 351 } 352 } 353 elseif ($name=='agents') 354 { 355 $agents=Array(); 356 for($l=0;$l<count($this->tree[$z3]['children']);$l++) 357 { 358 $z4 = $this->tree[$z3]['children'][$l]; 359 //$name is agent 360 $name = trim($this->tree[$z4]['name']); 361 if ($name = 'agent') 362 { 363 $agent = array(); 364 for($m=0;$m<count($this->tree[$z4]['children']);$m++) 365 { 366 $z5 = $this->tree[$z4]['children'][$m]; 367 //$name is agent_type or agent_datas 368 $name = trim($this->tree[$z5]['name']); 369 // data will be the agent_type or an array for agent_datas 370 $data = trim($this->tree[$z5]['data']); 371 if ($name=='agent_type') 372 { 373 $agent['wf_agent_type']=$data; 374 } 375 elseif ($name=='agent_datas') 376 { 377 for($n=0;$n<count($this->tree[$z5]['children']);$n++) 378 { 379 $z6 = $this->tree[$z5]['children'][$n]; 380 //$name is agent_data $val is an array 381 $name = trim($this->tree[$z6]['name']); 382 $val = trim($this->tree[$z6]['data']); 383 if ($name=='agent_data') 384 { 385 for($o=0;$o<count($this->tree[$z6]['children']);$o++) 386 { 387 $z7 = $this->tree[$z6]['children'][$o]; 388 //$name is agent_data $val is 'name' or 'value' 389 $name = trim($this->tree[$z7]['name']); 390 $content = trim($this->tree[$z7]['data']); 391 //echo "<br>z7 name $name content: $content"; 392 if ($name=='name') 393 { 394 $agent_data_name = $content; 395 } 396 elseif ($name=='value') 397 { 398 $agent_data_value =& $content; 399 } 400 } 401 //echo "<br>associate $agent_data_name to $agent_data_value <hr>"; 402 $agent[$agent_data_name] = $agent_data_value; 403 } 404 } 405 } 406 } 407 $agents[]=$agent; 408 } 409 } 410 } else { 411 $aux[$name]=$value; 412 //print("$name:$value<br/>"); 413 } 414 } 415 $aux['agents']=$agents; 416 $aux['roles']=$roles; 417 $activities[]=$aux; 418 } 419 } 420 } elseif($name=='transitions') { 421 for($j=0;$j<count($this->tree[$z]['children']);$j++) { 422 $z2 = $this->tree[$z]['children'][$j]; 423 // this is an activity $name = $this->tree[$z2]['name']; 424 $aux=Array(); 425 if($this->tree[$z2]['name']=='transition') { 426 for($k=0;$k<count($this->tree[$z2]['children']);$k++) { 427 $z3 = $this->tree[$z2]['children'][$k]; 428 $name = trim($this->tree[$z3]['name']); 429 $value= trim($this->tree[$z3]['data']); 430 if($name == 'from' || $name == 'to') { 431 $aux[$name]=$value; 432 } 433 } 434 } 435 $transitions[] = $aux; 436 } 437 } else { 438 $value = trim($this->tree[$z]['data']); 439 //print("$name is $value<br/>"); 440 $process[$name]=$value; 441 } 442 } 443 $process['configs']=$configs; 444 $process['activities']=$activities; 445 $process['transitions']=$transitions; 446 return $process; 447 } 448 449 /** 450 * 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. 451 * 452 * @access public 453 * @param string &$data 454 * @return bool 455 */ 456 function import_process(&$data) 457 { 458 //Now the show begins 459 if (!(isset($this->activity_manager))) $this->activity_manager = &Factory::newInstance('ActivityManager'); 460 if (!(isset($this->role_manager))) $this->role_manager = &Factory::newInstance('RoleManager'); 461 if (!isset($this->jobManager)) 462 $this->jobManager = &Factory::newInstance('JobManager'); 463 464 // First create the process. Always inactive and inactive first. 465 $vars = Array( 466 'wf_name' => trim($data['name']), 467 'wf_version' => $data['version'], 468 'wf_description' => $data['description'], 469 'wf_last_modif' => $data['lastModif'], 470 'wf_is_active' => false, 471 'wf_is_valid' => false, 472 'config' => $data['configs'], 473 ); 474 475 if (empty($vars['wf_name'])) 476 { 477 $msg = tra('invalid name specified'); 478 $this->error[] = $msg; 479 return false; 480 } 481 482 if (ereg('^[0-9]{1,2}\.[0-9]{1,2}$', $vars['wf_version']) === false) 483 { 484 $msg = tra('invalid version specified'); 485 $this->error[] = $msg; 486 return false; 487 } 488 489 if ($this->process_name_exists($vars['wf_name'], $vars['wf_version'])) 490 { 491 $msg = sprintf(tra('Process %s %s already exists, the import process was aborted'),$vars['wf_name'],$vars['wf_version']); 492 $this->error[] = $msg; 493 return false; 494 } 495 $pid = $this->replace_process(0,$vars,false); 496 //Put the shared code 497 $proc_info = $this->get_process($pid); 498 $wf_procname = $proc_info['wf_normalized_name']; 499 $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'shared.php',"w"); 500 fwrite($fp, $data['sharedCode']); 501 fclose($fp); 502 $actids = Array(); 503 504 // Foreach activity create activities 505 foreach($data['activities'] as $activity) { 506 507 $vars = Array( 508 'wf_name' => $activity['name'], 509 'wf_description' => $activity['description'], 510 'wf_type' => $activity['type'], 511 'wf_menu_path' => $activity['menuPath'], 512 'wf_last_modif' => $activity['lastModif'], 513 'wf_is_interactive' => $activity['isInteractive'], 514 'wf_is_autorouted' => $activity['isAutoRouted'] 515 ); 516 $actname=$this->activity_manager->_normalize_name($activity['name']); 517 $actid = $this->activity_manager->replace_activity($pid,0,$vars); 518 519 $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'activities'.SEP.$actname.'.php',"w"); 520 fwrite($fp, $activity['code']); 521 fclose($fp); 522 if($activity['isInteractive']=='y') { 523 $fp = fopen(GALAXIA_PROCESSES.SEP.$wf_procname.SEP.'code'.SEP.'templates'.SEP.$actname.'.tpl',"w"); 524 fwrite($fp,$activity['template']); 525 fclose($fp); 526 } 527 $actids[$activity['name']] = $this->activity_manager->_get_activity_id_by_name($pid, $activity['name']); 528 $actname = $this->activity_manager->_normalize_name($activity['name']); 529 $now = date("U"); 530 //roles 531 if( is_array($activity['roles']) && count($activity['roles']) > 0 ) 532 { 533 foreach($activity['roles'] as $role) 534 { 535 $rolename = $role['name']; 536 $vars = Array( 537 'wf_name' => $rolename, 538 'wf_description' => $rolename, 539 'wf_last_modif' => $now, 540 ); 541 if(!$this->role_manager->role_name_exists($pid,$rolename)) { 542 $rid=$this->role_manager->replace_role($pid,0,$vars); 543 } else { 544 $rid = $this->role_manager->get_role_id($pid,$rolename); 545 } 546 if($actid && $rid) { 547 $this->activity_manager->add_activity_role($actid,$rid,$role['readonly']); 548 } 549 } 550 } 551 //agents 552 if( is_array($activity['agents']) && count($activity['agents']) > 0 ) 553 { 554 foreach($activity['agents'] as $agent) 555 { 556 if (empty($agent['wf_agent_type'])) 557 { 558 $this->error[] = lang('empty agent type'); 559 } 560 else 561 { 562 //create a new agent of the same type for the new activity 563 $agentid = $this->activity_manager->add_activity_agent($actid,$agent['wf_agent_type']); 564 //save values of this new agent 565 $bindvars = Array(); 566 $query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$agent['wf_agent_type'].' 567 set '; 568 //we wont need the old type anymore 569 unset($agent['wf_agent_type']); 570 $countfields = 0; 571 foreach ($agent as $key => $value) 572 { 573 if ($key) 574 { 575 $countfields++; 576 $query .= "$key = ? ,"; 577 $bindvars[] = $value; 578 } 579 } 580 $query = substr($query,'0',-1); 581 $query .= ' where wf_agent_id = ?'; 582 $bindvars[] = $agentid; 583 if ($countfields) $this->query($query, $bindvars); 584 } 585 } 586 } 587 } 588 //transitions 589 foreach($data['transitions'] as $tran) 590 { 591 $this->activity_manager->add_transition($pid,$actids[$tran['from']],$actids[$tran['to']]); 592 } 593 594 foreach ($data['jobs'] as $job) 595 { 596 $this->jobManager->replaceJob($pid, 0, $job); 597 } 598 599 // create a graph for the new process 600 $this->activity_manager->build_process_graph($pid); 601 //Test the final process 602 $this->activity_manager->validate_process_activities($pid); 603 604 $msg = sprintf(tra('Process %s %s imported'),$proc_info['wf_name'],$proc_info['wf_version']); 605 $this->error[] = $msg; 606 return true; 607 } 608 609 /** 610 * Creates a new process based on an existing process changing the process version. 611 * By default the process is created as an unactive process and the version is by default a minor version of the process 612 * 613 * @param int $pId Process id 614 * @param bool $minor Process previous version 615 * @return int Process id 616 * @access public 617 */ 618 function new_process_version($pId, $minor=true) 619 { 620 if (!(isset($this->activity_manager))) $this->activity_manager = &Factory::newInstance('ActivityManager'); 621 $oldpid = $pId; 622 //retrieve process info with config rows 623 $proc_info = $this->get_process($pId, true); 624 if(!($proc_info) || (count($proc_info)==0)) return false; 625 $name = $proc_info['wf_name']; 626 627 // Now update the version 628 $version = $this->_new_version($proc_info['wf_version'],$minor); 629 while($this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_name=? and wf_version=?',array($name,$version))) 630 { 631 $version = $this->_new_version($version,$minor); 632 } 633 $oldname = $proc_info['wf_normalized_name']; 634 635 // Make new versions unactive 636 $proc_info['wf_version'] = $version; 637 $proc_info['wf_is_active'] = 'n'; 638 // create a new process, but don't create start/end activities 639 $pid = $this->replace_process(0, $proc_info, false); 640 if (!pid) return false; 641 642 //Since we are copying a process we should copy 643 //the old directory structure to the new directory 644 //oldname was saved a few lines before 645 $newname = $this->_get_normalized_name($pid); 646 $this->_rec_copy(GALAXIA_PROCESSES.SEP.$oldname.SEP.'code',GALAXIA_PROCESSES.SEP.$newname.SEP.'code'); 647 // And here copy all the activities & so 648 $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?'; 649 $result = $this->query($query, array($oldpid)); 650 $newaid = array(); 651 while($res = $result->fetchRow()) { 652 $oldaid = $res['wf_activity_id']; 653 // the false tell the am not to create activities source files 654 $newaid[$oldaid] = $this->activity_manager->replace_activity($pid,0,$res, false); 655 } 656 // create transitions 657 $query = 'select * from '.GALAXIA_TABLE_PREFIX.'transitions where wf_p_id=?'; 658 $result = $this->query($query, array($oldpid)); 659 660 /* create the jobs */ 661 $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 = ?)"; 662 $this->query($query, array($oldpid)); 663 664 while($res = $result->fetchRow()) { 665 if (empty($newaid[$res['wf_act_from_id']]) || empty($newaid[$res['wf_act_to_id']])) { 666 continue; 667 } 668 $this->activity_manager->add_transition($pid,$newaid[$res['wf_act_from_id']],$newaid[$res['wf_act_to_id']]); 669 } 670 // create roles 671 if (!(isset($this->role_manager))) $this->role_manager = &Factory::newInstance('RoleManager'); 672 $query = 'select * from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?'; 673 $result = $this->query($query, array($oldpid)); 674 $newrid = array(); 675 while($res = $result->fetchRow()) { 676 if(!$this->role_manager->role_name_exists($pid,$res['wf_name'])) { 677 $rid=$this->role_manager->replace_role($pid,0,$res); 678 } else { 679 $rid = $this->role_manager->get_role_id($pid,$res['wf_name']); 680 } 681 $newrid[$res['wf_role_id']] = $rid; 682 } 683 // map users to roles 684 if (count($newrid) > 0) { 685 $query = 'select * from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?'; 686 $result = $this->query($query, array($oldpid)); 687 while($res = $result->fetchRow()) { 688 if (empty($newrid[$res['wf_role_id']])) { 689 continue; 690 } 691 $this->role_manager->map_user_to_role($pid,$res['wf_user'],$newrid[$res['wf_role_id']], $res['wf_account_type']); 692 } 693 } 694 // add roles to activities 695 if (count($newaid) > 0 && count($newrid ) > 0) { 696 $query = 'select * from '.GALAXIA_TABLE_PREFIX.'activity_roles where wf_activity_id in (' . join(', ',array_keys($newaid)) . ')'; 697 $result = $this->query($query); 698 while($res = $result->fetchRow()) { 699 if (empty($newaid[$res['wf_activity_id']]) || empty($newrid[$res['wf_role_id']])) { 700 continue; 701 } 702 $this->activity_manager->add_activity_role($newaid[$res['wf_activity_id']],$newrid[$res['wf_role_id']], $res['wf_readonly']); 703 } 704 } 705 706 //create agents 707 //get the list of agents used by the old process 708 $query = 'select gaa.* from '.GALAXIA_TABLE_PREFIX.'activity_agents gaa 709 INNER JOIN '.GALAXIA_TABLE_PREFIX.'activities gac ON gaa.wf_activity_id = gac.wf_activity_id 710 where gac.wf_p_id=?'; 711 $result = $this->query($query, array($oldpid)); 712 if (!(empty($result))) 713 { 714 while ($res = $result->fetchRow()) 715 { 716 //create a new agent of the same type for the new activity 717 $agentid = $this->activity_manager->add_activity_agent($newaid[$res['wf_activity_id']],$res['wf_agent_type']); 718 //save values of this new agents, taking the old ones, we make a simple copy 719 $old_activity_agent_data =& $this->activity_manager->get_activity_agent_data($res['wf_activity_id'],$res['wf_agent_type']); 720 //we wont need the old id and type 721 unset($old_activity_agent_data['wf_agent_id']); 722 unset($old_activity_agent_data['wf_agent_type']); 723 $bindvars = Array(); 724 $query = 'update '.GALAXIA_TABLE_PREFIX.'agent_'.$res['wf_agent_type'].' 725 set '; 726 $countfields = 0; 727 foreach ($old_activity_agent_data as $key => $value) 728 { 729 if ($key) 730 { 731 $countfields++; 732 $query .= "$key = ? ,"; 733 $bindvars[] = $value; 734 } 735 } 736 $query = substr($query,'0',-1); 737 $query .= ' where wf_agent_id = ?'; 738 $bindvars[] = $agentid; 739 if ($countfields) $this->query($query, $bindvars); 740 } 741 } 742 743 // create a graph for the new process 744 $this->activity_manager->build_process_graph($pid); 745 746 return $pid; 747 } 748 749 /** 750 * 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 751 * create new versions of an existing process. The application must use this method to ensure that processes have unique names. 752 * 753 * @param string $name Process name 754 * @param string $version Process version 755 * @return bool 756 * @access public 757 */ 758 function process_name_exists($name,$version) 759 { 760 $name = addslashes($this->_normalize_name($name,$version)); 761 return $this->getOne('select count(*) from '.GALAXIA_TABLE_PREFIX.'processes where wf_normalized_name=?',array($name)); 762 } 763 764 765 /** 766 * Gets a process by pId. Fields are returned as an associative array. 767 * 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 768 * 769 * @param int $pId Process id 770 * @param bool $withConfig Configuration options 771 * @return bool 772 * @access public 773 */ 774 function get_process($pId, $withConfig=false) 775 { 776 $query = 'select * from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?'; 777 $result = $this->query($query, array($pId)); 778 if((empty($result)) || (!$result->numRows())) return false; 779 $res = $result->fetchRow(); 780 if ($withConfig) 781 { 782 // by setting true we force this function to keep type distinction on config values 783 $res['config'] = $this->getConfigValues($res['wf_p_id'], true); 784 } 785 return $res; 786 } 787 788 /** 789 * Lists all processes 790 * 791 * @param int $offset Resultset starting row 792 * @param int $maxRecords Max number of resulting rows 793 * @param string $sort_mode Sorting mode 794 * @param string $find Search query string 795 * @param string $where Condition query string 796 * @return bool 797 * @access public 798 */ 799 function list_processes($offset,$maxRecords,$sort_mode,$find='',$where='') 800 { 801 $sort_mode = $this->convert_sortmode($sort_mode); 802 if($find) { 803 $findesc = '%'.$find.'%'; 804 $mid=' where ((wf_name like ?) or (wf_description like ?))'; 805 $bindvars = array($findesc,$findesc); 806 } else { 807 $mid=''; 808 $bindvars = array(); 809 } 810 if($where) { 811 if($mid) { 812 $mid.= " and ($where) "; 813 } else { 814 $mid.= " where ($where) "; 815 } 816 } 817 $query = 'select * from '.GALAXIA_TABLE_PREFIX."processes $mid"; 818 $query_cant = 'select count(*) from '.GALAXIA_TABLE_PREFIX."processes $mid"; 819 $result = $this->query($query,$bindvars,$maxRecords,$offset, true, $sort_mode); 820 $cant = $this->getOne($query_cant,$bindvars); 821 $ret = Array(); 822 if (isset($result)) 823 { 824 while($res = $result->fetchRow()) 825 { 826 $ret[] = $res; 827 } 828 } 829 $retval = Array(); 830 $retval['data'] = $ret; 831 $retval['cant'] = $cant; 832 return $retval; 833 } 834 843 835 /*! 844 836 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 pId854 *855 * @param int $pId Process id856 * @return bool857 * @access public858 837 */ 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 } 838 function invalidate_process($pid) 839 { 840 $query = 'update '.GALAXIA_TABLE_PREFIX.'processes set wf_is_valid=? where wf_p_id=?'; 841 $this->query($query, array('n',$pid)); 842 } 843 844 /** 845 * Removes a process by pId 846 * 847 * @param int $pId Process id 848 * @return bool 849 * @access public 850 */ 851 function remove_process($pId) 852 { 853 if (!(isset($this->activity_manager))) $this->activity_manager = &Factory::newInstance('ActivityManager'); 854 if (!isset($this->jobManager)) 855 $this->jobManager = &Factory::newInstance('JobManager'); 856 $this->deactivate_process($pId); 857 $name = $this->_get_normalized_name($pId); 858 859 // start a transaction 860 $this->db->StartTrans(); 861 $this->jobManager->removeJobsByProcessID($pId); 862 863 // Remove process activities 864 $query = 'select wf_activity_id from '.GALAXIA_TABLE_PREFIX.'activities where wf_p_id=?'; 865 $result = $this->query($query, array($pId)); 866 while($res = $result->fetchRow()) { 867 //we add a false parameter to prevent the ActivityManager from opening a new transaction 868 $this->activity_manager->remove_activity($pId,$res['wf_activity_id'], false); 869 } 870 871 // Remove process roles 872 $query = 'delete from '.GALAXIA_TABLE_PREFIX.'roles where wf_p_id=?'; 873 $this->query($query, array($pId)); 874 $query = 'delete from '.GALAXIA_TABLE_PREFIX.'user_roles where wf_p_id=?'; 875 $this->query($query, array($pId)); 876 877 // Remove process instances 878 $query = 'delete from '.GALAXIA_TABLE_PREFIX.'instances where wf_p_id=?'; 879 $this->query($query, array($pId)); 880 881 // Remove the directory structure 882 if (!empty($name) && is_dir(GALAXIA_PROCESSES.SEP.$name)) { 883 $this->_remove_directory(GALAXIA_PROCESSES.SEP.$name,true); 884 } 885 if (GALAXIA_TEMPLATES && !empty($name) && is_dir(GALAXIA_TEMPLATES.SEP.$name)) { 886 $this->_remove_directory(GALAXIA_TEMPLATES.SEP.$name,true); 887 } 888 889 // Remove configuration data 890 $query = 'delete from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?'; 891 $this->query($query, array($pId)); 892 893 // And finally remove the proc 894 $query = 'delete from '.GALAXIA_TABLE_PREFIX.'processes where wf_p_id=?'; 895 $this->query($query, array($pId)); 896 $msg = sprintf(tra('Process %s removed'),$name); 897 $this->error[] = $msg; 898 899 // perform commit (return true) or Rollback (return false) 900 return $this->db->CompleteTrans(); 901 902 } 903 904 /** 905 * Updates or inserts a new process in the database, $vars is an associative array containing the fields to update or to insert as needed. 906 * Configuration options should be in an array associated with the 'config' key 907 * this config array should contain 'wf_config_name', 'wf_config_value' and 'wf_config_value_int' keys. 908 * $pId is the processI. If $pId is 0 then we create a new process, else we are in edit mode. 909 * if $create is true start and end activities will be created (when importing use $create=false) 910 * 911 * @param int $pId Process id, if 0 then we create a new process, else we are in edit mode 912 * @param array &$vars Associative containing the fields to update or to insert as needed 913 * @param bool $create If true, start and end activities will be created (when importing use $create=false). 914 * @return int Process id 915 * @access public 916 */ 917 function replace_process($pId, &$vars, $create = true) 918 { 919 if (!(isset($this->activity_manager))) $this->activity_manager = &Factory::newInstance('ActivityManager'); 920 $TABLE_NAME = GALAXIA_TABLE_PREFIX.'processes'; 921 $now = date("U"); 922 $vars['wf_last_modif']=$now; 923 $vars['wf_normalized_name'] = $this->_normalize_name($vars['wf_name'],$vars['wf_version']); 924 $config_array = array(); 925 926 foreach($vars as $key=>$value) 927 { 928 if ($key=='config') 929 { 930 $config_array_init =& $value; 931 // rebuild a nice config_array with type of config and value 932 if( is_array($config_array_init) && count($config_array_init) > 0 ) 933 { 934 foreach($config_array_init as $config) 935 { 936 if (isset($config['wf_config_value_int']) && (!($config['wf_config_value_int']==''))) 937 { 938 $config_array[$config['wf_config_name']] = array('int' => $config['wf_config_value_int']); 939 } 940 else 941 { 942 if (isset($config['wf_config_value'])) 943 { 944 $config_array[$config['wf_config_name']] = array('text' => $config['wf_config_value']); 945 } 946 } 947 } 948 } 949 //no need to keep it in the vars array, this array is used in queries 950 unset($vars['config']); 951 } 952 else // not config, it's just process's fields values 953 { 954 $vars[$key]=addslashes($value); 955 } 956 } 957 958 if($pId) { 959 // update mode 960 $old_proc = $this->get_process($pId); 961 $first = true; 962 $query ="update $TABLE_NAME set"; 963 foreach($vars as $key=>$value) { 964 if(!$first) $query.= ','; 965 if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'"; 966 $query.= " $key=$value "; 967 $first = false; 968 } 969 $query .= " where wf_p_id=$pId "; 970 $this->query($query); 971 972 //set config values 973 $this->setConfigValues($pId,$config_array); 974 975 // Note that if the name is being changed then 976 // the directory has to be renamed! 977 $oldname = $old_proc['wf_normalized_name']; 978 $newname = $vars['wf_normalized_name']; 979 if ($newname != $oldname) { 980 rename(GALAXIA_PROCESSES.SEP."$oldname",GALAXIA_PROCESSES.SEP."$newname"); 981 } 982 $msg = sprintf(tra('Process %s has been updated'),$vars['wf_name']); 983 $this->error[] = $msg; 984 } else { 985 unset($vars['wf_p_id']); 986 // insert mode 987 $name = $this->_normalize_name($vars['wf_name'],$vars['wf_version']); 988 $this->_create_directory_structure($name); 989 $first = true; 990 $query = "insert into $TABLE_NAME("; 991 foreach(array_keys($vars) as $key) { 992 if(!$first) $query.= ','; 993 $query.= "$key"; 994 $first = false; 995 } 996 $query .=") values("; 997 $first = true; 998 foreach(array_values($vars) as $value) { 999 if(!$first) $query.= ','; 1000 if(!is_numeric($value)||strstr($value,'.')) $value="'".$value."'"; 1001 $query.= "$value"; 1002 $first = false; 1003 } 1004 $query .=")"; 1005 $this->query($query); 1006 //FIXME: this query seems to be quite sure to get a result, I would prefer something 1007 // more sure to get the right result everytime 1008 $pId = $this->getOne("select max(wf_p_id) from $TABLE_NAME where wf_last_modif=$now"); 1009 1010 //set config values 1011 $this->setConfigValues($pId,$config_array); 1012 1013 // Now automatically add a start and end activity 1014 // unless importing ($create = false) 1015 if($create) { 1016 $vars1 = Array( 1017 'wf_name' => 'start', 1018 'wf_description' => 'default start activity', 1019 'wf_type' => 'start', 1020 'wf_is_interactive' => 'y', 1021 'wf_is_autorouted' => 'y' 1022 ); 1023 $vars2 = Array( 1024 'wf_name' => 'end', 1025 'wf_description' => 'default end activity', 1026 'wf_type' => 'end', 1027 'wf_is_interactive' => 'n', 1028 'wf_is_autorouted' => 'y' 1029 ); 1030 1031 $this->activity_manager->replace_activity($pId,0,$vars1); 1032 $this->activity_manager->replace_activity($pId,0,$vars2); 1033 } 1034 $msg = sprintf(tra('Process %s has been created'),$vars['wf_name']); 1035 $this->error[] = $msg; 1036 } 1037 // Get the id 1038 return $pId; 1039 } 1040 1041 /** 1042 * Gets the normalized name of a process by pid 1043 * 1044 * @param int $pId Process id 1045 * @access private 1046 * @return string 1047 */ 1048 function _get_normalized_name($pId) 1049 { 1050 $info = $this->get_process($pId); 1051 return $info['wf_normalized_name']; 1052 } 1053 1054 /** 1055 * Normalizes a process name 1056 * 1057 * @param string $name Process name to be normalized 1058 * @param string $version Process version 1059 * @access private 1060 * @return string Process normalized name 1061 */ 1062 function _normalize_name($name, $version) 1063 { 1064 $name = $name.'_'.$version; 1065 $name = str_replace(" ","_",$name); 1066 $name = preg_replace("/[^0-9A-Za-z\_]/",'',$name); 1067 return $name; 1068 } 1069 1070 /** 1071 * Generates a new minor version number 1072 * 1073 * @param string $version Current process version 1074 * @param bool $minor Generate minor version 1075 * @access private 1076 * @return string 1077 */ 1078 function _new_version($version,$minor=true) 1079 { 1080 $parts = explode('.',$version); 1081 if($minor) { 1082 $parts[count($parts)-1]++; 1083 } else { 1084 $parts[0]++; 1085 for ($i = 1; $i < count($parts); $i++) { 1086 $parts[$i] = 0; 1087 } 1088 } 1089 return implode('.',$parts); 1090 } 1091 1092 /** 1093 * Creates directory structure for process 1094 * 1095 * @param string $name Dir name in process repository 1096 * @access private 1097 * @return bool 1098 */ 1099 function _create_directory_structure($name) 1100 { 1101 $path = GALAXIA_PROCESSES.SEP.$name; 1102 if (!file_exists($path)) mkdir($path,0770); 1103 $path = GALAXIA_PROCESSES.SEP.$name.SEP."resources"; 1104 if (!file_exists($path)) mkdir($path,0770); 1105 $path = GALAXIA_PROCESSES.SEP.$name.SEP."graph"; 1106 if (!file_exists($path)) mkdir($path,0770); 1107 $path = GALAXIA_PROCESSES.SEP.$name.SEP."code"; 1108 if (!file_exists($path)) mkdir($path,0770); 1109 $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."activities"; 1110 if (!file_exists($path)) mkdir($path,0770); 1111 $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."templates"; 1112 if (!file_exists($path)) mkdir($path,0770); 1113 $path = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."jobs"; 1114 if (!file_exists($path)) mkdir($path,0770); 1115 $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty"; 1116 if (!file_exists($path)) mkdir($path,0770); 1117 $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."cache"; 1118 if (!file_exists($path)) mkdir($path,0770); 1119 $path = GALAXIA_PROCESSES.SEP.$name.SEP."smarty".SEP."compiled"; 1120 if (!file_exists($path)) mkdir($path,0770); 1121 if (GALAXIA_TEMPLATES) { 1122 $path = GALAXIA_TEMPLATES.SEP.$name; 1123 if (!file_exists($path)) mkdir($path,0770); 1124 } 1125 // Create shared file 1126 $file = GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php"; 1127 if (!file_exists($file)) 1128 { 1129 $fp = fopen(GALAXIA_PROCESSES.SEP.$name.SEP."code".SEP."shared.php","w"); 1130 if (!fp) return false; 1131 fwrite($fp,'<'.'?'.'php'."\n".'?'.'>'); 1132 fclose($fp); 1133 } 1134 } 1135 1136 /** 1137 * Removes a directory recursively 1138 * 1139 * @param string $dir Dir name to be erased 1140 * @param bool $rec Recursive mode 1141 * @access private 1142 * @return void 1143 */ 1144 function _remove_directory($dir,$rec=false) 1145 { 1146 // Prevent a disaster 1147 if(trim($dir) == SEP || trim($dir)=='.' || trim($dir)=='templates' || trim($dir)=='templates'.SEP) return false; 1148 $h = opendir($dir); 1149 while(($file = readdir($h)) != false) { 1150 if(is_file($dir.SEP.$file)) { 1151 @unlink($dir.SEP.$file); 1152 } else { 1153 if($rec && $file != '.' && $file != '..') { 1154 $this->_remove_directory($dir.SEP.$file, true); 1155 } 1156 } 1157 } 1158 closedir($h); 1159 @rmdir($dir); 1160 @unlink($dir); 1161 } 1162 1163 /** 1164 * Copies a directory recursively 1165 * 1166 * @param string $dir1 Dir name to be copied 1167 * @param string $dir2 Generated destination dir 1168 * @access private 1169 * @return void 1170 */ 1171 function _rec_copy($dir1,$dir2) 1172 { 1173 @mkdir($dir2,0777); 1174 $h = opendir($dir1); 1175 while(($file = readdir($h)) !== false) { 1176 if(is_file($dir1.SEP.$file)) { 1177 copy($dir1.SEP.$file,$dir2.SEP.$file); 1178 } else { 1179 if($file != '.' && $file != '..') { 1180 $this->_rec_copy($dir1.SEP.$file, $dir2.SEP.$file); 1181 } 1182 } 1183 } 1184 closedir($h); 1185 } 1186 1187 /** 1188 * XML parser start element handler 1189 * 1190 * @param resource $parser Parser handle 1191 * @param string $element XML tag 1192 * @param array $attribs XML tag attributes 1193 * @access private 1194 * @return void 1195 */ 1196 function _start_element_handler($parser, $element, $attribs) 1197 { 1198 $aux=Array('name'=>$element, 1199 'data'=>'', 1200 'parent' => $this->current, 1201 'children'=>Array(), 1202 'attribs' => $attribs); 1203 1204 $i = count($this->tree); 1205 $this->tree[$i] = $aux; 1206 1207 $this->tree[$this->current]['children'][]=$i; 1208 $this->current=$i; 1209 } 1210 1211 /** 1212 * XML parser end element handler 1213 * 1214 * @param resource $parser Parser handle 1215 * @param string $element XML tag 1216 * @param array $attribs XML tag attributes 1217 * @access private 1218 * @return void 1219 */ 1220 function _end_element_handler($parser, $element) 1221 { 1222 //when a tag ends put text 1223 $this->tree[$this->current]['data']=$this->buffer; 1224 $this->buffer=''; 1225 $this->current=$this->tree[$this->current]['parent']; 1226 } 1227 1228 /** 1229 * XML parser element data handler 1230 * 1231 * @param resource $parser Parser handle 1232 * @param string $element XML tag 1233 * @param string $data XML tag content 1234 * @access private 1235 * @return void 1236 */ 1237 function _data_handler($parser, $data) 1238 { 1239 $this->buffer .= $data; 1240 } 1241 1242 /** 1243 * This getConfigValues differs from the Process::getConfigValues because requires only process id. 1244 * This method gets the items defined in process_config table for this process, in fact this admin function bypass 1245 * the process behaviour and is just showing you the basic content of the table. 1246 * All config items are returned as a function result. 1247 * 1248 * @param int $pId Process id 1249 * @param bool $distinct_types If the distinct_type is set the returned array will follow the format: 1250 * * 0 =>('wf_config_name'=> 'foo') 1251 * =>('wf_config_value'=>'bar') 1252 * =>('wf_config_vale_int'=>null) 1253 * * 1 =>('wf_config_name' => 'toto') 1254 * =>('wf_config_value'=>'') 1255 * =>('wf_config_vale_int'=>15) 1256 * if set to false (default) the result array will be (note that this is the default result if having just the $pId): 1257 * * 'foo'=>'bar' 1258 * * 'toto'=>15 1259 * @param bool $askProcessObject If the askProcessObject is set to true (false by default) then the ProcessManager will load a process 1260 * object to run directly Process->getConfigValues($config_ask_array) this let you use this ProcessManager 1261 * getConfigValues the same way you would use $process->getConfigValues, with initialisation of default values. 1262 * you should then call this function this way: $conf_result=$pm->getConfigValues($pId,true,true,$my_conf_array) 1263 * @param array $config_array 1264 * @access public 1265 * @return array 1266 */ 1267 function getConfigValues($pId, $distinct_types=false, $askProcessObject=false, $config_array=array()) 1268 { 1269 if (!$askProcessObject) 1270 { 1271 $query = 'select * from '.GALAXIA_TABLE_PREFIX.'process_config where wf_p_id=?'; 1272 $result = $this->query($query, array($pId)); 1273 $result_array=array(); 1274 while($res = $result->fetchRow()) 1275 { 1276 if ( (!$distinct_types) ) 1277 {// we want a simple array 1278 if ($res['wf_config_value_int']==null) 1279 { 1280 $result_array[$res['wf_config_name']] = $res['wf_config_value']; 1281 } 1282 else 1283 { 1284 $result_array[$res['wf_config_name']] = $res['wf_config_value_int']; 1285 } 1286 } 1287 else 1288 {// build a more complex result array, which is just the table rows 1289 $result_array[] = $res; 1290 } 1291 } 1292 } 1293 else //we'll load a Process object and let him work for us 1294 { 1295 //Warning: this means you have to include the Process.php from the API 1296 $this->Process = &Factory::newInstance('Process'); 1297 $this->Process->getProcess($pId); 1298 $result_array = $this->Process->getConfigValues($config_array); 1299 unset ($this->Process); 1300 } 1301 return $result_array; 1302 } 1303 1304 /** 1305 * Calls a process object to save his new config values by taking a process Id as first argument and simply call 1306 * this process's setConfigValues method. We let the process define the better way to store the data given as second arg. 1307 * 1308 * @param int $pId Process id 1309 * @param array &$config_array 1310 * @return void 1311 * @access public 1312 */ 1313 function setConfigValues($pId, &$config_array) 1314 { 1315 //Warning: this means you have to include the Process.php from the API 1316 $this->Process = &Factory::newInstance('Process'); 1317 $this->Process->getProcess($pId); 1318 $this->Process->setConfigValues($config_array); 1319 unset ($this->Process); 1320 } 1321 1322 /** 1323 * Gets available agents list 1324 * 1325 * @return array 1326 * @access public 1327 */ 1328 function get_agents() 1329 { 1330 return galaxia_get_agents_list(); 1331 } 1332 1333 /** 1334 * Gets the view activity id avaible for a given process 1335 * 1336 * @param int $pId Process Id 1337 * @return bool False if no view activity is avaible for the process, return the activity id if there is one 1338 * @access public 1339 */ 1340 function get_process_view_activity($pId) 1341 { 1342 $mid = 'where gp.wf_p_id=? and ga.wf_type=?'; 1343 $bindvars = array($pId,'view'); 1344 $query = 'select ga.wf_activity_id 1345 from '.GALAXIA_TABLE_PREFIX.'processes gp 1346 INNER JOIN '.GALAXIA_TABLE_PREFIX."activities ga ON gp.wf_p_id=ga.wf_p_id 1347 $mid"; 1348 $result = $this->query($query,$bindvars); 1349 $ret = Array(); 1350 $retval = false; 1351 if (!(empty($result))) 1352 { 1353 while($res = $result->fetchRow()) 1354 { 1355 $retval = $res['wf_activity_id']; 1356 } 1357 } 1358 return $retval; 1359 } 1371 1360 1372 1361 } -
branches/2.2/workflow/inc/engine/src/ProcessManager/RoleManager.php
r795 r3167 19 19 * @access public 20 20 */ 21 function RoleManager( &$db)22 { 23 parent::Base( $db);21 function RoleManager() 22 { 23 parent::Base(); 24 24 $this->child_name = 'RoleManager'; 25 25 } … … 247 247 $result = $this->query($query,$bindvars); 248 248 $ret = Array(); 249 $ldap = & $GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP');249 $ldap = &Factory::getInstance('WorkflowLDAP'); 250 250 if (!(empty($result))) 251 251 { … … 256 256 //we have a group instead of a simple user and we want real users 257 257 $real_users = galaxia_retrieve_group_users($res['wf_user'], true); 258 foreach ($real_users as $key => $value) 259 { 260 $ret[$key]=$value; 261 } 258 if (!empty($real_users)) { 259 foreach ($real_users as $key => $value) 260 { 261 $ret[$key]=$value; 262 } 263 } 262 264 } 263 265 else
Note: See TracChangeset
for help on using the changeset viewer.