Skip to content
Snippets Groups Projects
class.ticket.php 75.1 KiB
Newer Older
  • Learn to ignore specific revisions
  •                 $vars['slaId'] = $vars['slaId']?$vars['slaId']:$cfg->getDefaultSLAId();
                elseif($topic && $topic->getSLAId())
    
                    $vars['slaId'] = $topic->getSLAId();
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            }elseif($vars['emailId'] && !$vars['deptId'] && ($email=Email::lookup($vars['emailId']))) { //Emailed Tickets
                $deptId=$email->getDeptId();
    
                if (!$form->getAnswer('priority'))
                    $form->setAnswer('priority', null, $email->getPriorityId());
    
    Jared Hancock's avatar
    Jared Hancock committed
                if($autorespond) $autorespond=$email->autoRespond();
                $email=null;
                $source='Email';
            }
            //Last minute checks
    
            if (!$form->getAnswer('priority'))
                $form->setAnswer('priority', null, $cfg->getDefaultPriorityId());
    
    Jared Hancock's avatar
    Jared Hancock committed
            $deptId=$deptId?$deptId:$cfg->getDefaultDeptId();
            $topicId=$vars['topicId']?$vars['topicId']:0;
            $ipaddress=$vars['ip']?$vars['ip']:$_SERVER['REMOTE_ADDR'];
    
    Jared Hancock's avatar
    Jared Hancock committed
            //We are ready son...hold on to the rails.
            $extId=Ticket::genExtRandID();
            $sql='INSERT INTO '.TICKET_TABLE.' SET created=NOW() '
                .' ,lastmessage= NOW()'
    
                .' ,user_id='.db_input($user->id)
                .' ,user_email_id='.db_input($user_email->id)
    
    Jared Hancock's avatar
    Jared Hancock committed
                .' ,ticketID='.db_input($extId)
                .' ,dept_id='.db_input($deptId)
                .' ,topic_id='.db_input($topicId)
    
    Jared Hancock's avatar
    Jared Hancock committed
                .' ,source='.db_input($source);
    
            //Make sure the origin is staff - avoid firebug hack!
            if($vars['duedate'] && !strcasecmp($origin,'staff'))
                 $sql.=' ,duedate='.db_input(date('Y-m-d G:i',Misc::dbtime($vars['duedate'].' '.$vars['time'])));
    
    
            if(!db_query($sql) || !($id=db_insert_id()) || !($ticket =Ticket::lookup($id)))
                return null;
    
            /* -------------------- POST CREATE ------------------------ */
    
    Jared Hancock's avatar
    Jared Hancock committed
                //Sequential ticketIDs support really..really suck arse.
                $extId=$id; //To make things really easy we are going to use autoincrement ticket_id.
    
                db_query('UPDATE '.TICKET_TABLE.' SET ticketID='.db_input($extId).' WHERE ticket_id='.$id.' LIMIT 1');
    
    Jared Hancock's avatar
    Jared Hancock committed
                //TODO: RETHING what happens if this fails?? [At the moment on failure random ID is used...making stuff usable]
    
            // Save the (common) dynamic form
            $form->setTicketId($id);
            $form->save();
    
    
            $dept = $ticket->getDept();
    
    Jared Hancock's avatar
    Jared Hancock committed
            //post the message.
    
            unset($vars['cannedattachments']); //Ticket::open() might have it set as part of  open & respond.
            $vars['title'] = $vars['subject']; //Use the initial subject as title of the post.
            $message = $ticket->postMessage($vars , $origin, false);
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            // Configure service-level-agreement for this ticket
            $ticket->selectSLAId($vars['slaId']);
    
            //Auto assign staff or team - auto assignment based on filter rules.
            if($vars['staffId'] && !$vars['assignId'])
    
                 $ticket->assignToStaff($vars['staffId'], 'Auto Assignment');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if($vars['teamId'] && !$vars['assignId'])
    
                $ticket->assignToTeam($vars['teamId'], 'Auto Assignment');
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            /**********   double check auto-response  ************/
    
            //Override auto responder if the FROM email is one of the internal emails...loop control.
    
    Jared Hancock's avatar
    Jared Hancock committed
            if($autorespond && (Email::getIdByEmail($ticket->getEmail())))
                $autorespond=false;
    
            # Messages that are clearly auto-responses from email systems should
            # not have a return 'ping' message
    
            if ($autorespond && $message && $message->isAutoResponse())
    
    Jared Hancock's avatar
    Jared Hancock committed
                $autorespond=false;
    
            //Don't auto respond to mailer daemons.
            if( $autorespond &&
                (strpos(strtolower($vars['email']),'mailer-daemon@')!==false
                 || strpos(strtolower($vars['email']),'postmaster@')!==false)) {
                $autorespond=false;
            }
    
    
            //post canned auto-response IF any (disables new ticket auto-response).
    
            if ($vars['cannedResponseId']
    
                && $ticket->postCannedReply($vars['cannedResponseId'], $message->getId(), $autorespond)) {
                    $ticket->markUnAnswered(); //Leave the ticket as unanswred.
    
                    $autorespond = false;
    
            //Check department's auto response settings
            // XXX: Dept. setting doesn't affect canned responses.
            if($autorespond && $dept && !$dept->autoRespONNewTicket())
                $autorespond=false;
    
    
            /***** See if we need to send some alerts ****/
    
            $ticket->onNewTicket($message, $autorespond, $alertstaff);
    
            /************ check if the user JUST reached the max. open tickets limit **********/
            if($cfg->getMaxOpenTickets()>0
                        && ($client=$ticket->getClient())
                        && ($client->getNumOpenTickets()==$cfg->getMaxOpenTickets())) {
                $ticket->onOpenLimit(($autorespond && strcasecmp($origin, 'staff')));
            }
    
            /* Start tracking ticket lifecycle events */
            $ticket->logEvent('created');
    
    
            /* Phew! ... time for tea (KETEPA) */
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $ticket;
        }
    
    
        function open($vars, &$errors) {
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            if(!$thisstaff || !$thisstaff->canCreateTickets()) return false;
    
    
            if($vars['source'] && !in_array(strtolower($vars['source']),array('email','phone','other')))
                $errors['source']='Invalid source - '.Format::htmlchars($vars['source']);
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!($ticket=Ticket::create($vars, $errors, 'staff', false, (!$vars['assignId']))))
                return false;
    
            $vars['msgId']=$ticket->getLastMsgId();
    
    Jared Hancock's avatar
    Jared Hancock committed
            // post response - if any
    
            $response = null;
            if($vars['response'] && $thisstaff->canPostReply()) {
    
                $vars['response'] = $ticket->replaceVars($vars['response']);
    
                if(($response=$ticket->postReply($vars, $errors, false))) {
    
    Jared Hancock's avatar
    Jared Hancock committed
                    //Only state supported is closed on response
                    if(isset($vars['ticket_state']) && $thisstaff->canCloseTickets())
                        $ticket->setState($vars['ticket_state']);
                }
            }
    
    Jared Hancock's avatar
    Jared Hancock committed
            //Post Internal note
    
    Jared Hancock's avatar
    Jared Hancock committed
            if($vars['assignId'] && $thisstaff->canAssignTickets()) { //Assign ticket to staff or team.
    
                $ticket->assign($vars['assignId'], $vars['note']);
    
    Jared Hancock's avatar
    Jared Hancock committed
            } elseif($vars['note']) { //Not assigned...save optional note if any
    
    Peter Rotich's avatar
    Peter Rotich committed
                $ticket->logNote('New Ticket', $vars['note'], $thisstaff, false);
    
    Jared Hancock's avatar
    Jared Hancock committed
            } else { //Not assignment and no internal note - log activity
                $ticket->logActivity('New Ticket by Staff','Ticket created by staff -'.$thisstaff->getName());
            }
    
            $ticket->reload();
    
            if(!$cfg->notifyONNewStaffTicket() || !isset($vars['alertuser']))
    
    Jared Hancock's avatar
    Jared Hancock committed
                return $ticket; //No alerts.
    
            //Send Notice to user --- if requested AND enabled!!
    
    Jared Hancock's avatar
    Jared Hancock committed
            $dept=$ticket->getDept();
            if(!$dept || !($tpl=$dept->getTemplate()))
                $tpl=$cfg->getDefaultTemplate();
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!$dept || !($email=$dept->getEmail()))
                $email =$cfg->getDefaultEmail();
    
            if($tpl && ($msg=$tpl->getNewTicketNoticeMsgTemplate()) && $email) {
    
                $message = $vars['issue'];
    
                if($response)
                    $message.="\n\n".$response->getBody();
    
    Jared Hancock's avatar
    Jared Hancock committed
    
                if($vars['signature']=='mine')
                    $signature=$thisstaff->getSignature();
                elseif($vars['signature']=='dept' && $dept && $dept->isPublic())
                    $signature=$dept->getSignature();
                else
                    $signature='';
    
                $attachments =($cfg->emailAttachments() && $response)?$response->getAttachments():array();
    
    
                $msg = $ticket->replaceVars($msg->asArray(),
    
                        array('message' => $message, 'signature' => $signature));
    
    Jared Hancock's avatar
    Jared Hancock committed
    
                if($cfg->stripQuotedReply() && ($tag=trim($cfg->getReplySeparator())))
    
                    $msg['body'] ="\n$tag\n\n".$msg['body'];
    
                $references = $ticket->getLastMessage()->getEmailMessageId();
                if (isset($response))
                    $references = array($response->getEmailMessageId(), $references);
                $options = array('references' => $references);
                $email->send($ticket->getEmail(), $msg['subj'], $msg['body'], $attachments,
                    $options);
    
    Jared Hancock's avatar
    Jared Hancock committed
            }
    
            return $ticket;
    
        function checkOverdue() {
    
            $sql='SELECT ticket_id FROM '.TICKET_TABLE.' T1 '
    
                .' INNER JOIN '.SLA_TABLE.' T2 ON (T1.sla_id=T2.id AND T2.isactive=1) '
    
                .' WHERE status=\'open\' AND isoverdue=0 '
                .' AND ((reopened is NULL AND duedate is NULL AND TIME_TO_SEC(TIMEDIFF(NOW(),T1.created))>=T2.grace_period*3600) '
                .' OR (reopened is NOT NULL AND duedate is NULL AND TIME_TO_SEC(TIMEDIFF(NOW(),reopened))>=T2.grace_period*3600) '
                .' OR (duedate is NOT NULL AND duedate<NOW()) '
                .' ) ORDER BY T1.created LIMIT 50'; //Age upto 50 tickets at a time?
    
    Jared Hancock's avatar
    Jared Hancock committed
            //echo $sql;
    
            if(($res=db_query($sql)) && db_num_rows($res)) {
                while(list($id)=db_fetch_row($res)) {
    
    Jared Hancock's avatar
    Jared Hancock committed
                    if(($ticket=Ticket::lookup($id)) && $ticket->markOverdue())
    
                        $ticket->logActivity('Ticket Marked Overdue', 'Ticket flagged as overdue by the system.');
    
            } else {
                //TODO: Trigger escalation on already overdue tickets - make sure last overdue event > grace_period.