xref: /plugin/statistics/Query.php (revision 7428e816a000a79987e124279d701cb1f094e3b3)
1b6632b6eSAndreas Gohr<?php
2b6632b6eSAndreas Gohr
3b6632b6eSAndreas Gohrnamespace dokuwiki\plugin\statistics;
4b6632b6eSAndreas Gohr
5b6632b6eSAndreas Gohruse helper_plugin_statistics;
6b6632b6eSAndreas Gohr
7b6632b6eSAndreas Gohrclass Query
8b6632b6eSAndreas Gohr{
9b6632b6eSAndreas Gohr    protected $hlp;
10*7428e816SAndreas Gohr    protected $from;
11*7428e816SAndreas Gohr    protected $to;
12b6632b6eSAndreas Gohr
13b6632b6eSAndreas Gohr    public function __construct(helper_plugin_statistics $hlp)
14b6632b6eSAndreas Gohr    {
15b6632b6eSAndreas Gohr        $this->hlp = $hlp;
16*7428e816SAndreas Gohr        $today = date('Y-m-d');
17*7428e816SAndreas Gohr        $this->setTimeFrame($today, $today);
18*7428e816SAndreas Gohr    }
19*7428e816SAndreas Gohr
20*7428e816SAndreas Gohr    /**
21*7428e816SAndreas Gohr     * Set the time frame for all queries
22*7428e816SAndreas Gohr     */
23*7428e816SAndreas Gohr    public function setTimeFrame($from, $to)
24*7428e816SAndreas Gohr    {
25*7428e816SAndreas Gohr        // fixme add better sanity checking here:
26*7428e816SAndreas Gohr        $from = preg_replace('/[^\d\-]+/', '', $from);
27*7428e816SAndreas Gohr        $to = preg_replace('/[^\d\-]+/', '', $to);
28*7428e816SAndreas Gohr        if (!$from) $from = date('Y-m-d');
29*7428e816SAndreas Gohr        if (!$to) $to = date('Y-m-d');
30*7428e816SAndreas Gohr
31*7428e816SAndreas Gohr        $this->from = $from. ' 00:00:00';
32*7428e816SAndreas Gohr        $this->to = $to. ' 23:59:59';
33b6632b6eSAndreas Gohr    }
34b6632b6eSAndreas Gohr
35b6632b6eSAndreas Gohr    /**
36b6632b6eSAndreas Gohr     * Return some aggregated statistics
37b6632b6eSAndreas Gohr     */
38*7428e816SAndreas Gohr    public function aggregate()
39b6632b6eSAndreas Gohr    {
40b6632b6eSAndreas Gohr        $data = [];
41b6632b6eSAndreas Gohr
42b6632b6eSAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
43*7428e816SAndreas Gohr                  FROM access as A
44*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
45*7428e816SAndreas Gohr                   AND ua_type = ?
46b6632b6eSAndreas Gohr              GROUP BY ref_type";
47*7428e816SAndreas Gohr        $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser']);
48b6632b6eSAndreas Gohr
49b6632b6eSAndreas Gohr        if (is_array($result)) foreach ($result as $row) {
50b6632b6eSAndreas Gohr            if ($row['ref_type'] == 'search') $data['search'] = $row['cnt'];
51b6632b6eSAndreas Gohr            if ($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
52b6632b6eSAndreas Gohr            if ($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
53b6632b6eSAndreas Gohr            if ($row['ref_type'] == '') $data['direct'] = $row['cnt'];
54b6632b6eSAndreas Gohr        }
55b6632b6eSAndreas Gohr
56b6632b6eSAndreas Gohr        // general user and session info
57b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
58b6632b6eSAndreas Gohr                       COUNT(session) as views,
59b6632b6eSAndreas Gohr                       COUNT(DISTINCT user) as users,
60b6632b6eSAndreas Gohr                       COUNT(DISTINCT uid) as visitors
61*7428e816SAndreas Gohr                  FROM access as A
62*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
63*7428e816SAndreas Gohr                   AND ua_type = ?";
64*7428e816SAndreas Gohr        $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser']);
65b6632b6eSAndreas Gohr
66b6632b6eSAndreas Gohr        $data['users'] = max($result[0]['users'] - 1, 0); // subtract empty user
67b6632b6eSAndreas Gohr        $data['sessions'] = $result[0]['sessions'];
68b6632b6eSAndreas Gohr        $data['pageviews'] = $result[0]['views'];
69b6632b6eSAndreas Gohr        $data['visitors'] = $result[0]['visitors'];
70b6632b6eSAndreas Gohr
71b6632b6eSAndreas Gohr        // calculate bounce rate
72b6632b6eSAndreas Gohr        if ($data['sessions']) {
73b6632b6eSAndreas Gohr            $sql = "SELECT COUNT(*) as cnt
74*7428e816SAndreas Gohr                      FROM session as A
75*7428e816SAndreas Gohr                     WHERE A.dt >= ? AND A.dt <= ?
76*7428e816SAndreas Gohr                       AND views = ?";
77*7428e816SAndreas Gohr            $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 1]);
78b6632b6eSAndreas Gohr            $data['bouncerate'] = $result[0]['cnt'] * 100 / $data['sessions'];
79b6632b6eSAndreas Gohr            $data['newvisitors'] = $result[0]['cnt'] * 100 / $data['sessions'];
80b6632b6eSAndreas Gohr        }
81b6632b6eSAndreas Gohr
82b6632b6eSAndreas Gohr        // calculate avg. number of views per session
83b6632b6eSAndreas Gohr        $sql = "SELECT AVG(views) as cnt
84*7428e816SAndreas Gohr                  FROM session as A
85*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?";
86*7428e816SAndreas Gohr        $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to]);
87b6632b6eSAndreas Gohr        $data['avgpages'] = $result[0]['cnt'];
88b6632b6eSAndreas Gohr
89b6632b6eSAndreas Gohr        /* not used currently
90b6632b6eSAndreas Gohr                $sql = "SELECT COUNT(id) as robots
91b6632b6eSAndreas Gohr                          FROM ".$this->hlp->prefix."access as A
92b6632b6eSAndreas Gohr                         WHERE $tlimit
93b6632b6eSAndreas Gohr                           AND ua_type = 'robot'";
94b6632b6eSAndreas Gohr                $result = $this->hlp->runSQL($sql);
95b6632b6eSAndreas Gohr                $data['robots'] = $result[0]['robots'];
96b6632b6eSAndreas Gohr        */
97b6632b6eSAndreas Gohr
98b6632b6eSAndreas Gohr        // average time spent on the site
99b6632b6eSAndreas Gohr        $sql = "SELECT AVG(end - dt)/60 as time
100*7428e816SAndreas Gohr                  FROM session as A
101*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
102b6632b6eSAndreas Gohr                   AND dt != end
103b6632b6eSAndreas Gohr                   AND DATE(dt) = DATE(end)";
104*7428e816SAndreas Gohr        $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to]);
105b6632b6eSAndreas Gohr        $data['timespent'] = $result[0]['time'];
106b6632b6eSAndreas Gohr
107b6632b6eSAndreas Gohr        // logins
108b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as logins
109*7428e816SAndreas Gohr                  FROM logins as A
110*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
111*7428e816SAndreas Gohr                   AND (type = ? OR type = ?)";
112*7428e816SAndreas Gohr        $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'l', 'p']);
113b6632b6eSAndreas Gohr        $data['logins'] = $result[0]['logins'];
114b6632b6eSAndreas Gohr
115b6632b6eSAndreas Gohr        // registrations
116b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as registrations
117*7428e816SAndreas Gohr                  FROM logins as A
118*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
119*7428e816SAndreas Gohr                   AND type = ?";
120*7428e816SAndreas Gohr        $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'C']);
121b6632b6eSAndreas Gohr        $data['registrations'] = $result[0]['registrations'];
122b6632b6eSAndreas Gohr
123b6632b6eSAndreas Gohr        // current users
124b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as current
125*7428e816SAndreas Gohr                  FROM lastseen
126*7428e816SAndreas Gohr                 WHERE dt >= datetime('now', '-10 minutes')";
127*7428e816SAndreas Gohr        $result = $this->hlp->getDB()->queryAll($sql);
128b6632b6eSAndreas Gohr        $data['current'] = $result[0]['current'];
129b6632b6eSAndreas Gohr
130b6632b6eSAndreas Gohr        return $data;
131b6632b6eSAndreas Gohr    }
132b6632b6eSAndreas Gohr
133b6632b6eSAndreas Gohr    /**
134b6632b6eSAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
135b6632b6eSAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
136b6632b6eSAndreas Gohr     */
137b6632b6eSAndreas Gohr
138b6632b6eSAndreas Gohr    /**
139b6632b6eSAndreas Gohr     * Return some trend data about visits and edits in the wiki
140b6632b6eSAndreas Gohr     */
141*7428e816SAndreas Gohr    public function dashboardviews($hours = false)
142b6632b6eSAndreas Gohr    {
143b6632b6eSAndreas Gohr        if ($hours) {
144*7428e816SAndreas Gohr            $TIME = 'strftime(\'%H\', dt)';
145b6632b6eSAndreas Gohr        } else {
146b6632b6eSAndreas Gohr            $TIME = 'DATE(dt)';
147b6632b6eSAndreas Gohr        }
148b6632b6eSAndreas Gohr
149b6632b6eSAndreas Gohr        $data = [];
150b6632b6eSAndreas Gohr
151b6632b6eSAndreas Gohr        // access trends
152b6632b6eSAndreas Gohr        $sql = "SELECT $TIME as time,
153b6632b6eSAndreas Gohr                       COUNT(DISTINCT session) as sessions,
154b6632b6eSAndreas Gohr                       COUNT(session) as pageviews,
155b6632b6eSAndreas Gohr                       COUNT(DISTINCT uid) as visitors
156*7428e816SAndreas Gohr                  FROM access as A
157*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
158*7428e816SAndreas Gohr                   AND ua_type = ?
159b6632b6eSAndreas Gohr              GROUP BY $TIME
160b6632b6eSAndreas Gohr              ORDER BY time";
161*7428e816SAndreas Gohr        $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser']);
162b6632b6eSAndreas Gohr        foreach ($result as $row) {
163b6632b6eSAndreas Gohr            $data[$row['time']]['sessions'] = $row['sessions'];
164b6632b6eSAndreas Gohr            $data[$row['time']]['pageviews'] = $row['pageviews'];
165b6632b6eSAndreas Gohr            $data[$row['time']]['visitors'] = $row['visitors'];
166b6632b6eSAndreas Gohr        }
167b6632b6eSAndreas Gohr        return $data;
168b6632b6eSAndreas Gohr    }
169b6632b6eSAndreas Gohr
170*7428e816SAndreas Gohr    public function dashboardwiki($hours = false)
171b6632b6eSAndreas Gohr    {
172b6632b6eSAndreas Gohr        if ($hours) {
173*7428e816SAndreas Gohr            $TIME = 'strftime(\'%H\', dt)';
174b6632b6eSAndreas Gohr        } else {
175b6632b6eSAndreas Gohr            $TIME = 'DATE(dt)';
176b6632b6eSAndreas Gohr        }
177b6632b6eSAndreas Gohr
178b6632b6eSAndreas Gohr        $data = [];
179b6632b6eSAndreas Gohr
180b6632b6eSAndreas Gohr        // edit trends
181b6632b6eSAndreas Gohr        foreach (['E', 'C', 'D'] as $type) {
182b6632b6eSAndreas Gohr            $sql = "SELECT $TIME as time,
183b6632b6eSAndreas Gohr                           COUNT(*) as cnt
184*7428e816SAndreas Gohr                      FROM edits as A
185*7428e816SAndreas Gohr                     WHERE A.dt >= ? AND A.dt <= ?
186*7428e816SAndreas Gohr                       AND type = ?
187b6632b6eSAndreas Gohr                  GROUP BY $TIME
188b6632b6eSAndreas Gohr                  ORDER BY time";
189*7428e816SAndreas Gohr            $result = $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, $type]);
190b6632b6eSAndreas Gohr            foreach ($result as $row) {
191b6632b6eSAndreas Gohr                $data[$row['time']][$type] = $row['cnt'];
192b6632b6eSAndreas Gohr            }
193b6632b6eSAndreas Gohr        }
194b6632b6eSAndreas Gohr        ksort($data);
195b6632b6eSAndreas Gohr        return $data;
196b6632b6eSAndreas Gohr    }
197b6632b6eSAndreas Gohr
198*7428e816SAndreas Gohr    public function history($info, $interval = false)
199b6632b6eSAndreas Gohr    {
200b6632b6eSAndreas Gohr        if ($interval == 'weeks') {
201*7428e816SAndreas Gohr            $TIME = 'strftime(\'%Y\', dt), strftime(\'%W\', dt)';
202b6632b6eSAndreas Gohr        } elseif ($interval == 'months') {
203*7428e816SAndreas Gohr            $TIME = 'strftime(\'%Y-%m\', dt)';
204b6632b6eSAndreas Gohr        } else {
205b6632b6eSAndreas Gohr            $TIME = 'dt';
206b6632b6eSAndreas Gohr        }
207b6632b6eSAndreas Gohr
208b6632b6eSAndreas Gohr        $mod = 1;
209b6632b6eSAndreas Gohr        if ($info == 'media_size' || $info == 'page_size') {
210b6632b6eSAndreas Gohr            $mod = 1024 * 1024;
211b6632b6eSAndreas Gohr        }
212b6632b6eSAndreas Gohr
213b6632b6eSAndreas Gohr        $sql = "SELECT $TIME as time,
214*7428e816SAndreas Gohr                       AVG(value)/$mod as cnt
215*7428e816SAndreas Gohr                  FROM history as A
216*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
217*7428e816SAndreas Gohr                   AND info = ?
218b6632b6eSAndreas Gohr                  GROUP BY $TIME
219b6632b6eSAndreas Gohr                  ORDER BY $TIME";
220*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, $info]);
221b6632b6eSAndreas Gohr    }
222b6632b6eSAndreas Gohr
223*7428e816SAndreas Gohr    public function searchengines($start = 0, $limit = 20)
224b6632b6eSAndreas Gohr    {
225b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, engine as eflag, engine
226*7428e816SAndreas Gohr                  FROM search as A
227*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
228b6632b6eSAndreas Gohr              GROUP BY engine
229b6632b6eSAndreas Gohr              ORDER BY cnt DESC, engine" .
230b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
231*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to]);
232b6632b6eSAndreas Gohr    }
233b6632b6eSAndreas Gohr
234*7428e816SAndreas Gohr    public function searchphrases($extern, $start = 0, $limit = 20)
235b6632b6eSAndreas Gohr    {
236b6632b6eSAndreas Gohr        if ($extern) {
237*7428e816SAndreas Gohr            $WHERE = "engine != ?";
238*7428e816SAndreas Gohr            $engineParam = 'dokuwiki';
239b6632b6eSAndreas Gohr            $I = '';
240b6632b6eSAndreas Gohr        } else {
241*7428e816SAndreas Gohr            $WHERE = "engine = ?";
242*7428e816SAndreas Gohr            $engineParam = 'dokuwiki';
243b6632b6eSAndreas Gohr            $I = 'i';
244b6632b6eSAndreas Gohr        }
245b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, query, query as ${I}lookup
246*7428e816SAndreas Gohr                  FROM search as A
247*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
248b6632b6eSAndreas Gohr                   AND $WHERE
249b6632b6eSAndreas Gohr              GROUP BY query
250b6632b6eSAndreas Gohr              ORDER BY cnt DESC, query" .
251b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
252*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, $engineParam]);
253b6632b6eSAndreas Gohr    }
254b6632b6eSAndreas Gohr
255*7428e816SAndreas Gohr    public function searchwords($extern, $start = 0, $limit = 20)
256b6632b6eSAndreas Gohr    {
257b6632b6eSAndreas Gohr        if ($extern) {
258*7428e816SAndreas Gohr            $WHERE = "engine != ?";
259*7428e816SAndreas Gohr            $engineParam = 'dokuwiki';
260b6632b6eSAndreas Gohr            $I = '';
261b6632b6eSAndreas Gohr        } else {
262*7428e816SAndreas Gohr            $WHERE = "engine = ?";
263*7428e816SAndreas Gohr            $engineParam = 'dokuwiki';
264b6632b6eSAndreas Gohr            $I = 'i';
265b6632b6eSAndreas Gohr        }
266b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, word, word as ${I}lookup
267*7428e816SAndreas Gohr                  FROM search as A,
268*7428e816SAndreas Gohr                       searchwords as B
269*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
270b6632b6eSAndreas Gohr                   AND A.id = B.sid
271b6632b6eSAndreas Gohr                   AND $WHERE
272b6632b6eSAndreas Gohr              GROUP BY word
273b6632b6eSAndreas Gohr              ORDER BY cnt DESC, word" .
274b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
275*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, $engineParam]);
276b6632b6eSAndreas Gohr    }
277b6632b6eSAndreas Gohr
278*7428e816SAndreas Gohr    public function outlinks($start = 0, $limit = 20)
279b6632b6eSAndreas Gohr    {
280b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, link as url
281*7428e816SAndreas Gohr                  FROM outlinks as A
282*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
283b6632b6eSAndreas Gohr              GROUP BY link
284b6632b6eSAndreas Gohr              ORDER BY cnt DESC, link" .
285b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
286*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to]);
287b6632b6eSAndreas Gohr    }
288b6632b6eSAndreas Gohr
289*7428e816SAndreas Gohr    public function pages($start = 0, $limit = 20)
290b6632b6eSAndreas Gohr    {
291b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
292*7428e816SAndreas Gohr                  FROM access as A
293*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
294*7428e816SAndreas Gohr                   AND ua_type = ?
295b6632b6eSAndreas Gohr              GROUP BY page
296b6632b6eSAndreas Gohr              ORDER BY cnt DESC, page" .
297b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
298*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser']);
299b6632b6eSAndreas Gohr    }
300b6632b6eSAndreas Gohr
301*7428e816SAndreas Gohr    public function edits($start = 0, $limit = 20)
302b6632b6eSAndreas Gohr    {
303b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
304*7428e816SAndreas Gohr                  FROM edits as A
305*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
306b6632b6eSAndreas Gohr              GROUP BY page
307b6632b6eSAndreas Gohr              ORDER BY cnt DESC, page" .
308b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
309*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to]);
310b6632b6eSAndreas Gohr    }
311b6632b6eSAndreas Gohr
312*7428e816SAndreas Gohr    public function images($start = 0, $limit = 20)
313b6632b6eSAndreas Gohr    {
314b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, media, SUM(size) as filesize
315*7428e816SAndreas Gohr                  FROM media as A
316*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
317*7428e816SAndreas Gohr                   AND mime1 = ?
318b6632b6eSAndreas Gohr              GROUP BY media
319b6632b6eSAndreas Gohr              ORDER BY cnt DESC, media" .
320b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
321*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'image']);
322b6632b6eSAndreas Gohr    }
323b6632b6eSAndreas Gohr
324*7428e816SAndreas Gohr    public function imagessum()
325b6632b6eSAndreas Gohr    {
326b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, SUM(size) as filesize
327*7428e816SAndreas Gohr                  FROM media as A
328*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
329*7428e816SAndreas Gohr                   AND mime1 = ?";
330*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'image']);
331b6632b6eSAndreas Gohr    }
332b6632b6eSAndreas Gohr
333*7428e816SAndreas Gohr    public function downloads($start = 0, $limit = 20)
334b6632b6eSAndreas Gohr    {
335b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, media, SUM(size) as filesize
336*7428e816SAndreas Gohr                  FROM media as A
337*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
338*7428e816SAndreas Gohr                   AND mime1 != ?
339b6632b6eSAndreas Gohr              GROUP BY media
340b6632b6eSAndreas Gohr              ORDER BY cnt DESC, media" .
341b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
342*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'image']);
343b6632b6eSAndreas Gohr    }
344b6632b6eSAndreas Gohr
345*7428e816SAndreas Gohr    public function downloadssum()
346b6632b6eSAndreas Gohr    {
347b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, SUM(size) as filesize
348*7428e816SAndreas Gohr                  FROM media as A
349*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
350*7428e816SAndreas Gohr                   AND mime1 != ?";
351*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'image']);
352b6632b6eSAndreas Gohr    }
353b6632b6eSAndreas Gohr
354*7428e816SAndreas Gohr    public function referer($start = 0, $limit = 20)
355b6632b6eSAndreas Gohr    {
356b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
357*7428e816SAndreas Gohr                  FROM access as A
358*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
359*7428e816SAndreas Gohr                   AND ua_type = ?
360*7428e816SAndreas Gohr                   AND ref_type = ?
361b6632b6eSAndreas Gohr              GROUP BY ref_md5
362b6632b6eSAndreas Gohr              ORDER BY cnt DESC, url" .
363b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
364*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser', 'external']);
365b6632b6eSAndreas Gohr    }
366b6632b6eSAndreas Gohr
367*7428e816SAndreas Gohr    public function newreferer($start = 0, $limit = 20)
368b6632b6eSAndreas Gohr    {
369b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
370*7428e816SAndreas Gohr                  FROM access as B,
371*7428e816SAndreas Gohr                       refseen as A
372*7428e816SAndreas Gohr                 WHERE B.dt >= ? AND B.dt <= ?
373*7428e816SAndreas Gohr                   AND ua_type = ?
374*7428e816SAndreas Gohr                   AND ref_type = ?
375b6632b6eSAndreas Gohr                   AND A.ref_md5 = B.ref_md5
376b6632b6eSAndreas Gohr              GROUP BY A.ref_md5
377b6632b6eSAndreas Gohr              ORDER BY cnt DESC, url" .
378b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
379*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser', 'external']);
380b6632b6eSAndreas Gohr    }
381b6632b6eSAndreas Gohr
382*7428e816SAndreas Gohr    public function countries($start = 0, $limit = 20)
383b6632b6eSAndreas Gohr    {
384b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
385*7428e816SAndreas Gohr                  FROM access as A,
386*7428e816SAndreas Gohr                       iplocation as B
387*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
388b6632b6eSAndreas Gohr                   AND A.ip = B.ip
389b6632b6eSAndreas Gohr              GROUP BY B.code
390b6632b6eSAndreas Gohr              ORDER BY cnt DESC, B.country" .
391b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
392*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to]);
393b6632b6eSAndreas Gohr    }
394b6632b6eSAndreas Gohr
395*7428e816SAndreas Gohr    public function browsers($start = 0, $limit = 20, $ext = true)
396b6632b6eSAndreas Gohr    {
397b6632b6eSAndreas Gohr        if ($ext) {
398b6632b6eSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
399b6632b6eSAndreas Gohr            $grp = 'ua_info, ua_ver';
400b6632b6eSAndreas Gohr        } else {
401b6632b6eSAndreas Gohr            $grp = 'ua_info';
402b6632b6eSAndreas Gohr            $sel = 'ua_info';
403b6632b6eSAndreas Gohr        }
404b6632b6eSAndreas Gohr
405b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
406*7428e816SAndreas Gohr                  FROM access as A
407*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
408*7428e816SAndreas Gohr                   AND ua_type = ?
409b6632b6eSAndreas Gohr              GROUP BY $grp
410b6632b6eSAndreas Gohr              ORDER BY cnt DESC, ua_info" .
411b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
412*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser']);
413b6632b6eSAndreas Gohr    }
414b6632b6eSAndreas Gohr
415*7428e816SAndreas Gohr    public function os($start = 0, $limit = 20)
416b6632b6eSAndreas Gohr    {
417b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
418*7428e816SAndreas Gohr                  FROM access as A
419*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
420*7428e816SAndreas Gohr                   AND ua_type = ?
421b6632b6eSAndreas Gohr              GROUP BY os
422b6632b6eSAndreas Gohr              ORDER BY cnt DESC, os" .
423b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
424*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser']);
425b6632b6eSAndreas Gohr    }
426b6632b6eSAndreas Gohr
427*7428e816SAndreas Gohr    public function topuser($start = 0, $limit = 20)
428b6632b6eSAndreas Gohr    {
429b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, user
430*7428e816SAndreas Gohr                  FROM access as A
431*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
432*7428e816SAndreas Gohr                   AND ua_type = ?
433*7428e816SAndreas Gohr                   AND user != ?
434b6632b6eSAndreas Gohr              GROUP BY user
435b6632b6eSAndreas Gohr              ORDER BY cnt DESC, user" .
436b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
437*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser', '']);
438b6632b6eSAndreas Gohr    }
439b6632b6eSAndreas Gohr
440*7428e816SAndreas Gohr    public function topeditor($start = 0, $limit = 20)
441b6632b6eSAndreas Gohr    {
442b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, user
443*7428e816SAndreas Gohr                  FROM edits as A
444*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
445*7428e816SAndreas Gohr                   AND user != ?
446b6632b6eSAndreas Gohr              GROUP BY user
447b6632b6eSAndreas Gohr              ORDER BY cnt DESC, user" .
448b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
449*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, '']);
450b6632b6eSAndreas Gohr    }
451b6632b6eSAndreas Gohr
452*7428e816SAndreas Gohr    public function topgroup($start = 0, $limit = 20)
453b6632b6eSAndreas Gohr    {
454b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, `group`
455*7428e816SAndreas Gohr                  FROM groups as A
456*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
457*7428e816SAndreas Gohr                   AND `type` = ?
458b6632b6eSAndreas Gohr              GROUP BY `group`
459b6632b6eSAndreas Gohr              ORDER BY cnt DESC, `group`" .
460b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
461*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'view']);
462b6632b6eSAndreas Gohr    }
463b6632b6eSAndreas Gohr
464*7428e816SAndreas Gohr    public function topgroupedit($start = 0, $limit = 20)
465b6632b6eSAndreas Gohr    {
466b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, `group`
467*7428e816SAndreas Gohr                  FROM groups as A
468*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
469*7428e816SAndreas Gohr                   AND `type` = ?
470b6632b6eSAndreas Gohr              GROUP BY `group`
471b6632b6eSAndreas Gohr              ORDER BY cnt DESC, `group`" .
472b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
473*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'edit']);
474b6632b6eSAndreas Gohr    }
475b6632b6eSAndreas Gohr
476b6632b6eSAndreas Gohr
477*7428e816SAndreas Gohr    public function resolution($start = 0, $limit = 20)
478b6632b6eSAndreas Gohr    {
479b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(DISTINCT uid) as cnt,
480b6632b6eSAndreas Gohr                       ROUND(screen_x/100)*100 as res_x,
481b6632b6eSAndreas Gohr                       ROUND(screen_y/100)*100 as res_y,
482*7428e816SAndreas Gohr                       (ROUND(screen_x/100)*100 || 'x' || ROUND(screen_y/100)*100) as resolution
483*7428e816SAndreas Gohr                  FROM access as A
484*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
485*7428e816SAndreas Gohr                   AND ua_type  = ?
486*7428e816SAndreas Gohr                   AND screen_x != ?
487*7428e816SAndreas Gohr                   AND screen_y != ?
488b6632b6eSAndreas Gohr              GROUP BY resolution
489b6632b6eSAndreas Gohr              ORDER BY cnt DESC" .
490b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
491*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser', 0, 0]);
492b6632b6eSAndreas Gohr    }
493b6632b6eSAndreas Gohr
494*7428e816SAndreas Gohr    public function viewport($start = 0, $limit = 20)
495b6632b6eSAndreas Gohr    {
496b6632b6eSAndreas Gohr        $sql = "SELECT COUNT(DISTINCT uid) as cnt,
497b6632b6eSAndreas Gohr                       ROUND(view_x/100)*100 as res_x,
498b6632b6eSAndreas Gohr                       ROUND(view_y/100)*100 as res_y,
499*7428e816SAndreas Gohr                       (ROUND(view_x/100)*100 || 'x' || ROUND(view_y/100)*100) as resolution
500*7428e816SAndreas Gohr                  FROM access as A
501*7428e816SAndreas Gohr                 WHERE A.dt >= ? AND A.dt <= ?
502*7428e816SAndreas Gohr                   AND ua_type  = ?
503*7428e816SAndreas Gohr                   AND view_x != ?
504*7428e816SAndreas Gohr                   AND view_y != ?
505b6632b6eSAndreas Gohr              GROUP BY resolution
506b6632b6eSAndreas Gohr              ORDER BY cnt DESC" .
507b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
508b6632b6eSAndreas Gohr
509*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql, [$this->from, $this->to, 'browser', 0, 0]);
510b6632b6eSAndreas Gohr    }
511b6632b6eSAndreas Gohr
512*7428e816SAndreas Gohr    public function seenusers($start = 0, $limit = 20)
513b6632b6eSAndreas Gohr    {
514b6632b6eSAndreas Gohr        $sql = "SELECT `user`, `dt`
515b6632b6eSAndreas Gohr                  FROM " . $this->hlp->prefix . "lastseen as A
516b6632b6eSAndreas Gohr              ORDER BY `dt` DESC" .
517b6632b6eSAndreas Gohr            $this->mklimit($start, $limit);
518b6632b6eSAndreas Gohr
519*7428e816SAndreas Gohr        return $this->hlp->getDB()->queryAll($sql);
520b6632b6eSAndreas Gohr    }
521b6632b6eSAndreas Gohr
522b6632b6eSAndreas Gohr
523b6632b6eSAndreas Gohr    /**
524b6632b6eSAndreas Gohr     * Builds a limit clause
525b6632b6eSAndreas Gohr     */
526b6632b6eSAndreas Gohr    public function mklimit($start, $limit)
527b6632b6eSAndreas Gohr    {
528b6632b6eSAndreas Gohr        $start = (int)$start;
529b6632b6eSAndreas Gohr        $limit = (int)$limit;
530b6632b6eSAndreas Gohr        if ($limit) {
531b6632b6eSAndreas Gohr            $limit += 1;
532b6632b6eSAndreas Gohr            return " LIMIT $start,$limit";
533b6632b6eSAndreas Gohr        } elseif ($start) {
534b6632b6eSAndreas Gohr            return " OFFSET $start";
535b6632b6eSAndreas Gohr        }
536b6632b6eSAndreas Gohr        return '';
537b6632b6eSAndreas Gohr    }
538b6632b6eSAndreas Gohr
539b6632b6eSAndreas Gohr}
540