diff options
Diffstat (limited to 'modules-available/statistics/inc/statisticsfilterset.inc.php')
-rw-r--r-- | modules-available/statistics/inc/statisticsfilterset.inc.php | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/modules-available/statistics/inc/statisticsfilterset.inc.php b/modules-available/statistics/inc/statisticsfilterset.inc.php new file mode 100644 index 00000000..26595e93 --- /dev/null +++ b/modules-available/statistics/inc/statisticsfilterset.inc.php @@ -0,0 +1,139 @@ +<?php + +class StatisticsFilterSet +{ + /** + * @var \DatabaseFilter[] + */ + private $filters; + + private $cache = false; + + /** + * @param DatabaseFilter[] $filters + */ + public function __construct(array $filters) + { + $this->filters = $filters; + } + + public function makeFragments(&$where, &$join, &$args) + { + if ($this->cache !== false) { + $where = $this->cache['where']; + $join = $this->cache['join']; + $args = $this->cache['args']; + return; + } + /* generate where clause & arguments */ + $where = ''; + $joins = []; + $args = []; + if (empty($this->filters)) { + $where = ' 1 '; + } else { + foreach ($this->filters as $filter) { + $sep = ($where != '' ? ' AND ' : ''); + $where .= $sep . $filter->whereClause($args, $joins); + } + } + $join = implode(' ', array_unique($joins)); + $this->cache = compact('where', 'join', 'args'); + } + + public function filterNonClients() + { + if (Module::get('runmode') === false || $this->hasFilter('IsClientStatisticsFilter') !== null) + return; + $this->cache = false; + // Runmode module exists, add filter + $this->filters[] = (new IsClientStatisticsFilter())->bind('=', true); + } + + /** + * @param string $type filter type (class name) + * @return ?DatabaseFilter The filter, null if not found + */ + public function hasFilter(string $type): ?DatabaseFilter + { + foreach ($this->filters as $filter) { + if ($filter->isClass($type)) { + return $filter; + } + } + return null; + } + + /** + * @param string $type filter type key/id + * @return ?DatabaseFilter The filter, null if not found + */ + public function hasFilterKey(string $type): ?DatabaseFilter + { + if (isset($this->filters[$type])) + return $this->filters[$type]; + return null; + } + + /** + * Add a location filter based on the allowed permissions for the given permission. + * Returns false if the user doesn't have the given permission for any location. + * + * @param string $permission permission to use + * @return bool false if no permission for any location, true otherwise + */ + public function setAllowedLocationsFromPermission(string $permission): bool + { + if (!Module::isAvailable('locations')) + return true; + $locs = User::getAllowedLocations($permission); + if (empty($locs)) + return false; + if (in_array(0, $locs)) { + if (!isset($this->filters['permissions'])) + return true; + unset($this->filters['permissions']); + } else { + $this->filters['permissions'] = StatisticsFilter::$columns['location']->bind('=', $locs); + } + $this->cache = false; + return true; + } + + /** + * @return false|array + */ + public function getAllowedLocations() + { + if (isset($this->filters['permissions']) && is_array($this->filters['permissions']->argument)) + return (array)$this->filters['permissions']->argument; + return false; + } + + public function suitableForUsageGraph(): bool + { + foreach ($this->filters as $filter) { + switch ($filter->getClass()) { + case 'LocationStatisticsFilter': + case 'IsClientStatisticsFilter': + break; + case 'DateStatisticsFilter': + if ($filter->op !== '>' && $filter->op !== '>=') + return false; + if (strtotime($filter->argument) + 3*86400 > time()) + return false; + break; + case 'RuntimeStatisticsFilter': + if ($filter->op !== '>' && $filter->op !== '>=') + return false; + if ($filter->argument < 3 * 24) + return false; + break; + default: + return false; + } + } + return true; + } + +} |