[ Index ]

Source Code Reference for V1.00

title

Body

[close]

/modules/projects/ -> vw_sub_projects_gantt.php (source)

   1  <?php /* $Id: vw_sub_projects_gantt.php 137 2008-04-04 16:12:02Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/modules/projects/vw_sub_projects_gantt.php $ */
   2  if (!defined('W2P_BASE_DIR')) {
   3      die('You should not access this file directly.');
   4  }
   5  
   6  // Pedro A.

   7  // The next lines tries to increase the processing time for php to render the image, that might be usefull when the system has

   8  // several projects.

   9  ini_set('max_execution_time', 180);
  10  ini_set('memory_limit', $w2Pconfig['reset_memory_limit']);
  11  
  12  include ($AppUI->getLibraryClass('jpgraph/src/jpgraph'));
  13  include ($AppUI->getLibraryClass('jpgraph/src/jpgraph_gantt'));
  14  
  15  global $AppUI, $company_id, $dept_ids, $department, $locale_char_set, $proFilter, $projectStatus, $showInactive, $showLabels, $showAllGantt, $user_id, $project_id, $project_original_id;
  16  
  17  // get the prefered date format

  18  
  19  $df = $AppUI->getPref('SHDATEFORMAT');
  20  
  21  $projectStatus = w2PgetSysVal('ProjectStatus');
  22  $projectStatus = arrayMerge(array('-2' => $AppUI->_('All w/o in progress')), $projectStatus);
  23  $user_id = w2PgetParam($_REQUEST, 'user_id', $AppUI->user_id);
  24  
  25  if ($AppUI->user_id == $user_id) {
  26      $projectStatus = arrayMerge(array('-3' => $AppUI->_('My projects')), $projectStatus);
  27  } else {
  28      $projectStatus = arrayMerge(array('-3' => $AppUI->_('User\'s projects')), $projectStatus);
  29  }
  30  
  31  $proFilter = w2PgetParam($_REQUEST, 'proFilter', '0');
  32  $company_id = w2PgetParam($_REQUEST, 'company_id', 0);
  33  $department = w2PgetParam($_REQUEST, 'department', 0);
  34  $showLabels = w2PgetParam($_REQUEST, 'showLabels', 1);
  35  $showInactive = w2PgetParam($_REQUEST, 'showInactive', 1);
  36  $original_project_id = w2PgetParam($_REQUEST, 'original_project_id', 1);
  37  
  38  $pjobj = &new CProject;
  39  $working_hours = $w2Pconfig['daily_working_hours'];
  40  
  41  // pull valid projects and their percent complete information

  42  // GJB: Note that we have to special case duration type 24 and this refers to the hours in a day, NOT 24 hours

  43  
  44  $q = new DBQuery;
  45  $q->addTable('projects', 'pr');
  46  $q->addQuery('DISTINCT pr.project_id, project_color_identifier, project_name, project_start_date, project_end_date,
  47                  max(t1.task_end_date) AS project_actual_end_date, SUM(task_duration * task_percent_complete *
  48                  IF(task_duration_type = 24, ' . $working_hours . ', task_duration_type))/ SUM(task_duration *
  49                  IF(task_duration_type = 24, ' . $working_hours . ', task_duration_type)) AS project_percent_complete,
  50                  project_status, project_active');
  51  $q->addJoin('tasks', 't1', 'pr.project_id = t1.task_project');
  52  $q->addJoin('companies', 'c1', 'pr.project_company = c1.company_id');
  53  if ($department > 0) {
  54      $q->addWhere('project_departments.department_id = ' . (int)$department);
  55  }
  56  
  57  if (!($department > 0) && $company_id != 0) {
  58      $q->addWhere('project_company = ' . (int)$company_id);
  59  }
  60  
  61  $q->addWhere('project_original_parent = ' . (int)$original_project_id);
  62  
  63  $pjobj->setAllowedSQL($AppUI->user_id, $q, null, 'pr');
  64  $q->addGroup('pr.project_id');
  65  //bl

  66  $q->addOrder('project_name, task_start_date DESC');
  67  
  68  //$projects = $q->loadList();

  69  //print_r($q->prepare());

  70  $projects = $q->loadHashList('project_id');
  71  $q->clear();
  72  
  73  $width = w2PgetParam($_GET, 'width', 600);
  74  $start_date = w2PgetParam($_GET, 'start_date', 0);
  75  $end_date = w2PgetParam($_GET, 'end_date', 0);
  76  
  77  $showAllGantt = w2PgetParam($_REQUEST, 'showAllGantt', '1');
  78  
  79  $graph = new GanttGraph($width);
  80  $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HDAY | GANTT_HWEEK);
  81  
  82  $graph->SetFrame(false);
  83  $graph->SetBox(true, array(0, 0, 0), 2);
  84  $graph->scale->week->SetStyle(WEEKSTYLE_FIRSTDAY);
  85  
  86  /*$jpLocale = w2PgetConfig( 'jpLocale' );

  87  

  88  if ($jpLocale) {

  89  

  90  $graph->scale->SetDateLocale( $jpLocale );

  91  

  92  }

  93  

  94  ** the jpgraph date locale is now set

  95  

  96  ** automatically by the user's locale settings

  97  

  98  */
  99  
 100  //$graph->scale->SetDateLocale( $AppUI->user_lang[0] );

 101  
 102  if ($start_date && $end_date) {
 103      $graph->SetDateRange($start_date, $end_date);
 104  }
 105  
 106  // Pedro A.

 107  //

 108  // The SetFont method changes the related bars caption text style and it will have all bars from its calling through all below

 109  // until a new SetFont call is executed again on the same object e subobjects.

 110  //

 111  // LOGIC: $graph->scale->actinfo->SetFont(font name, font style, font size);

 112  // EXAMPLE: $graph->scale->actinfo->SetFont(FF_CUSTOM, FS_BOLD, 10);

 113  //

 114  // Here is a list of possibilities you can use for the first parameter of the SetFont method:

 115  // TTF Font families (you must have them installed to use them):

 116  // FF_COURIER, FF_VERDANA, FF_TIMES, FF_COMIC, FF_CUSTOM, FF_GEORGIA, FF_TREBUCHE

 117  // Internal fonts:

 118  // FF_FONT0, FF_FONT1, FF_FONT2

 119  //

 120  // For the second parameter you have the TTF font style that can be:

 121  // FS_NORMAL, FS_BOLD, FS_ITALIC, FS_BOLDIT, FS_BOLDITALIC

 122  //

 123  
 124  // Pedro A.

 125  // This one will affect the captions of the columns on the left side, where you have the projects/tasks and dates

 126  $graph->scale->actinfo->SetFont(FF_CUSTOM, FS_NORMAL, 8);
 127  $graph->scale->actinfo->vgrid->SetColor('gray');
 128  $graph->scale->actinfo->SetColor('darkgray');
 129  
 130  //bl

 131  
 132  //$graph->scale->actinfo->SetColTitles(array( $AppUI->_('Project name', UI_OUTPUT_RAW), $AppUI->_('Start Date', UI_OUTPUT_RAW), $AppUI->_('Proj. End', UI_OUTPUT_RAW), $AppUI->_('Actual End', UI_OUTPUT_RAW)),array(160,10, 70,70));

 133  
 134  //$graph->scale->actinfo->SetColTitles(array( $AppUI->_('Project Name', UI_OUTPUT_RAW), $AppUI->_('Start Date', UI_OUTPUT_RAW), ),array(180,10));

 135  $graph->scale->actinfo->SetColTitles(array($AppUI->_('Project name', UI_OUTPUT_RAW), $AppUI->_('Start Date', UI_OUTPUT_RAW), $AppUI->_('Finish', UI_OUTPUT_RAW), $AppUI->_('Actual End', UI_OUTPUT_RAW)), array(160, 10, 70, 70));
 136  
 137  $original_project = new CProject();
 138  $original_project->load($original_project_id);
 139  $tableTitle = $original_project->project_name . ': ' . $AppUI->_('Multi-Project Gantt');
 140  $graph->scale->tableTitle->Set($tableTitle);
 141  
 142  // Use TTF font if it exists

 143  // try commenting out the following two lines if gantt charts do not display

 144  if (is_file(TTF_DIR . "FreeSans.ttf")) { // Pedro A.
 145      // This one will affect the title of the graph if you'd want to change its font you'd do something like:

 146      //    $graph->scale->tableTitle->SetFont(FF_FONT2);

 147      $graph->scale->tableTitle->SetFont(FF_CUSTOM, FS_BOLD, 10);
 148  }
 149  
 150  $graph->scale->SetTableTitleBackground('#eeeeee');
 151  $graph->scale->tableTitle->Show(true);
 152  
 153  //-----------------------------------------

 154  // nice Gantt image

 155  // if diff(end_date,start_date) > 90 days it shows only

 156  //week number

 157  // if diff(end_date,start_date) > 240 days it shows only

 158  //month number

 159  //-----------------------------------------

 160  
 161  if ($start_date && $end_date) {
 162      $min_d_start = new CDate($start_date);
 163      $max_d_end = new CDate($end_date);
 164      $graph->SetDateRange($start_date, $end_date);
 165  } else {
 166      // find out DateRange from gant_arr

 167      $d_start = new CDate();
 168      $d_end = new CDate();
 169      $i = 0;
 170      foreach ($projects as $project) {
 171          $start = substr($project["project_start_date"], 0, 10);
 172          $end = substr($project["project_actual_end_date"], 0, 10);
 173          ($start == '' || $start == null || $start == '0000-00-00') ? $d_start->Date() : $d_start->Date($start);
 174          ($end == '' || $end == null || $end == '0000-00-00') ? $d_end->Date() : $d_end->Date($end);
 175          if ($i == 0) {
 176              $min_d_start = $d_start;
 177              $max_d_end = $d_end;
 178          } else {
 179              if (Date::compare($min_d_start, $d_start) > 0) {
 180                  $min_d_start = $d_start;
 181              }
 182              if (Date::compare($max_d_end, $d_end) < 0) {
 183                  $max_d_end = $d_end;
 184              }
 185          }
 186          $i++;
 187      }
 188  }
 189  
 190  // check day_diff and modify Headers

 191  $day_diff = $min_d_start->dateDiff($max_d_end);
 192  //print_r($projects);

 193  //print_r($min_d_start);print_r($max_d_end);die;

 194  
 195  if ($day_diff > 120 || !$day_diff) {
 196      //more than 120 days

 197      $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH);
 198  } elseif ($day_diff > 60) {
 199      //more than 60 days and less of 120

 200      $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HWEEK);
 201      $graph->scale->week->SetStyle(WEEKSTYLE_WNBR);
 202  }
 203  
 204  $row = 0;
 205  if (!is_array($projects) || sizeof($projects) == 0) {
 206      $d = new CDate();
 207      $bar = new GanttBar($row++, array(' ' . $AppUI->_('No projects found'), ' ', ' ', ' '), $d->getDate(), $d->getDate(), ' ', 0.6);
 208      $bar->title->SetCOlor('red');
 209      $graph->Add($bar);
 210  }
 211  
 212  if (is_array($projects)) {
 213      //pull all tasks into an array keyed by the project id, and get the tasks in hierarchy

 214      if ($showAllGantt) {
 215          // insert tasks into Gantt Chart

 216          // select for tasks for each project

 217          // pull tasks

 218          $q = new DBQuery;
 219          $q->addTable('tasks', 't');
 220          $q->addQuery('t.task_id, task_parent, task_name, task_start_date, task_end_date, task_duration, task_duration_type, task_priority, task_percent_complete, task_order, task_project, task_milestone, project_id, project_name, task_dynamic');
 221          $q->addJoin('projects', 'p', 'project_id = t.task_project');
 222          $q->addOrder('project_id, task_start_date');
 223          $q->addWhere('project_original_parent = ' . (int)$original_project_id);
 224  
 225          //$tasks = $q->loadList();

 226          $task = &new CTask;
 227          $task->setAllowedSQL($AppUI->user_id, $q);
 228  
 229          $proTasks = $q->loadHashList('task_id');
 230          $orrarr[] = array('task_id' => 0, 'order_up' => 0, 'order' => '');
 231  
 232          $end_max = '0000-00-00 00:00:00';
 233          $start_min = date('Y-m-d H:i:s');
 234          //pull the tasks into an array

 235          foreach ($proTasks as $rec) {
 236              if ($rec['task_start_date'] == '0000-00-00 00:00:00') {
 237                  $rec['task_start_date'] = date('Y-m-d H:i:s');
 238              }
 239              $tsd = new CDate($rec['task_start_date']);
 240              if ($tsd->before(new CDate($start_min))) {
 241                  $start_min = $rec['task_start_date'];
 242              }
 243              // calculate or set blank task_end_date if unset

 244              if ($rec['task_end_date'] == '0000-00-00 00:00:00') {
 245                  if ($rec['task_duration']) {
 246                      $rec['task_end_date'] = db_unix2dateTime(db_dateTime2unix($rec['task_start_date']) + SECONDS_PER_DAY * convert2days($rec['task_duration'], $rec['task_duration_type']));
 247                  } else {
 248                      $rec['task_end_date'] = '';
 249                  }
 250              }
 251              $ted = new CDate($rec['task_end_date']);
 252              if ($ted->after(new CDate($end_max))) {
 253                  $end_max = $rec['task_end_date'];
 254              }
 255              $projects[$rec['task_project']]['tasks'][] = $rec;
 256          }
 257          $q->clear();
 258          /* $handle = fopen ( 'gantt.txt', 'w');

 259          $data = print_r($projects, true);

 260          fwrite($handle, $data);

 261          fclose($handle);*/
 262          //This kludgy function echos children tasks as threads

 263  
 264  		function showgtask(&$a, $level = 0, $project_id) {
 265              /* Add tasks to gantt chart */

 266              global $gantt_arr;
 267              $gantt_arr[$project_id][] = array($a, $level);
 268          }
 269  
 270  		function findgchild(&$tarr, $parent, $level = 0) {
 271              global $projects;
 272              $level = $level + 1;
 273              $n = count($tarr);
 274              for ($x = 0; $x < $n; $x++) {
 275                  if ($tarr[$x]['task_parent'] == $parent && $tarr[$x]['task_parent'] != $tarr[$x]['task_id']) {
 276                      showgtask($tarr[$x], $level, $tarr[$x]['project_id']);
 277                      findgchild($tarr, $tarr[$x]['task_id'], $level, $tarr[$x]['project_id']);
 278                  }
 279              }
 280          }
 281  
 282          reset($projects);
 283          //$p = &$projects[$project_id];

 284          foreach ($projects as $p) {
 285              $tnums = count($p['tasks']);
 286              for ($i = 0; $i < $tnums; $i++) {
 287                  $task = $p['tasks'][$i];
 288                  if ($task['task_parent'] == $task['task_id']) {
 289                      showgtask($task, 0, $p['project_id']);
 290                      findgchild($p['tasks'], $task['task_id'], 0, $p['project_id']);
 291                  }
 292              }
 293          }
 294  
 295          /* $handle = fopen ( 'gantt2.txt', 'w');

 296          $data = print_r($gantt_arr, true);

 297          fwrite($handle, $data);

 298          fclose($handle);*/
 299      }
 300  
 301      foreach ($projects as $p) {
 302          if ($locale_char_set == 'utf-8' && function_exists('utf8_decode')) {
 303              // Pedro A.

 304              // Depending on the font size you may increase or decrease the ammount of characters displayed from the project name by changing the:

 305              // ...25...23... ratio

 306              // to

 307              // ...30...28...   //more or

 308              // ...20...18...   //less

 309              $name = strlen(utf8_decode($p['project_name'])) > 35 ? substr(utf8_decode($p['project_name']), 0, 33) . '...' : utf8_decode($p['project_name']);
 310          } else {
 311              //while using charset different than UTF-8 we need not to use utf8_deocde

 312              $name = strlen($p['project_name']) > 25 ? substr($p['project_name'], 0, 22) . 'xxx' : $p['project_name'];
 313          }
 314          //using new jpGraph determines using Date object instead of string

 315          $start = ($p['project_start_date'] > '0000-00-00 00:00:00') ? $p['project_start_date'] : date('Y-m-d H:i:s');
 316          $end_date = $p['project_end_date'];
 317          $end_date = new CDate($end_date);
 318          //    $end->addDays(0);

 319          $end = $end_date->getDate();
 320          $start = new CDate($start);
 321          //    $start->addDays(0);

 322          $start = $start->getDate();
 323          $progress = $p['project_percent_complete'] + 0;
 324          $caption = ' ';
 325          if (!$start || $start == '0000-00-00') {
 326              $start = !$end ? date('Y-m-d') : $end;
 327              $caption .= $AppUI->_('(no start date)');
 328          }
 329          if (!$end) {
 330              $end = $start;
 331              $caption .= ' ' . $AppUI->_('(no end date)');
 332          } else {
 333              $cap = '';
 334          }
 335          if ($showLabels) {
 336              $caption .= $AppUI->_($projectStatus[$p['project_status']]) . ', ';
 337              $caption .= $p['project_active'] > 0 ? $AppUI->_('active') : $AppUI->_('archived');
 338          }
 339          $enddate = new CDate($end);
 340          $startdate = new CDate($start);
 341          $actual_end = $p['project_actual_end_date'] ? $p['project_actual_end_date'] : $end;
 342          $actual_enddate = new CDate($actual_end);
 343          $actual_enddate = $actual_enddate->after($startdate) ? $actual_enddate : $enddate;
 344  
 345          $bar = new GanttBar($row++, array($name, $startdate->format($df), $enddate->format($df), $actual_enddate->format($df)), $start, $actual_end, $cap, 0.6);
 346          $bar->progress->Set(min(($progress / 100), 1));
 347  
 348          // Pedro A.

 349          // This one will affect the style for the project names, alternative example:

 350          //      $bar->title->SetFont(FF_FONT1);

 351          $bar->title->SetFont(FF_CUSTOM, FS_BOLD, 7);
 352          $bar->SetFillColor('#' . $p['project_color_identifier']);
 353          $bar->SetPattern(BAND_SOLID, '#' . $p['project_color_identifier']);
 354  
 355          //adding captions

 356          $bar->caption = new TextProperty($caption);
 357          $bar->caption->Align('left', 'center');
 358          
 359          // Pedro A.

 360          // This one will affect the style for the caption of the projects status that appear on the right of the bar if they are selected to show, alternative example:

 361          //    $bar->title->SetFont(FF_FONT0);

 362          $bar->caption->SetFont(FF_CUSTOM, FS_NORMAL, 8);
 363  
 364          // gray out templates, completes, on ice, on hold

 365          if ($p['project_active'] < 1 || $p['project_percentage_complete'] > 99.9) {
 366              $bar->caption->SetColor('darkgray');
 367              $bar->title->SetColor('darkgray');
 368              $bar->SetColor('darkgray');
 369              $bar->SetFillColor('gray');
 370              //$bar->SetPattern(BAND_SOLID,'gray');

 371              $bar->progress->SetFillColor('darkgray');
 372              $bar->progress->SetPattern(BAND_SOLID, 'darkgray', 98);
 373          }
 374  
 375          $graph->Add($bar);