1b6632b6eSAndreas Gohr<?php 2b6632b6eSAndreas Gohr 3b6632b6eSAndreas Gohrnamespace dokuwiki\plugin\statistics; 4b6632b6eSAndreas Gohr 5f9e60319SAndreas Gohruse dokuwiki\plugin\sqlite\SQLiteDB; 6b6632b6eSAndreas Gohruse helper_plugin_statistics; 7b6632b6eSAndreas Gohr 8f9e60319SAndreas Gohr/** 9f9e60319SAndreas Gohr * This class defines a bunch of SQL queries to fetch various statistics from the database 10f9e60319SAndreas Gohr */ 11b6632b6eSAndreas Gohrclass Query 12b6632b6eSAndreas Gohr{ 13f9e60319SAndreas Gohr protected helper_plugin_statistics $hlp; 14f9e60319SAndreas Gohr protected SQLiteDB $db; 15f9e60319SAndreas Gohr protected string $from; 16f9e60319SAndreas Gohr protected string $to; 17f9e60319SAndreas Gohr protected string $limit = ''; 18b6632b6eSAndreas Gohr 19f9e60319SAndreas Gohr /** 20f9e60319SAndreas Gohr * @param helper_plugin_statistics $hlp 21f9e60319SAndreas Gohr */ 22b6632b6eSAndreas Gohr public function __construct(helper_plugin_statistics $hlp) 23b6632b6eSAndreas Gohr { 24b6632b6eSAndreas Gohr $this->hlp = $hlp; 25f9e60319SAndreas Gohr $this->db = $hlp->getDB(); 267428e816SAndreas Gohr $today = date('Y-m-d'); 277428e816SAndreas Gohr $this->setTimeFrame($today, $today); 28f9e60319SAndreas Gohr $this->setPagination(0, 20); 297428e816SAndreas Gohr } 307428e816SAndreas Gohr 317428e816SAndreas Gohr /** 327428e816SAndreas Gohr * Set the time frame for all queries 33f9e60319SAndreas Gohr * 34f9e60319SAndreas Gohr * @param string $from The start date as YYYY-MM-DD 35f9e60319SAndreas Gohr * @param string $to The end date as YYYY-MM-DD 367428e816SAndreas Gohr */ 37f9e60319SAndreas Gohr public function setTimeFrame(string $from, string $to): void 387428e816SAndreas Gohr { 39f9e60319SAndreas Gohr try { 40f9e60319SAndreas Gohr $from = new \DateTime($from); 41f9e60319SAndreas Gohr $to = new \DateTime($to); 42f9e60319SAndreas Gohr } catch (\Exception $e) { 43f9e60319SAndreas Gohr $from = new \DateTime(); 44f9e60319SAndreas Gohr $to = new \DateTime(); 45f9e60319SAndreas Gohr } 46f9e60319SAndreas Gohr $from->setTime(0, 0); 47f9e60319SAndreas Gohr $to->setTime(23, 59, 59); 487428e816SAndreas Gohr 49f9e60319SAndreas Gohr $this->from = $from->format('Y-m-d H:i:s'); 50f9e60319SAndreas Gohr $this->to = $to->format('Y-m-d H:i:s'); 51f9e60319SAndreas Gohr } 52f9e60319SAndreas Gohr 53f9e60319SAndreas Gohr /** 54f9e60319SAndreas Gohr * Set the pagination settings for some queries 55f9e60319SAndreas Gohr * 56f9e60319SAndreas Gohr * @param int $start The start offset 57f9e60319SAndreas Gohr * @param int $limit The number of results. If one more is returned, there is another page 58f9e60319SAndreas Gohr * @return void 59f9e60319SAndreas Gohr */ 60f9e60319SAndreas Gohr public function setPagination(int $start, int $limit) 61f9e60319SAndreas Gohr { 62f9e60319SAndreas Gohr // when a limit is set, one more is fetched to indicate when a next page exists 63f9e60319SAndreas Gohr if ($limit) $limit += 1; 64f9e60319SAndreas Gohr 65f9e60319SAndreas Gohr if ($limit) { 66f9e60319SAndreas Gohr $this->limit = " LIMIT $start,$limit"; 67f9e60319SAndreas Gohr } elseif ($start) { 68f9e60319SAndreas Gohr $this->limit = " OFFSET $start"; 69f9e60319SAndreas Gohr } 70b6632b6eSAndreas Gohr } 71b6632b6eSAndreas Gohr 72b6632b6eSAndreas Gohr /** 73b6632b6eSAndreas Gohr * Return some aggregated statistics 74b6632b6eSAndreas Gohr */ 75f9e60319SAndreas Gohr public function aggregate(): array 76b6632b6eSAndreas Gohr { 77b6632b6eSAndreas Gohr $data = []; 78b6632b6eSAndreas Gohr 79b6632b6eSAndreas Gohr $sql = "SELECT ref_type, COUNT(*) as cnt 807428e816SAndreas Gohr FROM access as A 817428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 827428e816SAndreas Gohr AND ua_type = ? 83b6632b6eSAndreas Gohr GROUP BY ref_type"; 84f9e60319SAndreas Gohr $result = $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 85b6632b6eSAndreas Gohr 86f9e60319SAndreas Gohr foreach ($result as $row) { 87b6632b6eSAndreas Gohr if ($row['ref_type'] == 'search') $data['search'] = $row['cnt']; 88b6632b6eSAndreas Gohr if ($row['ref_type'] == 'external') $data['external'] = $row['cnt']; 89b6632b6eSAndreas Gohr if ($row['ref_type'] == 'internal') $data['internal'] = $row['cnt']; 90b6632b6eSAndreas Gohr if ($row['ref_type'] == '') $data['direct'] = $row['cnt']; 91b6632b6eSAndreas Gohr } 92b6632b6eSAndreas Gohr 93b6632b6eSAndreas Gohr // general user and session info 94b6632b6eSAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as sessions, 95b6632b6eSAndreas Gohr COUNT(session) as views, 96b6632b6eSAndreas Gohr COUNT(DISTINCT user) as users, 97b6632b6eSAndreas Gohr COUNT(DISTINCT uid) as visitors 987428e816SAndreas Gohr FROM access as A 997428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 1007428e816SAndreas Gohr AND ua_type = ?"; 101f9e60319SAndreas Gohr $result = $this->db->queryRecord($sql, [$this->from, $this->to, 'browser']); 102b6632b6eSAndreas Gohr 103f9e60319SAndreas Gohr $data['users'] = max($result['users'] - 1, 0); // subtract empty user 104f9e60319SAndreas Gohr $data['sessions'] = $result['sessions']; 105f9e60319SAndreas Gohr $data['pageviews'] = $result['views']; 106f9e60319SAndreas Gohr $data['visitors'] = $result['visitors']; 107b6632b6eSAndreas Gohr 108b6632b6eSAndreas Gohr // calculate bounce rate 109b6632b6eSAndreas Gohr if ($data['sessions']) { 110b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt 1117428e816SAndreas Gohr FROM session as A 1127428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 1137428e816SAndreas Gohr AND views = ?"; 114f9e60319SAndreas Gohr $count = $this->db->queryValue($sql, [$this->from, $this->to, 1]); 115f9e60319SAndreas Gohr $data['bouncerate'] = $count * 100 / $data['sessions']; 116f9e60319SAndreas Gohr $data['newvisitors'] = $count * 100 / $data['sessions']; 117b6632b6eSAndreas Gohr } 118b6632b6eSAndreas Gohr 119b6632b6eSAndreas Gohr // calculate avg. number of views per session 120b6632b6eSAndreas Gohr $sql = "SELECT AVG(views) as cnt 1217428e816SAndreas Gohr FROM session as A 1227428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ?"; 123f9e60319SAndreas Gohr $data['avgpages'] = $this->db->queryValue($sql, [$this->from, $this->to]); 124b6632b6eSAndreas Gohr 125b6632b6eSAndreas Gohr // average time spent on the site 126b6632b6eSAndreas Gohr $sql = "SELECT AVG(end - dt)/60 as time 1277428e816SAndreas Gohr FROM session as A 1287428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 129b6632b6eSAndreas Gohr AND dt != end 130b6632b6eSAndreas Gohr AND DATE(dt) = DATE(end)"; 131f9e60319SAndreas Gohr $data['timespent'] = $this->db->queryValue($sql, [$this->from, $this->to]); 132b6632b6eSAndreas Gohr 133b6632b6eSAndreas Gohr // logins 134b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as logins 1357428e816SAndreas Gohr FROM logins as A 1367428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 1377428e816SAndreas Gohr AND (type = ? OR type = ?)"; 138f9e60319SAndreas Gohr $data['logins'] = $this->db->queryValue($sql, [$this->from, $this->to, 'l', 'p']); 139b6632b6eSAndreas Gohr 140b6632b6eSAndreas Gohr // registrations 141b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as registrations 1427428e816SAndreas Gohr FROM logins as A 1437428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 1447428e816SAndreas Gohr AND type = ?"; 145f9e60319SAndreas Gohr $data['registrations'] = $this->db->queryValue($sql, [$this->from, $this->to, 'C']); 146b6632b6eSAndreas Gohr 147b6632b6eSAndreas Gohr // current users 148b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as current 1497428e816SAndreas Gohr FROM lastseen 1507428e816SAndreas Gohr WHERE dt >= datetime('now', '-10 minutes')"; 151f9e60319SAndreas Gohr $data['current'] = $this->db->queryValue($sql); 152b6632b6eSAndreas Gohr 153b6632b6eSAndreas Gohr return $data; 154b6632b6eSAndreas Gohr } 155b6632b6eSAndreas Gohr 156b6632b6eSAndreas Gohr 157b6632b6eSAndreas Gohr /** 158b6632b6eSAndreas Gohr * Return some trend data about visits and edits in the wiki 159f9e60319SAndreas Gohr * 160f9e60319SAndreas Gohr * @param bool $hours Use hour resolution rather than days 161f9e60319SAndreas Gohr * @return array 162b6632b6eSAndreas Gohr */ 163f9e60319SAndreas Gohr public function dashboardviews(bool $hours = false): array 164b6632b6eSAndreas Gohr { 165b6632b6eSAndreas Gohr if ($hours) { 1667428e816SAndreas Gohr $TIME = 'strftime(\'%H\', dt)'; 167b6632b6eSAndreas Gohr } else { 168b6632b6eSAndreas Gohr $TIME = 'DATE(dt)'; 169b6632b6eSAndreas Gohr } 170b6632b6eSAndreas Gohr 171b6632b6eSAndreas Gohr $data = []; 172b6632b6eSAndreas Gohr 173b6632b6eSAndreas Gohr // access trends 174b6632b6eSAndreas Gohr $sql = "SELECT $TIME as time, 175b6632b6eSAndreas Gohr COUNT(DISTINCT session) as sessions, 176b6632b6eSAndreas Gohr COUNT(session) as pageviews, 177b6632b6eSAndreas Gohr COUNT(DISTINCT uid) as visitors 1787428e816SAndreas Gohr FROM access as A 1797428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 1807428e816SAndreas Gohr AND ua_type = ? 181b6632b6eSAndreas Gohr GROUP BY $TIME 182b6632b6eSAndreas Gohr ORDER BY time"; 183f9e60319SAndreas Gohr $result = $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 184b6632b6eSAndreas Gohr foreach ($result as $row) { 185b6632b6eSAndreas Gohr $data[$row['time']]['sessions'] = $row['sessions']; 186b6632b6eSAndreas Gohr $data[$row['time']]['pageviews'] = $row['pageviews']; 187b6632b6eSAndreas Gohr $data[$row['time']]['visitors'] = $row['visitors']; 188b6632b6eSAndreas Gohr } 189b6632b6eSAndreas Gohr return $data; 190b6632b6eSAndreas Gohr } 191b6632b6eSAndreas Gohr 192f9e60319SAndreas Gohr /** 193f9e60319SAndreas Gohr * @param bool $hours Use hour resolution rather than days 194f9e60319SAndreas Gohr * @return array 195f9e60319SAndreas Gohr */ 196f9e60319SAndreas Gohr public function dashboardwiki(bool $hours = false): array 197b6632b6eSAndreas Gohr { 198b6632b6eSAndreas Gohr if ($hours) { 1997428e816SAndreas Gohr $TIME = 'strftime(\'%H\', dt)'; 200b6632b6eSAndreas Gohr } else { 201b6632b6eSAndreas Gohr $TIME = 'DATE(dt)'; 202b6632b6eSAndreas Gohr } 203b6632b6eSAndreas Gohr 204b6632b6eSAndreas Gohr $data = []; 205b6632b6eSAndreas Gohr 206b6632b6eSAndreas Gohr // edit trends 207b6632b6eSAndreas Gohr foreach (['E', 'C', 'D'] as $type) { 208b6632b6eSAndreas Gohr $sql = "SELECT $TIME as time, 209b6632b6eSAndreas Gohr COUNT(*) as cnt 2107428e816SAndreas Gohr FROM edits as A 2117428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 2127428e816SAndreas Gohr AND type = ? 213b6632b6eSAndreas Gohr GROUP BY $TIME 214b6632b6eSAndreas Gohr ORDER BY time"; 215f9e60319SAndreas Gohr $result = $this->db->queryAll($sql, [$this->from, $this->to, $type]); 216b6632b6eSAndreas Gohr foreach ($result as $row) { 217b6632b6eSAndreas Gohr $data[$row['time']][$type] = $row['cnt']; 218b6632b6eSAndreas Gohr } 219b6632b6eSAndreas Gohr } 220b6632b6eSAndreas Gohr ksort($data); 221b6632b6eSAndreas Gohr return $data; 222b6632b6eSAndreas Gohr } 223b6632b6eSAndreas Gohr 224f9e60319SAndreas Gohr /** 225f9e60319SAndreas Gohr * @param string $info Which type of history to select (FIXME which ones are there?) 226f9e60319SAndreas Gohr * @param string $interval Group data by this interval (days, weeks, months) 227f9e60319SAndreas Gohr * @return array 228f9e60319SAndreas Gohr */ 229f9e60319SAndreas Gohr public function history(string $info, string $interval = 'day'): array 230b6632b6eSAndreas Gohr { 231b6632b6eSAndreas Gohr if ($interval == 'weeks') { 2327428e816SAndreas Gohr $TIME = 'strftime(\'%Y\', dt), strftime(\'%W\', dt)'; 233b6632b6eSAndreas Gohr } elseif ($interval == 'months') { 2347428e816SAndreas Gohr $TIME = 'strftime(\'%Y-%m\', dt)'; 235b6632b6eSAndreas Gohr } else { 236a087824eSAnna Dabrowska $TIME = 'strftime(\'%d-%m\', dt)'; 237b6632b6eSAndreas Gohr } 238b6632b6eSAndreas Gohr 239b6632b6eSAndreas Gohr $mod = 1; 240b6632b6eSAndreas Gohr if ($info == 'media_size' || $info == 'page_size') { 241b6632b6eSAndreas Gohr $mod = 1024 * 1024; 242b6632b6eSAndreas Gohr } 243b6632b6eSAndreas Gohr 244b6632b6eSAndreas Gohr $sql = "SELECT $TIME as time, 2457428e816SAndreas Gohr AVG(value)/$mod as cnt 2467428e816SAndreas Gohr FROM history as A 2477428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 2487428e816SAndreas Gohr AND info = ? 249b6632b6eSAndreas Gohr GROUP BY $TIME 250b6632b6eSAndreas Gohr ORDER BY $TIME"; 251f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, $info]); 252b6632b6eSAndreas Gohr } 253b6632b6eSAndreas Gohr 254f9e60319SAndreas Gohr /** 255f9e60319SAndreas Gohr * @return array 256f9e60319SAndreas Gohr */ 257f9e60319SAndreas Gohr public function searchengines(): array 258b6632b6eSAndreas Gohr { 259b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, engine as eflag, engine 2607428e816SAndreas Gohr FROM search as A 2617428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 262b6632b6eSAndreas Gohr GROUP BY engine 263b6632b6eSAndreas Gohr ORDER BY cnt DESC, engine" . 264f9e60319SAndreas Gohr $this->limit; 265f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to]); 266b6632b6eSAndreas Gohr } 267b6632b6eSAndreas Gohr 268f9e60319SAndreas Gohr /** 269f9e60319SAndreas Gohr * @param bool $extern Limit results to external search engine (true) or dokuwiki (false) 270f9e60319SAndreas Gohr * @return array 271f9e60319SAndreas Gohr */ 272*211caa5dSAndreas Gohr public function searchphrases(bool $extern = false): array 273b6632b6eSAndreas Gohr { 274b6632b6eSAndreas Gohr if ($extern) { 2757428e816SAndreas Gohr $WHERE = "engine != ?"; 2767428e816SAndreas Gohr $engineParam = 'dokuwiki'; 277b6632b6eSAndreas Gohr $I = ''; 278b6632b6eSAndreas Gohr } else { 2797428e816SAndreas Gohr $WHERE = "engine = ?"; 2807428e816SAndreas Gohr $engineParam = 'dokuwiki'; 281b6632b6eSAndreas Gohr $I = 'i'; 282b6632b6eSAndreas Gohr } 283b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, query, query as ${I}lookup 2847428e816SAndreas Gohr FROM search as A 2857428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 286b6632b6eSAndreas Gohr AND $WHERE 287b6632b6eSAndreas Gohr GROUP BY query 288b6632b6eSAndreas Gohr ORDER BY cnt DESC, query" . 289f9e60319SAndreas Gohr $this->limit; 290f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, $engineParam]); 291b6632b6eSAndreas Gohr } 292b6632b6eSAndreas Gohr 293f9e60319SAndreas Gohr /** 294f9e60319SAndreas Gohr * @param bool $extern Limit results to external search engine (true) or dokuwiki (false) 295f9e60319SAndreas Gohr * @return array 296f9e60319SAndreas Gohr */ 297*211caa5dSAndreas Gohr public function searchwords(bool $extern = false): array 298b6632b6eSAndreas Gohr { 299b6632b6eSAndreas Gohr if ($extern) { 3007428e816SAndreas Gohr $WHERE = "engine != ?"; 3017428e816SAndreas Gohr $engineParam = 'dokuwiki'; 302b6632b6eSAndreas Gohr $I = ''; 303b6632b6eSAndreas Gohr } else { 3047428e816SAndreas Gohr $WHERE = "engine = ?"; 3057428e816SAndreas Gohr $engineParam = 'dokuwiki'; 306b6632b6eSAndreas Gohr $I = 'i'; 307b6632b6eSAndreas Gohr } 308b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, word, word as ${I}lookup 3097428e816SAndreas Gohr FROM search as A, 3107428e816SAndreas Gohr searchwords as B 3117428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 312b6632b6eSAndreas Gohr AND A.id = B.sid 313b6632b6eSAndreas Gohr AND $WHERE 314b6632b6eSAndreas Gohr GROUP BY word 315b6632b6eSAndreas Gohr ORDER BY cnt DESC, word" . 316f9e60319SAndreas Gohr $this->limit; 317f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, $engineParam]); 318b6632b6eSAndreas Gohr } 319b6632b6eSAndreas Gohr 320f9e60319SAndreas Gohr /** 321f9e60319SAndreas Gohr * @return array 322f9e60319SAndreas Gohr */ 323f9e60319SAndreas Gohr public function outlinks(): array 324b6632b6eSAndreas Gohr { 325b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, link as url 3267428e816SAndreas Gohr FROM outlinks as A 3277428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 328b6632b6eSAndreas Gohr GROUP BY link 329b6632b6eSAndreas Gohr ORDER BY cnt DESC, link" . 330f9e60319SAndreas Gohr $this->limit; 331f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to]); 332b6632b6eSAndreas Gohr } 333b6632b6eSAndreas Gohr 334f9e60319SAndreas Gohr /** 335f9e60319SAndreas Gohr * @return array 336f9e60319SAndreas Gohr */ 337f9e60319SAndreas Gohr public function pages(): array 338b6632b6eSAndreas Gohr { 339b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, page 3407428e816SAndreas Gohr FROM access as A 3417428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 3427428e816SAndreas Gohr AND ua_type = ? 343b6632b6eSAndreas Gohr GROUP BY page 344b6632b6eSAndreas Gohr ORDER BY cnt DESC, page" . 345f9e60319SAndreas Gohr $this->limit; 346f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 347b6632b6eSAndreas Gohr } 348b6632b6eSAndreas Gohr 349f9e60319SAndreas Gohr /** 350f9e60319SAndreas Gohr * @return array 351f9e60319SAndreas Gohr */ 352f9e60319SAndreas Gohr public function edits(): array 353b6632b6eSAndreas Gohr { 354b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, page 3557428e816SAndreas Gohr FROM edits as A 3567428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 357b6632b6eSAndreas Gohr GROUP BY page 358b6632b6eSAndreas Gohr ORDER BY cnt DESC, page" . 359f9e60319SAndreas Gohr $this->limit; 360f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to]); 361b6632b6eSAndreas Gohr } 362b6632b6eSAndreas Gohr 363f9e60319SAndreas Gohr /** 364f9e60319SAndreas Gohr * @return array 365f9e60319SAndreas Gohr */ 366f9e60319SAndreas Gohr public function images(): array 367b6632b6eSAndreas Gohr { 368b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, media, SUM(size) as filesize 3697428e816SAndreas Gohr FROM media as A 3707428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 3717428e816SAndreas Gohr AND mime1 = ? 372b6632b6eSAndreas Gohr GROUP BY media 373b6632b6eSAndreas Gohr ORDER BY cnt DESC, media" . 374f9e60319SAndreas Gohr $this->limit; 375f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'image']); 376b6632b6eSAndreas Gohr } 377b6632b6eSAndreas Gohr 378f9e60319SAndreas Gohr /** 379f9e60319SAndreas Gohr * @return array 380f9e60319SAndreas Gohr */ 381f9e60319SAndreas Gohr public function imagessum(): array 382b6632b6eSAndreas Gohr { 383b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, SUM(size) as filesize 3847428e816SAndreas Gohr FROM media as A 3857428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 3867428e816SAndreas Gohr AND mime1 = ?"; 387f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'image']); 388b6632b6eSAndreas Gohr } 389b6632b6eSAndreas Gohr 390f9e60319SAndreas Gohr /** 391f9e60319SAndreas Gohr * @return array 392f9e60319SAndreas Gohr */ 393f9e60319SAndreas Gohr public function downloads(): array 394b6632b6eSAndreas Gohr { 395b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, media, SUM(size) as filesize 3967428e816SAndreas Gohr FROM media as A 3977428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 3987428e816SAndreas Gohr AND mime1 != ? 399b6632b6eSAndreas Gohr GROUP BY media 400b6632b6eSAndreas Gohr ORDER BY cnt DESC, media" . 401f9e60319SAndreas Gohr $this->limit; 402f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'image']); 403b6632b6eSAndreas Gohr } 404b6632b6eSAndreas Gohr 405f9e60319SAndreas Gohr /** 406f9e60319SAndreas Gohr * @return array 407f9e60319SAndreas Gohr */ 408f9e60319SAndreas Gohr public function downloadssum(): array 409b6632b6eSAndreas Gohr { 410b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, SUM(size) as filesize 4117428e816SAndreas Gohr FROM media as A 4127428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 4137428e816SAndreas Gohr AND mime1 != ?"; 414f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'image']); 415b6632b6eSAndreas Gohr } 416b6632b6eSAndreas Gohr 417f9e60319SAndreas Gohr /** 418f9e60319SAndreas Gohr * @return array 419f9e60319SAndreas Gohr */ 420f9e60319SAndreas Gohr public function referer(): array 421b6632b6eSAndreas Gohr { 422b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 4237428e816SAndreas Gohr FROM access as A 4247428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 4257428e816SAndreas Gohr AND ua_type = ? 4267428e816SAndreas Gohr AND ref_type = ? 427b6632b6eSAndreas Gohr GROUP BY ref_md5 428b6632b6eSAndreas Gohr ORDER BY cnt DESC, url" . 429f9e60319SAndreas Gohr $this->limit; 430f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', 'external']); 431b6632b6eSAndreas Gohr } 432b6632b6eSAndreas Gohr 433f9e60319SAndreas Gohr /** 434f9e60319SAndreas Gohr * @return array 435f9e60319SAndreas Gohr */ 436f9e60319SAndreas Gohr public function newreferer(): array 437b6632b6eSAndreas Gohr { 438b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 4397428e816SAndreas Gohr FROM access as B, 4407428e816SAndreas Gohr refseen as A 4417428e816SAndreas Gohr WHERE B.dt >= ? AND B.dt <= ? 4427428e816SAndreas Gohr AND ua_type = ? 4437428e816SAndreas Gohr AND ref_type = ? 444b6632b6eSAndreas Gohr AND A.ref_md5 = B.ref_md5 445b6632b6eSAndreas Gohr GROUP BY A.ref_md5 446b6632b6eSAndreas Gohr ORDER BY cnt DESC, url" . 447f9e60319SAndreas Gohr $this->limit; 448f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', 'external']); 449b6632b6eSAndreas Gohr } 450b6632b6eSAndreas Gohr 451f9e60319SAndreas Gohr /** 452f9e60319SAndreas Gohr * @return array 453f9e60319SAndreas Gohr */ 454f9e60319SAndreas Gohr public function countries(): array 455b6632b6eSAndreas Gohr { 456b6632b6eSAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country 4577428e816SAndreas Gohr FROM access as A, 4587428e816SAndreas Gohr iplocation as B 4597428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 460b6632b6eSAndreas Gohr AND A.ip = B.ip 461b6632b6eSAndreas Gohr GROUP BY B.code 462b6632b6eSAndreas Gohr ORDER BY cnt DESC, B.country" . 463f9e60319SAndreas Gohr $this->limit; 464f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to]); 465b6632b6eSAndreas Gohr } 466b6632b6eSAndreas Gohr 467f9e60319SAndreas Gohr /** 468f9e60319SAndreas Gohr * @param bool $ext return extended information 469f9e60319SAndreas Gohr * @return array 470f9e60319SAndreas Gohr */ 471f9e60319SAndreas Gohr public function browsers(bool $ext = true): array 472b6632b6eSAndreas Gohr { 473b6632b6eSAndreas Gohr if ($ext) { 474b6632b6eSAndreas Gohr $sel = 'ua_info as bflag, ua_info as browser, ua_ver'; 475b6632b6eSAndreas Gohr $grp = 'ua_info, ua_ver'; 476b6632b6eSAndreas Gohr } else { 477b6632b6eSAndreas Gohr $grp = 'ua_info'; 478b6632b6eSAndreas Gohr $sel = 'ua_info'; 479b6632b6eSAndreas Gohr } 480b6632b6eSAndreas Gohr 481b6632b6eSAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel 4827428e816SAndreas Gohr FROM access as A 4837428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 4847428e816SAndreas Gohr AND ua_type = ? 485b6632b6eSAndreas Gohr GROUP BY $grp 486b6632b6eSAndreas Gohr ORDER BY cnt DESC, ua_info" . 487f9e60319SAndreas Gohr $this->limit; 488f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 489b6632b6eSAndreas Gohr } 490b6632b6eSAndreas Gohr 491f9e60319SAndreas Gohr /** 492f9e60319SAndreas Gohr * @return array 493f9e60319SAndreas Gohr */ 494f9e60319SAndreas Gohr public function os(): array 495b6632b6eSAndreas Gohr { 496b6632b6eSAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os 4977428e816SAndreas Gohr FROM access as A 4987428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 4997428e816SAndreas Gohr AND ua_type = ? 500b6632b6eSAndreas Gohr GROUP BY os 501b6632b6eSAndreas Gohr ORDER BY cnt DESC, os" . 502f9e60319SAndreas Gohr $this->limit; 503f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 504b6632b6eSAndreas Gohr } 505b6632b6eSAndreas Gohr 506f9e60319SAndreas Gohr /** 507f9e60319SAndreas Gohr * @return array 508f9e60319SAndreas Gohr */ 509f9e60319SAndreas Gohr public function topuser(): array 510b6632b6eSAndreas Gohr { 511b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, user 5127428e816SAndreas Gohr FROM access as A 5137428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 5147428e816SAndreas Gohr AND ua_type = ? 5157428e816SAndreas Gohr AND user != ? 516b6632b6eSAndreas Gohr GROUP BY user 517b6632b6eSAndreas Gohr ORDER BY cnt DESC, user" . 518f9e60319SAndreas Gohr $this->limit; 519f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', '']); 520b6632b6eSAndreas Gohr } 521b6632b6eSAndreas Gohr 522f9e60319SAndreas Gohr /** 523f9e60319SAndreas Gohr * @return array 524f9e60319SAndreas Gohr */ 525f9e60319SAndreas Gohr public function topeditor(): array 526b6632b6eSAndreas Gohr { 527b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, user 5287428e816SAndreas Gohr FROM edits as A 5297428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 5307428e816SAndreas Gohr AND user != ? 531b6632b6eSAndreas Gohr GROUP BY user 532b6632b6eSAndreas Gohr ORDER BY cnt DESC, user" . 533f9e60319SAndreas Gohr $this->limit; 534f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, '']); 535b6632b6eSAndreas Gohr } 536b6632b6eSAndreas Gohr 537f9e60319SAndreas Gohr /** 538f9e60319SAndreas Gohr * @return array 539f9e60319SAndreas Gohr */ 540f9e60319SAndreas Gohr public function topgroup(): array 541b6632b6eSAndreas Gohr { 542b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, `group` 5437428e816SAndreas Gohr FROM groups as A 5447428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 5457428e816SAndreas Gohr AND `type` = ? 546b6632b6eSAndreas Gohr GROUP BY `group` 547b6632b6eSAndreas Gohr ORDER BY cnt DESC, `group`" . 548f9e60319SAndreas Gohr $this->limit; 549f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'view']); 550b6632b6eSAndreas Gohr } 551b6632b6eSAndreas Gohr 552f9e60319SAndreas Gohr /** 553f9e60319SAndreas Gohr * @return array 554f9e60319SAndreas Gohr */ 555f9e60319SAndreas Gohr public function topgroupedit(): array 556b6632b6eSAndreas Gohr { 557b6632b6eSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, `group` 5587428e816SAndreas Gohr FROM groups as A 5597428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 5607428e816SAndreas Gohr AND `type` = ? 561b6632b6eSAndreas Gohr GROUP BY `group` 562b6632b6eSAndreas Gohr ORDER BY cnt DESC, `group`" . 563f9e60319SAndreas Gohr $this->limit; 564f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'edit']); 565b6632b6eSAndreas Gohr } 566b6632b6eSAndreas Gohr 567b6632b6eSAndreas Gohr 568f9e60319SAndreas Gohr /** 569f9e60319SAndreas Gohr * @return array 570f9e60319SAndreas Gohr */ 571f9e60319SAndreas Gohr public function resolution(): array 572b6632b6eSAndreas Gohr { 573b6632b6eSAndreas Gohr $sql = "SELECT COUNT(DISTINCT uid) as cnt, 574b6632b6eSAndreas Gohr ROUND(screen_x/100)*100 as res_x, 575b6632b6eSAndreas Gohr ROUND(screen_y/100)*100 as res_y, 5767428e816SAndreas Gohr (ROUND(screen_x/100)*100 || 'x' || ROUND(screen_y/100)*100) as resolution 5777428e816SAndreas Gohr FROM access as A 5787428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 5797428e816SAndreas Gohr AND ua_type = ? 5807428e816SAndreas Gohr AND screen_x != ? 5817428e816SAndreas Gohr AND screen_y != ? 582b6632b6eSAndreas Gohr GROUP BY resolution 583b6632b6eSAndreas Gohr ORDER BY cnt DESC" . 584f9e60319SAndreas Gohr $this->limit; 585f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', 0, 0]); 586b6632b6eSAndreas Gohr } 587b6632b6eSAndreas Gohr 588f9e60319SAndreas Gohr /** 589f9e60319SAndreas Gohr * @return array 590f9e60319SAndreas Gohr */ 591f9e60319SAndreas Gohr public function viewport(): array 592b6632b6eSAndreas Gohr { 593b6632b6eSAndreas Gohr $sql = "SELECT COUNT(DISTINCT uid) as cnt, 594b6632b6eSAndreas Gohr ROUND(view_x/100)*100 as res_x, 595b6632b6eSAndreas Gohr ROUND(view_y/100)*100 as res_y, 5967428e816SAndreas Gohr (ROUND(view_x/100)*100 || 'x' || ROUND(view_y/100)*100) as resolution 5977428e816SAndreas Gohr FROM access as A 5987428e816SAndreas Gohr WHERE A.dt >= ? AND A.dt <= ? 5997428e816SAndreas Gohr AND ua_type = ? 6007428e816SAndreas Gohr AND view_x != ? 6017428e816SAndreas Gohr AND view_y != ? 602b6632b6eSAndreas Gohr GROUP BY resolution 603b6632b6eSAndreas Gohr ORDER BY cnt DESC" . 604f9e60319SAndreas Gohr $this->limit; 605b6632b6eSAndreas Gohr 606f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', 0, 0]); 607b6632b6eSAndreas Gohr } 608b6632b6eSAndreas Gohr 609f9e60319SAndreas Gohr /** 610f9e60319SAndreas Gohr * @return array 611f9e60319SAndreas Gohr */ 612f9e60319SAndreas Gohr public function seenusers(): array 613b6632b6eSAndreas Gohr { 614b6632b6eSAndreas Gohr $sql = "SELECT `user`, `dt` 615*211caa5dSAndreas Gohr FROM lastseen as A 616b6632b6eSAndreas Gohr ORDER BY `dt` DESC" . 617f9e60319SAndreas Gohr $this->limit; 618b6632b6eSAndreas Gohr 619f9e60319SAndreas Gohr return $this->db->queryAll($sql); 620b6632b6eSAndreas Gohr } 621b6632b6eSAndreas Gohr} 622