[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/projectmanager/inc/ -> class.ganttchart.inc.php (source)

   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  }


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7