diff --git a/include/ajax.search.php b/include/ajax.search.php index fabe2d810fdd8e694d566b418b656c028e94a916..2cf5521512e6cd6b32b26b36576757b868c069d5 100644 --- a/include/ajax.search.php +++ b/include/ajax.search.php @@ -394,8 +394,7 @@ class SearchAjaxAPI extends AjaxController { $criteria = array(); if ($ids && is_array($ids)) $criteria = array('id__in' => $ids); - - $counts = SavedQueue::counts($thisstaff, $criteria); + $counts = SavedQueue::counts($thisstaff, true, $criteria); Http::response(200, false, 'application/json'); return $this->encode($counts); } diff --git a/include/class.search.php b/include/class.search.php index 3ffae21424c16361e8f21370a8cc4dcf829f35bb..7248c25199776524be97dbae5f297761155cb8ca 100644 --- a/include/class.search.php +++ b/include/class.search.php @@ -847,41 +847,45 @@ class SavedQueue extends CustomQueue { return (!$errors); } + function getTotal($agent=null) { + $query = $this->getQuery(); + if ($agent) + $query = $agent->applyVisibility($query); + $query->limit(false)->offset(false)->order_by(false); + try { + return $query->count(); + } catch (Exception $e) { + return null; + } + } + function getCount($agent, $cached=true) { - $criteria = $cached ? array() : array('id' => $this->getId()); - $counts = self::counts($agent, $criteria, $cached); - return $counts["q{$this->getId()}"] ?: 0; + $count = null; + if ($cached && ($counts = self::counts($agent, $cached))) + $count = $counts["q{$this->getId()}"]; + + if ($count == null) + $count = $this->getTotal($agent); + + return $count; } // Get ticket counts for queues the agent has acces to. - static function counts($agent, $criteria=array(), $cached=true) { + static function counts($agent, $cached=true, $criteria=array()) { if (!$agent instanceof Staff) - return array(); + return null; // Cache TLS in seconds - $ttl = 3600; + $ttl = 5*60; // Cache key based on agent and salt of the installation $key = "counts.queues.{$agent->getId()}.".SECRET_SALT; if ($criteria && is_array($criteria)) // Consider additional criteria. $key .= '.'.md5(serialize($criteria)); // only consider cache if requesed - if ($cached) { - if (function_exists('apcu_store')) { - $found = false; - $counts = apcu_fetch($key, $found); - if ($found === true) - return $counts; - } elseif (isset($_SESSION[$key]) - && isset($_SESSION[$key]['qcount']) - && (time() - $_SESSION[$key]['time']) < $ttl) { - return $_SESSION[$key]['qcount']; - } else { - // Auto clear missed session cache (if any) - unset($_SESSION[$key]); - } - } + if ($cached && ($counts=self::getCounts($key, $ttl))) + return $counts; $queues = static::objects() ->filter(Q::any(array( @@ -913,17 +917,45 @@ class SavedQueue extends CustomQueue { } } - $counts = $query->values()->one(); + try { + $counts = $query->values()->one(); + } catch (Exception $ex) { + foreach ($queues as $q) + $counts['q'.$q->getId()] = $q->getTotal(); + } + // Always cache the results + self::storeCounts($key, $counts, $ttl); + + return $counts; + } + + static function getCounts($key, $ttl) { + + if (!$key) { + return array(); + } elseif (function_exists('apcu_store')) { + $found = false; + $counts = apcu_fetch($key, $found); + if ($found === true) + return $counts; + } elseif (isset($_SESSION['qcounts'][$key]) + && (time() - $_SESSION['qcounts'][$key]['time']) < $ttl) { + return $_SESSION['qcounts'][$key]['counts']; + } else { + // Auto clear missed session cache (if any) + unset($_SESSION['qcounts'][$key]); + } + } + + static function storeCounts($key, $counts, $ttl) { if (function_exists('apcu_store')) { apcu_store($key, $counts, $ttl); } else { // Poor man's cache - $_SESSION[$key]['qcount'] = $counts; - $_SESSION[$key]['time'] = time(); + $_SESSION['qcounts'][$key]['counts'] = $counts; + $_SESSION['qcounts'][$key]['time'] = time(); } - - return $counts; } static function clearCounts() { diff --git a/include/staff/templates/queue-tickets.tmpl.php b/include/staff/templates/queue-tickets.tmpl.php index fe82ff9a21460eda9090a000f4fda147a99bc323..41ffef2a6303925094eece20861e9b420d2c308d 100644 --- a/include/staff/templates/queue-tickets.tmpl.php +++ b/include/staff/templates/queue-tickets.tmpl.php @@ -88,7 +88,7 @@ $tickets = $tickets->filter(['ticket_id__in' => $criteria->values_flat('ticket_i # Index hint should be used on the $criteria query only $tickets->clearOption(QuerySet::OPT_INDEX_HINT); -$count = $queue->getCount($thisstaff); +$count = $queue->getCount($thisstaff) ?: (PAGE_LIMIT*3); $pageNav->setTotal($count, true); $pageNav->setURL('tickets.php', $args); ?> diff --git a/scp/autocron.php b/scp/autocron.php index cc124455f3a246ef97f37ce3fe7482d8d9797e93..c19e1520f4a465512ca3cd30e28d3fc26d49aec3 100644 --- a/scp/autocron.php +++ b/scp/autocron.php @@ -48,7 +48,7 @@ require_once(INCLUDE_DIR.'class.cron.php'); // Run tickets count every 3rd run or so... force new count by skipping cached // results if ((mt_rand(1, 12) % 3) == 0) - SavedQueue::counts($thisstaff, array(), false); + SavedQueue::counts($thisstaff, false); // Clear staff obj to avoid false credit internal notes & auto-assignment $thisstaff = null;