[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 /**************************************************************************\ 3 * eGroupWare - ProjectManager - Ganttchart creation * 4 * http://www.egroupware.org * 5 * Written and (c) 2005 by Ralf Becker <RalfBecker@outdoor-training.de> * 6 * -------------------------------------------- * 7 * This program is free software; you can redistribute it and/or modify it * 8 * under the terms of the GNU General Public License as published by the * 9 * Free Software Foundation; either version 2 of the License, or (at your * 10 * option) any later version. * 11 \**************************************************************************/ 12 13 /* $Id: class.ganttchart.inc.php 22989 2006-12-12 14:07:25Z ralfbecker $ */ 14 15 include_once (EGW_INCLUDE_ROOT.'/projectmanager/inc/class.boprojectelements.inc.php'); 16 17 // JPGraph does not work, if that got somehow set, so unset it 18 if (isset($GLOBALS['php_errormsg'])) { unset ($GLOBALS['php_errormsg']); } 19 20 // check if the admin installed a recent JPGraph parallel to eGroupWare 21 if(file_exists(EGW_SERVER_ROOT . '/../jpgraph/src/jpgraph.php')) 22 { 23 // using the OS font dir if we can find it, otherwise fall back to our bundled Vera font 24 foreach(array( 25 '/usr/X11R6/lib/X11/fonts/truetype/', // linux / *nix default 26 'C:/windows/fonts/', // windows default 27 // add your location here ... 28 EGW_SERVER_ROOT.'/projectmanager/inc/ttf-bitstream-vera-1.10/', // our bundled Vera font 29 ) as $dir) 30 { 31 if (@is_dir($dir) && (is_readable($dir.'arial.ttf') || is_readable($dir.'Vera.ttf'))) 32 { 33 define('TTF_DIR',$dir); 34 unset($dir); 35 break; 36 } 37 } 38 include(EGW_SERVER_ROOT . '/../jpgraph/src/jpgraph.php'); 39 include(EGW_SERVER_ROOT . '/../jpgraph/src/jpgraph_gantt.php'); 40 } 41 else 42 { 43 include (EGW_SERVER_ROOT . '/projectmanager/inc/jpgraph-1.5.2/src/jpgraph.php'); 44 include (EGW_SERVER_ROOT . '/projectmanager/inc/jpgraph-1.5.2/src/jpgraph_gantt.php'); 45 define('TTF_DIR',EGW_SERVER_ROOT.'/projectmanager/inc/ttf-bitstream-vera-1.10/'); 46 } 47 48 // some constanst for pre php4.3 49 if (!defined('PHP_SHLIB_SUFFIX')) 50 { 51 define('PHP_SHLIB_SUFFIX',strtoupper(substr(PHP_OS, 0,3)) == 'WIN' ? 'dll' : 'so'); 52 } 53 if (!defined('PHP_SHLIB_PREFIX')) 54 { 55 define('PHP_SHLIB_PREFIX',PHP_SHLIB_SUFFIX == 'dll' ? 'php_' : ''); 56 } 57 58 /** 59 * ProjectManager: Ganttchart creation 60 * 61 * @package projectmanager 62 * @author RalfBecker-AT-outdoor-training.de 63 * @copyright (c) 2005 by RalfBecker-AT-outdoor-training.de 64 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License 65 */ 66 class ganttchart extends boprojectelements 67 { 68 /** 69 * @var array $public_functions Functions to call via menuaction 70 */ 71 var $public_functions = array( 72 'create' => true, 73 'show' => true, 74 ); 75 /** 76 * true if JPGraph version > 1.13 77 * 78 * @var boolean 79 */ 80 var $modernJPGraph; 81 /** 82 * Charset used internaly by eGW, $GLOBALS['egw']->translation->charset() 83 * 84 * @var string 85 */ 86 var $charset; 87 /** 88 * Font used for the Gantt Chart, in the form used by JPGraphs SetFont method 89 * 90 * The constructor checks for FF_ARIAL if TTF_DIR.'arial.ttf' is readable and sets FF_VERA instead if not 91 * 92 * You can try with every font-family specified in jpgraph.php AND availible on your system: 93 * eg. FF_CHINESE, FF_MINCHO, ... 94 * Dont forget to also set $gantt_charset accordingly! 95 * 96 * @var string 97 */ 98 var $gantt_font = FF_ARIAL; 99 /** 100 * Charset used by the above font, gets set by constructor if $gannt_font is NOT set! 101 * 102 * @var string 103 */ 104 var $gantt_charset = 'iso-8859-1'; 105 106 var $debug; 107 var $scale_start,$scale_end; 108 var $tmpl; 109 var $prefs; 110 111 /** 112 * Constructor, calls the constructor of the extended class 113 */ 114 function ganttchart() 115 { 116 $this->tmpl =& CreateObject('etemplate.etemplate'); 117 118 $php_extension = 'gd'; 119 if (!extension_loaded($php_extension) && (!function_exists('dl') || 120 !dl(PHP_SHLIB_PREFIX.$php_extension.'.'.PHP_SHLIB_SUFFIX)) || 121 !function_exists('imagecopyresampled')) 122 { 123 $this->tmpl->Location(array( 124 'menuaction' => 'projectmanager.uiprojectmanager.index', 125 'msg' => lang("Necessary PHP extentions %1 not loaded and can't be loaded !!!",$php_extension.' ('.PHP_SHLIB_PREFIX.$php_extension.'.'.PHP_SHLIB_SUFFIX.')'), 126 )); 127 } 128 $this->modernJPGraph = version_compare('1.13',JPG_VERSION) < 0; 129 //echo "version=".JPG_VERSION.", modernJPGraph=".(int)$this->modernJPGraph; exit; 130 131 if (isset($_REQUEST['pm_id'])) 132 { 133 $pm_id = (int) $_REQUEST['pm_id']; 134 $GLOBALS['egw']->session->appsession('pm_id','projectmanager',$pm_id); 135 } 136 else 137 { 138 $pm_id = $GLOBALS['egw']->session->appsession('pm_id','projectmanager'); 139 } 140 if (!$pm_id) 141 { 142 $this->tmpl->Location(array( 143 'menuaction' => 'projectmanager.uiprojectmanager.index', 144 'msg' => lang('You need to select a project first'), 145 )); 146 } 147 $this->boprojectelements($pm_id); 148 149 // check if we have at least read-access to this project 150 if (!$this->project->check_acl(EGW_ACL_READ)) 151 { 152 $GLOBALS['egw']->redirect_link('/index.php',array( 153 'menuaction' => 'projectmanager.uiprojectmanager.index', 154 'msg' => lang('Permission denied !!!'), 155 )); 156 } 157 $this->charset = $GLOBALS['egw']->translation->charset(); 158 $this->prefs =& $GLOBALS['egw_info']['user']['preferences']; 159 160 // check if a arial font is availible and set FF_VERA (or bundled font) if not 161 if ($this->gantt_font == FF_ARIAL && !is_readable(TTF_DIR.'arial.ttf')) 162 { 163 $this->gantt_font = FF_VERA; 164 } 165 } 166 167 /** 168 * Converts text from eGW's internal encoding to something understood by JPGraph / GD 169 * 170 * The only working thing I found so far is numeric html-entities from iso-8859-1. 171 * If you found other encoding do work, please let mit know: RalfBecker-AT-outdoor-training.de 172 * It would be nice if we could use the full utf-8 charset, if supported by the used font. 173 * 174 * @param string $text 175 * @return string 176 */ 177 function text_encode($text) 178 { 179 // convert to the charset used for the gantchart 180 $text = $GLOBALS['egw']->translation->convert($text,$this->charset,$this->gantt_charset); 181 182 // convert everything above ascii to nummeric html entities 183 // not sure if this is necessary for non iso-8859-1 charsets, try to comment it out if you have problems 184 $text = preg_replace('/[^\x00-\x7F]/e', '"&#".ord("$0").";"',$text); 185 186 return $text; 187 } 188 189 /** 190 * Try to guess a locale supported by the server, with fallback to 'en_EN' and 'C' 191 * 192 * @return string 193 */ 194 function guess_locale() 195 { 196 $lang = $this->prefs['common']['lang']; 197 $country = $this->prefs['common']['country']; 198 199 if (strlen($lang) == 2) 200 { 201 $country_from_lang = strtoupper($lang); 202 } 203 else 204 { 205 list($lang,$country_from_lang) = explode('-',$lang); 206 $country_from_lang = strtoupper($country_from_lang); 207 } 208 if (setlocale(LC_ALL,$locale=$lang.'_'.$country)) return $locale; 209 if (setlocale(LC_ALL,$locale=$lang.'_'.$country_from_lang)) return $locale; 210 if (setlocale(LC_ALL,$locale=$lang)) return $locale; 211 if (setlocale(LC_ALL,$locale='en_EN')) return $locale; 212 213 return 'C'; 214 } 215 216 /** 217 * create a new JPGraph Ganttchart object and setup a fitting scale 218 * 219 * @param string $title 220 * @param string $subtile 221 * @param int $start startdate of the ganttchart 222 * @param int $end enddate of the ganttchart 223 * @return object GantGraph 224 */ 225 function &new_gantt($title,$subtitle,$start,$end,$width=940) 226 { 227 // create new graph object 228 $graph =& new GanttGraph($width,-1,'auto'); 229 230 $graph->SetShadow(); 231 $graph->SetBox(); 232 233 // set the start and end date 234 $graph->SetDateRange(date('Y-m-d',$start), date('Y-m-d',$end)); 235 236 // some localizations 237 if ($this->modernJPGraph) 238 { 239 $graph->scale->SetDateLocale($this->guess_locale()); 240 } 241 elseif ($this->prefs['common']['lang'] == 'de') 242 { 243 $graph->scale->SetDateLocale(LOCALE_DE); // others use english 244 } 245 // set start-day of the week from the cal-pref weekdaystarts 246 $weekdaystarts2day = array( 247 'Sunday' => 0, 248 'Monday' => 1, 249 'Saturday' => 6, 250 ); 251 $weekdaystarts = $this->prefs['calendar']['weekdaystarts']; 252 if ($this->modernJPGraph && isset($weekdaystarts2day[$weekdaystarts])) 253 { 254 $graph->scale->SetWeekStart($weekdaystarts2day[$weekdaystarts]); 255 } 256 // get and remember the real start- & enddates, to clip the bar for old JPGraph versions 257 $this->scale_start = $graph->scale->iStartDate; 258 $this->scale_end = $graph->scale->iEndDate; 259 260 $days = round(($this->scale_end - $this->scale_start) / 86400); 261 $month = $days / 31; 262 //echo date('Y-m-d',$this->scale_start).' - '.date('Y-m-d',$this->scale_end).' '.$month; 263 // 2 weeks and less: day (weekday date) and hour headers, only possible with modern JPGraph 264 if($this->modernJPGraph && $days <= 14) 265 { 266 $graph->ShowHeaders(GANTT_HDAY | GANTT_HHOUR); 267 $graph->scale->day->SetStyle($days < 7 ? DAYSTYLE_LONGDAYDATE1 : DAYSTYLE_SHORTDATE3); 268 $graph->scale->hour->SetStyle($this->prefs['common']['timeformat'] == 12 ? HOURSTYLE_HAMPM : HOURSTYLE_H24); 269 foreach(array(8=>6,5=>4,3=>2,2=>1) as $max => $int) 270 { 271 if ($days >= $max) break; 272 } 273 //echo "days=$days => $int ($max)"; 274 $graph->scale->hour->SetIntervall($int); 275 } 276 // 1.5 month and less: month (with year), week and day (date) headers 277 elseif($month <= 1.5) 278 { 279 $graph->ShowHeaders(GANTT_HMONTH | GANTT_HWEEK | GANTT_HDAY); 280 $graph->scale->month->SetStyle(MONTHSTYLE_LONGNAMEYEAR4); 281 if ($this->modernJPGraph) $graph->scale->day->SetStyle(DAYSTYLE_SHORTDATE4); 282 } 283 // 2.5 month and less: month (with year), week (week and startday) and day headers 284 elseif($month <= 2.5) 285 { 286 $graph->ShowHeaders(GANTT_HMONTH | GANTT_HWEEK | GANTT_HDAY); 287 if ($this->modernJPGraph) $graph->scale->week->SetStyle(WEEKSTYLE_FIRSTDAYWNBR); 288 $graph->scale->month->SetStyle(MONTHSTYLE_LONGNAMEYEAR4); 289 } 290 // 6 month and less: year, month and week (with weeknumber) headers 291 elseif($month <= 6) // half year 292 { 293 $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HWEEK); 294 $graph->scale->month->SetStyle(MONTHSTYLE_LONGNAME); 295 } 296 // more then 6 month: only year and month headers 297 else 298 { 299 $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH); 300 } 301 // Change the font scale 302 $graph->scale->week->SetFont($this->gantt_font,FS_NORMAL,8); 303 $graph->scale->year->SetFont($this->gantt_font,FS_BOLD,10); 304 305 // Title & subtitle 306 $graph->title->Set($this->text_encode($title)); 307 $graph->title->SetFont($this->gantt_font,FS_BOLD,12); 308 $graph->subtitle->Set($this->text_encode($subtitle)); 309 $graph->subtitle->SetFont($this->gantt_font,FS_NORMAL,10); 310 311 return $graph; 312 } 313 314 /** 315 * Ganttbar for a project 316 * 317 * @param array $pm project or project-element data array 318 * @param int $level hierarchy level, 0=main project 319 * @param int $line line-number of the gantchart, starting with 0 320 * @param boolean $planned_times=false show planned or real start- and end-dates 321 * @return object GanttBar 322 */ 323 function &project2bar($pm,$level,$line,$planned_times=false) 324 { 325 if ($pm['pe_id']) 326 { 327 $pe =& $pm; 328 } 329 else 330 { 331 $pe = array( 332 'pm_id' => $pm['pm_id'], 333 'pe_id' => 0, 334 ); 335 foreach($pm as $key => $val) 336 { 337 if ($key != 'pm_id') $pe[str_replace('pm_','pe_',$key)] =& $pm[$key]; 338 } 339 } 340 $bar =& $this->element2bar($pe,$level,$line,$planned_times); 341 342 // set project-specific attributes: bold, solid bar, ... 343 $bar->title->SetFont($this->gantt_font,FS_BOLD,!$level ? 9 : 8); 344 $bar->SetPattern(BAND_SOLID,"#9999FF"); 345 346 if ($this->modernJPGraph && !$pe['pe_id']) // main-project 347 { 348 $link = $GLOBALS['egw']->link('/index.php',array( 349 'menuaction' => 'projectmanager.uiprojectmanager.view', 350 'pm_id' => $pe['pm_id'], 351 )); 352 $title = lang('View this project'); 353 354 $bar->SetCSIMTarget($link,$title); 355 $bar->title->SetCSIMTarget($link,$title); 356 } 357 return $bar; 358 } 359 360 /** 361 * Ganttbar for a project-element 362 * 363 * @param array $pe projectelement-data array 364 * @param int $level hierarchy level, 0=main project 365 * @param int $line line-number of the gantchart, starting with 0 366 * @param boolean $planned_times=false show planned or real start- and end-dates 367 * @return object GanttBar 368 */ 369 function &element2bar($pe,$level,$line,$planned_times=false) 370 { 371 // create a shorter title (removes dates from calendar-titles and project-numbers from sub-projects 372 if ($pe['pe_app'] == 'calendar' || $pe['pe_app'] == 'projectmanager') 373 { 374 list(,$title) = explode(': ',$pe['pe_title'],2); 375 } 376 if (!$title) $title = $pe['pe_title']; 377 378 if ((int) $this->debug >= 1) 379 { 380 echo "<p>GanttBar($line,'".($level ? str_repeat(' ',$level) : ''). 381 $this->text_encode($title).' '."','". 382 date('Y-m-d H:i',$pe['pe_start'])."','".date('Y-m-d H:i',$pe['pe_end'])."','". 383 round($pe['pe_completion']).'%'."',0.5)</p>\n"; 384 } 385 if (!$this->modernJPGraph) // for an old JPGraph we have to clip the bar ourself 386 { 387 if ($pe['pe_start'] < $this->scale_start) $pe['pe_start'] = $this->scale_start; 388 if ($pe['pe_end'] > $this->scale_end) $pe['pe_end'] = $this->scale_end-1; 389 } 390 $bar =& new GanttBar($line,($level ? str_repeat(' ',$level) : ''). 391 $this->text_encode($title). 392 ($level ? ' ' : ''), // fix for wrong length calculation in JPGraph 393 date('Y-m-d'.($this->modernJPGraph ? ' H:i' : ''),$pe['pe_start']), 394 date('Y-m-d'.($this->modernJPGraph ? ' H:i' : ''),$pe['pe_end']), 395 round($pe['pe_completion']).'%',0.5); 396 397 $bar->progress->Set($pe['pe_completion']/100); 398 $bar->progress->SetHeight(0.5); 399 400 if ($this->modernJPGraph && $pe['pe_id']) 401 { 402 $bar->SetCSIMTarget('@'.$GLOBALS['egw']->link('/index.php',array( // @ = popup 403 'menuaction' => 'projectmanager.uiprojectelements.view', 404 'pm_id' => $pe['pm_id'], 405 'pe_id' => $pe['pe_id'], 406 )),$pe['pe_remark'] ? $pe['pe_remark'] : lang('View this project-element')); 407 408 $bar->title->SetCSIMTarget($GLOBALS['egw']->link('/index.php',$this->link->view($pe['pe_app'],$pe['pe_app_id'])), 409 lang('View this element in %1',lang($pe['pe_app']))); 410 } 411 return $bar; 412 } 413 414 /** 415 * Milestone 416 * 417 * @param array $milestone data-array 418 * @param int $level hierarchy level, 0=main project 419 * @param int $line line-number of the gantchart, starting with 0 420 * @return object MileStone 421 */ 422 function &milestone2bar($milestone,$level,$line) 423 { 424 if ((int) $this->debug >= 1) 425 { 426 echo "<p>MileStone($line,'$milestone[ms_title],". 427 date('Y-m-d',$milestone['ms_date']).','. 428 date($this->prefs['common']['dateformat'],$milestone['ms_date']).")</p>\n"; 429 } 430 $ms =& new MileStone($line,($level ? str_repeat(' ',$level) : ''). 431 $this->text_encode($milestone['ms_title']), 432 date('Y-m-d',$milestone['ms_date']), 433 date($this->prefs['common']['dateformat'],$milestone['ms_date'])); 434 435 $ms->title->SetFont($this->gantt_font,FS_ITALIC,8); 436 $ms->title->SetColor('blue'); 437 $ms->mark->SetColor('black'); 438 $ms->mark->SetFillColor('blue'); 439 440 if ($this->modernJPGraph) 441 { 442 $link = $GLOBALS['egw']->link('/index.php',array( 443 'menuaction' => 'projectmanager.uimilestones.view', 444 'pm_id' => $milestone['pm_id'], 445 'ms_id' => $milestone['ms_id'], 446 )); 447 $title = lang('View this milestone'); 448 $ms->SetCSIMTarget('@'.$link,$title); // @ = popup 449 $ms->title->SetCSIMTarget('@'.$link,$title); 450 } 451 return $ms; 452 } 453 454 /** 455 * Adds all elements of project $pm_id to the ganttchart, calls itself recursive for subprojects 456 * 457 * @param int $pm_id project-id 458 * @param array $params 459 * @param int &$line line-number of the gantchart, starting with 0, gets incremented 460 * @param array &$bars bars are added here, with their pe_id as key 461 * @param int $level hierarchy level starting with 1, function stops if $level > $params['deepth'] 462 */ 463 function add_elements($pm_id,$params,&$line,&$bars,$level=1) 464 { 465 static $filter=false; 466 static $extra_cols; 467 468 if (!$filter) // we do this only once for all shown projects 469 { 470 // defining start- and end-times depending on $params['planned_times'] and the availible data 471 foreach(array('start','end') as $var) 472 { 473 if ($params['planned_times']) 474 { 475 $$var = "CASE WHEN pe_planned_$var IS NULL THEN pe_real_$var ELSE pe_planned_$var END"; 476 } 477 else 478 { 479 $$var = "CASE WHEN pe_real_$var IS NULL THEN pe_planned_$var ELSE pe_real_$var END"; 480 } 481 } 482 $filter = array( 483 "pe_status != 'ignore'", 484 "$start IS NOT NULL", 485 "$end IS NOT NULL", 486 "$start <= ".(int)$this->scale_end, // starts befor the end of our period AND 487 "$end >= ".(int)$this->scale_start, // ends after the start of our period 488 ); 489 switch ($params['filter']) 490 { 491 case 'not': 492 $filter['pe_completion'] = 0; 493 break; 494 case 'ongoing': 495 $filter[] = 'pe_completion!=100'; 496 break; 497 case 'done': 498 $filter['pe_completion'] = 100; 499 break; 500 } 501 if ($params['pe_resources']) 502 { 503 $filter['pe_resources'] = $params['pe_resources']; 504 } 505 $extra_cols = array( 506 $start.' AS pe_start', 507 $end.' AS pe_end', 508 ); 509 } 510 $filter['pm_id'] = $pm_id; // this is NOT static 511 512 $pe_id2line = array(); 513 foreach((array) $this->search(array(),false,'pe_start,pe_end',$extra_cols, 514 '',false,'AND',false,$filter) as $pe) 515 { 516 //echo "$line: ".print_r($pe,true)."<br>\n"; 517 if (!$pe) continue; 518 519 $pe_id = $pe['pe_id']; 520 $pe_id2line[$pe_id] = $line; // need to remember the line to draw the constraints 521 $pes[$pe_id] = $pe; 522 523 if ($pe['pe_app'] == 'projectmanager') 524 { 525 $bars[$pe_id] =& $this->project2bar($pe,$level,$line++,$params['planned_times']); 526 } 527 else 528 { 529 $bars[$pe_id] =& $this->element2bar($pe,$level,$line++,$params['planned_times']); 530 } 531 // if we should display further levels, we call ourself recursive 532 if ($pe['pe_app'] == 'projectmanager' && $level < $params['depth']) 533 { 534 $this->add_elements($pe['pe_app_id'],$params,$line,$bars,$level+1); 535 } 536 } 537 if ($params['constraints'] && $this->modernJPGraph) // the old jpgraph does not support constrains 538 { 539 // adding milestones 540 foreach((array)$this->milestones->search(array(),'pm_id,ms_id,ms_title,ms_date','ms_date','','',false,'AND',false,array( 541 'pm_id' => $pm_id, 542 (int)$this->scale_start.' <= ms_date', 543 'ms_date <= '.(int)$this->scale_end, 544 )) as $milestone) 545 { 546 if (!$milestone || !($ms_id = $milestone['ms_id'])) continue; 547 548 $ms_id2line[$ms_id] = $line; 549 $milestones[$ms_id] = $milestone; 550 $bars[-$ms_id] =& $this->milestone2bar($milestone,$level,$line++); 551 } 552 // adding the constraints to the bars 553 foreach((array)$this->constraints->search(array('pm_id'=>$pm_id)) as $constraint) 554 { 555 $pe_id = $constraint['pe_id_end']; // start of the array at the end of this pe 556 if (isset($bars[$pe_id])) 557 { 558 $bar =& $bars[$pe_id]; 559 560 if ($constraint['pe_id_start'] && isset($pe_id2line[$constraint['pe_id_start']])) 561 { 562 // show violated constrains in red 563 $color = $pes[$constraint['pe_id_start']]['pe_start'] >= $pes[$pe_id]['pe_end'] ? 'black' : 'red'; 564 $bar->SetConstrain($pe_id2line[$constraint['pe_id_start']],CONSTRAIN_ENDSTART,$color); 565 } 566 if ($constraint['ms_id'] && isset($ms_id2line[$constraint['ms_id']])) 567 { 568 // show violated constrains in red 569 $color = $milestones[$constraint['ms_id']]['ms_date'] >= $pes[$pe_id]['pe_end'] ? 'black' : 'red'; 570 $bar->SetConstrain($ms_id2line[$constraint['ms_id']],CONSTRAIN_ENDSTART,$color); 571 } 572 } 573 } 574 } 575 } 576 577 /** 578 * Create a ganttchart 579 * 580 * @param array $params=null params, if (default) null, use them from the URL 581 * @param string $filename='' filename to store the chart or (default) empty to send it direct to the browser 582 */ 583 function create($params=null,$filename='',$imagemap='ganttchar') 584 { 585 if (!$params) $params = $this->url2params($params); 586 587 $title = lang('project overview').': '.(is_numeric($params['pm_id']) ? $this->project->data['pm_title'] : ''); 588 $subtitle = lang('from %1 to %2',date($this->prefs['common']['dateformat'],$params['start']),date($this->prefs['common']['dateformat'],$params['end'])); 589 // create new graph-object and set scale_{start|end} 590 $graph =& $this->new_gantt($title,$subtitle,$params['start'],$params['end'],$params['width']); 591 592 if ($params['start'] < $this->now_su && $this->now_su < $params['end']) 593 { 594 // add a vertical line to mark today 595 $graph->add(new GanttVLine($this->now_su-24*60*60, 596 date($GLOBALS['egw_info']['user']['preferences']['common']['dateformat'],$this->now_su))); 597 } 598 $line = 0; 599 $bars = array(); 600 foreach(explode(',',$params['pm_id']) as $pm_id) 601 { 602 if ($pm_id != $this->project->data['pm_id']) 603 { 604 if (!$this->project->read($pm_id) || !$this->project->check_acl(EGW_ACL_READ)) 605 { 606 continue; 607 } 608 } 609 $graph->Add($this->project2bar($this->project->data,0,$line++,$params['planned_times'])); 610 611 if ($params['depth'] > 0) 612 { 613 $this->add_elements($this->project->data['pm_id'],$params,$line,$bars); 614 } 615 } 616 foreach($bars as $pe_id => $bar) 617 { 618 $graph->Add($bar); 619 } 620 if (!$this->debug) $graph->Stroke($filename); 621 622 if ($filename && $imagemap) return $graph->GetHTMLImageMap($imagemap); 623 } 624 625 /** 626 * read the ganttchart params from the URL 627 * 628 * @param array $params already set parameters, default empty array 629 * @return array with params 630 */ 631 function url2params($params = array()) 632 { 633 if ((int) $this->debug >= 1) echo "<p>ganttchart::url2params(".print_r($params,true).")</p>\n"; 634 635 if (!count($params)) 636 { 637 if (!($params = $GLOBALS['egw']->session->appsession('ganttchart','projectmanager'))) 638 { 639 $params = array( // some defaults, if called the first time 640 'constraints' => true, 641 ); 642 } 643 // check if project changed => not use start and end 644 if ($params['pm_id'] != $this->project->data['pm_id']) 645 { 646 $params['pm_id'] = $this->project->data['pm_id']; 647 unset($params['start']); 648 unset($params['end']); 649 } 650 } 651 $data =& $this->project->data; 652 foreach(array('start','end') as $var) 653 { 654 // set used start- and end-times of the project 655 if ($params['planned_times'] && $data['pe_planned_'.$var] || !$data['pe_real_'.$var]) 656 { 657 $data['pm_'.$var] = $data['pm_planned_'.$var]; 658 } 659 else 660 { 661 $data['pm_'.$var] = $data['pm_real_'.$var]; 662 } 663 // set start- and end-times of the ganttchart 664 if (isset($_GET[$var])) 665 { 666 $params[$var] = $_GET[$var]; 667 } 668 elseif (isset($params[$var]) && $params[$var]) 669 { 670 // already set 671 } 672 elseif ($data['pm_id'] && $data['pm_'.$var]) 673 { 674 $params[$var] = $data['pm_'.$var]; 675 } 676 else 677 { 678 $params[$var] = $var == 'start' ? date('Y-m-1') : date('Y-m-1',time()+61*24*60*60); 679 } 680 $params[$var] = is_numeric($params[$var]) ? (int) $params[$var] : strtotime($params[$var]); 681 682 if ((int) $this->debug >= 1) echo "<p>$var=".$params[$var].'='.date('Y-m-d',$params[$var])."</p>\n"; 683 } 684 if ((int) $_GET['width']) 685 { 686 $params['width'] = (int) $_GET['width']; 687 } 688 else 689 { 690 $params['width'] = $this->tmpl->innerWidth - 691 ($this->prefs['common']['auto_hide_sidebox'] ? 60 : 245); 692 } 693 if (!isset($params['pm_id']) && $this->project->data['pm_id']) 694 { 695 $params['pm_id'] = $this->project->data['pm_id']; 696 } 697 if (!isset($params['depth'])) $params['depth'] = 1; 698 699 if ($_GET['pm_id'] && !is_numeric($_GET['pm_id'])) 700 { 701 $params['pm_id'] = $_GET['pm_id']; 702 } 703 $GLOBALS['egw']->session->appsession('ganttchart','projectmanager',$params); 704 if ((int) $this->debug >= 1) _debug_array($params); 705 706 return $params; 707 } 708 709 /** 710 * Shows a ganttchart 711 * 712 * As ganttcharts contain an image-map and the image, we save the image as a temporary file. 713 * This for performance reasons, it saves a second creation / script-run. 714 * projectmanager/ganttchart.php reads and output the temporary file/image and unlinks it after. 715 */ 716 function show($content=array(),$msg='') 717 { 718 if ($content['sync_all'] && $this->project->check_acl(EGW_ACL_ADD)) 719 { 720 $msg = lang('%1 element(s) updated',$this->sync_all()); 721 unset($content['sync_all']); 722 } 723 // run $_GET[msg] through htmlspecialchars, as we output it raw, to allow the link in the jpgraph message. 724 if (!$msg) $msg = $this->tmpl->html->htmlspecialchars($_GET['msg']); 725 726 if (!$GLOBALS['egw']->session->appsession('ganttchart','projectmanager') && !$this->modernJPGraph) 727 { 728 $msg .= lang('You are using the old version of JPGraph, bundled with eGroupWare. It has only limited functionality.'). 729 "<br />\n".lang('Please download a recent version from %1 and install it in %2.', 730 '<a href="http://www.aditus.nu/jpgraph/jpdownload.php" target="_blank">www.aditus.nu/jpgraph</a>', 731 realpath(EGW_SERVER_ROOT.'/..').SEP.'jpgraph'); 732 } 733 unset($content['update']); 734 $content = $this->url2params($content); 735 736 $tmp = $GLOBALS['egw_info']['server']['temp_dir']; 737 if (!is_dir($tmp) || !is_writable($tmp)) 738 { 739 $tmp = ''; 740 } 741 $img = tempnam($tmp,'ganttchart'); 742 $img_name = basename($img); 743 $map = $this->create($content,$img,'ganttchart'); 744 // replace the regular links with popups 745 $map = preg_replace('/href="@([^"]+)"/i','href="#" onclick="window.open(\'\\1\',\'_blank\',\'dependent=yes,width=600,height=450,scrollbars=yes,status=yes\'); return false;"' 746 //.$tmpl->html->tooltip('Hallo Ralf<br>das ist ja <b>fett</b>') 747 ,$map); 748 749 $content['ganttchart'] = $GLOBALS['egw']->link('/projectmanager/ganttchart.php',$content+array( 750 'img' => $img_name, 751 )); 752 $content['map'] = $map; 753 $content['msg'] = $msg; 754 755 $sel_options = array( 756 'depth' => array( 757 0 => '0: '.lang('Mainproject only'), 758 1 => '1: '.lang('Project-elements'), 759 2 => '2: '.lang('Elements of elements'), 760 3 => '3: '.lang('Elements of elements'), 761 99 => lang('Everything recursive'), 762 ), 763 'filter' => array( 764 '' => lang('All'), 765 'not' => lang('Not started (0%)'), 766 'ongoing' => lang('0ngoing (0 < % < 100)'), 767 'done' => lang('Done (100%)'), 768 ), 769 ); 770 $GLOBALS['egw_info']['flags']['app_header'] = lang('projectmanager').' - '.lang('Ganttchart').': '.$this->project->data['pm_title'];; 771 $this->tmpl->read('projectmanager.ganttchart'); 772 return $this->tmpl->exec('projectmanager.ganttchart.show',$content,$sel_options,'',array('pm_id'=>$content['pm_id'])); 773 } 774 }
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 |