help.verua.ch/scp/tickets.php

477 lines
25 KiB
PHP
Raw Permalink Normal View History

2026-01-05 08:46:20 +01:00
<?php
/*************************************************************************
tickets.php
Handles all tickets related actions.
Peter Rotich <peter@osticket.com>
Copyright (c) 2006-2010 osTicket
http://www.osticket.com
Released under the GNU General Public License WITHOUT ANY WARRANTY.
See LICENSE.TXT for details.
vim: expandtab sw=4 ts=4 sts=4:
$Id: $
**********************************************************************/
require('staff.inc.php');
require_once(INCLUDE_DIR.'class.ticket.php');
require_once(INCLUDE_DIR.'class.dept.php');
require_once(INCLUDE_DIR.'class.banlist.php');
$page='';
$ticket=null; //clean start.
//LOCKDOWN...See if the id provided is actually valid and if the user has access.
if(!$errors && ($id=$_REQUEST['id']?$_REQUEST['id']:$_POST['ticket_id']) && is_numeric($id)) {
$deptID=0;
$ticket= new Ticket($id);
if(!$ticket or !$ticket->getDeptId())
$errors['err']='Unbekannte Ticket ID#'.$id; //Sucker...invalid id
elseif(!$thisuser->isAdmin() && (!$thisuser->canAccessDept($ticket->getDeptId()) && $thisuser->getId()!=$ticket->getStaffId()))
$errors['err']='Zugriff verweigert. Denken Sie, dass dies ein Fehler ist, kontaktieren Sie den Administrator';
if(!$errors && $ticket->getId()==$id)
$page='viewticket.inc.php'; //Default - view
if(!$errors && $_REQUEST['a']=='edit') { //If it's an edit check permission.
if($thisuser->canEditTickets() || ($thisuser->isManager() && $ticket->getDeptId()==$thisuser->getDeptId()))
$page='editticket.inc.php';
else
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt das Ticket zu &auml;ndern. Denken Sie, dass dies ein Fehler ist, kontaktieren Sie den Administrator';
}
}elseif($_REQUEST['a']=='open') {
//TODO: Check perm here..
$page='newticket.inc.php';
}
//At this stage we know the access status. we can process the post.
if($_POST && !$errors):
if($ticket && $ticket->getId()) {
//More tea please.
$errors=array();
$lock=$ticket->getLock(); //Ticket lock if any
$statusKeys=array('open'=>'Offen','Reopen'=>'Offen','Close'=>'Geschlossen');
switch(strtolower($_POST['a'])):
case 'reply':
$fields=array();
$fields['msg_id'] = array('type'=>'int', 'required'=>1, 'error'=>'Nachrichten-ID fehlt');
$fields['response'] = array('type'=>'text', 'required'=>1, 'error'=>'Antwort erforderlich');
$params = new Validator($fields);
if(!$params->validate($_POST)){
$errors=array_merge($errors,$params->errors());
}
//Use locks to avoid double replies
if($lock && $lock->getStaffId()!=$thisuser->getId())
$errors['err']='Aktion verweigert. Ticket ist durch jemand anderen gesperrt!';
//Check attachments restrictions.
if($_FILES['attachment'] && $_FILES['attachment']['size']) {
if(!$_FILES['attachment']['name'] || !$_FILES['attachment']['tmp_name'])
$errors['attachment']='Ung&uuml;ltiger Anhang';
elseif(!$cfg->canUploadFiles()) //TODO: saved vs emailed attachments...admin config??
$errors['attachment']='Ung&uuml;ltige Verzeichnis. Administrator kontaktieren.';
elseif(!$cfg->canUploadFileType($_FILES['attachment']['name']))
$errors['attachment']='Ung&uuml;ltiger Dateityp';
}
//Make sure the email is not banned
if(!$errors && BanList::isbanned($ticket->getEmail()))
$errors['err']='Email befindet sich auf der Sperrliste. Bitte erst enfernen um zu antworten.';
//If no error...do the do.
if(!$errors && ($respId=$ticket->postResponse($_POST['msg_id'],$_POST['response'],$_POST['signature'],$_FILES['attachment']))){
$msg='Antwort erfolgreich erstellt';
//Set status if any.
$wasOpen=$ticket->isOpen();
if(isset($_POST['ticket_status']) && $_POST['ticket_status']) {
if($ticket->setStatus($_POST['ticket_status']) && $ticket->reload()) {
$note=sprintf('%s %s das Ticket von ',$thisuser->getName(),$ticket->isOpen()?'wieder ge&ouml;ffnet':'geschlossen');
$ticket->logActivity('Ticketstatus wurde ge&auml;ndert auf '.($ticket->isOpen()?'Offen':'Geschlossen'),$note);
}
}
//Finally upload attachment if any
if($_FILES['attachment'] && $_FILES['attachment']['size']){
$ticket->uploadAttachment($_FILES['attachment'],$respId,'R');
}
$ticket->reload();
//Mark the ticket answered if OPEN.
if($ticket->isopen()){
$ticket->markAnswered();
}elseif($wasOpen) { //Closed on response???
$page=$ticket=null; //Going back to main listing.
}
}elseif(!$errors['err']){
$errors['err']='Senden der Anwort war nicht m&ouml;glich.';
}
break;
case 'transfer':
$fields=array();
$fields['dept_id'] = array('type'=>'int', 'required'=>1, 'error'=>'Abteilung w&auml;hlen');
$fields['message'] = array('type'=>'text', 'required'=>1, 'error'=>'Notiz/Nachricht erforderlich');
$params = new Validator($fields);
if(!$params->validate($_POST)){
$errors=array_merge($errors,$params->errors());
}
if(!$errors && ($_POST['dept_id']==$ticket->getDeptId()))
$errors['dept_id']='Ticket befindet sich bereit in dieser Abteilung.';
if(!$errors && !$thisuser->canTransferTickets())
$errors['err']='Aktion verweigert. Sie sind nicht berechtigt Tickets zuzuweisen.';
if(!$errors && $ticket->transfer($_POST['dept_id'])){
$olddept=$ticket->getDeptName();
$ticket->reload(); //dept manager changed!
//Send out alerts?? - for now yes....part of internal note!
$title='Abteilungszuweisung von '.$olddept.' zur '.$ticket->getDeptName();
$ticket->postNote($title,$_POST['message']);
$msg='Ticket erfolgreich zu der Abteilung '.$ticket->getDeptName().' verschoben';
if(!$thisuser->canAccessDept($_POST['dept_id']) && $ticket->getStaffId()!=$thisuser->getId()) { //Check access.
//Staff doesn't have access to the new department.
$page='tickets.inc.php';
$ticket=null;
}
}elseif(!$errors['err']){
$errors['err']='Zuweisung konnte nicht abgeschlossen werden.';
}
break;
case 'assign':
$fields=array();
$fields['staffId'] = array('type'=>'int', 'required'=>1, 'error'=>'Bitte zuweisen');
$fields['assign_message'] = array('type'=>'text', 'required'=>1, 'error'=>'Nachricht erforderlich');
$params = new Validator($fields);
if(!$params->validate($_POST)){
$errors=array_merge($errors,$params->errors());
}
if(!$errors && $ticket->isAssigned()){
if($_POST['staffId']==$ticket->getStaffId())
$errors['staffId']='Ticket ist bereits dem Mitarbeiter zugewiessen.';
}
//if already assigned.
if(!$errors && $ticket->isAssigned()) { //Re assigning.
//Already assigned to the user?
if($_POST['staffId']==$ticket->getStaffId())
$errors['staffId']='Ticket ist bereits dem Mitarbeiter zugewiessen.';
//Admin, Dept manager (any) or current assigneee ONLY can reassign
if(!$thisuser->isadmin() && !$thisuser->isManager() && $thisuser->getId()!=$ticket->getStaffId())
$errors['err']='Ticket ist bereits zugewiesen. Sie sind nicht berechtigt zugewiesene Ticket neu zuzuweisen.';
}
if(!$errors && $ticket->assignStaff($_POST['staffId'],$_POST['assign_message'])){
$staff=$ticket->getStaff();
$msg='Ticket an '.($staff?$staff->getName():'staff').' zugewiesen';
//Remove all the logs and go back to index page.
TicketLock::removeStaffLocks($thisuser->getId(),$ticket->getId());
$page='tickets.inc.php';
$ticket=null;
}elseif(!$errors['err']) {
$errors['err']='Ticketzuweisung nicht m&ouml;glich';
}
break;
case 'postnote':
$fields=array();
$fields['title'] = array('type'=>'string', 'required'=>1, 'error'=>'Titel erforderlich');
$fields['note'] = array('type'=>'string', 'required'=>1, 'error'=>'Notiz erforderlich');
$params = new Validator($fields);
if(!$params->validate($_POST))
$errors=array_merge($errors,$params->errors());
if(!$errors && $ticket->postNote($_POST['title'],$_POST['note'])){
$msg='Interne Notiz erstellt';
if(isset($_POST['ticket_status']) && $_POST['ticket_status']){
if($ticket->setStatus($_POST['ticket_status']) && $ticket->reload()){
$msg.=' und Status gesetzt auf '.($ticket->isClosed()?'geschlossen':'offen');
if($ticket->isClosed())
$page=$ticket=null; //Going back to main listing.
}
}
}elseif(!$errors['err']) {
$errors['err']='Fehler aufgetreten. Notiz erstellen nicht m&ouml;glich.';
}
break;
case 'update':
$page='editticket.inc.php';
if(!$ticket || !$thisuser->canEditTickets())
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt Tickets zu bearbeiten';
elseif($ticket->update($_POST,$errors)){
$msg='Ticket erfolgreich ge&auml;ndert';
$page='viewticket.inc.php';
}elseif(!$errors['err']) {
$errors['err']='Fehler aufgetreten! Bitte nochmals versuchen.';
}
break;
case 'process':
$isdeptmanager=($ticket->getDeptId()==$thisuser->getDeptId())?true:false;
switch(strtolower($_POST['do'])):
case 'change_priority':
if(!$thisuser->canManageTickets() && !$thisuser->isManager()){
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt die Priorit&auml;t der Tickets zu &auml;ndern.';
}elseif(!$_POST['ticket_priority'] or !is_numeric($_POST['ticket_priority'])){
$errors['err']='Sie m&uuml;ssen eine Priorit&auml;t w&auml;hlen';
}
if(!$errors){
if($ticket->setPriority($_POST['ticket_priority'])){
$msg='Priorit&auml;t erfolgreich ge&auml;ndert';
$ticket->reload();
$note='Ticketpriorit&auml;t wurde ge&auml;ndert auf "'.$ticket->getPriority().'" durch '.$thisuser->getName();
$ticket->logActivity('Priorit&auml;t ge&auml;ndert',$note);
}else{
$errors['err']='Probleme beim &Auml;ndern der Priorit&auml;t. Bitte nochmals versuchen.';
}
}
break;
case 'close':
if(!$thisuser->isadmin() && !$thisuser->canCloseTickets()){
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt Tickets zu schlie&beta;en.';
}else{
if($ticket->close()){
$msg='Ticket #'.$ticket->getExtId().' wurde GESCHLOSSEN';
$note='Ticket wurde mit einer Nachricht geschlossen von '.$thisuser->getName();
$ticket->logActivity('Ticket geschlossen',$note);
$page=$ticket=null; //Going back to main listing.
}else{
$errors['err']='Probleme beim Schlie&beta;en des Ticket. Bitte nochmals versuchen.';
}
}
break;
case 'reopen':
//if they can close...then assume they can reopen.
if(!$thisuser->isadmin() && !$thisuser->canCloseTickets()){
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt Tickets wieder zu &ouml;ffnen.';
}else{
if($ticket->reopen()){
$msg='Ticketstatus wurde auf OFFEN gesetzt';
$note='Ticket wieder ge&ouml;ffnet (ohne Kommentare)';
if($_POST['ticket_priority']) {
$ticket->setPriority($_POST['ticket_priority']);
$ticket->reload();
$note.=' und Pririt&auml;t gesetzt auf '.$ticket->getPriority();
}
$note.=' durch '.$thisuser->getName();
$ticket->logActivity('Ticket wieder ge&ouml;ffnet',$note);
}else{
$errors['err']='Probleme bei Wiederer&ouml;ffnen des Tickets. Bitte nochmals versuchen.';
}
}
break;
case 'release':
if(!($staff=$ticket->getStaff()))
$errors['err']='Ticket ist ist nicht zugewiesen!';
elseif($ticket->release()) {
$msg='Ticket freigegeben (nicht zugewiesen) durch '.$staff->getName().' von '.$thisuser->getName();
$ticket->logActivity('Ticket nicht zugewiesen',$msg);
}else
$errors['err']='Probleme beim Freigeben des Tickets. Bitte nochmals versuchen';
break;
case 'overdue':
//Mark the ticket as overdue
if(!$thisuser->isadmin() && !$thisuser->isManager()){
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt Ticket auf &Uuml;berf&auml;llig zu setzen.';
}else{
if($ticket->markOverdue()){
$msg='Ticket ist als &uuml;berf&auml;llig markiert';
$note=$msg;
if($_POST['ticket_priority']) {
$ticket->setPriority($_POST['ticket_priority']);
$ticket->reload();
$note.=' und Status gesetzt auf '.$ticket->getPriority();
}
$note.=' von '.$thisuser->getName();
$ticket->logActivity('Ticket als &Uuml;berf&auml;llig markiert',$note);
}else{
$errors['err']='Probleme beim markieren als &Uuml;berf&auml;llig. Bitte nochmals versuchen';
}
}
break;
case 'banemail':
if(!$thisuser->isadmin() && !$thisuser->canManageBanList()){
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt Emails zur Sperrliste hinzuzuf&uuml;gen';
}elseif(Banlist::add($ticket->getEmail(),$thisuser->getName())){
$msg='Email ('.$ticket->getEmail().') zur Sperrliste hinzugef&uuml;t';
if($ticket->isOpen() && $ticket->close()) {
$msg.=' & Ticketstatus auf geschlossen gesetzt';
$ticket->logActivity('Ticket geschlossen',$msg);
$page=$ticket=null; //Going back to main listing.
}
}else{
$errors['err']='Hinzuf&uuml;gen zur Sperrliste nicht m&ouml;glich';
}
break;
case 'unbanemail':
if(!$thisuser->isadmin() && !$thisuser->canManageBanList()){
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt Email-Adressen von der Sperrliste zu entfernen.';
}elseif(Banlist::remove($ticket->getEmail())){
$msg='Email von Sperrliste entfernt';
}else{
$errors['err']='Entfernen von Sperrliste nicht m&ouml;glich. Bitte nochmals versuchen.';
}
break;
case 'delete': // Dude what are you trying to hide? bad customer support??
if(!$thisuser->isadmin() && !$thisuser->canDeleteTickets()){
$errors['err']='Zugriff verweigert. Sie sind nicht berechtigt Tickets zu l&ouml;schen!';
}else{
if($ticket->delete()){
$page='tickets.inc.php'; //ticket is gone...go back to the listing.
$msg='Ticket F&Uuml;R IMMER gel&ouml;scht';
$ticket=null; //clear the object.
}else{
$errors['err']='Probleme bei L&ouml;schen des Tickets. Bitte nochmals versuchen';
}
}
break;
default:
$errors['err']='Sie m&uuml;ssen eine Aktion ausw&auml;hlen um fortzufahren';
endswitch;
break;
default:
$errors['err']='Unbekannte Aktion';
endswitch;
if($ticket && is_object($ticket))
$ticket->reload();//Reload ticket info following post processing
}elseif($_POST['a']) {
switch($_POST['a']) {
case 'mass_process':
if(!$thisuser->canManageTickets())
$errors['err']='Sie haben keine Berechtigung mehrere Tickets gleichzeitig zu verwalten. Kontaktieren Sie bitte den Administrator um dieses Recht zu erhalten.';
elseif(!$_POST['tids'] || !is_array($_POST['tids']))
$errors['err']='Keine Tickets ausgew&auml;hlt. Sie m&uuml;ssen mindestens ein Ticket ausw&auml;hlen.';
elseif(($_POST['reopen'] || $_POST['close']) && !$thisuser->canCloseTickets())
$errors['err']='Sie haben keine Berechtigung Tickets zu schlie&beta;en oder wieder zu er&ouml;ffnen.';
elseif($_POST['delete'] && !$thisuser->canDeleteTickets())
$errors['err']='Sie haben keine Berechtigung Tickets zu l&ouml;schen';
elseif(!$_POST['tids'] || !is_array($_POST['tids']))
$errors['err']='Sie m&uuml;ssen mindestens ein Ticket ausw&auml;hlen';
if(!$errors) {
$count=count($_POST['tids']);
if(isset($_POST['reopen'])){
$i=0;
$note='Ticket wieder ge&ouml;ffnet durch '.$thisuser->getName();
foreach($_POST['tids'] as $k=>$v) {
$t = new Ticket($v);
if($t && @$t->reopen()) {
$i++;
$t->logActivity('Ticket wieder ge&ouml;ffnet',$note,false,'System');
}
}
$msg="$i von $count gew&auml;hlten Tickets wieder ge&ouml;ffnet";
}elseif(isset($_POST['close'])){
$i=0;
$note='Ticket ohne Antwort geschlossen durch '.$thisuser->getName();
foreach($_POST['tids'] as $k=>$v) {
$t = new Ticket($v);
if($t && @$t->close()){
$i++;
$t->logActivity('Ticket geschlossen',$note,false,'System');
}
}
$msg="$i von $count gew&auml;hlten Tickets geschlossen";
}elseif(isset($_POST['overdue'])){
$i=0;
$note='Ticket als &uuml;berf&auml;llig markiert durch '.$thisuser->getName();
foreach($_POST['tids'] as $k=>$v) {
$t = new Ticket($v);
if($t && !$t->isoverdue())
if($t->markOverdue()) {
$i++;
$t->logActivity('Ticket als &Uuml;berf&auml;llig markiert',$note,false,'System');
}
}
$msg="$i von $count gew&auml;hlten Tickets als &uuml;berf&auml;llig markiert";
}elseif(isset($_POST['delete'])){
$i=0;
foreach($_POST['tids'] as $k=>$v) {
$t = new Ticket($v);
if($t && @$t->delete()) $i++;
}
$msg="$i von $count gew&auml;hlten Tickets gel&ouml;scht";
}
}
break;
case 'open':
$ticket=null;
//TODO: check if the user is allowed to create a ticet.
if(($ticket=Ticket::create_by_staff($_POST,$errors))) {
$ticket->reload();
$msg='Ticket erfolgreich erstellt';
if($thisuser->canAccessDept($ticket->getDeptId()) || $ticket->getStaffId()==$thisuser->getId()) {
//View the sucker
$page='viewticket.inc.php';
}else {
//Staff doesn't have access to the newly created ticket's department.
$page='tickets.inc.php';
$ticket=null;
}
}elseif(!$errors['err']) {
$errors['err']='Erstellung des Tickets nicht m&ouml;glich. Beheben sie die Fehler und versuchen es erneut.';
}
break;
}
}
$crap='';
endif;
//Navigation
$submenu=array();
/*quick stats...*/
$sql='SELECT count(open.ticket_id) as open, count(answered.ticket_id) as answered '.
',count(overdue.ticket_id) as overdue, count(assigned.ticket_id) as assigned '.
' FROM '.TICKET_TABLE.' ticket '.
'LEFT JOIN '.TICKET_TABLE.' open ON open.ticket_id=ticket.ticket_id AND open.status=\'open\' AND open.isanswered=0 '.
'LEFT JOIN '.TICKET_TABLE.' answered ON answered.ticket_id=ticket.ticket_id AND answered.status=\'open\' AND answered.isanswered=1 '.
'LEFT JOIN '.TICKET_TABLE.' overdue ON overdue.ticket_id=ticket.ticket_id AND overdue.status=\'open\' AND overdue.isoverdue=1 '.
'LEFT JOIN '.TICKET_TABLE.' assigned ON assigned.ticket_id=ticket.ticket_id AND assigned.staff_id='.db_input($thisuser->getId());
if(!$thisuser->isAdmin()){
$sql.=' WHERE ticket.dept_id IN('.implode(',',$thisuser->getDepts()).') OR ticket.staff_id='.db_input($thisuser->getId());
}
//echo $sql;
$stats=db_fetch_array(db_query($sql));
//print_r($stats);
$nav->setTabActive('tickets');
if($cfg->showAnsweredTickets()) {
$nav->addSubMenu(array('desc'=>'Offen ('.($stats['open']+$stats['answered']).')','title'=>'Offene Tickets', 'href'=>'tickets.php', 'iconclass'=>'Ticket'));
}else{
if($stats['open'])
$nav->addSubMenu(array('desc'=>'Offen ('.$stats['open'].')','title'=>'Offene Tickets', 'href'=>'tickets.php', 'iconclass'=>'Ticket'));
if($stats['answered']) {
$nav->addSubMenu(array('desc'=>'Beantwortet ('.$stats['answered'].')','title'=>'Beantwortete Tickets', 'href'=>'tickets.php?status=answered', 'iconclass'=>'answeredTickets'));
}
}
if($stats['assigned']) {
if(!$sysnotice && $stats['assigned']>10)
$sysnotice=$stats['assigned'].' Ihnen zugewiesen!';
$nav->addSubMenu(array('desc'=>'Zugewiesen ('.$stats['assigned'].')','title'=>'Mir zugewiesene Tickets','href'=>'tickets.php?status=assigned','iconclass'=>'assignedTickets'));
}
if($stats['overdue']) {
$nav->addSubMenu(array('desc'=>'&Uuml;berf&auml;llig ('.$stats['overdue'].')','title'=>'&Uuml;berf&auml;lligene Tickets',
'href'=>'tickets.php?status=overdue','iconclass'=>'overdueTickets'));
if(!$sysnotice && $stats['overdue']>10)
$sysnotice=$stats['overdue'] .' &uuml;berf&auml;llige Tickets!';
}
$nav->addSubMenu(array('desc'=>'Geschlossen','title'=>'Geschlossene Tickets', 'href'=>'tickets.php?status=closed', 'iconclass'=>'closedTickets'));
if($thisuser->canCreateTickets()) {
$nav->addSubMenu(array('desc'=>'Neues Ticket','href'=>'tickets.php?a=open','iconclass'=>'newTicket'));
}
//Render the page...
$inc=$page?$page:'tickets.inc.php';
//If we're on tickets page...set refresh rate if the user has it configured. No refresh on search and POST to avoid repost.
if(!$_POST && $_REQUEST['a']!='search' && !strcmp($inc,'tickets.inc.php') && ($min=$thisuser->getRefreshRate())){
define('AUTO_REFRESH',1);
}
require_once(STAFFINC_DIR.'header.inc.php');
require_once(STAFFINC_DIR.$inc);
require_once(STAFFINC_DIR.'footer.inc.php');
?>