diff --git a/include/class.staff.php b/include/class.staff.php index 33f9cef7f14a870da5d7b5e37a34393c8bbd8a4f..231717bef71bf8aa720b5f67c7f22a19fadc1f5b 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -22,6 +22,18 @@ include_once(INCLUDE_DIR.'class.passwd.php'); include_once(INCLUDE_DIR.'class.user.php'); include_once(INCLUDE_DIR.'class.auth.php'); +class StaffModel extends VerySimpleModel { + static $meta = array( + 'table' => STAFF_TABLE, + 'pk' => array('staff_id'), + 'joins' => array( + 'dept' => array( + 'constraint' => array('dept_id' => 'Dept.dept_id'), + ), + ), + ); +} + class Staff extends AuthenticatedUser { var $ht; diff --git a/include/class.ticket.php b/include/class.ticket.php index e21b1bc46cacb269fb9b5befe0cee12e82e065d1..81201705984c97f9c26b0a00cfa30d1f46762045 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -34,6 +34,82 @@ require_once(INCLUDE_DIR.'class.user.php'); require_once(INCLUDE_DIR.'class.collaborator.php'); require_once(INCLUDE_DIR.'class.faq.php'); +class TicketModel extends VerySimpleModel { + static $meta = array( + 'table' => TICKET_TABLE, + 'pk' => array('ticket_id'), + 'joins' => array( + 'user' => array( + 'constraint' => array('user_id' => 'User.id') + ), + 'status' => array( + 'constraint' => array('status_id' => 'TicketStatus.id') + ), + 'lock' => array( + 'reverse' => 'TicketLock.ticket', + 'list' => false, + 'null' => true, + ), + 'dept' => array( + 'constraint' => array('dept_id' => 'Dept.dept_id'), + ), + 'staff' => array( + 'constraint' => array('staff_id' => 'StaffModel.staff_id'), + 'null' => true, + ), + 'team' => array( + 'constraint' => array('team_id' => 'Team.team_id'), + 'null' => true, + ), + 'topic' => array( + 'constraint' => array('topic_id' => 'Topic.topic_id'), + 'null' => true, + ), + 'cdata' => array( + 'reverse' => 'TicketCData.ticket', + 'list' => false, + ), + ) + ); + + function getId() { + return $this->ticket_id; + } + + function getEffectiveDate() { + return max( + strtotime($this->lastmessage), + strtotime($this->closed), + strtotime($this->reopened), + strtotime($this->created) + ); + } + + function delete() { + + if (($ticket=Ticket::lookup($this->getId())) && @$ticket->delete()) + return true; + + return false; + } +} + +class TicketCData extends VerySimpleModel { + static $meta = array( + 'pk' => array('ticket_id'), + 'joins' => array( + 'ticket' => array( + 'constraint' => array('ticket_id' => 'TicketModel.ticket_id'), + ), + ':priority' => array( + 'constraint' => array('priority' => 'Priority.priority_id'), + 'null' => true, + ), + ), + ); +} +TicketCData::$meta['table'] = TABLE_PREFIX . 'ticket__cdata'; + class Ticket { diff --git a/include/class.user.php b/include/class.user.php index 5c927b3f15d534e6f37472287ba0d899b9864829..13521ad42cf1ff2b95238767f833face6a1357cc 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -33,33 +33,6 @@ class UserEmailModel extends VerySimpleModel { } } -class TicketModel extends VerySimpleModel { - static $meta = array( - 'table' => TICKET_TABLE, - 'pk' => array('ticket_id'), - 'joins' => array( - 'user' => array( - 'constraint' => array('user_id' => 'UserModel.id') - ), - 'status' => array( - 'constraint' => array('status_id' => 'TicketStatus.id') - ) - ) - ); - - function getId() { - return $this->ticket_id; - } - - function delete() { - - if (($ticket=Ticket::lookup($this->getId())) && @$ticket->delete()) - return true; - - return false; - } -} - class UserModel extends VerySimpleModel { static $meta = array( 'table' => USER_TABLE, @@ -1163,8 +1136,4 @@ class UserList extends ListObject { return $list ? implode(', ', $list) : ''; } } - -require_once(INCLUDE_DIR . 'class.organization.php'); -User::_inspect(); -UserAccount::_inspect(); ?> diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index f27de7cf3f5a79c9b902f0ecc72a97615651bba7..b0dca99dd0d197f0a1d7fb235f381e8936eabe0d 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -1,311 +1,91 @@ <?php -if(!defined('OSTSCPINC') || !$thisstaff || !@$thisstaff->isStaff()) die('Access Denied'); +$search = SavedSearch::create(); +$tickets = TicketModel::objects(); +$clear_button = false; +// Add "other" fields (via $_POST['other'][]) -$qstr='&'; //Query string collector -if($_REQUEST['status']) { //Query string status has nothing to do with the real status used below; gets overloaded. - $qstr.='status='.urlencode($_REQUEST['status']); -} - -//See if this is a search -$search=($_REQUEST['a']=='search'); -$searchTerm=''; -//make sure the search query is 3 chars min...defaults to no query with warning message -if($search) { - $searchTerm=$_REQUEST['query']; - if( ($_REQUEST['query'] && strlen($_REQUEST['query'])<3) - || (!$_REQUEST['query'] && isset($_REQUEST['basic_search'])) ){ //Why do I care about this crap... - $search=false; //Instead of an error page...default back to regular query..with no search. - $errors['err']=__('Search term must be more than 3 chars'); - $searchTerm=''; - } -} -$showoverdue=$showanswered=false; -$staffId=0; //Nothing for now...TODO: Allow admin and manager to limit tickets to single staff level. -$showassigned= true; //show Assigned To column - defaults to true - -//Get status we are actually going to use on the query...making sure it is clean! -$status=null; switch(strtolower($_REQUEST['status'])){ //Status is overloaded - case 'open': - $status='open'; - $results_type=__('Open Tickets'); - break; - case 'closed': - $status='closed'; - $results_type=__('Closed Tickets'); - $showassigned=true; //closed by. - break; - case 'overdue': - $status='open'; - $showoverdue=true; - $results_type=__('Overdue Tickets'); - break; - case 'assigned': - $status='open'; - $staffId=$thisstaff->getId(); - $results_type=__('My Tickets'); - break; - case 'answered': - $status='open'; - $showanswered=true; - $results_type=__('Answered Tickets'); +case 'closed': + $status='closed'; + $results_type=__('Closed Tickets'); + $showassigned=true; //closed by. + break; +case 'overdue': + $status='open'; + $results_type=__('Overdue Tickets'); + $tickets->filter(array('isoverdue'=>1)); + break; +case 'assigned': + $status='open'; + $staffId=$thisstaff->getId(); + $results_type=__('My Tickets'); + $tickets->filter(array('staff_id'=>$thisstaff->getId())); + break; +case 'answered': + $status='open'; + $showanswered=true; + $results_type=__('Answered Tickets'); + $tickets->filter(array('isanswered'=>1)); + break; +default: + if (isset($_GET['clear_filter'])) + unset($_SESSION['advsearch']); + if (isset($_SESSION['advsearch'])) { + $form = $search->getForm(); + $form->loadState($_SESSION['advsearch']); + $tickets = $search->mangleQuerySet($tickets, $form); + $results_type=__('Advanced Search') + . '<a class="action-button" href="?clear_filter"><i class="icon-ban-circle"></i> <em>' . __('clear') . '</em></a>'; break; - default: - if (!$search && !isset($_REQUEST['advsid'])) { - $_REQUEST['status']=$status='open'; - $results_type=__('Open Tickets'); - } -} - -$qwhere =''; -/* - STRICT DEPARTMENTS BASED PERMISSION! - User can also see tickets assigned to them regardless of the ticket's dept. -*/ - -$depts=$thisstaff->getDepts(); -$qwhere =' WHERE ( ' - .' ( ticket.staff_id='.db_input($thisstaff->getId()) - .' AND status.state="open") '; - -if(!$thisstaff->showAssignedOnly()) - $qwhere.=' OR ticket.dept_id IN ('.($depts?implode(',', db_input($depts)):0).')'; - -if(($teams=$thisstaff->getTeams()) && count(array_filter($teams))) - $qwhere.=' OR (ticket.team_id IN ('.implode(',', db_input(array_filter($teams))) - .') AND status.state="open") '; - -$qwhere .= ' )'; - -//STATUS to states -$states = array( - 'open' => array('open'), - 'closed' => array('closed')); - -if($status && isset($states[$status])) { - $qwhere.=' AND status.state IN ( - '.implode(',', db_input($states[$status])).' ) '; -} - -if (isset($_REQUEST['uid']) && $_REQUEST['uid']) { - $qwhere .= ' AND (ticket.user_id='.db_input($_REQUEST['uid']) - .' OR collab.user_id='.db_input($_REQUEST['uid']).') '; - $qstr .= '&uid='.urlencode($_REQUEST['uid']); -} - -//Queues: Overloaded sub-statuses - you've got to just have faith! -if($staffId && ($staffId==$thisstaff->getId())) { //My tickets - $results_type=__('Assigned Tickets'); - $qwhere.=' AND ticket.staff_id='.db_input($staffId); - $showassigned=false; //My tickets...already assigned to the staff. -}elseif($showoverdue) { //overdue - $qwhere.=' AND ticket.isoverdue=1 '; -}elseif($showanswered) { ////Answered - $qwhere.=' AND ticket.isanswered=1 '; -}elseif(!strcasecmp($status, 'open') && !$search) { //Open queue (on search OPEN means all open tickets - regardless of state). - //Showing answered tickets on open queue?? - if(!$cfg->showAnsweredTickets()) - $qwhere.=' AND ticket.isanswered=0 '; - - /* Showing assigned tickets on open queue? - Don't confuse it with show assigned To column -> F'it it's confusing - just trust me! - */ - if(!($cfg->showAssignedTickets() || $thisstaff->showAssignedTickets())) { - $qwhere.=' AND ticket.staff_id=0 '; //XXX: NOT factoring in team assignments - only staff assignments. - $showassigned=false; //Not showing Assigned To column since assigned tickets are not part of open queue } + // Fall-through and show open tickets +case 'open': + $status='open'; + $results_type=__('Open Tickets'); + $tickets->filter(array('isanswered'=>0)); + break; } -//Search?? Somebody...get me some coffee -$deep_search=false; -$order_by=$order=null; -if($search): - $qstr.='&a='.urlencode($_REQUEST['a']); - $qstr.='&t='.urlencode($_REQUEST['t']); - - //query - if($searchTerm){ - $qstr.='&query='.urlencode($searchTerm); - $queryterm=db_real_escape($searchTerm,false); //escape the term ONLY...no quotes. - if (is_numeric($searchTerm)) { - $qwhere.=" AND ticket.`number` LIKE '$queryterm%'"; - } elseif (strpos($searchTerm,'@') && Validator::is_email($searchTerm)) { - //pulling all tricks! - # XXX: What about searching for email addresses in the body of - # the thread message - $qwhere.=" AND email.address='$queryterm'"; - } else {//Deep search! - //This sucks..mass scan! search anything that moves! - require_once(INCLUDE_DIR.'ajax.tickets.php'); - - $tickets = TicketsAjaxApi::_search(array('query'=>$queryterm)); - if (count($tickets)) { - $ticket_ids = implode(',',db_input($tickets)); - $qwhere .= ' AND ticket.ticket_id IN ('.$ticket_ids.')'; - $order_by = 'FIELD(ticket.ticket_id, '.$ticket_ids.')'; - $order = ' '; - } - else - // No hits -- there should be an empty list of results - $qwhere .= ' AND false'; - } - } - -endif; - -if ($_REQUEST['advsid'] && isset($_SESSION['adv_'.$_REQUEST['advsid']])) { - $ticket_ids = implode(',', db_input($_SESSION['adv_'.$_REQUEST['advsid']])); - $qstr.='advsid='.$_REQUEST['advsid']; - $qwhere .= ' AND ticket.ticket_id IN ('.$ticket_ids.')'; - // Thanks, http://stackoverflow.com/a/1631794 - $order_by = 'FIELD(ticket.ticket_id, '.$ticket_ids.')'; - $order = ' '; -} - -$sortOptions=array('date'=>'effective_date','ID'=>'ticket.`number`*1', - 'pri'=>'pri.priority_urgency','name'=>'user.name','subj'=>'cdata.subject', - 'status'=>'status.name','assignee'=>'assigned','staff'=>'staff', - 'dept'=>'dept.dept_name'); - -$orderWays=array('DESC'=>'DESC','ASC'=>'ASC'); - -//Sorting options... -$queue = isset($_REQUEST['status'])?strtolower($_REQUEST['status']):$status; -if($_REQUEST['sort'] && $sortOptions[$_REQUEST['sort']]) - $order_by =$sortOptions[$_REQUEST['sort']]; -elseif($sortOptions[$_SESSION[$queue.'_tickets']['sort']]) { - $_REQUEST['sort'] = $_SESSION[$queue.'_tickets']['sort']; - $_REQUEST['order'] = $_SESSION[$queue.'_tickets']['order']; - - $order_by = $sortOptions[$_SESSION[$queue.'_tickets']['sort']]; - $order = $_SESSION[$queue.'_tickets']['order']; -} - -if($_REQUEST['order'] && $orderWays[strtoupper($_REQUEST['order'])]) - $order=$orderWays[strtoupper($_REQUEST['order'])]; - -//Save sort order for sticky sorting. -if($_REQUEST['sort'] && $queue) { - $_SESSION[$queue.'_tickets']['sort'] = $_REQUEST['sort']; - $_SESSION[$queue.'_tickets']['order'] = $_REQUEST['order']; -} - -//Set default sort by columns. -if(!$order_by ) { - if($showanswered) - $order_by='ticket.lastresponse, ticket.created'; //No priority sorting for answered tickets. - elseif(!strcasecmp($status,'closed')) - $order_by='ticket.closed, ticket.created'; //No priority sorting for closed tickets. - elseif($showoverdue) //priority> duedate > age in ASC order. - $order_by='pri.priority_urgency ASC, ISNULL(ticket.duedate) ASC, ticket.duedate ASC, effective_date ASC, ticket.created'; - else //XXX: Add due date here?? No - - $order_by='pri.priority_urgency ASC, effective_date DESC, ticket.created'; -} - -$order=$order?$order:'DESC'; -if($order_by && strpos($order_by,',') && $order) - $order_by=preg_replace('/(?<!ASC|DESC),/', " $order,", $order_by); - -$sort=$_REQUEST['sort']?strtolower($_REQUEST['sort']):'pri.priority_urgency'; //Urgency is not on display table. -$x=$sort.'_sort'; -$$x=' class="'.strtolower($order).'" '; - -if($_GET['limit']) - $qstr.='&limit='.urlencode($_GET['limit']); - -$qselect ='SELECT ticket.ticket_id,tlock.lock_id,ticket.`number`,ticket.dept_id,ticket.staff_id,ticket.team_id ' - .' ,user.name' - .' ,email.address as email, dept.dept_name, status.state ' - .' ,status.name as status,ticket.source,ticket.isoverdue,ticket.isanswered,ticket.created '; - -$qfrom=' FROM '.TICKET_TABLE.' ticket '. - ' LEFT JOIN '.TICKET_STATUS_TABLE. ' status - ON (status.id = ticket.status_id) '. - ' LEFT JOIN '.USER_TABLE.' user ON user.id = ticket.user_id'. - ' LEFT JOIN '.USER_EMAIL_TABLE.' email ON user.id = email.user_id'. - ' LEFT JOIN '.DEPT_TABLE.' dept ON ticket.dept_id=dept.dept_id '; - -if ($_REQUEST['uid']) - $qfrom.=' LEFT JOIN '.TICKET_COLLABORATOR_TABLE.' collab - ON (ticket.ticket_id = collab.ticket_id )'; - - -$sjoin=''; - -if($search && $deep_search) { - $sjoin.=' LEFT JOIN '.TICKET_THREAD_TABLE.' thread ON (ticket.ticket_id=thread.ticket_id )'; -} - -//get ticket count based on the query so far.. -$total=db_count("SELECT count(DISTINCT ticket.ticket_id) $qfrom $sjoin $qwhere"); -//pagenate +// Apply primary ticket status +if ($status) + $tickets->filter(array('status__state'=>$status)); + +// Impose visibility constraints +// ------------------------------------------------------------ +// -- Open and assigned to me +$visibility = array( + new Q(array('status__state'=>'open', 'staff_id' => $thisstaff->getId())) +); +// -- Routed to a department of mine +if (!$thisstaff->showAssignedOnly() && ($depts=$thisstaff->getDepts())) + $visibility[] = new Q(array('dept_id__in' => $depts)); +// -- Open and assigned to a team of mine +if (($teams = $thisstaff->getTeams()) && count(array_filter($teams))) + $visibility[] = new Q(array( + 'team_id__in' => array_filter($teams), 'status__state'=>'open' + )); +$tickets->filter(Q::any($visibility)); + +// Select pertinent columns +// ------------------------------------------------------------ +$tickets->select_related('lock', 'dept', 'staff', 'user', 'user__default_email', 'topic', 'status', 'cdata', 'cdata__:priority'); + +// Apply requested quick filter + +// Apply requested sorting + +// Apply requested pagination $pagelimit=($_GET['limit'] && is_numeric($_GET['limit']))?$_GET['limit']:PAGE_LIMIT; $page=($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1; -$pageNav=new Pagenate($total,$page,$pagelimit); -$pageNav->setURL('tickets.php',$qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order'])); - -//ADD attachment,priorities, lock and other crap -$qselect.=' ,IF(ticket.duedate IS NULL,IF(sla.id IS NULL, NULL, DATE_ADD(ticket.created, INTERVAL sla.grace_period HOUR)), ticket.duedate) as duedate ' - .' ,CAST(GREATEST(IFNULL(ticket.lastmessage, 0), IFNULL(ticket.closed, 0), IFNULL(ticket.reopened, 0), ticket.created) as datetime) as effective_date ' - .' ,ticket.created as ticket_created, CONCAT_WS(" ", staff.firstname, staff.lastname) as staff, team.name as team ' - .' ,IF(staff.staff_id IS NULL,team.name,CONCAT_WS(" ", staff.lastname, staff.firstname)) as assigned ' - .' ,IF(ptopic.topic_pid IS NULL, topic.topic, CONCAT_WS(" / ", ptopic.topic, topic.topic)) as helptopic ' - .' ,cdata.priority as priority_id, cdata.subject, pri.priority_desc, pri.priority_color'; - -$qfrom.=' LEFT JOIN '.TICKET_LOCK_TABLE.' tlock ON (ticket.ticket_id=tlock.ticket_id AND tlock.expire>NOW() - AND tlock.staff_id!='.db_input($thisstaff->getId()).') ' - .' LEFT JOIN '.STAFF_TABLE.' staff ON (ticket.staff_id=staff.staff_id) ' - .' LEFT JOIN '.TEAM_TABLE.' team ON (ticket.team_id=team.team_id) ' - .' LEFT JOIN '.SLA_TABLE.' sla ON (ticket.sla_id=sla.id AND sla.isactive=1) ' - .' LEFT JOIN '.TOPIC_TABLE.' topic ON (ticket.topic_id=topic.topic_id) ' - .' LEFT JOIN '.TOPIC_TABLE.' ptopic ON (ptopic.topic_id=topic.topic_pid) ' - .' LEFT JOIN '.TABLE_PREFIX.'ticket__cdata cdata ON (cdata.ticket_id = ticket.ticket_id) ' - .' LEFT JOIN '.PRIORITY_TABLE.' pri ON (pri.priority_id = cdata.priority)'; +$pageNav=new Pagenate($tickets->count(), $page,$pagelimit); TicketForm::ensureDynamicDataView(); -$query="$qselect $qfrom $qwhere ORDER BY $order_by $order LIMIT ".$pageNav->getStart().",".$pageNav->getLimit(); -//echo $query; -$hash = md5($query); -$_SESSION['search_'.$hash] = $query; -$res = db_query($query); -$showing=db_num_rows($res)? ' — '.$pageNav->showing():""; -if(!$results_type) - $results_type = sprintf(__('%s Tickets' /* %s will be a status such as 'open' */), - mb_convert_case($status, MB_CASE_TITLE)); - -if($search) - $results_type.= ' ('.__('Search Results').')'; - -$negorder=$order=='DESC'?'ASC':'DESC'; //Negate the sorting.. - -// Fetch the results -$results = array(); -while ($row = db_fetch_array($res)) { - $results[$row['ticket_id']] = $row; -} +// Save the query to the session for exporting +$_SESSION[':Q:tickets'] = $tickets; -// Fetch attachment and thread entry counts -if ($results) { - $counts_sql = 'SELECT ticket.ticket_id, - count(DISTINCT attach.attach_id) as attachments, - count(DISTINCT thread.id) as thread_count, - count(DISTINCT collab.id) as collaborators - FROM '.TICKET_TABLE.' ticket - LEFT JOIN '.TICKET_ATTACHMENT_TABLE.' attach ON (ticket.ticket_id=attach.ticket_id) ' - .' LEFT JOIN '.TICKET_THREAD_TABLE.' thread ON ( ticket.ticket_id=thread.ticket_id) ' - .' LEFT JOIN '.TICKET_COLLABORATOR_TABLE.' collab - ON ( ticket.ticket_id=collab.ticket_id) ' - .' WHERE ticket.ticket_id IN ('.implode(',', db_input(array_keys($results))).') - GROUP BY ticket.ticket_id'; - $ids_res = db_query($counts_sql); - while ($row = db_fetch_array($ids_res)) { - $results[$row['ticket_id']] += $row; - } -} - -//YOU BREAK IT YOU FIX IT. ?> + <!-- SEARCH FORM START --> <div id='basic_search'> <form action="tickets.php" method="get"> @@ -317,7 +97,7 @@ if ($results) { autocomplete="off" autocorrect="off" autocapitalize="off"></td> <td><input type="submit" name="basic_search" class="button" value="<?php echo __('Search'); ?>"></td> <td> <a href="#" onclick="javascript: - $.dialog('ajax.php/tickets/advanced-search', 201);" + $.dialog('ajax.php/tickets/search', 201);" >[<?php echo __('advanced'); ?>]</a> <i class="help-tip icon-question-sign" href="#advanced"></i></td> </tr> </table> @@ -412,55 +192,54 @@ if ($results) { $subject_field = TicketForm::objects()->one()->getField('subject'); $class = "row1"; $total=0; - if($res && ($num=count($results))): - $ids=($errors && $_POST['tids'] && is_array($_POST['tids']))?$_POST['tids']:null; - foreach ($results as $row) { - $tag=$row['staff_id']?'assigned':'openticket'; + $ids=($errors && $_POST['tids'] && is_array($_POST['tids']))?$_POST['tids']:null; + $subject_field = TicketForm::objects()->one()->getField('subject'); + foreach ($tickets as $T) { + $total += 1; + $tag=$T->staff_id?'assigned':'openticket'; $flag=null; - if($row['lock_id']) + if($T->lock) $flag='locked'; - elseif($row['isoverdue']) + elseif($T->isoverdue) $flag='overdue'; $lc=''; + $dept = ($T->dept) ? $T->dept->getLocalName() : ''; if($showassigned) { - if($row['staff_id']) - $lc=sprintf('<span class="Icon staffAssigned">%s</span>',Format::truncate($row['staff'],40)); + if($T->staff_id) + $lc=sprintf('<span class="Icon staffAssigned">%s</span>',Format::truncate($T->staff->getName(),40)); elseif($row['team_id']) - $lc=sprintf('<span class="Icon teamAssigned">%s</span>',Format::truncate($row['team'],40)); + $lc=sprintf('<span class="Icon teamAssigned">%s</span>',Format::truncate($T->team->getName(),40)); else $lc=' '; }else{ - $lc=Format::truncate($row['dept_name'],40); + $lc=Format::truncate($dept,40); } - $tid=$row['number']; - - $subject = Format::truncate($subject_field->display( - $subject_field->to_php($row['subject']) ?: $row['subject'] - ), 40); + $tid=$T->number; + $subject = Format::truncate($subject_field->display($subject_field->to_php($T->cdata->subject)),40); $threadcount=$row['thread_count']; - if(!strcasecmp($row['state'],'open') && !$row['isanswered'] && !$row['lock_id']) { + if(!strcasecmp($T->status->state,'open') && !$T->isanswered && !$T->lock) { $tid=sprintf('<b>%s</b>',$tid); } ?> - <tr id="<?php echo $row['ticket_id']; ?>"> + <tr id="<?php echo $T->ticket_id; ?>"> <?php if($thisstaff->canManageTickets()) { $sel=false; - if($ids && in_array($row['ticket_id'], $ids)) + if($ids && in_array($T->ticket_id, $ids)) $sel=true; ?> <td align="center" class="nohover"> <input class="ckb" type="checkbox" name="tids[]" - value="<?php echo $row['ticket_id']; ?>" <?php echo $sel?'checked="checked"':''; ?>> + value="<?php echo $T->ticket_id; ?>" <?php echo $sel?'checked="checked"':''; ?>> </td> <?php } ?> - <td title="<?php echo $row['email']; ?>" nowrap> - <a class="Icon <?php echo strtolower($row['source']); ?>Ticket ticketPreview" title="Preview Ticket" - href="tickets.php?id=<?php echo $row['ticket_id']; ?>"><?php echo $tid; ?></a></td> - <td align="center" nowrap><?php echo Format::datetime($row['effective_date']); ?></td> + <td title="<?php echo $T->user->getDefaultEmailAddress(); ?>" nowrap> + <a class="Icon <?php echo strtolower($T->source); ?>Ticket ticketPreview" title="Preview Ticket" + href="tickets.php?id=<?php echo $T->ticket_id; ?>"><?php echo $tid; ?></a></td> + <td align="center" nowrap><?php echo Format::datetime($T->getEffectiveDate()); ?></td> <td><a <?php if ($flag) { ?> class="Icon <?php echo $flag; ?>Ticket" title="<?php echo ucfirst($flag); ?> Ticket" <?php } ?> - href="tickets.php?id=<?php echo $row['ticket_id']; ?>"><?php echo $subject; ?></a> + href="tickets.php?id=<?php echo $T->ticket_id; ?>"><?php echo $subject; ?></a> <?php if ($threadcount>1) echo "<small>($threadcount)</small> ".'<i @@ -472,31 +251,31 @@ if ($results) { ?> </td> <td nowrap> <?php echo Format::htmlchars( - Format::truncate($row['name'], 22, strpos($row['name'], '@'))); ?> </td> + Format::truncate($T->user->getName(), 22, strpos($T->user->getName(), '@'))); ?> </td> <?php if($search && !$status){ - $displaystatus=ucfirst($row['status']); - if(!strcasecmp($row['state'],'open')) + $displaystatus=ucfirst($T->status); + if(!strcasecmp($T->status->state,'open')) $displaystatus="<b>$displaystatus</b>"; echo "<td>$displaystatus</td>"; } else { ?> - <td class="nohover" align="center" style="background-color:<?php echo $row['priority_color']; ?>;"> - <?php echo $row['priority_desc']; ?></td> + <td class="nohover" align="center" style="background-color:<?php echo $T->cdata->{':priority'}->priority_color; ?>;"> + <?php echo $T->cdata->{':priority'}->priority_desc; ?></td> <?php } ?> <td nowrap> <?php echo $lc; ?></td> </tr> <?php - } //end of while. - else: //not tickets found!! set fetch error. + } //end of foreach + if (!$total) $ferror=__('There are no tickets matching your criteria.'); - endif; ?> + ?> </tbody> <tfoot> <tr> <td colspan="7"> - <?php if($res && $num && $thisstaff->canManageTickets()){ ?> + <?php if($total && $thisstaff->canManageTickets()){ ?> <?php echo __('Select');?>: <a id="selectAll" href="#ckb"><?php echo __('All');?></a> <a id="selectNone" href="#ckb"><?php echo __('None');?></a> @@ -511,7 +290,7 @@ if ($results) { </tfoot> </table> <?php - if($num>0){ //if we actually had any tickets returned. + if($total>0){ //if we actually had any tickets returned. echo '<div> '.__('Page').':'.$pageNav->getPageLinks().' '; echo '<a class="export-csv no-pjax" href="?a=export&h=' .$hash.'&status='.$_REQUEST['status'] .'">'.__('Export').'</a> <i class="help-tip icon-question-sign" href="#export"></i></div>'; @@ -557,3 +336,4 @@ $(function() { }); }); </script> + diff --git a/scp/css/dropdown.css b/scp/css/dropdown.css index 4fb664178aaa2ab61f663d6b9219ad00740bf64d..54c277ec96063ac30b7e33c0ec6824e7a0939db7 100644 --- a/scp/css/dropdown.css +++ b/scp/css/dropdown.css @@ -131,3 +131,21 @@ color: #777; text-decoration: none; } +.action-buttons { + display: inline-block; + vertical-align: middle; +} +.action-buttons .action-button + .action-button { + margin-left: 0; + padding-left: 0; + border-left: none; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.action-buttons .action-button:not(:last-of-type) { + margin-right: 0; + padding-right: 0; + border-right: none; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} diff --git a/scp/tickets.php b/scp/tickets.php index 33300cb44131eaa48136d958f1160478fa20bd28..74fa99bff5df98e7fcc711d74bd8f398e0564872 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -448,7 +448,6 @@ $ost->addExtraHeader('<script type="text/javascript" src="js/ticket.js"></script $ost->addExtraHeader('<meta name="tip-namespace" content="tickets.queue" />', "$('#content').data('tipNamespace', 'tickets.queue');"); -$inc = 'tickets.inc.php'; if($ticket) { $ost->setPageTitle(sprintf(__('Ticket #%s'),$ticket->getNumber())); $nav->setActiveSubMenu(-1);