diff --git a/include/class.collaborator.php b/include/class.collaborator.php index b123644a0d85b3276f2a8e3c9403adaaaa9b60f4..20e827c065a17d9d5a7207293b171c10b96dfc47 100644 --- a/include/class.collaborator.php +++ b/include/class.collaborator.php @@ -156,4 +156,19 @@ class Collaborator extends TicketUser { ? $c : null; } } + +class TicketCollaborator extends VerySimpleModel { + static $meta = array( + 'table' => TICKET_COLLABORATOR_TABLE, + 'pk' => array('id'), + 'joins' => array( + 'ticket' => array( + 'constraint' => array('ticket_id' => 'TicketModel.ticket_id'), + ), + 'user' => array( + 'constraint' => array('user_id' => 'User.id'), + ), + ), + ); +} ?> diff --git a/include/class.dept.php b/include/class.dept.php index 4f8567d9256d8bc9e2db73bdf5d35b8cf6a6c567..bd77e48ec3ec973cfbc3d33211836006f00be127 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -364,7 +364,12 @@ class Dept extends VerySimpleModel { function getDefaultDeptName() { global $cfg; - return ($cfg && $cfg->getDefaultDeptId() && ($name=Dept::getNameById($cfg->getDefaultDeptId())))?$name:null; + + return ($cfg + && ($did = $cfg->getDefaultDeptId()) + && ($names = self::getDepartments())) + ? $names[$did] + : null; } static function getDepartments( $criteria=null) { diff --git a/include/class.orm.php b/include/class.orm.php index 58cf0a8f66067f9446dce449572d70bc8d3ef438..8338b84c7e65e739c9743a0112075de693a6fd47 100644 --- a/include/class.orm.php +++ b/include/class.orm.php @@ -1018,7 +1018,7 @@ class ModelInstanceManager extends ResultSet { } static function checkCache($modelClass, $fields) { - $key = $modelClass::$meta->model; + $key = $modelClass; foreach ($modelClass::$meta['pk'] as $f) $key .= '.'.$fields[$f]; return @self::$objectCache[$key]; diff --git a/include/class.ticket.php b/include/class.ticket.php index 1e3c1eb64240842ab2d5867bc9fcf837ceeea220..0d3296f1f8a7cb2a7975b7270b3954cc376d3bb1 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -42,6 +42,10 @@ class TicketModel extends VerySimpleModel { 'user' => array( 'constraint' => array('user_id' => 'User.id') ), + 'collaborators' => array( + 'reverse' => 'TicketCollaborator.ticket', + 'null' => true, + ), 'status' => array( 'constraint' => array('status_id' => 'TicketStatus.id') ), diff --git a/include/class.user.php b/include/class.user.php index aa016cd00ef53350f3d7d52480d208f55c62be4a..c8da82c12e6217340df74bbfd75ad5efbb6b3188 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -571,7 +571,7 @@ class User extends UserModel { } static function lookupByEmail($email) { - return self::lookup(array('emails__address'=>$email)); + return static::lookup(array('emails__address'=>$email)); } } diff --git a/include/client/tickets.inc.php b/include/client/tickets.inc.php index 8ebae5be121324e0a2221a51d66c0c65e6684b96..eb09a8559fcc39352bc794eeaf61ee7efd02bbe3 100644 --- a/include/client/tickets.inc.php +++ b/include/client/tickets.inc.php @@ -1,6 +1,8 @@ <?php if(!defined('OSTCLIENTINC') || !is_object($thisclient) || !$thisclient->isValid()) die('Access Denied'); +$tickets = TicketModel::objects(); + $qstr='&'; //Query string collector $status=null; if(isset($_REQUEST['status'])) { //Query string status has nothing to do with the real status used below. @@ -10,11 +12,11 @@ if(isset($_REQUEST['status'])) { //Query string status has nothing to do with th switch(strtolower($_REQUEST['status'])) { case 'open': $results_type=__('Open Tickets'); + $tickets->filter(array('status__state'=>'open')); + break; case 'closed': $results_type=__('Closed Tickets'); - break; - case 'resolved': - $results_type=__('Resolved Tickets'); + $tickets->filter(array('status__state'=>'closed')); break; default: $status=''; //ignore @@ -24,92 +26,66 @@ if(isset($_REQUEST['status'])) { //Query string status has nothing to do with th $results_type=__('Open Tickets'); } -$sortOptions=array('id'=>'`number`', 'subject'=>'cdata.subject', - 'status'=>'status.name', 'dept'=>'dept.name','date'=>'ticket.created'); -$orderWays=array('DESC'=>'DESC','ASC'=>'ASC'); +$sortOptions=array('id'=>'number', 'subject'=>'cdata__subject', + 'status'=>'status__name', 'dept'=>'dept__name','date'=>'created'); +$orderWays=array('DESC'=>'-','ASC'=>''); //Sorting options... $order_by=$order=null; $sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'date'; if($sort && $sortOptions[$sort]) $order_by =$sortOptions[$sort]; -$order_by=$order_by?$order_by:'ticket_created'; +$order_by=$order_by ?: $sortOptions['date']; if($_REQUEST['order'] && $orderWays[strtoupper($_REQUEST['order'])]) $order=$orderWays[strtoupper($_REQUEST['order'])]; -$order=$order?$order:'ASC'; -if($order_by && strpos($order_by,',')) - $order_by=str_replace(','," $order,",$order_by); - $x=$sort.'_sort'; -$$x=' class="'.strtolower($order).'" '; - -$qselect='SELECT ticket.ticket_id,ticket.`number`,ticket.dept_id,isanswered, ' - .'dept.ispublic, cdata.subject,' - .'dept.name as dept_name, status.name as status, status.state, ticket.source, ticket.created '; +$$x=' class="'.strtolower($_REQUEST['order'] ?: 'desc').'" '; -$qfrom='FROM '.TICKET_TABLE.' ticket ' - .' LEFT JOIN '.TICKET_STATUS_TABLE.' status - ON (status.id = ticket.status_id) ' - .' LEFT JOIN '.TABLE_PREFIX.'ticket__cdata cdata ON (cdata.ticket_id = ticket.ticket_id)' - .' LEFT JOIN '.DEPT_TABLE.' dept ON (ticket.dept_id=dept.dept_id) ' - .' LEFT JOIN '.TICKET_COLLABORATOR_TABLE.' collab - ON (collab.ticket_id = ticket.ticket_id - AND collab.user_id ='.$thisclient->getId().' )'; - -$qwhere = sprintf(' WHERE ( ticket.user_id=%d OR collab.user_id=%d )', - $thisclient->getId(), $thisclient->getId()); - -$states = array( - 'open' => 'open', - 'closed' => 'closed'); -if($status && isset($states[$status])){ - $qwhere.=' AND status.state='.db_input($states[$status]); -} +// Add visibility constraints +$tickets->filter(Q::any(array( + 'user_id' => $thisclient->getId(), + 'collaborators__user_id' => $thisclient->getId(), +))); +// Perform basic search $search=($_REQUEST['a']=='search' && $_REQUEST['q']); if($search) { $qstr.='&a='.urlencode($_REQUEST['a']).'&q='.urlencode($_REQUEST['q']); - if(is_numeric($_REQUEST['q'])) { - $qwhere.=" AND ticket.`number` LIKE '$queryterm%'"; - } else {//Deep search! - $queryterm=db_real_escape($_REQUEST['q'],false); //escape the term ONLY...no quotes. - $qwhere.=' AND ( ' - ." cdata.subject LIKE '%$queryterm%'" - ." OR thread.body LIKE '%$queryterm%'" - .' ) '; - $deep_search=true; - //Joins needed for search - $qfrom.=' LEFT JOIN '.TICKET_THREAD_TABLE.' thread ON (' - .'ticket.ticket_id=thread.ticket_id AND thread.thread_type IN ("M","R"))'; + if (is_numeric($_REQUEST['q'])) { + $tickets->filter(array('number__startswith'=>$_REQUEST['q'])); + } else { //Deep search! + // Use the search engine to perform the search + $tickets = $ost->searcher->find($_REQUEST['q'], $tickets); } } TicketForm::ensureDynamicDataView(); -$total=db_count('SELECT count(DISTINCT ticket.ticket_id) '.$qfrom.' '.$qwhere); +$total=$tickets->count(); $page=($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1; $pageNav=new Pagenate($total, $page, PAGE_LIMIT); $pageNav->setURL('tickets.php',$qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order'])); +$pageNav->paginate($tickets); -//more stuff... -$qselect.=' ,count(attach_id) as attachments '; -$qfrom.=' LEFT JOIN '.TICKET_ATTACHMENT_TABLE.' attach ON ticket.ticket_id=attach.ticket_id '; -$qgroup=' GROUP BY ticket.ticket_id'; - -$query="$qselect $qfrom $qwhere $qgroup ORDER BY $order_by $order LIMIT ".$pageNav->getStart().",".$pageNav->getLimit(); //echo $query; -$res = db_query($query); -$showing=($res && db_num_rows($res))?$pageNav->showing():""; +$showing =$total ? $pageNav->showing() : ""; if(!$results_type) { - $results_type=ucfirst($status).' Tickets'; + $results_type=ucfirst($status).' '.__('Tickets'); } $showing.=($status)?(' '.$results_type):' '.__('All Tickets'); if($search) $showing=__('Search Results').": $showing"; -$negorder=$order=='DESC'?'ASC':'DESC'; //Negate the sorting +$negorder=$order=='-'?'ASC':'DESC'; //Negate the sorting + +$tickets->order_by($order.$order_by); +$tickets->values( + 'ticket_id', 'number', 'created', 'isanswered', 'source', 'status__id', + 'status__state', 'status__name', 'cdata__subject', 'dept_id', + 'dept__name', 'dept__ispublic', 'user__default_email__address' +); ?> <h1><?php echo __('Tickets');?></h1> @@ -158,31 +134,33 @@ $negorder=$order=='DESC'?'ASC':'DESC'; //Negate the sorting <tbody> <?php $subject_field = TicketForm::objects()->one()->getField('subject'); - if($res && ($num=db_num_rows($res))) { - $defaultDept=Dept::getDefaultDeptName(); //Default public dept. - while ($row = db_fetch_array($res)) { - $dept= $row['ispublic']? $row['dept_name'] : $defaultDept; + $defaultDept=Dept::getDefaultDeptName(); //Default public dept. + if ($tickets->exists(true)) { + foreach ($tickets as $T) { + $dept = $T['dept__ispublic'] + ? Dept::getLocalById($T['dept_id'], 'name', $T['dept__name']) + : $defaultDept; $subject = Format::truncate($subject_field->display( - $subject_field->to_php($row['subject']) ?: $row['subject'] + $subject_field->to_php($T['cdata__subject']) ?: $T['cdata__subject'] ), 40); - if($row['attachments']) + if (false) // XXX: Reimplement attachment count support $subject.=' <span class="Icon file"></span>'; - $ticketNumber=$row['number']; - if($row['isanswered'] && !strcasecmp($row['state'], 'open')) { + $ticketNumber=$T['number']; + if($T['isanswered'] && !strcasecmp($T['status__state'], 'open')) { $subject="<b>$subject</b>"; $ticketNumber="<b>$ticketNumber</b>"; } ?> - <tr id="<?php echo $row['ticket_id']; ?>"> + <tr id="<?php echo $T['ticket_id']; ?>"> <td> - <a class="Icon <?php echo strtolower($row['source']); ?>Ticket" title="<?php echo $row['email']; ?>" - href="tickets.php?id=<?php echo $row['ticket_id']; ?>"><?php echo $ticketNumber; ?></a> + <a class="Icon <?php echo strtolower($T['source']); ?>Ticket" title="<?php echo $T['user__default_email__address']; ?>" + href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><?php echo $ticketNumber; ?></a> </td> - <td> <?php echo Format::date($row['created']); ?></td> - <td> <?php echo $row['status']; ?></td> + <td> <?php echo Format::date($T['created']); ?></td> + <td> <?php echo $T['status__name']; ?></td> <td> - <a href="tickets.php?id=<?php echo $row['ticket_id']; ?>"><?php echo $subject; ?></a> + <a href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><?php echo $subject; ?></a> </td> <td> <?php echo Format::truncate($dept,30); ?></td> </tr> @@ -196,7 +174,7 @@ $negorder=$order=='DESC'?'ASC':'DESC'; //Negate the sorting </tbody> </table> <?php -if($res && $num>0) { +if ($total) { echo '<div> '.__('Page').':'.$pageNav->getPageLinks().' </div>'; } ?>