[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 3 require_once(dirname(__FILE__) . SEP . 'class.workflow.inc.php'); 4 5 class run_activity extends workflow 6 { 7 var $public_functions = array( 8 'go' => true, 9 ); 10 11 //Runtime Object from the workflow engine 12 var $runtime; 13 // Activity engine object. This is the object we'll be running to obtain the rigth activity 14 //var $base_activity; 15 //This is the right activity object 16 var $activity; 17 //Process engine object. Used to retrieve at least paths and configuration values 18 var $process; 19 // GUI engine object. Act carefully with it. 20 var $GUI; 21 //a message array 22 var $message = Array(); 23 // a categorie object for categories 24 var $categories; 25 // local process configuration cache 26 var $conf = array(); 27 // local activity template 28 var $wf_template; 29 // The instance object we will manipulate 30 var $instance; 31 var $activity_type; 32 // then we retain all usefull vars as members, to make them avaible in user's source code 33 // theses are data which can be set before the user code and which are not likely to change because of the user code 34 var $db; 35 var $process_id; 36 var $activity_id; 37 var $process_name; 38 var $process_version; 39 var $activity_name; 40 var $user_name; 41 var $view_activity; //activity id of the view activity avaible for this process 42 // theses 4 vars aren't avaible for the user code, they're set only after this user code was executed 43 var $instance_id=0; 44 var $instance_name=''; 45 var $instance_owner=0; 46 var $owner_name=''; 47 // array used by automatic parsing: 48 var $priority_array = Array(); 49 var $submit_array = Array(); 50 // vars used by automatic parsing 51 var $display_owner=0; // if 0 draw nothing, 1 draw selected owner, else draw a select box for owner, see function descr 52 var $display_next_user=0; // if 0 draw nothing, 1 draw selected next user, else draw a select box for next_user, see function descr 53 var $display_history=0; //if 0 draw nothing, 1 draw the history table in the bottom of the screen (ignore use_automatic_parsing config value) 54 //print mode 55 var $print_mode = false; 56 var $enable_print_mode = false; 57 // array of roles associated with the activity, usefull for lists of users associated with theses roles 58 var $act_role_names= Array(); 59 //Array of ui_agent objects 60 var $agents = Array(); 61 62 function run_activity() 63 { 64 parent::workflow(); 65 $this->runtime =& CreateObject('workflow.workflow_wfruntime'); 66 $this->runtime->setDebug(_DEBUG); 67 //$this->base_activity =& CreateObject('workflow.workflow_baseactivity'); 68 //$this->process =& CreateObject('workflow.workflow_process'); 69 $this->GUI =& CreateObject('workflow.workflow_gui'); 70 $this->categories =& CreateObject('phpgwapi.categories'); 71 // TODO: open a new connection to the database under a different username to allow privilege handling on tables 72 $this->db =& $GLOBALS['egw']->ADOdb; 73 } 74 75 /** 76 * * This function is used to run all activities for specified instances. it could be interactive activities 77 * * or automatic activities. this second case is the reason why we return some values 78 * * @param $activityId is the activity_id it run 79 * * @param $iid is the instance id it run for 80 * * @param $auto is true by default 81 * * @return AN ARRAY, or at least true or false. This array can contain : 82 * * a key 'failure' with an error string the engine will retrieve in instance error messages in case of 83 * failure (this will mark your execution as Bad), 84 * * a key 'debug' with a debug string the engine will retrieve in instance error messages, 85 */ 86 function go($activity_id=0, $iid=0, $auto=0) 87 { 88 $result=Array(); 89 90 if ($iid) 91 { 92 $_REQUEST['iid'] = $iid; 93 } 94 $iid = $_REQUEST['iid']; 95 96 //$activity_id is set when we are in auto mode. In interactive mode we get if from POST or GET 97 if (!$activity_id) 98 { 99 $activity_id = (int)get_var('activity_id', array('GET','POST'), 0); 100 } 101 102 // load activity and instance 103 if (!$activity_id) 104 { 105 $result['failure'] = $this->runtime->fail(lang('Cannot run unknown activity'), true, _DEBUG, $auto); 106 return $result; 107 } 108 109 //initalising activity and instance objects inside the WfRuntime object 110 if (!($this->runtime->loadRuntime($activity_id,$iid))) 111 { 112 $result['failure'] = $this->runtime->fail(lang('Cannot run the activity'), true, _DEBUG, $auto); 113 return $result; 114 } 115 116 $activity =& $this->runtime->getActivity($activity_id, true, true); 117 $this->activity =& $activity; 118 // the instance is avaible with $instance or $this->instance 119 // note that for standalone activities this instance can be an empty instance object, but false is a bad value 120 //$this->instance =& $this->runtime->loadInstance($iid); 121 122 // HERE IS A BIG POINT: we map the instance to a runtime object 123 // user code will manipulate a stance, thinking it's an instance, but it is 124 // in fact a WfRuntime object, mapping all instance functions 125 $this->instance =& $this->runtime; 126 $instance =& $this->instance; 127 if (!($instance)) 128 { 129 $result['failure'] = $this->runtime->fail(lang('Cannot run the activity without instance'), true, _DEBUG, $auto); 130 return $result; 131 } 132 $this->instance_id = $instance->getInstanceId(); 133 134 // load process 135 $this->process =& $this->runtime->getProcess(); 136 if (!($this->process)) 137 { 138 $result['failure'] = $this->runtime->fail(lang('Cannot run the activity without her process').$instance, true, _DEBUG, $auto); 139 return $result; 140 } 141 142 //set some global variables needed 143 $GLOBALS['workflow']['__leave_activity']=false; 144 $GLOBALS['user'] = $GLOBALS['egw_info']['user']['account_id']; 145 146 //load role names, just an information 147 $this->act_role_names = $activity->getActivityRoleNames(); 148 149 // load code sources 150 $source = GALAXIA_PROCESSES . SEP . $this->process->getNormalizedName(). SEP . 'compiled' . SEP . $activity->getNormalizedName(). '.php'; 151 //$shared = GALAXIA_PROCESSES . SEP . $this->process->getNormalizedName(). SEP . 'code' . SEP . 'shared.php'; 152 153 // Activities' code will have at their disposition the $db object to handle database interactions 154 // they can access it in 3 ways: $db $this->db or $GLOBALS['workflow']['db'] 155 $db =& $this->db; 156 $GLOBALS['workflow']['db'] =& $this->db; 157 //set some other usefull vars 158 $this->activity_type = $activity->getType(); 159 $this->process_id = $activity->getProcessId(); 160 $this->activity_id = $activity_id; 161 $this->process_name = $this->process->getName(); 162 $this->process_version = $this->process->getVersion(); 163 $this->activity_name = $activity->getName(); 164 $this->user_name = $GLOBALS['egw']->accounts->id2name($GLOBALS['user']); 165 $this->view_activity = $this->GUI->gui_get_process_view_activity($this->process_id); 166 167 //we set them in $GLOBALS['workflow'] as well 168 $GLOBALS['workflow']['wf_activity_type'] =& $this->activity_type; 169 $GLOBALS['workflow']['wf_process_id'] =& $this->process_id; 170 $GLOBALS['workflow']['wf_activity_id'] =& $this->activity_id; 171 $GLOBALS['workflow']['wf_process_name'] =& $this->process_name; 172 $GLOBALS['workflow']['wf_process_version'] =& $this->process_version; 173 $GLOBALS['workflow']['wf_activity_name'] =& $this->activity_name; 174 $GLOBALS['workflow']['wf_user_name'] =& $this->user_name; 175 $GLOBALS['workflow']['wf_view_activity'] =& $this->view_activity; 176 177 //FIXed: useless, we remove it 178 // run the shared code (just in case because each activity is supposed to include it) 179 //include_once($shared); 180 181 // run the activity 182 //interactive section 183 if (!$auto && $activity->isInteractive()) 184 { 185 186 $this->print_mode = get_var('print_mode', array('POST','GET'), false); 187 188 //get configuration options with default values if no init was done before 189 $myconf = array( 190 'display_please_wait_message' => 0, 191 'use_automatic_parsing' => 1, 192 'show_activity_title' => 1, 193 'show_instance_name' => 0, 194 'show_multiple_submit_as_select' => 0, 195 'show_activity_info_zone' => 1, 196 ); 197 //this will give use asked options and som others used by WfRuntime 198 $this->conf =& $this->runtime->getConfigValues($myconf); 199 // if process conf says so we display a please wait message until the activity form is shown 200 if ($this->conf['display_please_wait_message']) 201 { 202 $this->show_wait_message(); 203 } 204 $this->prepare_javascript_submit(); 205 206 if (!($this->print_mode)) 207 { 208 $GLOBALS['egw_info']['flags']['app_header'] = $GLOBALS['egw_info']['apps']['workflow']['title'] . ' - ' . lang('Running Activity'); 209 $GLOBALS['egw']->common->egw_header(); 210 echo parse_navbar(); 211 } 212 else 213 { 214 $GLOBALS['egw_info']['flags'] = array( 215 'noheader' => True, 216 'nonavbar' => True, 217 'currentapp' => 'workflow', 218 'enable_nextmatchs_class' => True 219 ); 220 $GLOBALS['egw_info']['flags']['app_header'] = $GLOBALS['egw_info']['apps']['workflow']['title'] . ' - ' . lang('Running Activity'); 221 $GLOBALS['egw']->common->egw_header(); 222 } 223 224 // activities' code will have at their disposition the $template object to handle the corresponding activity template, 225 // but $GLOBALS['egw']->template will also be available, in case global scope for this is needed 226 // and we have as well the $this->wf_template for the same template 227 $template =& CreateObject('phpgwapi.Template', GALAXIA_PROCESSES.SEP); 228 229 $template->set_file('template', $this->process->getNormalizedName().SEP.'code'.SEP.'templates'.SEP.$activity->getNormalizedName().'.tpl'); 230 $GLOBALS['egw']->template =& $template; 231 $this->wf_template =& $template; 232 233 // They will also have at their disposition theses array, used for automatic parsing 234 $GLOBALS['workflow']['priority_array'] =& $this->priority_array; 235 $GLOBALS['workflow']['submit_array'] =& $this->submit_array; 236 // and some vars for automatic parsing as well 237 $GLOBALS['workflow']['display_owner'] =& $this->display_owner; 238 $GLOBALS['workflow']['display_next_user']=& $this->display_next_user; 239 } 240 //echo "<br><br><br><br><br>Including $source <br>In request: <pre>";print_r($_REQUEST);echo "</pre>"; 241 //[__leave_activity] is setted if needed in the xxx_pre code or by the user in his code 242 // HERE the user code is 'executed'. Note that we do not use include_once or require_once because 243 //it could the same code several times with automatic activities looping in the graph and it still 244 //need to be executed 245 include ($source); 246 //Now that the instance is ready and that user code has maybe change some things 247 // we can catch some others usefull vars 248 $this->instance_id = $instance->getInstanceId(); 249 $this->instance_name = $instance->getName(); 250 $this->instance_owner = $instance->getOwner(); 251 $this->owner_name = $GLOBALS['egw']->accounts->id2name($this->instance_owner); 252 if ($this->owner_name == '') 253 { 254 $this->owner_name = lang('Nobody'); 255 } 256 $GLOBALS['workflow']['wf_instance_id'] =& $this->instance_id; 257 $GLOBALS['workflow']['wf_instance_name']=& $this->instance_name; 258 $GLOBALS['workflow']['wf_instance_owner']=& $this->instance_owner; 259 $GLOBALS['workflow']['wf_owner_name']=& $this->owner_name; 260 261 262 // TODO: process instance comments 263 264 $instructions = $this->runtime->handle_postUserCode(_DEBUG); 265 switch($instructions['action']) 266 { 267 //interactive activity completed 268 case 'completed': 269 // re-retrieve instance data which could have been modified by an automatic activity 270 $this->instance_id = $instance->getInstanceId(); 271 $this->instance_name = $instance->getName(); 272 273 $this->show_common_vars(); 274 // and display completed template 275 $this->show_completed_page($instructions['engine_info']); 276 break; 277 //interactive activity still in interactive mode 278 case 'loop': 279 $this->show_common_vars(); 280 $this->show_form(); 281 break; 282 //nothing more 283 case 'leaving': 284 $this->show_common_vars(); 285 $this->show_leaving_page(); 286 break; 287 //non-interactive activities, auto-mode 288 case 'return': 289 $result=Array(); 290 $this->message[] = $this->GUI->get_error(false, _DEBUG); 291 $this->message[] = $this->runtime->get_error(false, _DEBUG); 292 //$this->message[] = $this->process->get_error(false, _DEBUG); 293 $result =& $instructions['engine_info']; 294 $this->message[] = $result['debug']; 295 $result['debug'] = implode('<br />',array_filter($this->message)); 296 return $result; 297 break; 298 default: 299 return $this->runtime->fail(lang('unknown instruction from the workflow engine: %1', $instructions['action']), true, _DEBUG); 300 break; 301 } 302 } 303 304 function prepare_javascript_submit() 305 { 306 if(!@is_object($GLOBALS['egw']->js)) 307 { 308 $GLOBALS['egw']->js =& CreateObject('phpgwapi.javascript'); 309 } 310 $GLOBALS['egw_info']['flags']['java_script'] .= '<script type="text/javascript"> 311 function confirmSubmit(submit_name,txt_confirm) 312 { 313 if(confirm(txt_confirm)) 314 return true ; 315 else 316 return false; 317 }</script>'; 318 } 319 320 //! show a waiting message using css and script to hide it on onLoad events. 321 /** 322 * You can enable/disable it in process configuration. 323 * Css for the please wait message is defined in app.css, a css automatically included by egroupware 324 */ 325 function show_wait_message() 326 { 327 if(!@is_object($GLOBALS['egw']->js)) 328 { 329 $GLOBALS['egw']->js =& CreateObject('phpgwapi.javascript'); 330 } 331 $please_wait=lang('Please wait, task in progress ...'); 332 $GLOBALS['egw_info']['flags']['java_script'] .= '<script type="text/javascript"> 333 document.write(\'<DIV id="loading"><BR><BR>\'+"'.$please_wait.'" +\'</DIV>\'); 334 function hide_loading() 335 { 336 document.getElementById("loading").style.display="none"; 337 }</script>'; 338 $GLOBALS['egw']->js->set_onload('hide_loading();'); 339 } 340 341 //! show the page avaible when completing an activity 342 function show_completed_page(&$infos) 343 { 344 $this->t->set_file('activity_completed', 'activity_completed.tpl'); 345 $this->t->set_block('activity_completed', 'report_row', 'rowreport'); 346 //build an icon array for show_engine_infos 347 $icon_array = Array(); 348 349 $icon_array['ok'] = '<img src="'.$GLOBALS['egw']->common->image('workflow', 'check').'">'; 350 $icon_array['failure'] = '<img src="'.$GLOBALS['egw']->common->image('workflow', 'stop').'">'; 351 $icon_array['transition'] = '<img src="'.$GLOBALS['egw']->common->image('workflow', 'transition').'">'; 352 $icon_array['transition_human'] = '<img src="'.$GLOBALS['egw']->common->image('workflow', 'transition_human').'">'; 353 $icon_array['activity'] = '<img src="'.$GLOBALS['egw']->common->image('workflow', 'auto_activity').'">'; 354 $icon_array['dot'] = '<img src="'.$GLOBALS['egw']->common->image('workflow', 'puce').'"> '; 355 $this->show_engine_infos($infos, $icon_array); 356 $this->t->set_var(array( 357 'wf_procname' => $this->process_name, 358 'procversion' => $this->process_version, 359 'actname' => $this->activity_name, 360 'rowreport' => '', 361 )); 362 363 $this->translate_template('activity_completed'); 364 $this->t->pparse('output', 'activity_completed'); 365 $this->show_after_running_page(); 366 } 367 368 function show_engine_infos(&$infos, &$icon_array, $level=0) 369 { 370 //_debug_array($infos); 371 if (!(is_array($infos))) 372 { 373 return ; 374 } 375 foreach ($infos as $infoitem => $content) 376 { 377 if (is_int($infoitem)) //splitting! 378 { 379 //recursive call with level increment 380 $this->show_engine_infos($content, $icon_array,$level+1); 381 } 382 else 383 { 384 switch($infoitem) 385 { 386 case 'transition': 387 $icon_type = $icon_array['transition']; 388 if (isset($content['failure'])) 389 { 390 $icon = $icon_array['failure']; 391 $comment = lang('failure').'<br />'.$content['failure']; 392 if (isset($content['target_name'])) 393 { 394 $report = str_repeat($icon_array['dot'], $level).lang('transition to %1', $content['target_name']); 395 } 396 else 397 { 398 $report = str_repeat($icon_array['dot'], $level).lang('transition'); 399 } 400 } 401 else 402 { 403 if ($content['status']=='not autorouted') 404 { 405 $icon_type = $icon_array['transition_human']; 406 $icon = ' '; 407 $report = str_repeat($icon_array['dot'], $level).lang('transition waiting for human interaction'); 408 $comment = lang('no routage').'<br />'; 409 } 410 else 411 { 412 if ($content['status']=='waiting') 413 { 414 $comment = lang('activity is waiting for pending transitions').'<br />'; 415 } 416 else 417 { 418 $comment = ''; 419 } 420 $icon = $icon_array['ok']; 421 $report = str_repeat($icon_array['dot'], $level).lang('transition to %1', $content['target_name']); 422 } 423 $comment .= $content['debug']; 424 } 425 $this->t->set_var(array( 426 'icon_type_report' => $icon_type, 427 'icon_report' => $icon, 428 'label_report' => $report, 429 'comment_report' => $comment, 430 'row_class' => $this->nextmatchs->alternate_row_color($tr_color, true), 431 )); 432 $this->t->parse('report','report_row', true); 433 break; 434 case 'activity': 435 $icon_type = $icon_array['activity']; 436 if (isset($content['failure'])) 437 { 438 $icon = $icon_array['failure']; 439 $report = str_repeat($icon_array['dot'], $level).lang('activity failure'); 440 if (isset($content['info'])) 441 { 442 $comment = $content['info']['activity_name'].'<br />'.$content['failure']; 443 } 444 else 445 { 446 $comment = $content['failure']; 447 } 448 } 449 else 450 { 451 if (isset($content['completed'])) 452 { 453 $icon = $icon_array['ok']; 454 $report = str_repeat($icon_array['dot'], $level).lang('activity completed'); 455 } 456 else 457 { 458 459 $icon = $icon_array['failure']; 460 $report = str_repeat($icon_array['dot'], $level).lang('activity failure'); 461 } 462 if (isset($content['info'])) 463 { 464 $comment = $content['info']['activity_name']; 465 } 466 else 467 { 468 $comment = ''; 469 } 470 } 471 $this->t->set_var(array( 472 'icon_type_report' => $icon_type, 473 'icon_report' => $icon, 474 'label_report' => $report, 475 'comment_report' => $comment, 476 'row_class' => $this->nextmatchs->alternate_row_color($tr_color, true), 477 )); 478 $this->t->parse('report','report_row', true); 479 if (isset($content['next'])) 480 { 481 //recursive call 482 $this->show_engine_infos($content['next'], $icon_array,$level); 483 } 484 break; 485 } 486 } 487 } 488 489 } 490 491 //! show the common variable of interactive forms (like messages) 492 function show_common_vars() 493 { 494 $this->message[] = $this->GUI->get_error(false, _DEBUG); 495 $this->message[] = $this->runtime->get_error(false, _DEBUG); 496 $this->t->set_var(array( 497 'wf_message' => implode('<br />',array_filter($this->message)), 498 ) 499 ); 500 } 501 502 //! show the page avaible when leaving an activity (with a Cancel or Quit button) 503 function show_leaving_page() 504 { 505 $this->t->set_file('leaving_activity', 'leaving_activity.tpl'); 506 $this->t->set_var(array( 507 'wf_procname' => $this->process_name, 508 'procversion' => $this->process_version, 509 'actname' => $this->activity_name, 510 )); 511 512 //check real avaible actions on this instance 513 //we assume user is not in read-only mode, if he were actions would be blocked anyway, and he should not come 514 //here with a read-only right 515 $actions = $this->GUI->getUserActions($GLOBALS['user'],$this->instance_id,$this->activity_id, false); 516 if (isset($actions['release'])) 517 {//we can release, it means we were not in auto-release mode 518 //prepare a release command on the user_instance form 519 $link_array = array( 520 'menuaction' => 'workflow.ui_userinstances.form', 521 'filter_process' => $this->process_id, 522 'filter_instance' => $this->instance_id, 523 'iid' => $this->instance_id, 524 'aid' => $this->activity_id, 525 'release' => 1, 526 ); 527 $releasetxt = lang('release activity for this instance'); 528 $this->t->set_var(array( 529 'release_text' => lang('This activity for this instance is actually only avaible for you.'), 530 'release_button'=> '<a href="'.$GLOBALS['egw']->link('/index.php',$link_array) 531 .'"><img src="'. $GLOBALS['egw']->common->image('workflow', 'fix') 532 .'" alt="'.$releasetxt.'" title="'.$releasetxt.'" width="16" >' 533 .$releasetxt.'</a>', 534 )); 535 } 536 else 537 {//we cannot release, 3 reasons 538 // * already done in auto-release 539 // * standalone or view activity 540 // * multi-user concurrency problem moved some engine objects in other states 541 $this->t->set_var(array( 542 'release_text' => lang('This activity for this instance is not specifically assigned to you.'), 543 'release_button'=> '', 544 )); 545 546 } 547 $this->translate_template('leaving_activity'); 548 $this->t->pparse('output', 'leaving_activity'); 549 $this->show_after_running_page(); 550 } 551 552 //! show the bottom of end run_activity interactive pages with links to user_instance form 553 /** 554 * for start activities we link back to user_openinstance form 555 * and for standalone activities we loop back to global activities form 556 */ 557 function show_after_running_page() 558 { 559 $this->t->set_file('after_running', 'after_running.tpl'); 560 561 //prepare the links form 562 $link_data_proc = array( 563 'menuaction' => 'workflow.ui_userinstances.form', 564 'filter_process' => $this->process_id, 565 ); 566 $link_data_inst = array( 567 'menuaction' => 'workflow.ui_userinstances.form', 568 'filter_instance' => $this->instance_id, 569 ); 570 if ($this->activity_type == 'start') 571 { 572 $activitytxt = lang('get back to instance creation'); 573 $act_button_name = lang('New instance'); 574 $link_data_act = array( 575 'menuaction' => 'workflow.ui_useropeninstance.form', 576 ); 577 } 578 elseif ($this->activity_type == 'standalone') 579 { 580 $activitytxt = lang('get back to global activities'); 581 $act_button_name = lang('Global activities'); 582 $link_data_act = array( 583 'menuaction' => 'workflow.ui_useractivities.form', 584 'show_globals' => true, 585 ); 586 } 587 else 588 { 589 $activitytxt = lang('go to same activities for other instances of this process'); 590 $act_button_name = lang('activity %1', $this->activity_name); 591 $link_data_act = array( 592 'menuaction' => 'workflow.ui_userinstances.form', 593 'filter_process' => $this->process_id, 594 'filter_activity_name' => $this->activity_name, 595 ); 596 } 597 $button='<img src="'. $GLOBALS['egw']->common->image('workflow', 'next') 598 .'" alt="'.lang('go').'" title="'.lang('go').'" width="16" >'; 599 $this->t->set_var(array( 600 'same_instance_text' => ($this->activity_type=='standalone')? '-' : lang('go to the actual state of this instance'), 601 'same_activities_text' => $activitytxt, 602 'same_process_text' => lang('go to same process activities'), 603 'same_instance_button' => ($this->activity_type=='standalone')? '-' : '<a href="'.$GLOBALS['egw']->link('/index.php',$link_data_inst).'">' 604 .$button.lang('instance %1', ($this->instance_name=='')? $this->instance_id: $this->instance_name).'</a>', 605 'same_activities_button'=> '<a href="'.$GLOBALS['egw']->link('/index.php',$link_data_act).'">' 606 .$button.$act_button_name.'</a>', 607 'same_process_button' => '<a href="'.$GLOBALS['egw']->link('/index.php',$link_data_proc).'">' 608 .$button.lang('process %1', $this->process_name).'</a>', 609 )); 610 $this->translate_template('after_running'); 611 $this->t->pparse('output', 'after_running'); 612 $GLOBALS['egw']->common->egw_footer(); 613 } 614 615 //! show the activity form with automated parts if needed 616 function show_form() 617 { 618 //set a global template for interactive activities 619 $this->t->set_file('run_activity','run_activity.tpl'); 620 621 //set the css style files links 622 $this->t->set_var(array( 623 'run_activity_css_link' => $this->get_css_link('run_activity', $this->print_mode), 624 'run_activity_print_css_link' => $this->get_css_link('run_activity', true), 625 )); 626 627 628 // draw the activity's title zone 629 $this->parse_title($this->activity_name); 630 631 //draw the instance_name input or label 632 // init wf_name to the requested one or the stored name 633 // the requested one handle the looping in activity form 634 635 $wf_name = get_var('wf_name','post',$this->instance->getName()); 636 $this->parse_instance_name($wf_name); 637 638 //draw the instance_name input or label 639 // init wf_set_owner to the requested one or the stored owner 640 // the requested one handle the looping in activity form 641 $wf_set_owner = get_var('wf_set_owner','post',$this->instance->getOwner()); 642 $this->parse_instance_owner($wf_set_owner); 643 644 // draw the activity central user form 645 $this->t->set_var(array('activity_template' => $this->wf_template->parse('output', 'template'))); 646 647 //draw the select priority box 648 // init priority to the requested one or the stored priority 649 // the requested one handle the looping in activity form 650 $priority = get_var('wf_priority','post',$this->instance->getPriority()); 651 $this->parse_priority($priority); 652 653 //draw the select next_user box 654 // init next_user to the requested one or the stored one 655 // the requested one handle the looping in activity form 656 $next_user = get_var('wf_next_user','POST',$this->instance->getNextUser()); 657 $this->parse_next_user($next_user); 658 659 //draw print_mode buttons 660 $this->parse_print_mode_buttons(); 661 662 //draw the activity submit buttons 663 $this->parse_submit(); 664 665 //draw the info zone 666 $this->parse_info_zone(); 667 668 //draw the history zone if user wanted it 669 $this->parse_history_zone(); 670 671 $this->translate_template('run_activity'); 672 $this->t->pparse('output', 'run_activity'); 673 $GLOBALS['egw']->common->egw_footer(); 674 } 675 676 677 /** 678 * * Draw a 'print mode' or 'back to normal mode' button if $this->print_mode is not false 679 * * and if $this->enable_print_mode is true 680 */ 681 function parse_print_mode_buttons() 682 { 683 $this->t->set_block('run_activity', 'block_print_mode_zone', 'print_mode_zone'); 684 685 if (($this->conf['use_automatic_parsing']) && ($this->enable_print_mode)) 686 { 687 if ($this->print_mode) 688 { 689 $this->t->set_var(array( 690 'print_mode_value' => lang('Close Printer friendly mode'), 691 'print_mode_name' => 'not_print_mode', 692 )); 693 } 694 else 695 { 696 $this->t->set_var(array( 697 'print_mode_value' => lang('Printer friendly'), 698 'print_mode_name' => 'print_mode', 699 )); 700 } 701 $this->t->parse('print_mode_zone', 'block_print_mode_zone', true); 702 } 703 else 704 { 705 $this->t->set_var(array( 'print_mode_zone' => '')); 706 } 707 } 708 709 //!Parse the title in the activity form, the user can decide if he want this title to be shown or not 710 /** 711 * * if you do not want thuis to be displayed set your process config value for show_activity_title to false 712 * * @param title is by default empty, You can give a title as a parameter. 713 */ 714 function parse_title($title='') 715 { 716 $this->t->set_block('run_activity', 'block_title_zone', 'title_zone'); 717 718 if (($this->conf['use_automatic_parsing']) && ($this->conf['show_activity_title'])) 719 { 720 $this->t->set_var(array('activity_title'=> $title)); 721 $this->t->parse('title_zone', 'block_title_zone', true); 722 } 723 else 724 { 725 $this->t->set_var(array( 'title_zone' => '')); 726 } 727 } 728 729 //!Parse the instance name input in the activity form, the user can decide if he want this name to be shown or not 730 /** 731 * * if you do not want this to be displayed set your process config value for show_instance_name to false 732 * * @param instance_name is the name we will display. 733 */ 734 function parse_instance_name($instance_name) 735 { 736 $this->t->set_block('run_activity', 'block_instance_name_zone', 'instance_name_zone'); 737 738 if (($this->conf['use_automatic_parsing']) && ($this->conf['show_instance_name'])) 739 { 740 $this->t->set_var(array('wf_name'=> $instance_name)); 741 $this->t->parse('instance_name_zone', 'block_instance_name_zone', true); 742 } 743 else 744 { 745 $this->t->set_var(array( 'instance_name_zone' => '')); 746 } 747 } 748 749 //!Parse the set_owner select/display in the activity form, the user can decide if he want this name to be shown or not 750 /** 751 * * if $this->display_owner is 0 we draw nothing (default value) 752 * * if $this->display_owner is 1 the owner is just shown 753 * * if $this->display_owner is anything else we draw a select box 754 * * this 'anything else' can be an associative array containing the 'role' and/or 'activity' key 755 * * the values associated with theses keys can be strings or array of strings containing roles and/or 756 * * activities's names. Users displayed in the select will then be the users having access to theses activities 757 * * and users which are mapped to theses roles (one match per user is enought to be displayed). 758 * * ie: $this->display_owner = 2; will display all users mapped to roles on the process 759 * * $this->display_owner = array('role' => array('Chiefs','assistant'), 'activity' => 'updating foo'); will 760 * * display users having access to activity 'updating foo' AND which are mapped to 'Chief' OR 'assistant' roles 761 * * of course roles and activities names must be matching the current process's roles and activities names. 762 * * @param actual_owner is the selected owner in the select list we will display or the shown owner. 763 */ 764 function parse_instance_owner($actual_owner) 765 { 766 //inside the select 767 $this->t->set_block('run_activity', 'block_owner_options', 'owner_options'); 768 //the select 769 $this->t->set_block('run_activity', 'block_select_owner', 'wf_select_owner'); 770 // the whole area 771 $this->t->set_block('run_activity', 'block_set_owner_zone', 'set_owner_zone'); 772 if ( (!$this->conf['use_automatic_parsing']) 773 || ( empty($this->display_owner) || (!($this->display_owner)) )) 774 { 775 //hide the instance owner zone 776 $this->t->set_var(array( 'set_owner_zone' => '')); 777 } 778 else 779 { 780 // a little label before the select box 781 $this->t->set_var(array('set_owner_text' => lang('Owner:'))); 782 if ((!(is_array($this->display_owner))) && ($this->display_owner==1)) 783 { 784 //we will just display the owner 785 $this->t->set_var(array('wf_select_owner' => $this->owner_name)); 786 } 787 else 788 { //we will display a select 789 790 //prepare retrieval of datas 791 $subset=Array(); 792 if (is_array($this->display_owner)) 793 { 794 foreach($this->display_owner as $key => $value) 795 { 796 if ($key=='role') 797 { 798 if (!(is_array($value))) 799 { 800 $value = explode(';',$value); 801 } 802 $subset[wf_role_name]= $value; 803 } 804 elseif ($key=='activity') 805 { 806 if (!(is_array($value))) 807 { 808 $value = explode(';',$value); 809 } 810 $subset[wf_activity_name]= $value; 811 } 812 } 813 } 814 //we'll ask the role_manager for it 815 $role_manager =& CreateObject('workflow.workflow_rolemanager'); 816 // we expand groups to real users and want users mapped for a subset of the process 817 // which is given by a user defined value 818 $authorized_users = $role_manager->list_mapped_users($this->process_id, true, $subset ); 819 //first line of the select 820 $this->t->set_var(array( 821 'selected_owner_options_default'=> (!!$actual_owner)? 'selected="selected"' :'', 822 'lang_default_owner' => lang('Default owner'), 823 )); 824 //other lines 825 foreach ($authorized_users as $user_id => $user_name) 826 { 827 $this->t->set_var(array( 828 'owner_option_id' => $user_id, 829 'owner_option_value' => $user_name, 830 'selected_owner_options' => ($user_id == $actual_owner)? 'selected="selected"' :'', 831 )); 832 //show the select line 833 $this->t->parse('owner_options','block_owner_options',true); 834 } 835 //show the select 836 $this->t->parse('wf_select_owner','block_select_owner',true); 837 } 838 //show the set owner zone 839 $this->t->parse('set_owner_zone', 'block_set_owner_zone', true); 840 } 841 } 842 843 //! Draw the priority select box in the activity form 844 /** 845 * * Parse the priority select box in the activity form. The user can decide if he want this select box to be shown or not 846 * * by completing $this->priority_array. 847 * * For example like that : $this->priority_array = array(1 => '1-Low',2 =>'2', 3 => '3-High'); 848 * * If the array is empty or the conf values says the user does not want automatic parsing no select box will be shown 849 * * @param actual_priority is by default at 1 and will be the selected activity level. 850 */ 851 function parse_priority($actual_priority=1) 852 { 853 $this->t->set_block('run_activity', 'block_priority_options', 'priority_options'); 854 $this->t->set_block('run_activity', 'block_priority_zone', 'priority_zone'); 855 if ((!$this->conf['use_automatic_parsing']) || (count($this->priority_array)==0)) 856 { 857 //hide the priority zone 858 $this->t->set_var(array( 'priority_zone' => '')); 859 } 860 else 861 { 862 if (!is_array($this->priority_array)) 863 { 864 $this->priority_array = explode(" ",$this->priority_array); 865 } 866 //handling the select box 867 foreach ($this->priority_array as $priority_level => $priority_label) 868 { 869 $this->t->set_var(array( 870 'priority_option_name' => $priority_level, 871 'priority_option_value' => $priority_label, 872 'selected_priority_options' => ($priority_level == $actual_priority)? 'selected="selected"' :'', 873 )); 874 //show the select box 875 $this->t->parse('priority_options','block_priority_options',true); 876 } 877 // a little label before the select box 878 $this->t->set_var(array('Priority_text' => lang('Priority level:'))); 879 //show the priority zone 880 $this->t->parse('priority_zone', 'block_priority_zone', true); 881 } 882 } 883 884 //!Parse the next_user select/display in the activity form, the user can decide if he want this to be shown or not 885 /** 886 * * if $this->display_next_user is 0 we draw nothing (default value) 887 * * if $this->display_next_user is 1 the next_user is just shown 888 * * if $this->display_next_user is anything else we draw a select box 889 * * this 'anything else' can be an associative array containing the 'role' and/or 'activity' key 890 * * the values associated with theses keys can be strings or array of strings containing roles and/or 891 * * activities's names. Users displayed in the select will then be the users having access to theses activities 892 * * and users which are mapped to theses roles (one match per user is enought to be displayed). 893 * * ie: $this->display_next_user = 2; will display all users mapped to roles on the process 894 * * $this->display_next_user = array('role' => array('Chiefs','assistant'), 'activity' => 'updating foo'); will 895 * * display users having access to activity 'updating foo' AND which are mapped to 'Chief' OR 'assistant' roles 896 * * of course roles and activities names must be matching the current process's roles and activities names. 897 * * @param actual_next_user is the selected next_user in the select list we will display or the shown next_user. 898 */ 899 function parse_next_user($actual_next_user) 900 { 901 //echo "DEBUG parse_instance_next_user:actual_next_user:".$actual_next_user.'display_next_user:' 902 //_debug_array($this->display_next_user); 903 904 //inside the select 905 $this->t->set_block('run_activity', 'block_next_user_options', 'next_user_options'); 906 //the select 907 $this->t->set_block('run_activity', 'block_select_next_user', 'wf_select_next_user'); 908 // the whole area 909 $this->t->set_block('run_activity', 'block_set_next_user_zone', 'set_next_user_zone'); 910 if ( (!$this->conf['use_automatic_parsing']) 911 || ( empty($this->display_next_user) || (!($this->display_next_user)) )) 912 { 913 //hide the instance next_user zone 914 $this->t->set_var(array( 'set_next_user_zone' => '')); 915 } 916 else 917 { 918 // a little label before the select box 919 $this->t->set_var(array('set_next_user_text' => lang('Next user:'))); 920 if ((!(is_array($this->display_next_user))) && ($this->display_next_user==1)) 921 { 922 //we will just display the next_user 923 $next_user_name = $GLOBALS['egw']->accounts->id2name($actual_next_user); 924 if ($next_user_name == '') 925 { 926 $next_user_name = lang('not defined'); 927 } 928 $this->t->set_var(array('wf_select_next_user' => $next_user_name)); 929 } 930 else 931 { //we will display a select 932 933 //prepare retrieval of datas 934 $subset=Array(); 935 if (is_array($this->display_next_user)) 936 { 937 foreach($this->display_next_user as $key => $value) 938 { 939 if ($key=='role') 940 { 941 if (!(is_array($value))) 942 { 943 $value = explode(';',$value); 944 } 945 $subset[wf_role_name]= $value; 946 } 947 elseif ($key=='activity') 948 { 949 if (!(is_array($value))) 950 { 951 $value = explode(';',$value); 952 } 953 $subset[wf_activity_name]= $value; 954 } 955 } 956 } 957 //we'll ask the role_manager for it 958 $role_manager =& CreateObject('workflow.workflow_rolemanager'); 959 // we expand groups to real users and want users mapped for a subset of the process 960 // which is given by a user defined value 961 $authorized_users = $role_manager->list_mapped_users($this->process_id, true, $subset ); 962 //first line of the select 963 $this->t->set_var(array( 964 'selected_next_user_options_default'=> (!!$actual_next_user)? 'selected="selected"' :'', 965 'lang_default_next_user' => lang('Default next user'), 966 )); 967 //other lines 968 foreach ($authorized_users as $user_id => $user_name) 969 { 970 $this->t->set_var(array( 971 'next_user_option_id' => $user_id, 972 'next_user_option_value' => $user_name, 973 'selected_next_user_options' => ($user_id == $actual_next_user)? 'selected="selected"' :'', 974 )); 975 //show the select line 976 $this->t->parse('next_user_options','block_next_user_options',true); 977 } 978 //show the select 979 $this->t->parse('wf_select_next_user','block_select_next_user',true); 980 } 981 //show the set next_user zone 982 $this->t->parse('set_next_user_zone', 'block_set_next_user_zone', true); 983 } 984 } 985 986 //! Draw the submit buttons on the activity form 987 /** 988 * In this function we'll draw the command buttons asked for this activity. 989 * else we'll check $this->submit_array which should be completed in the activity source 990 * and is an array with the names of the submit options corresponding to the value like this: 991 * $this->submit_array['the_value_you_want']=lang('the label you want'); 992 * if this array is empty we'll draw a simple submit button. 993 * The poweruser can decide to handle theses buttons in his own way in the config section 994 * He'll then have to draw it himself in his activity template. 995 * Note that the special value '__Cancel' is automatically handled and set the ['__leaving_activity'] 996 * var to true. 997 */ 998 function parse_submit() 999 { 1000 //inside the select box for submits 1001 $this->t->set_block('run_activity', 'block_submit_options', 'submit_options'); 1002 //the select submit box 1003 $this->t->set_block('run_activity', 'block_submit_select_area', 'submit_select_area'); 1004 //submit as buttons 1005 $this->t->set_block('run_activity', 'block_submit_buttons_area', 'submit_buttons_area'); 1006 //the whole zone 1007 $this->t->set_block('run_activity', 'block_submit_zone', 'submit_zone'); 1008 1009 if (!($this->conf['use_automatic_parsing'])) 1010 { 1011 // the user decided he'll do it his own way 1012 //empty the whole zone 1013 $this->t->set_var(array('submit_zone' => '')); 1014 } 1015 else 1016 { 1017 $buttons = ''; 1018 if (count($this->submit_array)==0) 1019 { 1020 //the user didn't give us any instruction 1021 // we draw a simple submit button 1022 $this->t->set_var(array('submit_area','')); 1023 $buttons .= '<td class="wf_submit_buttons_button">'; 1024 $buttons .= '<input name="wf_submit" type="submit" value="'.lang('Submit').'"/>'; 1025 $buttons .= '</td>'; 1026 //set the buttons 1027 $this->t->set_var(array('submit_buttons' => $buttons)); 1028 // hide the select box zone 1029 $this->t->set_var(array('submit_select_area'=> '')); 1030 //show the buttons zone 1031 $this->t->parse('submit_buttons_area', 'block_submit_buttons_area', true); 1032 1033 } 1034 else 1035 { 1036 //now we have another user choice. he can choose multiple submit buttons 1037 //or a select with only one submit 1038 if ( ($this->conf['show_multiple_submit_as_select']) && (count($this->submit_array) > 1) ) 1039 { 1040 //multiple submits in a select box 1041 //handling the select box 1042 foreach ($this->submit_array as $submit_button_name => $submit_button_value) 1043 { 1044 $this->t->set_var(array( 1045 'submit_option_value' => $submit_button_value, 1046 'submit_option_name' => $submit_button_name, 1047 )); 1048 1049 //show the select box 1050 $this->t->parse('submit_options','block_submit_options',true); 1051 } 1052 //we need at least one submit button 1053 $this->t->set_var(array( 1054 'submit_button_name' => 'wf_submit', 1055 'submit_button_value' => lang('submit'), 1056 )); 1057 // hide the multiple buttons zone 1058 $this->t->set_var(array('submit_buttons_area'=> '')); 1059 //show the select box zone 1060 $this->t->parse('submit_select_area', 'block_submit_select_area', true); 1061 } 1062 else 1063 { 1064 //multiple buttons with no select box or just one 1065 //draw input button for each entry 1066 foreach ($this->submit_array as $submit_button_name => $submit_button_value) 1067 { 1068 //now we can have some special options, like jscode 1069 if (is_array($submit_button_value)) 1070 { 1071 $button_val = $submit_button_value['label']; 1072 $confirm = $submit_button_value['confirm']; 1073 1074 } 1075 else 1076 { 1077 $button_val = $submit_button_value; 1078 $confirm = false; 1079 } 1080 $buttons .= '<td class="wf_submit_buttons_button">'; 1081 $buttons .= '<input name="'.$submit_button_name.'" type="submit" value="'.$button_val.'" '; 1082 if (!!($confirm)) 1083 { 1084 $buttons .= 'onClick="return confirmSubmit(\''.$submit_button_name.'\',\''.$confirm.'\')"/>'; 1085 } 1086 else 1087 { 1088 $buttons .= '/>'; 1089 } 1090 $buttons .= '</td>'; 1091 } 1092 //set the buttons 1093 $this->t->set_var(array('submit_buttons' => $buttons)); 1094 // hide the select box zone 1095 $this->t->set_var(array('submit_select_area'=> '')); 1096 //show the buttons zone 1097 $this->t->parse('submit_buttons_area', 'block_submit_buttons_area', true); 1098 } 1099 } 1100 //show the whole submit zone 1101 $this->t->parse('submit_zone', 'block_submit_zone', true); 1102 } 1103 } 1104 1105 //!Parse the activity info zone in the activity form, the user can decide if he want it or not 1106 function parse_info_zone() 1107 { 1108 $this->t->set_block('run_activity', 'workflow_info_zone', 'info_zone'); 1109 1110 if (($this->conf['use_automatic_parsing']) && ($this->conf['show_activity_info_zone'])) 1111 { 1112 $this->t->set_var(array( 1113 'wf_process_name' => $this->process_name, 1114 'wf_process_version' => $this->process_version, 1115 'wf_instance_id' => $this->instance_id, 1116 'wf_instance_name' => $this->instance_name, 1117 'wf_owner' => $this->owner_name, 1118 'wf_activity_name' => $this->activity_name, 1119 'wf_user_name' => $this->user_name, 1120 'wf_started' => $GLOBALS['egw']->common->show_date($this->instance->getStarted()), 1121 'wf_date' => $GLOBALS['egw']->common->show_date(), 1122 )); 1123 $this->translate_template('workflow_info_zone'); 1124 $this->t->parse('info_zone', 'workflow_info_zone', true); 1125 } 1126 else 1127 { 1128 $this->t->set_var(array( 'info_zone' => '')); 1129 } 1130 } 1131 1132 //!Parse the history zone in the activity form, the user can decide if he want this name to be shown or not 1133 /** 1134 * * if $this->display_history is 0 we draw nothing (default value) 1135 * * 1136 * * if $this->display_history is 1 we draw the history table 1137 * * this function does not test the use_automatic_parsing configuration value 1138 */ 1139 function parse_history_zone() 1140 { 1141 if ( (empty($this->display_history)) || (!($this->display_history))) 1142 { 1143 //hide the history zone 1144 $this->t->set_var(array( 'history' => '')); 1145 } 1146 else 1147 { 1148 $inst_parser =& CreateObject('workflow.bo_uiinstance', $this->t); 1149 $inst_parser->t =& $this->t; 1150 $inst_parser->parse_instance_history($this->instance->workitems); 1151 $this->t->set_var('history', $this->t->parse('output', 'history_tpl')); 1152 } 1153 } 1154 1155 } 1156 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |