1<?php 2/************************************************************************* 3 tasks.php 4 5 Copyright (c) 2006-2013 osTicket 6 http://www.osticket.com 7 8 Released under the GNU General Public License WITHOUT ANY WARRANTY. 9 See LICENSE.TXT for details. 10 11 vim: expandtab sw=4 ts=4 sts=4: 12**********************************************************************/ 13 14require('staff.inc.php'); 15require_once(INCLUDE_DIR.'class.task.php'); 16require_once(INCLUDE_DIR.'class.export.php'); 17 18$page = ''; 19$task = null; //clean start. 20if ($_REQUEST['id']) { 21 if (!($task=Task::lookup($_REQUEST['id']))) 22 $errors['err'] = sprintf(__('%s: Unknown or invalid ID.'), __('task')); 23 elseif (!$task->checkStaffPerm($thisstaff)) { 24 $errors['err'] = __('Access denied. Contact admin if you believe this is in error'); 25 $task = null; 26 } 27} 28 29// Configure form for file uploads 30$note_attachments_form = new SimpleForm(array( 31 'attachments' => new FileUploadField(array('id'=>'attach', 32 'name'=>'attach:note', 33 'configuration' => array('extensions'=>''))) 34)); 35 36$reply_attachments_form = new SimpleForm(array( 37 'attachments' => new FileUploadField(array('id'=>'attach', 38 'name'=>'attach:reply', 39 'configuration' => array('extensions'=>''))) 40)); 41 42//At this stage we know the access status. we can process the post. 43if($_POST && !$errors): 44 if ($task) { 45 //More coffee please. 46 $errors=array(); 47 $role = $thisstaff->getRole($task->getDept()); 48 switch(strtolower($_POST['a'])): 49 case 'postnote': /* Post Internal Note */ 50 $vars = $_POST; 51 $vars['files'] = $note_attachments_form->getField('attachments')->getFiles(); 52 53 $wasOpen = ($task->isOpen()); 54 if(($note=$task->postNote($vars, $errors, $thisstaff))) { 55 56 $msg=__('Internal note posted successfully'); 57 // Clear attachment list 58 $note_attachments_form->setSource(array()); 59 $note_attachments_form->getField('attachments')->reset(); 60 61 if($wasOpen && $task->isClosed()) 62 $task = null; //Going back to main listing. 63 else 64 // Task is still open -- clear draft for the note 65 Draft::deleteForNamespace('task.note.'.$task->getId(), 66 $thisstaff->getId()); 67 68 } else { 69 if(!$errors['err']) 70 $errors['err'] = __('Unable to post internal note - missing or invalid data.'); 71 72 $errors['postnote'] = sprintf('%s %s', 73 __('Unable to post the note.'), 74 __('Correct any errors below and try again.')); 75 } 76 break; 77 case 'postreply': /* Post an update */ 78 $vars = $_POST; 79 $vars['files'] = $reply_attachments_form->getField('attachments')->getFiles(); 80 81 $wasOpen = ($task->isOpen()); 82 if (($response=$task->postReply($vars, $errors))) { 83 84 $msg=__('Reply posted successfully'); 85 // Clear attachment list 86 $reply_attachments_form->setSource(array()); 87 $reply_attachments_form->getField('attachments')->reset(); 88 89 if ($wasOpen && $task->isClosed()) 90 $task = null; //Going back to main listing. 91 else 92 // Task is still open -- clear draft for the note 93 Draft::deleteForNamespace('task.response.'.$task->getId(), 94 $thisstaff->getId()); 95 96 } else { 97 if (!$errors['err']) 98 $errors['err'] = __('Unable to post the reply - missing or invalid data.'); 99 100 $errors['postreply'] = sprintf('%s %s', 101 __('Unable to post the reply.'), 102 __('Correct any errors below and try again.')); 103 } 104 break; 105 default: 106 $errors['err']=__('Unknown action'); 107 endswitch; 108 109 switch(strtolower($_POST['do'])): 110 case 'addcc': 111 $errors = array(); 112 if (!$role->hasPerm(Ticket::PERM_EDIT)) { 113 $errors['err']=__('Permission Denied. You are not allowed to add collaborators'); 114 } elseif (!$_POST['user_id'] || !($user=User::lookup($_POST['user_id']))) { 115 $errors['err'] = __('Unknown user selected'); 116 } elseif ($c2 = $task->addCollaborator($user, array(), $errors)) { 117 $c2->setFlag(Collaborator::FLAG_CC, true); 118 $c2->save(); 119 $msg = sprintf(__('Collaborator %s added'), 120 Format::htmlchars($user->getName())); 121 } 122 else 123 $errors['err'] = sprintf('%s %s', __('Unable to add collaborator.'), __('Please try again!')); 124 break; 125 endswitch; 126 } 127 if(!$errors) 128 $thisstaff->resetStats(); //We'll need to reflect any changes just made! 129endif; 130 131/*... Quick stats ...*/ 132$stats= $thisstaff->getTasksStats(); 133 134// Clear advanced search upon request 135if (isset($_GET['clear_filter'])) 136 unset($_SESSION['advsearch:tasks']); 137 138 139if (!$task) { 140 $queue_key = sprintf('::Q:%s', ObjectModel::OBJECT_TYPE_TASK); 141 $queue_name = strtolower($_GET['status'] ?: $_GET['a']); 142 if (!$queue_name && isset($_SESSION[$queue_key])) 143 $queue_name = $_SESSION[$queue_key]; 144 145 // Stash current queue view 146 $_SESSION[$queue_key] = $queue_name; 147 148 // Set queue as status 149 if (@!isset($_REQUEST['advanced']) 150 && @$_REQUEST['a'] != 'search' 151 && !isset($_GET['status']) 152 && $queue_name) 153 $_GET['status'] = $_REQUEST['status'] = $queue_name; 154} 155 156//Navigation 157$nav->setTabActive('tasks'); 158$open_name = _P('queue-name', 159 /* This is the name of the open tasks queue */ 160 'Open'); 161 162$nav->addSubMenu(array('desc'=>$open_name.' ('.number_format($stats['open']).')', 163 'title'=>__('Open Tasks'), 164 'href'=>'tasks.php?status=open', 165 'iconclass'=>'Ticket'), 166 ((!$_REQUEST['status'] && !isset($_SESSION['advsearch:tasks'])) || $_REQUEST['status']=='open')); 167 168if ($stats['assigned']) { 169 170 $nav->addSubMenu(array('desc'=>__('My Tasks').' ('.number_format($stats['assigned']).')', 171 'title'=>__('Assigned Tasks'), 172 'href'=>'tasks.php?status=assigned', 173 'iconclass'=>'assignedTickets'), 174 ($_REQUEST['status']=='assigned')); 175} 176 177if ($stats['overdue']) { 178 $nav->addSubMenu(array('desc'=>__('Overdue').' ('.number_format($stats['overdue']).')', 179 'title'=>__('Stale Tasks'), 180 'href'=>'tasks.php?status=overdue', 181 'iconclass'=>'overdueTickets'), 182 ($_REQUEST['status']=='overdue')); 183 184 if(!$sysnotice && $stats['overdue']>10) 185 $sysnotice=sprintf(__('%d overdue tasks!'), $stats['overdue']); 186} 187 188if ($stats['closed']) { 189 $nav->addSubMenu(array('desc' => __('Completed').' ('.number_format($stats['closed']).')', 190 'title'=>__('Completed Tasks'), 191 'href'=>'tasks.php?status=closed', 192 'iconclass'=>'closedTickets'), 193 ($_REQUEST['status']=='closed')); 194} 195 196if ($thisstaff->hasPerm(TaskModel::PERM_CREATE, false)) { 197 $nav->addSubMenu(array('desc'=>__('New Task'), 198 'title'=> __('Open a New Task'), 199 'href'=>'#tasks/add', 200 'iconclass'=>'newTicket new-task', 201 'id' => 'new-task', 202 'attr' => array( 203 'data-dialog-config' => '{"size":"large"}' 204 ) 205 ), 206 ($_REQUEST['a']=='open')); 207} 208 209 210$ost->addExtraHeader('<script type="text/javascript" src="js/ticket.js?6bd7884"></script>'); 211$ost->addExtraHeader('<script type="text/javascript" src="js/thread.js?6bd7884"></script>'); 212$ost->addExtraHeader('<meta name="tip-namespace" content="tasks.queue" />', 213 "$('#content').data('tipNamespace', 'tasks.queue');"); 214 215if($task) { 216 $ost->setPageTitle(sprintf(__('Task #%s'),$task->getNumber())); 217 $nav->setActiveSubMenu(-1); 218 $inc = 'task-view.inc.php'; 219 if ($_REQUEST['a']=='edit' 220 && $task->checkStaffPerm($thisstaff, TaskModel::PERM_EDIT)) { 221 $inc = 'task-edit.inc.php'; 222 if (!$forms) $forms=DynamicFormEntry::forObject($task->getId(), 'A'); 223 // Auto add new fields to the entries 224 foreach ($forms as $f) $f->addMissingFields(); 225 } elseif($_REQUEST['a'] == 'print' && !$task->pdfExport($_REQUEST['psize'])) 226 $errors['err'] = __('Unable to print to PDF.') 227 .' '.__('Internal error occurred'); 228} else { 229 $inc = 'tasks.inc.php'; 230 if ($_REQUEST['a']=='open' && 231 $thisstaff->hasPerm(Task::PERM_CREATE, false)) 232 $inc = 'task-open.inc.php'; 233 elseif($_REQUEST['a'] == 'export') { 234 $ts = strftime('%Y%m%d'); 235 if (!($query=$_SESSION[':Q:tasks'])) 236 $errors['err'] = __('Query token not found'); 237 elseif (!Export::saveTasks($query, "tasks-$ts.csv", 'csv')) 238 $errors['err'] = __('Unable to dump query results.') 239 .' '.__('Internal error occurred'); 240 } 241 242 //Clear active submenu on search with no status 243 if($_REQUEST['a']=='search' && !$_REQUEST['status']) 244 $nav->setActiveSubMenu(-1); 245 246 //set refresh rate if the user has it configured 247 if(!$_POST && !$_REQUEST['a'] && ($min=$thisstaff->getRefreshRate())) { 248 $js = "clearTimeout(window.task_refresh); 249 window.task_refresh = setTimeout($.refreshTaskView," 250 .($min*60000).");"; 251 $ost->addExtraHeader('<script type="text/javascript">'.$js.'</script>', 252 $js); 253 } 254} 255 256require_once(STAFFINC_DIR.'header.inc.php'); 257require_once(STAFFINC_DIR.$inc); 258require_once(STAFFINC_DIR.'footer.inc.php'); 259