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