Skip to content
Snippets Groups Projects
ajax.tickets.php 57.1 KiB
Newer Older
Jared Hancock's avatar
Jared Hancock committed
<?php
/*********************************************************************
    ajax.tickets.php

    AJAX interface for tickets

    Peter Rotich <peter@osticket.com>
    Copyright (c)  2006-2013 osTicket
Jared Hancock's avatar
Jared Hancock committed
    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:
**********************************************************************/

if(!defined('INCLUDE_DIR')) die('403');

include_once(INCLUDE_DIR.'class.ticket.php');
require_once(INCLUDE_DIR.'class.ajax.php');
require_once(INCLUDE_DIR.'class.note.php');
include_once INCLUDE_DIR . 'class.thread_actions.php';
Jared Hancock's avatar
Jared Hancock committed

class TicketsAjaxAPI extends AjaxController {
    function lookup() {
        global $thisstaff;
        $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25;
        $tickets=array();
        // Bail out of query is empty
        if (!$_REQUEST['q'])
            return $this->json_encode($tickets);
Peter Rotich's avatar
Peter Rotich committed
        $visibility = $thisstaff->getTicketsVisibility();
        $hits = Ticket::objects()
            ->values('user__default_email__address')
            ->annotate(array(
                'number' => new SqlCode('null'),
                'tickets' => SqlAggregate::COUNT('ticket_id', true),
            ))
            ->order_by(SqlAggregate::SUM(new SqlCode('Z1.relevance')), QuerySet::DESC)
        if (strlen(Format::searchable($q)) < 3)
            return $this->encode(array());
        $hits = $ost->searcher->find($q, $hits, false);
        if (preg_match('/\d{2,}[^*]/', $q, $T = array())) {
            $hits = Ticket::objects()
                ->values('user__default_email__address', 'number')
                ->annotate(array(
                    'tickets' => new SqlCode('1'),
                ))
                ->filter(array('number__startswith' => $q))
                ->order_by('number')
                ->limit($limit)
                ->union($hits);
        }
        elseif (!count($hits) && preg_match('`\w$`u', $q)) {
            // Do wild-card fulltext search
            $_REQUEST['q'] = $q.'*';
            return $this->lookup();
            $email = $T['user__default_email__address'];
            if ($T['number']) {
                $tickets[] = array('id'=>$T['number'], 'value'=>$T['number'],
                    'info'=>"{$T['number']}{$email}",
                    'matches'=>$_REQUEST['q']);
            }
            else {
                $tickets[] = array('email'=>$email, 'value'=>$email,
                    'info'=>"$email ($count)", 'matches'=>$_REQUEST['q']);
            }
        return $this->json_encode($tickets);
Jared Hancock's avatar
Jared Hancock committed
    }

    function acquireLock($tid) {
        global $cfg, $thisstaff;
        if(!$cfg || !$cfg->getLockTime() || $cfg->getTicketLockMode() == Lock::MODE_DISABLED)
            Http::response(418, $this->encode(array('id'=>0, 'retry'=>false)));

        if(!$tid || !is_numeric($tid) || !$thisstaff)
Jared Hancock's avatar
Jared Hancock committed
            return 0;
        if (!($ticket = Ticket::lookup($tid)) || !$ticket->checkStaffPerm($thisstaff))
            return $this->encode(array('id'=>0, 'retry'=>false, 'msg'=>__('Lock denied!')));
Jared Hancock's avatar
Jared Hancock committed
        //is the ticket already locked?
        if ($ticket->isLocked() && ($lock=$ticket->getLock()) && !$lock->isExpired()) {
Jared Hancock's avatar
Jared Hancock committed
            /*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' => sprintf(__('Currently locked by %s'),
                        $lock->getStaff()->getAvatarAndName())
Jared Hancock's avatar
Jared Hancock committed
            //Ticket already locked by staff...try renewing it.
            $lock->renew(); //New clock baby!
        } elseif(!($lock=$ticket->acquireLock($thisstaff->getId(),$cfg->getLockTime()))) {
            //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));
        return $this->json_encode(array(
            'id'=>$lock->getId(), 'time'=>$lock->getTime(),
            'code' => $lock->getCode()
        ));
    function renewLock($id, $ticketId) {
Jared Hancock's avatar
Jared Hancock committed
        global $thisstaff;

        if (!$id || !is_numeric($id) || !$thisstaff)
            Http::response(403, $this->encode(array('id'=>0, 'retry'=>false)));
        if (!($lock = Lock::lookup($id)))
            Http::response(404, $this->encode(array('id'=>0, 'retry'=>'acquire')));
        if (!($ticket = Ticket::lookup($ticketId)) || $ticket->lock_id != $lock->lock_id)
            // Ticket / Lock mismatch
            Http::response(400, $this->encode(array('id'=>0, 'retry'=>false)));

        if (!$lock->getStaffId() || $lock->isExpired())
            // Said lock doesn't exist or is is expired — fetch a new lock
            return self::acquireLock($ticket->getId());

        if ($lock->getStaffId() != $thisstaff->getId())
            // user doesn't own the lock anymore??? sorry...try to next time.
            Http::response(403, $this->encode(array('id'=>0, 'retry'=>false,
                'msg' => sprintf(__('Currently locked by %s'),
                    $lock->getStaff->getAvatarAndName())
            ))); //Give up...

        // Ensure staff still has access
        if (!$ticket->checkStaffPerm($thisstaff))
            Http::response(403, $this->encode(array('id'=>0, 'retry'=>false,
                'msg' => sprintf(__('You no longer have access to #%s.'),
                $ticket->getNumber())
            )));

        // Renew the lock.
        // Failure here is not an issue since the lock is not expired yet.. client need to check time!
        $lock->renew();

        return $this->encode(array('id'=>$lock->getId(), 'time'=>$lock->getTime(),
            'code' => $lock->getCode()));
    function releaseLock($id) {
Jared Hancock's avatar
Jared Hancock committed
        global $thisstaff;

        if (!$id || !is_numeric($id) || !$thisstaff)
            Http::response(403, $this->encode(array('id'=>0, 'retry'=>true)));
        if (!($lock = Lock::lookup($id)))
            Http::response(404, $this->encode(array('id'=>0, 'retry'=>true)));

        // You have to own the lock
        if ($lock->getStaffId() != $thisstaff->getId()) {
        // Can't be expired
        if ($lock->isExpired()) {
            return 1;
        return $lock->release() ? 1 : 0;
Jared Hancock's avatar
Jared Hancock committed
    }

    function previewTicket ($tid) {
        global $thisstaff;

        if(!$thisstaff || !($ticket=Ticket::lookup($tid))
                || !$ticket->checkStaffPerm($thisstaff))
            Http::response(404, __('No such ticket'));
        include STAFFINC_DIR . 'templates/ticket-preview.tmpl.php';
Peter Rotich's avatar
Peter Rotich committed
    function viewUser($tid) {
        global $thisstaff;

        if(!$thisstaff
                || !($ticket=Ticket::lookup($tid))
                || !$ticket->checkStaffPerm($thisstaff))
Peter Rotich's avatar
Peter Rotich committed
            Http::response(404, 'No such ticket');


        if(!($user = User::lookup($ticket->getOwnerId())))
Loading
Loading full blame...