function onTicketCreated($answer) { try { global $ost; if (!($ticket = Ticket::lookup($answer->object_id))) { die('Unknown or invalid ticket ID.'); } //Slack payload $payload = array('attachments' => array(array('pretext' => "New Ticket <" . $ost->getConfig()->getUrl() . "scp/tickets.php?id=" . $ticket->getId() . "|#" . $ticket->getId() . "> in " . Format::htmlchars($ticket->getDept() instanceof Dept ? $ticket->getDept()->getName() : '') . " via " . $ticket->getSource() . " (" . Format::db_datetime($ticket->getCreateDate()) . ")", 'fallback' => "New Ticket <" . $ost->getConfig()->getUrl() . "scp/tickets.php?id=" . $ticket->getId() . "|#" . $ticket->getId() . "> in " . Format::htmlchars($ticket->getDept() instanceof Dept ? $ticket->getDept()->getName() : '') . " via " . $ticket->getSource() . " (" . Format::db_datetime($ticket->getCreateDate()) . ")", 'color' => "#D00000", 'fields' => array(array('title' => "From: " . mb_convert_case(Format::htmlchars($ticket->getName()), MB_CASE_TITLE) . " (" . $ticket->getEmail() . ")", 'value' => '', 'short' => false))))); //Curl to webhook $data_string = utf8_encode(json_encode($payload)); $url = $this->getConfig()->get('slack-webhook-url'); if (!function_exists('curl_init')) { error_log('osticket slackplugin error: cURL is not installed!'); } $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $result = curl_exec($ch); if ($result === false) { error_log($url . ' - ' . curl_error($ch)); } else { $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($statusCode != '200') { error_log($url . ' Http code: ' . $statusCode); } } curl_close($ch); } catch (Exception $e) { error_log('Error posting to Slack. ' . $e->getMessage()); } }
function delete() { if (($ticket = Ticket::lookup($this->getId())) && @$ticket->delete()) { return true; } return false; }
function cannedResp($id, $format = '') { global $thisstaff, $_GET; include_once INCLUDE_DIR . 'class.canned.php'; if (!$id || !($canned = Canned::lookup($id)) || !$canned->isEnabled()) { Http::response(404, 'No such premade reply'); } //Load ticket. if ($_GET['tid']) { include_once INCLUDE_DIR . 'class.ticket.php'; $ticket = Ticket::lookup($_GET['tid']); } switch ($format) { case 'json': $resp['id'] = $canned->getId(); $resp['ticket'] = $canned->getTitle(); $resp['response'] = $ticket ? $ticket->replaceVars($canned->getResponse()) : $canned->getResponse(); $resp['files'] = $canned->getAttachments(); $response = $this->json_encode($resp); break; case 'txt': default: $response = $ticket ? $ticket->replaceVars($canned->getResponse()) : $canned->getResponse(); } return $response; }
public function addByTicketAction($id = 0) { $args = array(); if (isset($id) && $id > 0) { $ticket = Ticket::lookup($id); } $ticket_items = Equipment_Ticket::getAllTickets(); $tickets = array(); foreach ($ticket_items as $item) { $ti = array('id' => $item->getId(), 'number' => $item->getNumber(), 'subject' => $item->getSubject()); $tickets[] = $ti; } $equipment_items = Equipment_Ticket::getAllEquipment(); $equipments = array(); foreach ($equipment_items as $item) { $ti = array('id' => $item->id, 'asset_id' => $item->asset_id); $equipments[] = $ti; } $title = 'New Recurring Ticket'; $args['ticket'] = $ticket; $args['tickets'] = $tickets; $args['equipments'] = $equipments; $args['title'] = $title; $template_name = $this->getAddTemplateName(); $this->render($template_name, $args); }
public function getTicket() { if ($this->ticket_id > 0) { return \Ticket::lookup($this->ticket_id); } return null; }
function acquireLock($tid) { global $cfg, $thisstaff; if (!$tid or !is_numeric($tid) or !$thisstaff or !$cfg) { return 0; } $ticket = Ticket::lookup($tid); if (!$ticket || !$ticket->checkStaffAccess($thisstaff)) { return $this->json_encode(array('id' => 0, 'retry' => false, 'msg' => 'Lock denied!')); } //is the ticket already locked? if ($ticket->isLocked() && ($lock = $ticket->getLock()) && !$lock->isExpired()) { /*Note: Ticket->acquireLock does the same logic...but we need it here since we need to know who owns the lock up front*/ //Ticket is locked by someone else.?? if ($lock->getStaffId() != $thisstaff->getId()) { return $this->json_encode(array('id' => 0, 'retry' => false, 'msg' => 'Unable to acquire lock.')); } //Ticket already locked by staff...try renewing it. $lock->renew(); //New clock baby! return $this->json_encode(array('id' => $lock->getId(), 'time' => $lock->getTime())); } //Ticket is not locked or the lock is expired...try locking it... if ($lock = $ticket->acquireLock($thisstaff->getId(), $cfg->getLockTime())) { //Set the lock. return $this->json_encode(array('id' => $lock->getId(), 'time' => $lock->getTime())); } //unable to obtain the lock..for some really weired reason! //Client should watch for possible loop on retries. Max attempts? return $this->json_encode(array('id' => 0, 'retry' => true)); }
function getTicket() { if (!$this->ticket && $this->getTicketId()) { $this->ticket = Ticket::lookup($this->getTicketId()); } return $this->ticket; }
function onThreadEntry($threadEntry) { if ($threadEntry->getType() == "N") { return; } //system entry $ticket = Ticket::lookup($threadEntry->ht['ticket_id']); $recip = $ticket->getRecipients(); // conntact api for each recipient foreach ($recip as $user) { //skip thread entry creator if ($threadEntry->getUserId() == $user->getId()) { continue; } //$fields = $this->getConfig()->get('webapi-fields'); try { //format Your payload as Your api need $payload = array('method' => 'addNotification', 'params' => array('ticketID' => $ticket->getId(), 'title' => $ticket->getSubject(), 'value' => $threadEntry->getBody(), 'poster' => $threadEntry->getPoster())); $data_string = utf8_encode(json_encode($payload)); $url = $this->getConfig()->get('webapi-url'); $ch = curl_init($url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($data_string))); $content = curl_exec($ch); if ($content === false) { throw new Exception($url . ' - ' . curl_error($ch)); } else { $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($statusCode != '200') { throw new Exception($url . ' Http code: ' . $statusCode); } } curl_close($ch); } catch (Exception $e) { error_log('Error posting to Web API. ' . $e->getMessage()); } } }
<?php require('staff.inc.php'); require_once(INCLUDE_DIR.'class.ticket.php'); require_once(INCLUDE_DIR.'class.dept.php'); if($_REQUEST['transferDeptId']==0) { echo ("not an available department"); } else{ $dept=Dept::lookup($_REQUEST['transferDeptId']); $count = count($_REQUEST['tids']); $i=0; foreach ($_REQUEST['tids'] as $tid) { if (($ticket=Ticket::lookup($tid))) { $ticket->setDeptId($_REQUEST['transferDeptId']); $ticket->setStaffId(0); $ticket->setTeamId(0); $ticket->setSLAId($dept->getSLAId()); if($ticket->getTeamId()==0&&$ticket->getStaffId()==0) $i++; } } echo "Transferred ".$i." tickets successfully"; } ?>
/** * Cooperates with the cron system to automatically find content that is * not index in the _search table and add it to the index. */ function IndexOldStuff() { $class = get_class(); $auto_create = function ($db_error) use($class) { if ($db_error != 1146) { // Perform the standard error handling return true; } // Create the search table automatically $class::__init(); }; // THREADS ---------------------------------- $sql = "SELECT A1.`id`, A1.`title`, A1.`body`, A1.`format` FROM `" . TICKET_THREAD_TABLE . "` A1\n LEFT JOIN `" . TABLE_PREFIX . "_search` A2 ON (A1.`id` = A2.`object_id` AND A2.`object_type`='H')\n WHERE A2.`object_id` IS NULL AND (A1.poster <> 'SYSTEM')\n AND (LENGTH(A1.`title`) + LENGTH(A1.`body`) > 0)\n ORDER BY A1.`id` DESC"; if (!($res = db_query_unbuffered($sql, $auto_create))) { return false; } while ($row = db_fetch_row($res)) { $body = ThreadBody::fromFormattedText($row[2], $row[3]); $body = $body->getSearchable(); $title = Format::searchable($row[1]); if (!$body && !$title) { continue; } $record = array('H', $row[0], $title, $body); if (!$this->__index($record)) { return; } } // TICKETS ---------------------------------- $sql = "SELECT A1.`ticket_id` FROM `" . TICKET_TABLE . "` A1\n LEFT JOIN `" . TABLE_PREFIX . "_search` A2 ON (A1.`ticket_id` = A2.`object_id` AND A2.`object_type`='T')\n WHERE A2.`object_id` IS NULL\n ORDER BY A1.`ticket_id` DESC"; if (!($res = db_query_unbuffered($sql, $auto_create))) { return false; } while ($row = db_fetch_row($res)) { $ticket = Ticket::lookup($row[0]); $cdata = $ticket->loadDynamicData(); $content = array(); foreach ($cdata as $k => $a) { if ($k != 'subject' && ($v = $a->getSearchable())) { $content[] = $v; } } $record = array('T', $ticket->getId(), Format::searchable($ticket->getNumber() . ' ' . $ticket->getSubject()), implode("\n", $content)); if (!$this->__index($record)) { return; } } // USERS ------------------------------------ $sql = "SELECT A1.`id` FROM `" . USER_TABLE . "` A1\n LEFT JOIN `" . TABLE_PREFIX . "_search` A2 ON (A1.`id` = A2.`object_id` AND A2.`object_type`='U')\n WHERE A2.`object_id` IS NULL\n ORDER BY A1.`id` DESC"; if (!($res = db_query_unbuffered($sql, $auto_create))) { return false; } while ($row = db_fetch_row($res)) { $user = User::lookup($row[0]); $cdata = $user->getDynamicData(); $content = array(); foreach ($user->emails as $e) { $content[] = $e->address; } foreach ($cdata as $e) { foreach ($e->getAnswers() as $a) { if ($c = $a->getSearchable()) { $content[] = $c; } } } $record = array('U', $user->getId(), Format::searchable($user->getFullName()), trim(implode("\n", $content))); if (!$this->__index($record)) { return; } } // ORGANIZATIONS ---------------------------- $sql = "SELECT A1.`id` FROM `" . ORGANIZATION_TABLE . "` A1\n LEFT JOIN `" . TABLE_PREFIX . "_search` A2 ON (A1.`id` = A2.`object_id` AND A2.`object_type`='O')\n WHERE A2.`object_id` IS NULL\n ORDER BY A1.`id` DESC"; if (!($res = db_query_unbuffered($sql, $auto_create))) { return false; } while ($row = db_fetch_row($res)) { $org = Organization::lookup($row[0]); $cdata = $org->getDynamicData(); $content = array(); foreach ($cdata as $e) { foreach ($e->getAnswers() as $a) { if ($c = $a->getSearchable()) { $content[] = $c; } } } $record = array('O', $org->getId(), Format::searchable($org->getName()), trim(implode("\n", $content))); if (!$this->__index($record)) { return null; } } // KNOWLEDGEBASE ---------------------------- require_once INCLUDE_DIR . 'class.faq.php'; $sql = "SELECT A1.`faq_id` FROM `" . FAQ_TABLE . "` A1\n LEFT JOIN `" . TABLE_PREFIX . "_search` A2 ON (A1.`faq_id` = A2.`object_id` AND A2.`object_type`='K')\n WHERE A2.`object_id` IS NULL\n ORDER BY A1.`faq_id` DESC"; if (!($res = db_query_unbuffered($sql, $auto_create))) { return false; } while ($row = db_fetch_row($res)) { $faq = FAQ::lookup($row[0]); $q = $faq->getQuestion(); if ($k = $faq->getKeywords()) { $q = $k . ' ' . $q; } $record = array('K', $faq->getId(), Format::searchable($q), $faq->getSearchableAnswer()); if (!$this->__index($record)) { return; } } // FILES ------------------------------------ // Flush non-full batch of records $this->__index(null, true); if (!$this->_reindexed) { // Stop rebuilding the index $this->getConfig()->set('reindex', 0); } }
<?php // this is an ajax API to remove the collaborators for a ticket require('staff.inc.php'); require_once(INCLUDE_DIR.'class.ticket.php'); if(($tid=$_POST['ticketId'])&&($ticket=Ticket::lookup($tid))&&($ticket->deleteCollaborators())) { echo $tid; } else echo 'false'; ?>
function previewTicket($tid) { global $thisstaff; if (!$thisstaff || !($ticket = Ticket::lookup($tid)) || !$ticket->checkStaffAccess($thisstaff)) { Http::response(404, 'No such ticket'); } $staff = $ticket->getStaff(); $lock = $ticket->getLock(); $error = $msg = $warn = null; if ($lock && $lock->getStaffId() == $thisstaff->getId()) { $warn .= ' <span class="Icon lockedTicket">Ticket is locked by ' . $lock->getStaffName() . '</span>'; } elseif ($ticket->isOverdue()) { $warn .= ' <span class="Icon overdueTicket">Marked overdue!</span>'; } ob_start(); echo sprintf('<div style="width:500px; padding: 2px 2px 0 5px;"> <h2>%s</h2><br>', Format::htmlchars($ticket->getSubject())); if ($error) { echo sprintf('<div id="msg_error">%s</div>', $error); } elseif ($msg) { echo sprintf('<div id="msg_notice">%s</div>', $msg); } elseif ($warn) { echo sprintf('<div id="msg_warning">%s</div>', $warn); } echo '<table border="0" cellspacing="" cellpadding="1" width="100%" class="ticket_info">'; $ticket_state = sprintf('<span>%s</span>', ucfirst($ticket->getStatus())); if ($ticket->isOpen()) { if ($ticket->isOverdue()) { $ticket_state .= ' — <span>Overdue</span>'; } else { $ticket_state .= sprintf(' — <span>%s</span>', $ticket->getPriority()); } } echo sprintf(' <tr> <th width="100">Ticket State:</th> <td>%s</td> </tr> <tr> <th>Create Date:</th> <td>%s</td> </tr>', $ticket_state, Format::db_datetime($ticket->getCreateDate())); if ($ticket->isClosed()) { echo sprintf(' <tr> <th>Close Date:</th> <td>%s <span class="faded">by %s</span></td> </tr>', Format::db_datetime($ticket->getCloseDate()), $staff ? $staff->getName() : 'staff'); } elseif ($ticket->getDueDate()) { echo sprintf(' <tr> <th>Due Date:</th> <td>%s</td> </tr>', Format::db_datetime($ticket->getDueDate())); } echo '</table>'; echo '<hr> <table border="0" cellspacing="" cellpadding="1" width="100%" class="ticket_info">'; if ($ticket->isOpen()) { echo sprintf(' <tr> <th width="100">Assigned To:</th> <td>%s</td> </tr>', $ticket->isAssigned() ? implode('/', $ticket->getAssignees()) : ' <span class="faded">— Unassigned —</span>'); } echo sprintf(' <tr> <th width="100">Department:</th> <td>%s</td> </tr> <tr> <th>Help Topic:</th> <td>%s</td> </tr> <tr> <th>From:</th> <td>%s <span class="faded">%s</span></td> </tr>', Format::htmlchars($ticket->getDeptName()), Format::htmlchars($ticket->getHelpTopic()), Format::htmlchars($ticket->getName()), $ticket->getEmail()); echo ' </table>'; $options[] = array('action' => 'Thread (' . $ticket->getThreadCount() . ')', 'url' => "tickets.php?id={$tid}"); if ($ticket->getNumNotes()) { $options[] = array('action' => 'Notes (' . $ticket->getNumNotes() . ')', 'url' => "tickets.php?id={$tid}#notes"); } if ($ticket->isOpen()) { $options[] = array('action' => 'Reply', 'url' => "tickets.php?id={$tid}#reply"); } if ($thisstaff->canAssignTickets()) { $options[] = array('action' => $ticket->isAssigned() ? 'Reassign' : 'Assign', 'url' => "tickets.php?id={$tid}#assign"); } if ($thisstaff->canTransferTickets()) { $options[] = array('action' => 'Transfer', 'url' => "tickets.php?id={$tid}#transfer"); } $options[] = array('action' => 'Post Note', 'url' => "tickets.php?id={$tid}#note"); if ($thisstaff->canEditTickets()) { $options[] = array('action' => 'Edit Ticket', 'url' => "tickets.php?id={$tid}&a=edit"); } if ($options) { echo '<ul class="tip_menu">'; foreach ($options as $option) { echo sprintf('<li><a href="%s">%s</a></li>', $option['url'], $option['action']); } echo '</ul>'; } echo '</div>'; $resp = ob_get_contents(); ob_end_clean(); return $resp; }
$i++; $t->logNote('Ticket Marked Overdue', $note, $thisstaff); } } if ($i == $count) { $msg = "Selected tickets ({$i}) marked overdue"; } elseif ($i) { $warn = "{$i} of {$count} selected tickets marked overdue"; } else { $errors['err'] = 'Unable to flag selected tickets as overdue'; } break; case 'delete': if ($thisstaff->canDeleteTickets()) { foreach ($_POST['tids'] as $k => $v) { if (($t = Ticket::lookup($v)) && @$t->delete()) { $i++; } } //Log a warning if ($i) { $log = sprintf('%s (%s) just deleted %d ticket(s)', $thisstaff->getName(), $thisstaff->getUserName(), $i); $ost->logWarning('Tickets deleted', $log, false); } if ($i == $count) { $msg = "Selected tickets ({$i}) deleted successfully"; } elseif ($i) { $warn = "{$i} of {$count} selected tickets deleted"; } else { $errors['err'] = 'Unable to delete selected tickets'; }
protected function validate($authkey) { $regex = '/^(?P<type>\\w{1})(?P<id>\\d+)t(?P<tid>\\d+)h(?P<hash>.*)$/i'; $matches = array(); if (!preg_match($regex, $authkey, $matches)) { return false; } $user = null; switch ($matches['type']) { case 'c': //Collaborator $criteria = array('userId' => $matches['id'], 'ticketId' => $matches['tid']); if (($c = Collaborator::lookup($criteria)) && $c->getTicketId() == $matches['tid']) { $user = new ClientSession($c); } break; case 'o': //Ticket owner if (($ticket = Ticket::lookup($matches['tid'])) && ($o = $ticket->getOwner()) && $o->getId() == $matches['id']) { $user = new ClientSession($o); } break; } //Make sure the authkey matches. if (!$user || strcmp($this->getAuthKey($user), $authkey)) { return null; } $user->flagGuest(); return $user; }
function cannedResponse($tid, $cid, $format = 'text') { global $thisstaff, $cfg; if (!($ticket = Ticket::lookup($tid)) || !$ticket->checkStaffAccess($thisstaff)) { Http::response(404, 'Unknown ticket ID'); } if ($cid && !is_numeric($cid)) { if (!($response = $ticket->getThread()->getVar($cid))) { Http::response(422, 'Unknown ticket variable'); } // Ticket thread variables are assumed to be quotes $response = "<br/><blockquote>{$response}</blockquote><br/>"; // Return text if html thread is not enabled if (!$cfg->isHtmlThreadEnabled()) { $response = Format::html2text($response, 90); } // XXX: assuming json format for now. return Format::json_encode(array('response' => $response)); } if (!$cfg->isHtmlThreadEnabled()) { $format .= '.plain'; } $varReplacer = function (&$var) use($ticket) { return $ticket->replaceVars($var); }; include_once INCLUDE_DIR . 'class.canned.php'; if (!$cid || !($canned = Canned::lookup($cid)) || !$canned->isEnabled()) { Http::response(404, 'No such premade reply'); } return $canned->getFormattedResponse($format, $varReplacer); }
<a class="Icon <?php echo strtolower($row['source']); ?>Ticket ticketPreview" title="<?php echo "tickets.php?id=".$row['ticket_id']; ?>" href="<?php echo $ticketUrl; ?>"><?php echo $tid; ?> <?php if($row['lock_id']) { ?> <img src="/images/lock.jpg" style="height:16px;width:16px;"> <?php } ?> </a> </td> <td align="center" nowrap><?php echo Format::db_datetime($row['effective_date']); ?></td> <td><a <?php if ($flag) { ?> class="Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket" <?php } ?> href="<?php echo $ticketUrl; ?>"><?php echo $subject; ?></a> <?php $ticket = Ticket::lookup($row['ticket_id']); $threadcount = $ticket->getNumResponses() + $ticket->getNumMessages(); $messageCount = 0; $responseCount = 0; $internalNoteCount = 0; if($ticket->getNumMessages()) $messageCount = $ticket->getNumMessages(); if($ticket->getNumResponses()) $responseCount = $ticket->getNumResponses(); if($ticket->getNumInternalNotes()) $internalNoteCount = $ticket->getNumInternalNotes(); if ($threadcount>0) { echo "<small>M(".$messageCount.")</small> "; echo "<small>R(".$responseCount.")</small> "; if($internalNoteCount>0)
public static function getAllTickets() { $items = array(); $sql = 'SELECT DISTINCT(ticket_id) as ticket_id ' . ' FROM ' . EQUIPMENT_TICKET_TABLE; $res = db_query($sql); if ($res && ($num = db_num_rows($res))) { while ($row = db_fetch_array($res)) { $item = \Ticket::lookup($row['ticket_id']); if (isset($item)) { $items[] = $item; } } } return $items; }
Released under the GNU General Public License WITHOUT ANY WARRANTY. See LICENSE.TXT for details. vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ require 'staff.inc.php'; require_once INCLUDE_DIR . 'class.ticket.php'; require_once INCLUDE_DIR . 'class.dept.php'; require_once INCLUDE_DIR . 'class.filter.php'; require_once INCLUDE_DIR . 'class.canned.php'; $page = ''; $ticket = null; //clean start. //LOCKDOWN...See if the id provided is actually valid and if the user has access. if ($_REQUEST['id']) { if (!($ticket = Ticket::lookup($_REQUEST['id']))) { $errors['err'] = 'Unknown or invalid ticket ID'; } elseif (!$ticket->checkStaffAccess($thisstaff)) { $errors['err'] = 'Access denied. Contact admin if you believe this is in error'; $ticket = null; //Clear ticket obj. } } //At this stage we know the access status. we can process the post. if ($_POST && !$errors) { if ($ticket && $ticket->getId()) { //More coffee please. $errors = array(); $lock = $ticket->getLock(); //Ticket lock if any $statusKeys = array('open' => 'Open', 'Reopen' => 'Open', 'Close' => 'Closed');
protected function ticketsAction($type, $ticket_id) { $tickets = array(); foreach ($ticket_id as $id) { $ticket = \Ticket::lookup($id['ticket_id']); $equipment = new \model\Equipment($id['equipment_id']); if (isset($ticket) && isset($equipment)) { $ticket_data = array('id' => $ticket->getId(), 'number' => $ticket->getNumber(), 'equipment' => $equipment->getAsset_id(), 'create_date' => \Format::db_datetime($ticket->getCreateDate()), 'subject' => $ticket->getSubject(), 'name' => $ticket->getName()->getFull(), 'priority' => $ticket->getPriority()); if ($type == 'closed') { $ts_open = strtotime($ticket->getCreateDate()); $ts_closed = strtotime($ticket->getCloseDate()); $ticket_data['close_date'] = \Format::db_datetime($ticket->getCloseDate()); $ticket_data['closed_by'] = $ticket->getStaff()->getUserName(); $ticket_data['elapsed'] = $this->elapsedTime($ts_closed - $ts_open); } $tickets[] = $ticket_data; } } return $tickets; }
function setSelectedTicketsStatus($state) { global $thisstaff, $ost; $errors = $info = array(); if (!$thisstaff || !$thisstaff->canManageTickets()) { $errors['err'] = sprintf('%s %s', sprintf(__('You do not have permission %s.'), __('to mass manage tickets')), __('Contact admin for such access')); } elseif (!$_REQUEST['tids'] || !count($_REQUEST['tids'])) { $errors['err'] = sprintf(__('You must select at least %s.'), __('one ticket')); } elseif (!($status = TicketStatus::lookup($_REQUEST['status_id']))) { $errors['status_id'] = sprintf('%s %s', __('Unknown or invalid'), __('status')); } elseif (!$errors) { // Make sure the agent has permission to set the status switch (mb_strtolower($status->getState())) { case 'open': if (!$thisstaff->canCloseTickets() && !$thisstaff->canCreateTickets()) { $errors['err'] = sprintf(__('You do not have permission %s.'), __('to reopen tickets')); } break; case 'closed': if (!$thisstaff->canCloseTickets()) { $errors['err'] = sprintf(__('You do not have permission %s.'), __('to resolve/close tickets')); } break; case 'deleted': if (!$thisstaff->canDeleteTickets()) { $errors['err'] = sprintf(__('You do not have permission %s.'), __('to archive/delete tickets')); } break; default: $errors['err'] = sprintf('%s %s', __('Unknown or invalid'), __('status')); } } $count = count($_REQUEST['tids']); if (!$errors) { $i = 0; $comments = $_REQUEST['comments']; foreach ($_REQUEST['tids'] as $tid) { if (($ticket = Ticket::lookup($tid)) && $ticket->getStatusId() != $status->getId() && $ticket->checkStaffAccess($thisstaff) && $ticket->setStatus($status, $comments)) { $i++; } } if (!$i) { $errors['err'] = sprintf(__('Unable to change status for %s'), _N('the selected ticket', 'any of the selected tickets', $count)); } else { // Assume success if ($i == $count) { if (!strcasecmp($status->getState(), 'deleted')) { $msg = sprintf(__('Successfully deleted %s.'), _N('selected ticket', 'selected tickets', $count)); } else { $msg = sprintf(__('Successfully changed status of %1$s to %2$s'), _N('selected ticket', 'selected tickets', $count), $status->getName()); } $_SESSION['::sysmsgs']['msg'] = $msg; } else { if (!strcasecmp($status->getState(), 'deleted')) { $warn = sprintf(__('Successfully deleted %s.'), sprintf(__('%1$d of %2$d selected tickets'), $i, $count)); } else { $warn = sprintf(__('%1$d of %2$d %3$s status changed to %4$s'), $i, $count, _N('selected ticket', 'selected tickets', $count), $status->getName()); } $_SESSION['::sysmsgs']['warn'] = $warn; } Http::response(201, 'Successfully processed'); } } return self::_changeSelectedTicketsStatus($state, $info, $errors); }
function processEmail() { $data = $this->getEmailRequest(); if ($data['ticketId'] && ($ticket = Ticket::lookup($data['ticketId']))) { if ($msgid = $ticket->postMessage($data, 'Email')) { return $ticket; } } if (($thread = ThreadEntry::lookupByEmailHeaders($data)) && $thread->postEmail($data)) { return $thread->getTicket(); } return $this->createTicket($data); }
function checkOverdue() { $sql = 'SELECT ticket_id FROM ' . TICKET_TABLE . ' T1 ' . ' INNER JOIN ' . TICKET_STATUS_TABLE . ' status ON (status.id=T1.status_id AND status.state="open") ' . ' LEFT JOIN ' . SLA_TABLE . ' T2 ON (T1.sla_id=T2.id AND T2.isactive=1) ' . ' WHERE 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? if (($res = db_query($sql)) && db_num_rows($res)) { while (list($id) = db_fetch_row($res)) { if (($ticket = Ticket::lookup($id)) && $ticket->markOverdue()) { $ticket->logActivity(_S('Ticket Marked Overdue'), _S('Ticket flagged as overdue by the system.')); } } } else { //TODO: Trigger escalation on already overdue tickets - make sure last overdue event > grace_period. } }
static function lookupByToken($token) { //Expecting well formatted token see getAuthToken routine for details. $matches = array(); if (!preg_match(static::$token_regex, $token, $matches)) { return null; } //Unpack the user and ticket ids $matches += unpack('Vuid/Vtid', Base32::decode(strtolower(substr($matches['hash'], 0, 13)))); $user = null; switch ($matches['type']) { case 'c': //Collaborator c if (($user = Collaborator::lookup($matches['uid'])) && $user->getTicketId() != $matches['tid']) { $user = null; } break; case 'o': //Ticket owner if ($ticket = Ticket::lookup($matches['tid'])) { if (($user = $ticket->getOwner()) && $user->getId() != $matches['uid']) { $user = null; } } break; } if (!$user || !$user instanceof TicketUser || strcasecmp($user->getAuthToken($matches['algo']), $token)) { return false; } return $user; }
function checkOverdue() { $sql = 'SELECT ticket_id FROM ' . TICKET_TABLE . ' T1 JOIN ' . SLA_TABLE . ' T2 ON T1.sla_id=T2.id ' . 'WHERE status=\'open\' AND isoverdue=0 ' . ' AND ((reopened is NULL AND duedate is NULL AND TIME_TO_SEC(TIMEDIFF(NOW(),T1.created))>=grace_period*3600)' . ' OR (reopened is NOT NULL AND duedate is NULL AND TIME_TO_SEC(TIMEDIFF(NOW(),reopened))>=grace_period*3600)' . ' OR (duedate is NOT NULL AND duedate<NOW()) ' . ') ORDER BY T1.created LIMIT 50'; //Age upto 50 tickets at a time? //echo $sql; if (($stale = db_query($sql)) && db_num_rows($stale)) { while (list($id) = db_fetch_row($stale)) { if (($ticket = Ticket::lookup($id)) && $ticket->markOverdue()) { $ticket->logActivity('Ticket Marked Overdue', 'Ticket flagged as overdue by the system.'); } # TODO: Send out notifications about the now-overdue # ticket XXX: markOverdue sends out notifications. } } }