[ Index ]

Source Code Reference for V1.00

title

Body

[close]

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

   1  <?php /* $Id: gantt.php 133 2008-04-04 11:40:44Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/modules/tasks/gantt.php $ */
   2  if (!defined('W2P_BASE_DIR')) {
   3      die('You should not access this file directly.');
   4  }
   5  
   6  /*

   7  * Gantt.php - by J. Christopher Pereira

   8  * TASKS $Id: gantt.php 133 2008-04-04 11:40:44Z pedroix $

   9  */
  10  global $caller, $locale_char_set, $showWork, $sortByName, $showLabels, $showPinned, $showArcProjs, $showHoldProjs, $showDynTasks, $showLowTasks, $user_id, $w2Pconfig;
  11  
  12  ini_set('memory_limit', $w2Pconfig['reset_memory_limit']);
  13  
  14  include ($AppUI->getLibraryClass('jpgraph/src/jpgraph'));
  15  include ($AppUI->getLibraryClass('jpgraph/src/jpgraph_gantt'));
  16  
  17  $showLabels = w2PgetParam($_REQUEST, 'showLabels', false);
  18  $sortByName = w2PgetParam($_REQUEST, 'sortByName', false);
  19  $project_id = defVal($_REQUEST['project_id'], 0);
  20  $f = defVal($_REQUEST['f'], 0);
  21  
  22  // get the prefered date format

  23  $df = $AppUI->getPref('SHDATEFORMAT');
  24  
  25  require_once $AppUI->getModuleClass('projects');
  26  $project = &new CProject;
  27  $criticalTasks = ($project_id > 0) ? $project->getCriticalTasks($project_id) : null;
  28  
  29  // pull valid projects and their percent complete information

  30  
  31  $q = new DBQuery;
  32  $q->addTable('projects', 'pr');
  33  $q->addQuery('pr.project_id, project_color_identifier, project_name, project_start_date, project_end_date');
  34  $q->addJoin('tasks', 't1', 'pr.project_id = t1.task_project', 'inner');
  35  $q->addWhere('project_active = 1');
  36  $q->addGroup('pr.project_id');
  37  $q->addOrder('project_name');
  38  $project->setAllowedSQL($AppUI->user_id, $q, null, 'pr');
  39  $projects = $q->loadHashList('project_id');
  40  $q->clear();
  41  
  42  ##############################################

  43  /* gantt is called now by the todo page, too.

  44  ** there is a different filter approach in todo

  45  ** so we have to tweak a little bit,

  46  ** also we do not have a special project available

  47  */
  48  $caller = defVal($_REQUEST['caller'], null);
  49  if ($caller == 'todo') {
  50      $user_id = defVal(w2PgetParam($_REQUEST, 'user_id', 0), 0);
  51  
  52      $projects[$project_id]['project_name'] = $AppUI->_('Todo for') . ' ' . w2PgetUsername($user_id);
  53      $projects[$project_id]['project_color_identifier'] = 'ff6000';
  54  
  55      $showLabels = w2PgetParam($_REQUEST, 'showLabels', false);
  56      $showPinned = w2PgetParam($_REQUEST, 'showPinned', false);
  57      $showArcProjs = w2PgetParam($_REQUEST, 'showArcProjs', false);
  58      $showHoldProjs = w2PgetParam($_REQUEST, 'showHoldProjs', false);
  59      $showDynTasks = w2PgetParam($_REQUEST, 'showDynTasks', false);
  60      $showLowTasks = w2PgetParam($_REQUEST, 'showLowTasks', true);
  61  
  62      $q = new DBQuery;
  63      $q->addQuery('ta.*');
  64      $q->addQuery('project_name, project_id, project_color_identifier');
  65      $q->addQuery('tp.task_pinned');
  66      $q->addTable('projects', 'pr');
  67      $q->addTable('tasks', 'ta');
  68      $q->addTable('user_tasks', 'ut');
  69      $q->leftJoin('user_task_pin', 'tp', 'tp.task_id = ta.task_id and tp.user_id = ' . (int)$user_id);
  70  
  71      $q->addWhere('ut.task_id = ta.task_id');
  72      $q->addWhere('ut.user_id = ' . (int)$user_id);
  73      $q->addWhere('(ta.task_percent_complete < 100 OR ta.task_percent_complete is null)');
  74      $q->addWhere('ta.task_status = 0');
  75      $q->addWhere('pr.project_id = ta.task_project');
  76      if (!$showArcProjs) {
  77          $q->addWhere('pr.project_active = 1');
  78          if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
  79              $q->addWhere('pr.project_status <> ' . (int)$template_status);
  80          }
  81      }
  82      if (!$showLowTasks) {
  83          $q->addWhere('task_priority >= 0');
  84      }
  85      if (!$showHoldProjs) {
  86          $q->addWhere('project_active = 1');
  87      }
  88      if (!$showDynTasks) {
  89          $q->addWhere('task_dynamic <> 1');
  90      }
  91      if ($showPinned) {
  92          $q->addWhere('task_pinned = 1');
  93      }
  94  
  95      $q->addGroup('ta.task_id');
  96  
  97      if ($sortByName) {
  98          $q->addOrder('ta.task_name, ta.task_end_date');
  99          $q->addOrder('task_priority DESC');
 100      } else {
 101          $q->addOrder('ta.task_end_date');
 102          $q->addOrder('task_priority DESC');
 103      }
 104      ##############################################################

 105  } else {
 106      // pull tasks

 107      $q = new DBQuery;
 108      $q->addTable('tasks', 't');
 109      $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_name, task_dynamic');
 110      $q->addJoin('projects', 'p', 'project_id = t.task_project', 'inner');
 111      $q->addWhere('project_active = 1');
 112  
 113      if ($sortByName) {
 114          $q->addOrder('project_id, t.task_name, task_start_date');
 115      } else {
 116          $q->addOrder('project_id, task_start_date');
 117      }
 118  
 119      if ($project_id) {
 120          $q->addWhere('task_project = ' . (int)$project_id);
 121      }
 122      switch ($f) {
 123          case 'all':
 124              $q->addWhere('task_status > -1');
 125              break;
 126          case 'myproj':
 127              $q->addWhere('task_status > -1');
 128              $q->addWhere('project_owner = ' . (int)$AppUI->user_id);
 129              break;
 130          case 'mycomp':
 131              $q->addWhere('task_status > -1');
 132              $q->addWhere('project_company = ' . (int)$AppUI->user_company);
 133              break;
 134          case 'myinact':
 135              $q->addTable('user_tasks', 'ut');
 136              $q->addWhere('task_project = p.project_id');
 137              $q->addWhere('ut.user_id = ' . (int)$AppUI->user_id);
 138              $q->addWhere('ut.task_id = t.task_id');
 139              break;
 140          default:
 141              $q->addTable('user_tasks', 'ut');
 142              $q->addWhere('task_status > -1');
 143              $q->addWhere('task_project = p.project_id');
 144              $q->addWhere('ut.user_id = ' . (int)$AppUI->user_id);
 145              $q->addWhere('ut.task_id = t.task_id');
 146              break;
 147      }
 148  
 149  }
 150  
 151  // get any specifically denied tasks

 152  $task = &new CTask;
 153  $task->setAllowedSQL($AppUI->user_id, $q);
 154  
 155  $proTasks = $q->loadHashList('task_id');
 156  $orrarr[] = array('task_id' => 0, 'order_up' => 0, 'order' => '');
 157  
 158  $end_max = '0000-00-00 00:00:00';
 159  $start_min = date('Y-m-d H:i:s');
 160  
 161  //pull the tasks into an array

 162  if ($caller != 'todo') {
 163      $criticalTasks = $project->getCriticalTasks($project_id);
 164      $actual_end_date = new CDate($criticalTasks[0]['task_end_date']);
 165  } else {
 166      $actual_end_date = new CDate(null);
 167  }
 168  if ($actual_end_date->after($project->project_end_date)) {
 169      $p_end_date = $criticalTasks[0]['task_end_date'];
 170  } else {
 171      $p_end_date = $project->project_end_date;
 172  }
 173  
 174  foreach ($proTasks as $row) {
 175  
 176      //Check if start date exists, if not try giving it the end date.

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

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

 179      if ($row['task_start_date'] == '0000-00-00 00:00:00') {
 180          if ($row['task_end_date'] == '0000-00-00 00:00:00') {
 181              $todaydate = new CDate();
 182              $row['task_start_date'] = $todaydate->format(FMT_TIMESTAMP_DATE);
 183          } else {
 184              $row['task_start_date'] = $row['task_end_date'];
 185          }
 186      }
 187  
 188      $tsd = new CDate($row['task_start_date']);
 189  
 190      if ($tsd->before(new CDate($start_min))) {
 191          $start_min = $row['task_start_date'];
 192      }
 193  
 194      //Check if end date exists, if not try giving it the start date.

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

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

 197      if ($row['task_end_date'] == '0000-00-00 00:00:00') {
 198          if ($row['task_duration']) {
 199              $row['task_end_date'] = db_unix2dateTime(db_dateTime2unix($row['task_start_date']) + SECONDS_PER_DAY * convert2days($row['task_duration'], $row['task_duration_type']));
 200          } else {
 201              $todaydate = new CDate();
 202              $row['task_end_date'] = $todaydate->format(FMT_TIMESTAMP_DATE);
 203          }
 204      }
 205  
 206      $ted = new CDate($row['task_end_date']);
 207  
 208      if ($ted->after(new CDate($end_max))) {
 209          $end_max = $row['task_end_date'];
 210      }
 211      if ($ted->after(new CDate($projects[$row['task_project']]['project_end_date'])) || $projects[$row['task_project']]['project_end_date'] == '') {
 212          $projects[$row['task_project']]['project_end_date'] = $row['task_end_date'];
 213      }
 214  
 215      $projects[$row['task_project']]['tasks'][] = $row;
 216  }
 217  $q->clear();
 218  unset($proTasks);
 219  
 220  $width = min(w2PgetParam($_GET, 'width', 600), 1400);
 221  //consider critical (concerning end date) tasks as well

 222  if ($caller != 'todo') {
 223      $start_min = $projects[$project_id]['project_start_date'];
 224      $end_max = ($projects[$project_id]['project_end_date'] > $criticalTasks[0]['task_end_date']) ? $projects[$project_id]['project_end_date'] : $criticalTasks[0]['task_end_date'];
 225  }
 226  $start_date = w2PgetParam($_GET, 'start_date', $start_min);
 227  $end_date = w2PgetParam($_GET, 'end_date', $end_max);
 228  
 229  $count = 0;
 230  
 231  $graph = new GanttGraph($width);
 232  $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HDAY | GANTT_HWEEK);
 233  //$graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HDAY);

 234  
 235  $graph->SetFrame(false);
 236  $graph->SetBox(true, array(0, 0, 0), 2);
 237  $graph->scale->week->SetStyle(WEEKSTYLE_FIRSTDAY);
 238  //$graph->scale->day->SetStyle(DAYSTYLE_SHORTDATE2);

 239  
 240  $pLocale = setlocale(LC_TIME, 0); // get current locale for LC_TIME

 241  $res = setlocale(LC_TIME, $AppUI->user_lang[2]);
 242  if ($res) { // Setting locale doesn't fail
 243      $graph->scale->SetDateLocale($AppUI->user_lang[2]);
 244  }
 245  setlocale(LC_TIME, $pLocale);
 246  
 247  if ($start_date && $end_date) {
 248      $graph->SetDateRange($start_date, $end_date);
 249  }
 250  if (is_file(TTF_DIR . 'FreeSans.ttf')) {
 251      $graph->scale->actinfo->SetFont(FF_CUSTOM);
 252  }
 253  $graph->scale->actinfo->vgrid->SetColor('gray');
 254  $graph->scale->actinfo->SetColor('darkgray');
 255  
 256  if ($caller == 'todo') {
 257      if ($showWork == '1') {
 258          $graph->scale->actinfo->SetColTitles(array($AppUI->_('Task name', UI_OUTPUT_RAW), $AppUI->_('Project name', UI_OUTPUT_RAW), $AppUI->_('Work', UI_OUTPUT_RAW), $AppUI->_('Start', UI_OUTPUT_RAW), $AppUI->_('Finish', UI_OUTPUT_RAW)), array(180, 50, 60, 60, 60));
 259      } else {
 260          $graph->scale->actinfo->SetColTitles(array($AppUI->_('Task name', UI_OUTPUT_RAW), $AppUI->_('Project name', UI_OUTPUT_RAW), $AppUI->_('Dur.', UI_OUTPUT_RAW), $AppUI->_('Start', UI_OUTPUT_RAW), $AppUI->_('Finish', UI_OUTPUT_RAW)), array(180, 50, 60, 60, 60));
 261      }
 262  } else {
 263      if ($showWork == '1') {
 264          $graph->scale->actinfo->SetColTitles(array($AppUI->_('Task name', UI_OUTPUT_RAW), $AppUI->_('Work', UI_OUTPUT_RAW), $AppUI->_('Start', UI_OUTPUT_RAW), $AppUI->_('Finish', UI_OUTPUT_RAW)), array(230, 60, 60, 60));
 265      } else {
 266          $graph->scale->actinfo->SetColTitles(array($AppUI->_('Task name', UI_OUTPUT_RAW), $AppUI->_('Dur.', UI_OUTPUT_RAW), $AppUI->_('Start', UI_OUTPUT_RAW), $AppUI->_('Finish', UI_OUTPUT_RAW)), array(230, 60, 60, 60));
 267      }
 268  
 269  }
 270  $graph->scale->tableTitle->Set($projects[$project_id]['project_name']);
 271  
 272  // Use TTF font if it exists

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

 274  if (is_file(TTF_DIR . 'FreeSans.ttf')) {
 275      $graph->scale->tableTitle->SetFont(FF_CUSTOM, FS_BOLD, 12);
 276  }
 277  $graph->scale->SetTableTitleBackground('#' . $projects[$project_id]['project_color_identifier']);
 278  $font_color = bestColor('#' . $projects[$project_id]['project_color_identifier']);
 279  $graph->scale->tableTitle->SetColor($font_color);
 280  $graph->scale->tableTitle->Show(true);
 281  
 282  //-----------------------------------------

 283  // nice Gantt image

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

 285  //week number

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

 287  //month number

 288  //-----------------------------------------

 289  if ($start_date && $end_date) {
 290      $min_d_start = new CDate($start_date);
 291      $max_d_end = new CDate($end_date);
 292  } else {
 293      // find out DateRange from gant_arr

 294      $d_start = new CDate();
 295      $d_end = new CDate();
 296      for ($i = 0, $i_cmp = count($gantt_arr); $i < $i_cmp; $i++) {
 297          $a = $gantt_arr[$i][0];
 298          $start = substr($a['task_start_date'], 0, 10);
 299          $end = substr($a['task_end_date'], 0, 10);
 300  
 301          $d_start->Date($start);
 302          $d_end->Date($end);
 303  
 304          if ($i == 0) {
 305              $min_d_start = $d_start->duplicate();
 306              $max_d_end = $d_end->duplicate();
 307          } else {
 308              if (Date::compare($min_d_start, $d_start) > 0) {
 309                  $min_d_start = $d_start->duplicate();
 310              }
 311              if (Date::compare($max_d_end, $d_end) < 0) {
 312                  $max_d_end = $d_end->duplicate();
 313              }
 314          }
 315      }
 316  }
 317  
 318  // check day_diff and modify Headers

 319  $day_diff = $min_d_start->dateDiff($max_d_end);
 320  
 321  if ($day_diff > 240) {
 322      //more than 240 days

 323      $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH);
 324  } elseif ($day_diff > 90) {
 325      //more than 90 days and less of 241

 326      $graph->ShowHeaders(GANTT_HYEAR | GANTT_HMONTH | GANTT_HWEEK);
 327      $graph->scale->week->SetStyle(WEEKSTYLE_WNBR);
 328  }
 329  
 330  //This kludgy function echos children tasks as threads

 331  
 332  function showgtask(&$a, $level = 0) {
 333      /* Add tasks to gantt chart */

 334      global $gantt_arr;
 335      $gantt_arr[] = array($a, $level);
 336  }
 337  
 338  function findgchild(&$tarr, $parent, $level = 0) {
 339      global $projects;
 340      $level = $level + 1;
 341      $n = count($tarr);
 342      for ($x = 0; $x < $n; $x++) {
 343          if ($tarr[$x]['task_parent'] == $parent && $tarr[$x]['task_parent'] != $tarr[$x]['task_id']) {
 344              showgtask($tarr[$x], $level);
 345              findgchild($tarr, $tarr[$x]['task_id'], $level);
 346          }
 347      }
 348  }
 349  
 350  reset($projects);
 351  //$p = &$projects[$project_id];

 352  foreach ($projects as $p) {
 353      $parents = array();
 354      $tnums = count($p['tasks']);
 355  
 356      for ($i = 0; $i < $tnums; $i++) {
 357          $t = $p['tasks'][$i];
 358          if (!isset($parents[$t['task_parent']])) {
 359              $parents[$t['task_parent']] = false;
 360          }
 361          if ($t['task_parent'] == $t['task_id']) {
 362