[ Index ]

Source Code Reference for V1.00

title

Body

[close]

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

   1  <?php /* $Id: gantt.php 114 2008-03-21 16:19:46Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/modules/projects/gantt.php $ */
   2  if (!defined('W2P_BASE_DIR')) {
   3      die('You should not access this file directly.');
   4  }
   5  
   6  global $AppUI, $company_id, $dept_ids, $department, $locale_char_set, $proFilter, $projectStatus, $showInactive, $showLabels, $showAllGantt, $sortTasksByName, $user_id, $w2Pconfig;
   7  
   8  ini_set('max_execution_time', 180);
   9  ini_set('memory_limit', $w2Pconfig['reset_memory_limit']);
  10  
  11  include ($AppUI->getLibraryClass('jpgraph/src/jpgraph'));
  12  include ($AppUI->getLibraryClass('jpgraph/src/jpgraph_gantt'));
  13  
  14  // get the prefered date format

  15  $df = $AppUI->getPref('SHDATEFORMAT');
  16  
  17  $projectStatus = w2PgetSysVal('ProjectStatus');
  18  $projectStatus = arrayMerge(array('-2' => $AppUI->_('All w/o in progress')), $projectStatus);
  19  $user_id = w2PgetParam($_REQUEST, 'user_id', $AppUI->user_id);
  20  if ($AppUI->user_id == $user_id) {
  21      $projectStatus = arrayMerge(array('-3' => $AppUI->_('My projects')), $projectStatus);
  22  } else {
  23      $projectStatus = arrayMerge(array('-3' => $AppUI->_('User\'s projects')), $projectStatus);
  24  }
  25  $proFilter = w2PgetParam($_REQUEST, 'proFilter', '-1');
  26  $company_id = w2PgetParam($_REQUEST, 'company_id', 0);
  27  $department = w2PgetParam($_REQUEST, 'department', 0);
  28  $showLabels = w2PgetParam($_REQUEST, 'showLabels', 0);
  29  $showInactive = w2PgetParam($_REQUEST, 'showInactive', 0);
  30  $sortTasksByName = w2PgetParam($_REQUEST, 'sortTasksByName', 0);
  31  $addPwOiD = w2PgetParam($_REQUEST, 'addPwOiD', 0);
  32  
  33  $pjobj = &new CProject;
  34  $working_hours = $w2Pconfig['daily_working_hours'];
  35  
  36  /*

  37  ** Load department info for the case where one

  38  ** wants to see the ProjectsWithOwnerInDeparment (PwOiD)

  39  ** instead of the projects related to the given department.

  40  */
  41  if ($addPwOiD && $department > 0) {
  42      $owner_ids = array();
  43      $q = new DBQuery;
  44      $q->addTable('users');
  45      $q->addQuery('user_id');
  46      $q->addJoin('contacts', 'c', 'c.contact_id = user_contact', 'inner');
  47      $q->addWhere('c.contact_department = ' . (int)$department);
  48      $owner_ids = $q->loadColumn();
  49      $q->clear();
  50  }
  51  
  52  // pull valid projects and their percent complete information

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

  54  $q = new DBQuery;
  55  $q->addTable('projects', 'pr');
  56  $q->addQuery('DISTINCT pr.project_id, project_color_identifier, project_name, project_start_date, project_end_date,
  57                  max(t1.task_end_date) AS project_actual_end_date, SUM(task_duration * task_percent_complete *
  58                  IF(task_duration_type = 24, ' . $working_hours . ', task_duration_type))/ SUM(task_duration *
  59                  IF(task_duration_type = 24, ' . $working_hours . ', task_duration_type)) AS project_percent_complete,
  60                  project_status, project_active');
  61  $q->addJoin('tasks', 't1', 'pr.project_id = t1.task_project');
  62  $q->addJoin('companies', 'c1', 'pr.project_company = c1.company_id');
  63  if ($department > 0 && !$addPwOiD) {
  64      $q->addWhere('project_departments.department_id = ' . (int)$department);
  65  }
  66  if ($proFilter == '-3') {
  67      $q->addWhere('pr.project_owner = ' . (int)$user_id);
  68  } elseif ($proFilter != '-1') {
  69      $q->addWhere('pr.project_status = ' . (int)$proFilter);
  70  }
  71  if (!($department > 0) && $company_id != 0 && !$addPwOiD) {
  72      $q->addWhere('pr.project_company = ' . (int)$company_id);
  73  }
  74  // Show Projects where the Project Owner is in the given department

  75  if ($addPwOiD && !empty($owner_ids)) {
  76      $q->addWhere('pr.project_owner IN (' . implode(',', $owner_ids) . ')');
  77  }
  78  
  79  if ($showInactive != '1') {
  80      $q->addWhere('pr.project_active = 1');
  81      if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
  82          $q->addWhere('pr.project_status <> ' . $template_status);
  83      }
  84  }
  85  $pjobj->setAllowedSQL($AppUI->user_id, $q, null, 'pr');
  86  $AppUI->getModuleClass('departments');
  87  $q->addGroup('pr.project_id');
  88  $q->addOrder('pr.project_name, task_end_date DESC');
  89  
  90  $projects = $q->loadList();
  91  $q->clear();
  92  
  93  // Don't push the width higher than about 1200 pixels, otherwise it may not display.

  94  $width = min(w2PgetParam($_GET, 'width', 600), 1400);
  95  $start_date = w2PgetParam($_GET, 'start_date', 0);
  96  $end_date = w2PgetParam($_GET, 'end_date', 0);
  97  
  98  $showAllGantt = w2PgetParam($_REQUEST, 'showAllGantt', '0');
  99  //$showTaskGantt = w2PgetParam( $_GET, 'showTaskGantt', '0' );

 100  
 101  $graph = new GanttGraph($width);
 102  $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HDAY | GANTT_HWEEK);
 103  
 104  $graph->SetFrame(false);
 105  $graph->SetBox(true, array(0, 0, 0), 2);
 106  $graph->scale->week->SetStyle(WEEKSTYLE_FIRSTDAY);
 107  
 108  $pLocale = setlocale(LC_TIME, 0); // get current locale for LC_TIME

 109  $res = setlocale(LC_TIME, $AppUI->user_lang[2]);
 110  if ($res) { // Setting locale doesn't fail
 111      $graph->scale->SetDateLocale($AppUI->user_lang[2]);
 112  }
 113  setlocale(LC_TIME, $pLocale);
 114  
 115  if ($start_date && $end_date) {
 116      $graph->SetDateRange($start_date, $end_date);
 117  }
 118  
 119  //$graph->scale->actinfo->SetFont(FF_CUSTOM);

 120  $graph->scale->actinfo->vgrid->SetColor('gray');
 121  $graph->scale->actinfo->SetColor('darkgray');
 122  $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));
 123  
 124  $tableTitle = ($proFilter == '-1') ? $AppUI->_('All Projects') : $projectStatus[$proFilter];
 125  $graph->scale->tableTitle->Set($tableTitle);
 126  
 127  // Use TTF font if it exists

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

 129  if (is_file(TTF_DIR . 'FreeSansBold.ttf')) {
 130      $graph->scale->tableTitle->SetFont(FF_CUSTOM, FS_BOLD, 12);
 131  }
 132  $graph->scale->SetTableTitleBackground('#eeeeee');
 133  $graph->scale->tableTitle->Show(true);
 134  
 135  //-----------------------------------------

 136  // nice Gantt image

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

 138  //week number

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

 140  //month number

 141  //-----------------------------------------

 142  if ($start_date && $end_date) {
 143      $min_d_start = new CDate($start_date);
 144      $max_d_end = new CDate($end_date);
 145      $graph->SetDateRange($start_date, $end_date);
 146  } else {
 147      // find out DateRange from gant_arr

 148      $d_start = new CDate();
 149      $d_end = new CDate();
 150      for ($i = 0, $i_cmp = count($projects); $i < $i_cmp; $i++) {
 151          $start = substr($p['project_start_date'], 0, 10);
 152          $end = substr($p['project_end_date'], 0, 10);
 153  
 154          $d_start->Date($start);
 155          $d_end->Date($end);
 156  
 157          if ($i == 0) {
 158              $min_d_start = $d_start;
 159              $max_d_end = $d_end;
 160          } else {
 161              if (Date::compare($min_d_start, $d_start) > 0) {
 162                  $min_d_start = $d_start;
 163              }
 164              if (Date::compare($max_d_end, $d_end) < 0) {
 165                  $max_d_end = $d_end;
 166              }
 167          }
 168      }
 169  }
 170  
 171  // check day_diff and modify Headers

 172  $day_diff = $min_d_start->dateDiff($max_d_end);
 173  
 174  if ($day_diff > 240) {
 175      //more than 240 days

 176      $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH);
 177  } else
 178      if ($day_diff > 90) {
 179          //more than 90 days and less of 241

 180          $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HWEEK);
 181          $graph->scale->week->SetStyle(WEEKSTYLE_WNBR);
 182      }
 183  
 184  $row = 0;
 185  
 186  if (!is_array($projects) || sizeof($projects) == 0) {
 187      $d = new CDate();
 188      $bar = new GanttBar($row++, array(' ' . $AppUI->_('No projects found'), ' ', ' ', ' '), $d->getDate(), $d->getDate(), ' ', 0.6);
 189      $bar->title->SetCOlor('red');
 190      $graph->Add($bar);
 191  }
 192  
 193  if (is_array($projects)) {
 194      foreach ($projects as $p) {
 195  
 196          if ($locale_char_set == 'utf-8' && function_exists('utf8_decode')) {
 197              $name = strlen(utf8_decode($p['project_name'])) > 25 ? substr(utf8_decode($p['project_name']), 0, 22) . '...' : utf8_decode($p['project_name']);
 198          } else {
 199              //while using charset different than UTF-8 we need not to use utf8_deocde

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

 204          $start = ($p['project_start_date'] > '0000-00-00 00:00:00') ? $p['project_start_date'] : '';
 205          $end_date = ($p['project_end_date'] > '0000-00-00 00:00:00') ? $p['project_end_date'] : '';
 206  
 207          $end_date = new CDate($end_date);
 208          //    $end->addDays(0);

 209          $end = $end_date->getDate();
 210  
 211          $start = new CDate($start);
 212          //    $start->addDays(0);

 213          $start = $start->getDate();
 214  
 215          $progress = $p['project_percent_complete'] + 0;
 216  
 217          $caption = '';
 218          if (!$start || $start == '0000-00-00') {
 219              $start = !$end ? date('Y-m-d') : $end;
 220              $caption .= $AppUI->_('(no start date)');
 221          }
 222  
 223          if (!$end) {
 224              $end = $start;
 225              $caption .= ' ' . $AppUI->_('(no end date)');
 226          } else {
 227              $cap = '';
 228          }
 229  
 230          if ($showLabels) {
 231              $caption .= $AppUI->_($projectStatus[$p['project_status']]) . ', ';
 232              $caption .= $p['project_active'] != 0 ? $AppUI->_('active') : $AppUI->_('archived');
 233          }
 234          $enddate = new CDate($end);
 235          $startdate = new CDate($start);
 236          $actual_end = intval($p['project_actual_end_date']) ? $p['project_actual_end_date'] : $end;
 237  
 238          $actual_enddate = new CDate($actual_end);
 239          $actual_enddate = $actual_enddate->after($startdate) ? $actual_enddate : $enddate;
 240          $bar = new GanttBar($row++, array($name, $startdate->format($df), $enddate->format($df), $actual_enddate->format($df)), $start, $actual_end, $cap, 0.6);
 241          $bar->progress->Set(min(($progress / 100), 1));
 242  
 243          if (is_file(TTF_DIR . 'FreeSans.ttf')) {
 244              $bar->title->SetFont(FF_CUSTOM, FS_NORMAL, 9);
 245          }
 246          $bar->SetFillColor('#' . $p['project_color_identifier']);
 247          $bar->SetPattern(BAND_SOLID, '#' . $p['project_color_identifier']);
 248  
 249          //adding captions

 250          $bar->caption = new TextProperty($caption);
 251          $bar->caption->Align('left', 'center');
 252  
 253          // gray out templates, completes, on ice, on hold

 254          if ($p['project_active'] == '0') {
 255              $bar->caption->SetColor('darkgray');
 256              $bar->title->SetColor('darkgray');
 257              $bar->SetColor('darkgray');
 258              $bar->SetFillColor('gray');
 259              //$bar->SetPattern(BAND_SOLID,'gray');

 260              $bar->progress->SetFillColor('darkgray');
 261              $bar->progress->SetPattern(BAND_SOLID, 'darkgray', 98);
 262          }
 263  
 264          $graph->Add($bar);
 265  
 266          // If showAllGant checkbox is checked

 267          if ($showAllGantt) {
 268              // insert tasks into Gantt Chart

 269              // select for tasks for each project

 270  
 271              $q = new DBQuery;
 272              $q->addTable('tasks');
 273              $q->addQuery('DISTINCT tasks.task_id, tasks.task_name, tasks.task_start_date, tasks.task_end_date, tasks.task_duration, tasks.task_duration_type, tasks.task_milestone, tasks.task_dynamic');
 274              $q->addJoin('projects', 'p', 'p.project_id = tasks.task_project');
 275              $q->addWhere('p.project_id = ' . (int)$p['project_id']);
 276              if ($sortTasksByName) {
 277                  $q->addOrder('tasks.task_name');
 278              } else {
 279                  $q->addOrder('tasks.task_end_date ASC');
 280              }
 281              $tasks = $q->loadList();
 282              $q->clear();
 283              foreach ($tasks as $t) {
 284                  //Check if start date exists, if not try giving it the end date.

 285                  //If the end date does not exist then set it for today.

 286                  //This avoids jpgraphs internal errors that render the gantt completely useless

 287                  if ($t['task_start_date'] == '0000-00-00 00:00:00') {
 288                      if ($t['task_end_date'] == '0000-00-00 00:00:00') {
 289                          $todaydate = new CDate();
 290                          $t['task_start_date'] = $todaydate->format(FMT_TIMESTAMP_DATE);
 291                      } else {
 292                          $t['task_start_date'] = $t['task_end_date'];
 293                      }
 294                  }
 295                          
 296                  //Check if end date exists, if not try giving it the start date.

 297                  //If the start date does not exist then set it for today.

 298                  //This avoids jpgraphs internal errors that render the gantt completely useless

 299                  if ($t['task_end_date'] == '0000-00-00 00:00:00') {
 300                      if ($t['task_duration']) {
 301                          $t['task_end_date'] = db_unix2dateTime(db_dateTime2unix($t['task_start_date']) + SECONDS_PER_DAY * convert2days($t['task_duration'], $t['task_duration_type']));
 302                      } else {
 303                          $todaydate = new CDate();
 304                          $t['task_end_date'] = $todaydate->format(FMT_TIMESTAMP_DATE);
 305                      }
 306                  }
 307  
 308                  $tStart = intval($t['task_start_date']) ? $t['task_start_date'] : $start;
 309                  $tEnd = intval($t['task_end_date']) ? $t['task_end_date'] : $end;
 310                  $tStartObj = new CDate($t['task_start_date']);
 311                  $tEndObj = new CDate($t['task_end_date']);
 312  
 313                  if ($t['task_milestone'] != 1) {
 314                      $bar2 = new GanttBar($row++, array(substr(' --' . $t['task_name'], 0, 20) . '...', $tStartObj->format($df), $tEndObj->format($df), ' '), $tStart, $tEnd, ' ', $t['task_dynamic'] == 1 ? 0.1 : 0.6);
 315  
 316                      $bar2->title->SetColor(bestColor('#ffffff', '#' . $p['project_color_identifier'], '#000000'));
 317                      $bar2->title->SetFont(FF_CUSTOM, FS_NORMAL, 9);
 318                      $bar2->SetFillColor('#' . $p['project_color_identifier']);
 319                      $graph->Add($bar2);
 320                  } else {
 321                      $bar2 = new MileStone($row++, '-- ' . $t['task_name'], $t['task_start_date'], $tStartObj->format($df));
 322                      $bar2->title->SetFont(FF_CUSTOM, FS_NORMAL, 9);
 323                      $bar2->title->SetColor('#CC0000');
 324                      $graph->Add($bar2);
 325                  }
 326  
 327                  // Insert workers for each task into Gantt Chart

 328                  $q = new DBQuery;
 329                  $q->addTable('user_tasks', 't');
 330                  $q->addQuery('DISTINCT contact_first_name, contact_last_name, t.task_id');
 331                  $q->addJoin('users', 'u', 'u.user_id = t.user_id', 'inner');
 332                  $q->addJoin('contacts', 'c', 'c.contact_id = u.user_contact', 'inner');
 333