[ Index ]

Source Code Reference for V1.00

title

Body

[close]

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

   1  <?php /* $Id: tasks.php 210 2008-08-18 17:40:05Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/modules/tasks/tasks.php $ */
   2  if (!defined('W2P_BASE_DIR')) {
   3      die('You should not access this file directly.');
   4  }
   5  
   6  global $m, $a, $project_id, $f, $min_view, $query_string, $durnTypes;
   7  global $task_sort_item1, $task_sort_type1, $task_sort_order1;
   8  global $task_sort_item2, $task_sort_type2, $task_sort_order2;
   9  global $user_id, $w2Pconfig, $currentTabId, $currentTabName, $canEdit, $showEditCheckbox;
  10  /*
  11  tasks.php
  12  
  13  This file contains common task list rendering code used by
  14  modules/tasks/index.php and modules/projects/vw_tasks.php
  15  
  16  in
  17  
  18  External used variables:
  19  * $min_view: hide some elements when active (used in the vw_tasks.php)
  20  * $project_id
  21  * $f
  22  * $query_string
  23  */
  24  
  25  if (empty($query_string)) {
  26      $query_string = '?m=' . $m . '&amp;a=' . $a;
  27  }
  28  
  29  // Number of columns (used to calculate how many columns to span things through)
  30  $cols = 13;
  31  
  32  /*
  33  * Let's figure out which tasks are selected
  34  */
  35  $task_id = intval(w2PgetParam($_GET, 'task_id', 0));
  36  
  37  $q = new DBQuery;
  38  $pinned_only = intval(w2PgetParam($_GET, 'pinned', 0));
  39  if (isset($_GET['pin'])) {
  40      $pin = intval(w2PgetParam($_GET, 'pin', 0));
  41      $msg = '';
  42  
  43      // load the record data
  44      if ($pin) {
  45          $q->addTable('user_task_pin');
  46          $q->addInsert('user_id', $AppUI->user_id);
  47          $q->addInsert('task_id', $task_id);
  48      } else {
  49          $q->setDelete('user_task_pin');
  50          $q->addWhere('user_id = ' . (int)$AppUI->user_id);
  51          $q->addWhere('task_id = ' . (int)$task_id);
  52      }
  53  
  54      if (!$q->exec()) {
  55          $AppUI->setMsg('ins/del err', UI_MSG_ERROR, true);
  56      } else {
  57          $q->clear();
  58      }
  59  
  60      $AppUI->redirect('', -1);
  61  }
  62  
  63  $durnTypes = w2PgetSysVal('TaskDurationType');
  64  $taskPriority = w2PgetSysVal('TaskPriority');
  65  
  66  $task_project = intval(w2PgetParam($_GET, 'task_project', null));
  67  
  68  $task_sort_item1 = w2PgetParam($_GET, 'task_sort_item1', '');
  69  $task_sort_type1 = w2PgetParam($_GET, 'task_sort_type1', '');
  70  $task_sort_item2 = w2PgetParam($_GET, 'task_sort_item2', '');
  71  $task_sort_type2 = w2PgetParam($_GET, 'task_sort_type2', '');
  72  $task_sort_order1 = intval(w2PgetParam($_GET, 'task_sort_order1', 0));
  73  $task_sort_order2 = intval(w2PgetParam($_GET, 'task_sort_order2', 0));
  74  if (isset($_POST['show_task_options'])) {
  75      $AppUI->setState('TaskListShowIncomplete', w2PgetParam($_POST, 'show_incomplete', 0));
  76  }
  77  $showIncomplete = $AppUI->getState('TaskListShowIncomplete', 0);
  78  
  79  require_once $AppUI->getModuleClass('projects');
  80  $project = &new CProject;
  81  $allowedProjects = $project->getAllowedSQL($AppUI->user_id, 'p.project_id');
  82  
  83  if (count($allowedProjects)) {
  84      $where_list = implode(' AND ', $allowedProjects);
  85  }
  86  
  87  $working_hours = ($w2Pconfig['daily_working_hours'] ? $w2Pconfig['daily_working_hours'] : 8);
  88  
  89  $q = new DBQuery;
  90  $q->addTable('projects', 'p');
  91  $q->addQuery('company_name, p.project_id, project_color_identifier, project_name, ' . ' SUM(t1.task_duration * t1.task_percent_complete' . ' * IF(t1.task_duration_type = 24, ' . $working_hours . ', t1.task_duration_type))' . ' / SUM(t1.task_duration * IF(t1.task_duration_type = 24, ' . $working_hours . ', t1.task_duration_type)) AS project_percent_complete ');
  92  $q->addJoin('companies', 'com', 'company_id = project_company', 'inner');
  93  $q->addJoin('tasks', 't1', 'p.project_id = t1.task_project', 'inner');
  94  $q->leftJoin('project_departments', 'project_departments', 'p.project_id = project_departments.project_id OR project_departments.project_id IS NULL');
  95  $q->leftJoin('departments', 'departments', 'departments.dept_id = project_departments.department_id OR dept_id IS NULL');
  96  $q->addWhere($where_list . (($where_list) ? ' AND ' : '') . 't1.task_id = t1.task_parent');
  97  $q->addGroup('p.project_id');
  98  if (!$project_id && !$task_id) {
  99      $q->addOrder('project_name');
 100  }
 101  
 102  $q2 = new DBQuery;
 103  $q2->addTable('projects');
 104  $q2->addQuery('project_id, COUNT(t1.task_id) AS total_tasks');
 105  $q2->addJoin('tasks', 't1', 'projects.project_id = t1.task_project', 'inner');
 106  if ($where_list) {
 107      $q2->addWhere($where_list);
 108  }
 109  $q2->addGroup('project_id');
 110  
 111  $perms = &$AppUI->acl();
 112  $projects = array();
 113  $canViewTask = $perms->checkModule('tasks', 'view');
 114  if ($canViewTask) {
 115  
 116      $prc = $q->exec();
 117      echo db_error();
 118      while ($row = $q->fetchRow()) {
 119          $projects[$row['project_id']] = $row;
 120      }
 121  
 122      $prc2 = $q2->fetchRow();
 123      echo db_error();
 124      while ($row2 = $q2->fetchRow()) {
 125          if ($projects[$row2['project_id']]) {
 126              array_push($projects[$row2['project_id']], $row2);
 127          }
 128      }
 129  }
 130  $q->clear();
 131  $q2->clear();
 132  
 133  $q->addQuery('tasks.task_id, task_parent, task_name');
 134  $q->addQuery('task_start_date, task_end_date, task_dynamic');
 135  $q->addQuery('count(tasks.task_parent) as children');
 136  $q->addQuery('task_pinned, pin.user_id as pin_user');
 137  $q->addQuery('task_priority, task_percent_complete');
 138  $q->addQuery('task_duration, task_duration_type');
 139  $q->addQuery('task_project');
 140  $q->addQuery('task_description, task_owner, task_status');
 141  $q->addQuery('usernames.user_username, usernames.user_id');
 142  $q->addQuery('assignees.user_username as assignee_username');
 143  $q->addQuery('count(distinct assignees.user_id) as assignee_count');
 144  $q->addQuery('co.contact_first_name, co.contact_last_name');
 145  $q->addQuery('CONCAT(co.contact_first_name,\' \', co.contact_last_name) AS owner');
 146  $q->addQuery('task_milestone');
 147  $q->addQuery('count(distinct f.file_task) as file_count');
 148  $q->addQuery('tlog.task_log_problem');
 149  
 150  //subquery the parent state
 151  $sq = new DBQuery;
 152  $sq->addTable('tasks', 'stasks');
 153  $sq->addQuery('COUNT(task_id)');
 154  $sq->addWhere('stasks.task_id <> tasks.task_id AND stasks.task_parent = tasks.task_id');
 155  $subquery = $sq->prepare();
 156  $sq->clear();
 157  
 158  $q->addQuery('(' . $subquery . ') AS task_nr_of_children');
 159  
 160  $q->addTable('tasks');
 161  $mods = $AppUI->getActiveModules();
 162  if (!empty($mods['history']) && !getDenyRead('history')) {
 163      $q->addQuery('MAX(history_date) as last_update');
 164      $q->leftJoin('history', 'h', 'history_item = tasks.task_id AND history_table=\'tasks\'');
 165  }
 166  
 167  $q->addJoin('projects', 'p', 'p.project_id = task_project', 'inner');
 168  $q->addJoin('users', 'usernames', 'task_owner = usernames.user_id', 'inner');
 169  
 170  $q->leftJoin('user_tasks', 'ut', 'ut.task_id = tasks.task_id');
 171  $q->leftJoin('users', 'assignees', 'assignees.user_id = ut.user_id');
 172  $q->addJoin('contacts', 'co', 'co.contact_id = usernames.user_contact', 'inner');
 173  $q->leftJoin('task_log', 'tlog', 'tlog.task_log_task = tasks.task_id AND tlog.task_log_problem > 0');
 174  $q->leftJoin('files', 'f', 'tasks.task_id = f.file_task');
 175  $q->leftJoin('project_departments', 'project_departments', 'p.project_id = project_departments.project_id OR project_departments.project_id IS NULL');
 176  $q->leftJoin('departments', 'departments', 'departments.dept_id = project_departments.department_id OR dept_id IS NULL');
 177  $q->leftJoin('user_task_pin', 'pin', 'tasks.task_id = pin.task_id AND pin.user_id = ' . (int)$AppUI->user_id);
 178  
 179  if ($project_id) {
 180      $q->addWhere('task_project = ' . (int)$project_id);
 181  } else { 
 182      $q->addWhere('project_active = 1');
 183      if (($template_status = w2PgetConfig('template_projects_status_id')) != '') {
 184          $q->addWhere('project_status <> ' . $template_status);
 185      }
 186  }
 187  
 188  if ($project_id) {
 189      $q->addWhere('task_project = ' . (int)$project_id);
 190      //if we are on a project context make sure we show all tasks
 191      $f = 'all';
 192  }
 193  if ($task_id) {
 194      //if we are on a task context make sure we show ALL the children tasks
 195      $f = 'deepchildren';
 196  }
 197  if ($pinned_only) {
 198      $q->addWhere('task_pinned = 1');
 199  }
 200  
 201  $f = (($f) ? $f : '');
 202  $never_show_with_dots = array('children', ''); //used when displaying tasks
 203  switch ($f) {
 204      case 'all':
 205          break;
 206      case 'myfinished7days':
 207          $q->addWhere('ut.user_id = ' . (int)$user_id);
 208      case 'allfinished7days': // patch 2.12.04 tasks finished in the last 7 days
 209          //$q->addTable('user_tasks');
 210          $q->addTable('user_tasks');
 211          $q->addWhere('user_tasks.user_id = ' . (int)$user_id);
 212          $q->addWhere('user_tasks.task_id = tasks.task_id');
 213  
 214          $q->addWhere('task_percent_complete = 100');
 215          //TODO: use date class to construct date.
 216          $q->addWhere('task_end_date >= \'' . date('Y-m-d 00:00:00', mktime(0, 0, 0, date('m'), date('d') - 7, date('Y'))) . '\'');
 217          break;
 218      case 'children':
 219          $q->addWhere('task_parent = ' . (int)$task_id);
 220          $q->addWhere('tasks.task_id <> ' . $task_id);
 221          break;
 222      case 'deepchildren':
 223          $taskobj = new CTask;
 224          $taskobj->load((int)$task_id);
 225          $deepchildren = $taskobj->getDeepChildren();
 226          $q->addWhere('tasks.task_id IN (' . implode(',', $deepchildren) . ')');
 227          $q->addWhere('tasks.task_id <> ' . $task_id);
 228          break;
 229      case 'myproj':
 230          $q->addWhere('project_owner = ' . (int)$user_id);
 231          break;
 232      case 'mycomp':
 233          if (!$AppUI->user_company) {
 234              $AppUI->user_company = 0;
 235          }
 236          $q->addWhere('project_company = ' . (int)$AppUI->user_company);
 237          break;
 238      case 'myunfinished':
 239          $q->addTable('user_tasks');
 240          $q->addWhere('user_tasks.user_id = ' . (int)$user_id);
 241          $q->addWhere('user_tasks.task_id = tasks.task_id');
 242          $q->addWhere('(task_percent_complete < 100 OR task_end_date = \'\')');
 243          break;
 244      case 'allunfinished':
 245          $q->addWhere('(task_percent_complete < 100 OR task_end_date = \'\')');
 246          break;
 247      case 'unassigned':
 248          $q->leftJoin('user_tasks', 'ut_empty', 'tasks.task_id = ut_empty.task_id');
 249          $q->addWhere('ut_empty.task_id IS NULL');
 250          break;
 251      case 'taskcreated':
 252          $q->addWhere('task_owner = ' . (int)$user_id);
 253          break;
 254      default:
 255          $q->addTable('user_tasks');
 256          $q->addWhere('user_tasks.user_id = ' . (int)$user_id);
 257          $q->addWhere('user_tasks.task_id = tasks.task_id');
 258          break;
 259  }
 260  
 261  if (($project_id || $task_id) && $showIncomplete) {
 262      $q->addWhere('( task_percent_complete < 100 OR task_percent_complete IS NULL)');
 263  }
 264  
 265  $task_status = 0;
 266  if ($min_view && isset($_GET['task_status'])) {
 267      $task_status = intval(w2PgetParam($_GET, 'task_status', null));
 268  } elseif ($currentTabId == 1 && $project_id) {
 269      $task_status = -1;
 270  } elseif (!$currentTabName) {
 271      // If we aren't tabbed we are in the tasks list.
 272      $task_status = intval($AppUI->getState('inactive'));
 273  }
 274  
 275  //When in task view context show all the tasks, active and inactive. (by not limiting the query by task status)
 276  //When in a project view or in the tasks list, show the active or the inactive tasks depending on the selected tab or button.
 277  if (!$task_id) {
 278      $q->addWhere('task_status = ' . (int)$task_status);
 279  }
 280  
 281  if ($task_type) {
 282      if ($task_type <> -1) {
 283          $q->addWhere('task_type = ' . (int)$task_type);
 284      }
 285  }
 286  if ($task_owner) {
 287      if ($task_owner <> -1) {
 288          $q->addWhere('task_owner = ' . (int)$task_owner);
 289      }
 290  }
 291  
 292  if (($project_id || !$task_id) && !$min_view) {
 293      if ($search_text = $AppUI->getState('searchtext')) {
 294          $q->addWhere('( task_name LIKE (\'%' . $search_text . '%\') OR task_description LIKE (\'%' . $search_text . '%\') )');
 295      }
 296  }
 297  
 298  // filter tasks considering task and project permissions
 299  $projects_filter = '';
 300  $tasks_filter = '';
 301  
 302  // TODO: Enable tasks filtering
 303  $allowedProjects = $project->getAllowedSQL($AppUI->user_id, 'task_project');
 304  if (count($allowedProjects)) {
 305      $q->addWhere($allowedProjects);
 306  }
 307  
 308  $obj = &new CTask;
 309  $allowedTasks = $obj->getAllowedSQL($AppUI->user_id, 'tasks.task_id');
 310  if (count($allowedTasks)) {
 311      $q->addWhere($allowedTasks);
 312  }
 313  
 314  // Filter by company
 315  if (!$min_view && $f2 != 'all') {
 316      $q->addJoin('companies', 'c', 'c.company_id = p.project_company', 'inner');
 317      $q->addWhere('company_id = ' . intval($f2));
 318  }
 319  
 320  $q->addGroup('tasks.task_id');
 321  if (!$project_id && !$task_id) {
 322      $q->addOrder('p.project_id, task_start_date');
 323  } else {
 324      $q->addOrder('task_start_date');
 325  }
 326  //print_r($q->prepare());
 327  if ($canViewTask) {
 328      $tasks = $q->loadList();
 329  }
 330  
 331  // POST PROCESSING TASKS
 332  foreach ($tasks as $row) {
 333      //add information about assigned users into the page output
 334      $q->clear();
 335      $q->addQuery('ut.user_id,    u.user_username');
 336      $q->addQuery('contact_email, ut.perc_assignment, SUM(ut.perc_assignment) AS assign_extent');
 337      $q->addQuery('CONCAT(contact_first_name, \' \',contact_last_name) AS assignee');
 338      $q->addTable('user_tasks', 'ut');
 339      $q->addJoin('users', 'u', 'u.user_id = ut.user_id', 'inner');
 340      $q->addJoin('contacts', 'c', 'u.user_contact = c.contact_id', 'inner');
 341      $q->addWhere('ut.task_id = ' . (int)$row['task_id']);
 342      $q->addGroup('ut.user_id');
 343      $q->addOrder('perc_assignment desc, contact_first_name, contact_last_name');
 344  
 345      $assigned_users = array();
 346      $row['task_assigned_users'] = $q->loadList();
 347  
 348      //pull the final task row into array
 349      $projects[$row['task_project']]['tasks'][] = $row;
 350  }
 351  
 352  $showEditCheckbox = ((isset($canEdit) && $canEdit && w2PgetConfig('direct_edit_assignment')) ? true : false);
 353  global $history_active;
 354  $history_active = !empty($mods['history']) && !getDenyRead('history');
 355  ?>
 356  
 357  <script type="text/JavaScript">
 358  function toggle_users(id){
 359    var element = document.getElementById(id);
 360    element.style.display = (element.style.display == '' || element.style.display == "none") ? "inline" : "none";
 361  }
 362  
 363  <?php
 364  // security improvement:
 365  // some javascript functions may not appear on client side in case of user not having write permissions
 366  // else users would be able to arbitrarily run 'bad' functions
 367  if (isset($canEdit) && $canEdit && $w2Pconfig['direct_edit_assignment']) {
 368  ?>
 369  function checkAll(project_id) {
 370      var f = eval('document.assFrm' + project_id);
 371      var cFlag = f.master.checked ? false : true;
 372      
 373      for (var i=0, i_cmp=f.elements.length; i<i_cmp;i++) {
 374          var e = f.elements[i];
 375          // only if it's a checkbox.
 376          if(e.type == 'checkbox' && e.checked == cFlag && e.name != 'master') {
 377              e.checked = !e.checked;
 378          }
 379      }
 380  
 381  }
 382  
 383  function chAssignment(project_id, rmUser, del) {
 384      var f = eval('document.assFrm' + project_id);
 385      var fl = f.add_users.length-1;
 386      var c = 0;
 387      var a = 0;
 388      
 389      f.hassign.value = '';
 390      f.htasks.value = '';
 391      
 392      // harvest all checked checkboxes (tasks to process)
 393      for (var i=0, i_cmp=f.elements.length; i<i_cmp;i++) {
 394          var e = f.elements[i];
 395          // only if it's a checkbox.
 396          if(e.type == 'checkbox' && e.checked == true && e.name != 'master') {
 397              c++;
 398              f.htasks.value = f.htasks.value +', '+ e.value;
 399          }
 400      }
 401      
 402      // harvest all selected possible User Assignees
 403      for (fl; fl > -1; fl--) {
 404          if (f.add_users.options[fl].selected) {
 405              a++;
 406              f.hassign.value = ', ' + f.hassign.value +', '+ f.add_users.options[fl].value;
 407          }
 408      }
 409      
 410      if (del == true) {
 411          if (c == 0) {
 412              alert ('<?php echo $AppUI->_('Please select at least one Task!', UI_OUTPUT_JS); ?>');
 413          } 
 414          else if (a == 0 && rmUser == 1){
 415              alert ('<?php echo $AppUI->_('Please select at least one Assignee!', UI_OUTPUT_JS); ?>');
 416          } 
 417          else if (confirm('<?php echo $AppUI->_('Are you sure you want to unassign the User from Task(s)?', UI_OUTPUT_JS); ?>')) {
 418              f.del.value = 1;
 419              f.rm.value = rmUser;
 420              f.project_id.value = project_id;
 421              f.submit();
 422          }
 423      }
 424      else {
 425          
 426          if (c == 0) {
 427              alert ('<?php echo $AppUI->_('Please select at least one Task!', UI_OUTPUT_JS); ?>');
 428          } 
 429          else if (a == 0) {
 430              alert ('<?php echo $AppUI->_('Please select at least one Assignee!', UI_OUTPUT_JS); ?>');
 431          } else {
 432              f.rm.value = rmUser;
 433              f.del.value = del;
 434              f.project_id.value = project_id;
 435              f.submit();
 436          }
 437      }
 438  }
 439  <?php } ?>
 440  </script>
 441  
 442  
 443  <?php 
 444  global $expanded;
 445  //if we are on a task view context then all subtasks are expanded by default, on other contexts config option stands.
 446  $expanded = $task_id ? true : $AppUI->getPref('TASKSEXPANDED');
 447  if ($project_id) {
 448      $open_link = w2PtoolTip($m, 'click to expand/collapse all the tasks for this project.') . '<a href="javascript: void(0);"><img onclick="expand_collapse(\'project_' . $project_id . '_\', \'tblProjects\',\'collapse\',0,2);" id="project_' . $project_id . '__collapse" src="' . w2PfindImage('up22.png', $m) . '" border="0" width="22" height="22" align="center" ' . (!$expanded ? 'style="display:none"' : '') . ' /><img onclick="expand_collapse(\'project_' . $project_id .