diff --git a/include/class.pagenate.php b/include/class.pagenate.php index b20ad52a5da542faa088d21d31045a338761c313..70d1ca1262d3111ed962bc54a5233d335fdd4f2a 100644 --- a/include/class.pagenate.php +++ b/include/class.pagenate.php @@ -22,6 +22,7 @@ class PageNate { var $total; var $page; var $pages; + var $approx=false; function __construct($total,$page,$limit=20,$url='') { @@ -32,7 +33,7 @@ class PageNate { $this->setTotal($total); } - function setTotal($total) { + function setTotal($total, $approx=false) { $this->total = intval($total); $this->pages = ceil( $this->total / $this->limit ); @@ -42,6 +43,7 @@ class PageNate { if (($this->limit-1)*$this->start > $this->total) { $this->start -= $this->start % $this->limit; } + $this->approx = $approx; } function setURL($url='',$vars='') { @@ -97,8 +99,12 @@ class PageNate { } $html=__('Showing')." "; if ($this->total > 0) { - $html .= sprintf(__('%1$d - %2$d of %3$d' /* Used in pagination output */), - $start, $end, $this->total); + if ($this->approx) + $html .= sprintf(__('%1$d - %2$d of about %3$d' /* Used in pagination output */), + $start, $end, $this->total); + else + $html .= sprintf(__('%1$d - %2$d of %3$d' /* Used in pagination output */), + $start, $end, $this->total); }else{ $html .= " 0 "; } diff --git a/include/class.queue.php b/include/class.queue.php index e6230001753346aca441ec4da623a7b84135fd1a..643fdb712ec85742509ae87b575beb85a2276cc8 100644 --- a/include/class.queue.php +++ b/include/class.queue.php @@ -1085,6 +1085,57 @@ class CustomQueue extends VerySimpleModel { $this->clearFlag(self::FLAG_DISABLED); } + function getRoughCount() { + if (($count = $this->getRoughCountAPC()) !== false) + return $count; + + $query = Ticket::objects(); + $Q = $this->getBasicQuery(); + $expr = SqlCase::N()->when(new SqlExpr(new Q($Q->constraints)), + new SqlField('ticket_id')); + $query = $query->aggregate(array( + "ticket_count" => SqlAggregate::COUNT($expr) + )); + + $row = $query->values()->one(); + return $row['ticket_count']; + } + + function getRoughCountAPC() { + if (!function_exists('apcu_store')) + return false; + + $key = "rough.counts.".SECRET_SALT; + $cached = false; + $counts = apcu_fetch($key, $cached); + if ($cached === true && isset($counts["q{$this->id}"])) + return $counts["q{$this->id}"]; + + // Fetch rough counts of all queues. That is, fetch a total of the + // counts based on the queue criteria alone. Do no consider agent + // access. This should be fast and "rought" + $queues = static::objects() + ->filter(['flags__hasbit' => CustomQueue::FLAG_PUBLIC]) + ->exclude(['flags__hasbit' => CustomQueue::FLAG_DISABLED]); + + $query = Ticket::objects(); + $prefix = ""; + + foreach ($queues as $queue) { + $Q = $queue->getBasicQuery(); + $expr = SqlCase::N()->when(new SqlExpr(new Q($Q->constraints)), + new SqlField('ticket_id')); + $query = $query->aggregate(array( + "q{$queue->id}" => SqlAggregate::COUNT($expr) + )); + } + + $counts = $query->values()->one(); + + apcu_store($key, $counts, 900); + return @$counts["q{$this->id}"]; + } + function updateExports($fields, $save=true) { if (!$fields) diff --git a/include/class.search.php b/include/class.search.php index 6dad6141606b49e1b326d3b8507f921fe190a080..aa2919910bc918f5843b7c247e986bac6a5263a2 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -899,6 +899,8 @@ class SavedQueue extends CustomQueue { foreach (new APCUIterator($regex, APC_ITER_KEY) as $key) { apcu_delete($key); } + // Also clear rough counts + apcu_delete("rough.counts.".SECRET_SALT); } } diff --git a/include/staff/templates/queue-tickets.tmpl.php b/include/staff/templates/queue-tickets.tmpl.php index 37d7cced74789b85fd6aa1f6cf6b0dc720eacc30..205ac43c339a21b1b9b89927f629fec6f78e5bb0 100644 --- a/include/staff/templates/queue-tickets.tmpl.php +++ b/include/staff/templates/queue-tickets.tmpl.php @@ -76,8 +76,8 @@ if (!$sorted && isset($sort['queuesort'])) { $page = ($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1; $pageNav = new Pagenate(PHP_INT_MAX, $page, PAGE_LIMIT); $tickets = $pageNav->paginateSimple($tickets); -$count = $tickets->total(); -$pageNav->setTotal($count); +$count = $queue->getRoughCount(); +$pageNav->setTotal($count, true); $pageNav->setURL('tickets.php', $args); ?>