diff options
author | Christian Klinger | 2016-07-13 12:40:58 +0200 |
---|---|---|
committer | Christian Klinger | 2016-07-13 12:40:58 +0200 |
commit | c5712e1c26b31afd38ebd8b7d79b0740c0dd0d60 (patch) | |
tree | c6bca52b94d12014999d97026dc5f291a27b8b29 /modules-available/statistics/inc/filter.inc.php | |
parent | fixed bug. (diff) | |
download | slx-admin-c5712e1c26b31afd38ebd8b7d79b0740c0dd0d60.tar.gz slx-admin-c5712e1c26b31afd38ebd8b7d79b0740c0dd0d60.tar.xz slx-admin-c5712e1c26b31afd38ebd8b7d79b0740c0dd0d60.zip |
Squashed commit of the following:
commit af19d2aa593a4b4b068a5bc3707d74378625d774
Author: Christian Klinger <spam@klinch.de>
Date: Wed Jul 13 12:32:17 2016 +0200
added sorting functionality.
commit 0030ebebb49bad18fba8e74184d331be5485ed4e
Author: Christian Klinger <spam@klinch.de>
Date: Fri Jul 8 16:09:16 2016 +0200
small improvements.
commit 8dc5ee1173ffbc6e689f3197ad4d1ecf700a9374
Author: Christian Klinger <spam@klinch.de>
Date: Fri Jul 8 12:49:29 2016 +0200
added location fiter.
commit 63a2da244a6def5cdd76c654bd5a6a0c108cc47b
Author: Christian Klinger <spam@klinch.de>
Date: Fri Jul 8 12:25:15 2016 +0200
most filters should work.
commit 847536b34cec0194c58cb41a17006a8bd88f748d
Author: Christian Klinger <spam@klinch.de>
Date: Tue Jul 5 15:57:38 2016 +0200
rudimentary filter options.
Diffstat (limited to 'modules-available/statistics/inc/filter.inc.php')
-rw-r--r-- | modules-available/statistics/inc/filter.inc.php | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/modules-available/statistics/inc/filter.inc.php b/modules-available/statistics/inc/filter.inc.php new file mode 100644 index 00000000..0f1a0d20 --- /dev/null +++ b/modules-available/statistics/inc/filter.inc.php @@ -0,0 +1,205 @@ +<?php + +/* base class with rudimentary SQL generation abilities. + * WARNING: argument is escaped, but $column and $operator are passed unfiltered into SQL */ +class Filter +{ + public $column; + public $operator; + public $argument; + public function __construct($column, $operator, $argument = null) + { + $this->column = trim($column); + $this->operator = trim($operator); + $this->argument = trim($argument); + } + /* returns a where clause and adds needed operators to the passed array */ + public function whereClause(&$args, &$joins) + { + global $unique_key; + $key = $this->column.'_arg' . ($unique_key++); + + /* check if we have to do some parsing*/ + if (Page_Statistics::$columns[$this->column]['type'] == 'date') { + $args[$key] = strtotime($this->argument); + } else { + $args[$key] = $this->argument; + } + + $op = $this->operator; + if ($this->operator == '~') { + $op = 'LIKE'; + } elseif ($this->operator == '!~') { + $op = 'NOT LIKE'; + } + + return $this->column.' '.$op.' :'.$key; + } + /* parse a query into an array of filters */ + public static function parseQuery($query) + { + $operators = ['<=', '>=', '!=', '!~', '=', '~', '<', '>']; + $filters = []; + foreach (explode(',', $query) as $q) { + $q = trim($q); + /* find position of first operator */ + $pos = 10000; + $operator; + foreach ($operators as $op) { + $newpos = strpos($q, $op); + if ($newpos > -1 && ($newpos < $pos)) { + $pos = $newpos; + $operator = $op; + } + } + if ($pos == 10000) { + error_log("couldn't find operator in segment ".$q); + /* TODO */ + continue; + } + $lhs = trim(substr($q, 0, $pos)); + $rhs = trim(substr($q, $pos + strlen($operator))); + + if ($lhs == 'gbram') { + $filters[] = new RamGbFilter($operator, $rhs); + } elseif ($lhs == 'state') { + error_log('new state filter with ' . $rhs); + $filters[] = new StateFilter($operator, $rhs); + } elseif ($lhs == 'hddgb') { + $filters[] = new Id44Filter($operator, $rhs); + } elseif ($lhs == 'location') { + $filters[] = new LocationFilter($operator, $rhs); + } elseif ($lhs == 'subnet') { + $filters[] = new SubnetFilter($operator, $rhs); + } else { + if (array_key_exists($lhs, Page_Statistics::$columns) && Page_Statistics::$columns[$lhs]['column']) { + $filters[] = new Filter($lhs, $operator, $rhs); + } else { + Message::addError('invalid-filter'); + } + } + } + + return $filters; + } +} + +class RamGbFilter extends Filter +{ + public function __construct($operator, $argument) + { + parent::__construct('mbram', $operator, $argument); + } + public function whereClause(&$args, &$joins) + { + global $SIZE_RAM; + $lower = floor(Page_Statistics::findBestValue($SIZE_RAM, (int) $this->argument, false) * 1024 - 100); + $upper = ceil(Page_Statistics::findBestValue($SIZE_RAM, (int) $this->argument, true) * 1024 + 100); + if ($this->operator == '=') { + return " mbram BETWEEN $lower AND $upper"; + } elseif ($this->operator == '<') { + return " mbram < $lower"; + } elseif ($this->operator == '<=') { + return " mbram <= $upper"; + } elseif ($this->operator == '>') { + return " mbram > $upper"; + } elseif ($this->operator == '>=') { + return " mbram >= $lower"; + } elseif ($this->operator == '!=') { + return " (mbram < $lower OR mbram > $upper)"; + } else { + error_log("unimplemented operator in RamGbFilter: $this->operator"); + + return ' 1'; + } + } +} +class Id44Filter extends Filter +{ + public function __construct($operator, $argument) + { + parent::__construct('id44mb', $operator, $argument); + } + public function whereClause(&$args, &$joins) + { + global $SIZE_ID44; + $lower = floor(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, false) * 1024 - 100); + $upper = ceil(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, true) * 1024 + 100); + + if ($this->operator == '=') { + return " id44mb BETWEEN $lower AND $upper"; + } elseif ($this->operator == '!=') { + return " id44mb < $lower OR id44mb > $upper"; + } elseif ($this->operator == '<=') { + return " id44mb < $upper"; + } elseif ($this->operator == '>=') { + return " id44mb > $lower"; + } elseif ($this->operator == '<') { + return " id44mb < $lower"; + } elseif ($this->operator == '>') { + return " id44mb > $upper"; + } else { + error_log("unimplemented operator in Id44Filter: $this->operator"); + + return ' 1'; + } + } +} +class StateFilter extends Filter +{ + public function __construct($operator, $argument) + { + $this->operator = $operator; + $this->argument = $argument; + } + + public function whereClause(&$args, &$joins) + { + $neg = $this->operator == '!=' ? 'NOT ' : ''; + if ($this->argument === 'on') { + return " $neg (lastseen + 600 > UNIX_TIMESTAMP() ) "; + } elseif ($this->argument === 'off') { + return " $neg (lastseen + 600 < UNIX_TIMESTAMP() ) "; + } elseif ($this->argument === 'idle') { + return " $neg (lastseen + 600 > UNIX_TIMESTAMP() AND logintime = 0 ) "; + } elseif ($this->argument === 'occupied') { + return " $neg (lastseen + 600 > UNIX_TIMESTAMP() AND logintime <> 0 ) "; + } else { + Message::addError('invalid-filter'); + + return ' 1'; + } + } +} + +class LocationFilter extends Filter +{ + public function __construct($operator, $argument) { + parent::__construct('locationid', $operator, $argument); + } + + public function whereClause(&$args, &$joins) { + settype($this->argument, 'int'); + if ($this->argument === 0) { + $joins[] = 'LEFT JOIN subnet s ON (INET_ATON(machine.clientip) BETWEEN s.startaddr AND s.endaddr)'; + return 'machine.locationid IS NULL AND s.locationid IS NULL'; + } else { + $joins[] = ' INNER JOIN subnet ON (INET_ATON(clientip) BETWEEN startaddr AND endaddr) '; + $args['lid'] = $this->argument; + $neg = $this->operator == '=' ? '' : 'NOT'; + return "$neg (subnet.locationid = :lid OR machine.locationid = :lid)"; + } + } +} + +class SubnetFilter extends Filter +{ + public function __construct($operator, $argument) { + parent::__construct(null, $operator, $argument); + } + public function whereClause(&$args, &$joins) { + $argument = preg_replace('/[^0-9\.:]/', '', $this->argument); + return " clientip LIKE '$argument%'"; + } +} + |