1b6632b6eSAndreas Gohr<?php 2b6632b6eSAndreas Gohr 3b6632b6eSAndreas Gohrnamespace dokuwiki\plugin\statistics; 4b6632b6eSAndreas Gohr 5*f9e60319SAndreas Gohr 6*f9e60319SAndreas Gohruse dokuwiki\plugin\sqlite\SQLiteDB; 7b6632b6eSAndreas Gohruse helper_plugin_statistics; 8b6632b6eSAndreas Gohr 9*f9e60319SAndreas Gohr/** 10*f9e60319SAndreas Gohr * This class defines a bunch of SQL queries to fetch various statistics from the database 11*f9e60319SAndreas Gohr */ 12b6632b6eSAndreas Gohrclass Query 13b6632b6eSAndreas Gohr{ 14*f9e60319SAndreas Gohr protected helper_plugin_statistics $hlp; 15*f9e60319SAndreas Gohr protected SQLiteDB $db; 16*f9e60319SAndreas Gohr protected string $from; 17*f9e60319SAndreas Gohr protected string $to; 18*f9e60319SAndreas Gohr protected string $limit = ''; 19b6632b6eSAndreas Gohr 20*f9e60319SAndreas Gohr /** 21*f9e60319SAndreas Gohr * @param helper_plugin_statistics $hlp 22*f9e60319SAndreas Gohr */ 23b6632b6eSAndreas Gohr public function __construct(helper_plugin_statistics $hlp) 24b6632b6eSAndreas Gohr { 25b6632b6eSAndreas Gohr $this->hlp = $hlp; 26*f9e60319SAndreas Gohr $this->db = $hlp->getDB(); 277428e816SAndreas Gohr $today = date('Y-m-d'); 287428e816SAndreas Gohr $this->setTimeFrame($today, $today); 29*f9e60319SAndreas Gohr $this->setPagination(0, 20); 307428e816SAndreas Gohr } 317428e816SAndreas Gohr 327428e816SAndreas Gohr /** 337428e816SAndreas Gohr * Set the time frame for all queries 34*f9e60319SAndreas Gohr * 35*f9e60319SAndreas Gohr * @param string $from The start date as YYYY-MM-DD 36*f9e60319SAndreas Gohr * @param string $to The end date as YYYY-MM-DD 377428e816SAndreas Gohr */ 38*f9e60319SAndreas Gohr public function setTimeFrame(string $from, string $to): void 397428e816SAndreas Gohr { 40*f9e60319SAndreas Gohr try { 41*f9e60319SAndreas Gohr $from = new \DateTime($from); 42*f9e60319SAndreas Gohr $to = new \DateTime($to); 43*f9e60319SAndreas Gohr } catch (\Exception $e) { 44*f9e60319SAndreas Gohr $from = new \DateTime(); 45*f9e60319SAndreas Gohr $to = new \DateTime(); 46*f9e60319SAndreas Gohr } 47*f9e60319SAndreas Gohr $from->setTime(0, 0); 48*f9e60319SAndreas Gohr $to->setTime(23, 59, 59); 497428e816SAndreas Gohr 50*f9e60319SAndreas Gohr $this->from = $from->format('Y-m-d H:i:s'); 51*f9e60319SAndreas Gohr $this->to = $to->format('Y-m-d H:i:s'); 52*f9e60319SAndreas Gohr } 53*f9e60319SAndreas Gohr 54*f9e60319SAndreas Gohr /** 55*f9e60319SAndreas Gohr * Set the pagination settings for some queries 56*f9e60319SAndreas Gohr * 57*f9e60319SAndreas Gohr * @param int $start The start offset 58*f9e60319SAndreas Gohr * @param int $limit The number of results. If one more is returned, there is another page 59*f9e60319SAndreas Gohr * @return void 60*f9e60319SAndreas Gohr */ 61*f9e60319SAndreas Gohr public function setPagination(int $start, int $limit) 62*f9e60319SAndreas Gohr { 63*f9e60319SAndreas Gohr // when a limit is set, one more is fetched to indicate when a next page exists 64*f9e60319SAndreas Gohr if ($limit) $limit += 1; 65*f9e60319SAndreas Gohr 66*f9e60319SAndreas Gohr if ($limit) { 67*f9e60319SAndreas Gohr $this->limit = " LIMIT $start,$limit"; 68*f9e60319SAndreas Gohr } elseif ($start) { 69*f9e60319SAndreas Gohr $this->limit = " OFFSET $start"; 70*f9e60319SAndreas Gohr } 71b6632b6eSAndreas Gohr } 72b6632b6eSAndreas Gohr 73b6632b6eSAndreas Gohr /** 74b6632b6eSAndreas Gohr * Return some aggregated statistics 75b6632b6eSAndreas Gohr */ 76*f9e60319SAndreas 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"; 85*f9e60319SAndreas Gohr $result = $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 86b6632b6eSAndreas Gohr 87*f9e60319SAndreas 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 = ?"; 102*f9e60319SAndreas Gohr $result = $this->db->queryRecord($sql, [$this->from, $this->to, 'browser']); 103b6632b6eSAndreas Gohr 104*f9e60319SAndreas Gohr $data['users'] = max($result['users'] - 1, 0); // subtract empty user 105*f9e60319SAndreas Gohr $data['sessions'] = $result['sessions']; 106*f9e60319SAndreas Gohr $data['pageviews'] = $result['views']; 107*f9e60319SAndreas 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 = ?"; 115*f9e60319SAndreas Gohr $count = $this->db->queryValue($sql, [$this->from, $this->to, 1]); 116*f9e60319SAndreas Gohr $data['bouncerate'] = $count * 100 / $data['sessions']; 117*f9e60319SAndreas 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 <= ?"; 124*f9e60319SAndreas 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)"; 132*f9e60319SAndreas 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 = ?)"; 139*f9e60319SAndreas 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 = ?"; 146*f9e60319SAndreas 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')"; 152*f9e60319SAndreas 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 160*f9e60319SAndreas Gohr * 161*f9e60319SAndreas Gohr * @param bool $hours Use hour resolution rather than days 162*f9e60319SAndreas Gohr * @return array 163b6632b6eSAndreas Gohr */ 164*f9e60319SAndreas 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"; 184*f9e60319SAndreas 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 193*f9e60319SAndreas Gohr /** 194*f9e60319SAndreas Gohr * @param bool $hours Use hour resolution rather than days 195*f9e60319SAndreas Gohr * @return array 196*f9e60319SAndreas Gohr */ 197*f9e60319SAndreas 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"; 216*f9e60319SAndreas 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 225*f9e60319SAndreas Gohr /** 226*f9e60319SAndreas Gohr * @param string $info Which type of history to select (FIXME which ones are there?) 227*f9e60319SAndreas Gohr * @param string $interval Group data by this interval (days, weeks, months) 228*f9e60319SAndreas Gohr * @return array 229*f9e60319SAndreas Gohr */ 230*f9e60319SAndreas 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 { 237b6632b6eSAndreas Gohr $TIME = '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"; 252*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, $info]); 253b6632b6eSAndreas Gohr } 254b6632b6eSAndreas Gohr 255*f9e60319SAndreas Gohr /** 256*f9e60319SAndreas Gohr * @return array 257*f9e60319SAndreas Gohr */ 258*f9e60319SAndreas 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" . 265*f9e60319SAndreas Gohr $this->limit; 266*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to]); 267b6632b6eSAndreas Gohr } 268b6632b6eSAndreas Gohr 269*f9e60319SAndreas Gohr /** 270*f9e60319SAndreas Gohr * @param bool $extern Limit results to external search engine (true) or dokuwiki (false) 271*f9e60319SAndreas Gohr * @return array 272*f9e60319SAndreas Gohr */ 273*f9e60319SAndreas 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" . 290*f9e60319SAndreas Gohr $this->limit; 291*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, $engineParam]); 292b6632b6eSAndreas Gohr } 293b6632b6eSAndreas Gohr 294*f9e60319SAndreas Gohr /** 295*f9e60319SAndreas Gohr * @param bool $extern Limit results to external search engine (true) or dokuwiki (false) 296*f9e60319SAndreas Gohr * @return array 297*f9e60319SAndreas Gohr */ 298*f9e60319SAndreas 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" . 317*f9e60319SAndreas Gohr $this->limit; 318*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, $engineParam]); 319b6632b6eSAndreas Gohr } 320b6632b6eSAndreas Gohr 321*f9e60319SAndreas Gohr /** 322*f9e60319SAndreas Gohr * @return array 323*f9e60319SAndreas Gohr */ 324*f9e60319SAndreas 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" . 331*f9e60319SAndreas Gohr $this->limit; 332*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to]); 333b6632b6eSAndreas Gohr } 334b6632b6eSAndreas Gohr 335*f9e60319SAndreas Gohr /** 336*f9e60319SAndreas Gohr * @return array 337*f9e60319SAndreas Gohr */ 338*f9e60319SAndreas 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" . 346*f9e60319SAndreas Gohr $this->limit; 347*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 348b6632b6eSAndreas Gohr } 349b6632b6eSAndreas Gohr 350*f9e60319SAndreas Gohr /** 351*f9e60319SAndreas Gohr * @return array 352*f9e60319SAndreas Gohr */ 353*f9e60319SAndreas 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" . 360*f9e60319SAndreas Gohr $this->limit; 361*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to]); 362b6632b6eSAndreas Gohr } 363b6632b6eSAndreas Gohr 364*f9e60319SAndreas Gohr /** 365*f9e60319SAndreas Gohr * @return array 366*f9e60319SAndreas Gohr */ 367*f9e60319SAndreas 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" . 375*f9e60319SAndreas Gohr $this->limit; 376*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'image']); 377b6632b6eSAndreas Gohr } 378b6632b6eSAndreas Gohr 379*f9e60319SAndreas Gohr /** 380*f9e60319SAndreas Gohr * @return array 381*f9e60319SAndreas Gohr */ 382*f9e60319SAndreas 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 = ?"; 388*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'image']); 389b6632b6eSAndreas Gohr } 390b6632b6eSAndreas Gohr 391*f9e60319SAndreas Gohr /** 392*f9e60319SAndreas Gohr * @return array 393*f9e60319SAndreas Gohr */ 394*f9e60319SAndreas 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" . 402*f9e60319SAndreas Gohr $this->limit; 403*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'image']); 404b6632b6eSAndreas Gohr } 405b6632b6eSAndreas Gohr 406*f9e60319SAndreas Gohr /** 407*f9e60319SAndreas Gohr * @return array 408*f9e60319SAndreas Gohr */ 409*f9e60319SAndreas 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 != ?"; 415*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'image']); 416b6632b6eSAndreas Gohr } 417b6632b6eSAndreas Gohr 418*f9e60319SAndreas Gohr /** 419*f9e60319SAndreas Gohr * @return array 420*f9e60319SAndreas Gohr */ 421*f9e60319SAndreas 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" . 430*f9e60319SAndreas Gohr $this->limit; 431*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', 'external']); 432b6632b6eSAndreas Gohr } 433b6632b6eSAndreas Gohr 434*f9e60319SAndreas Gohr /** 435*f9e60319SAndreas Gohr * @return array 436*f9e60319SAndreas Gohr */ 437*f9e60319SAndreas 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" . 448*f9e60319SAndreas Gohr $this->limit; 449*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', 'external']); 450b6632b6eSAndreas Gohr } 451b6632b6eSAndreas Gohr 452*f9e60319SAndreas Gohr /** 453*f9e60319SAndreas Gohr * @return array 454*f9e60319SAndreas Gohr */ 455*f9e60319SAndreas 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" . 464*f9e60319SAndreas Gohr $this->limit; 465*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to]); 466b6632b6eSAndreas Gohr } 467b6632b6eSAndreas Gohr 468*f9e60319SAndreas Gohr /** 469*f9e60319SAndreas Gohr * @param bool $ext return extended information 470*f9e60319SAndreas Gohr * @return array 471*f9e60319SAndreas Gohr */ 472*f9e60319SAndreas 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" . 488*f9e60319SAndreas Gohr $this->limit; 489*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 490b6632b6eSAndreas Gohr } 491b6632b6eSAndreas Gohr 492*f9e60319SAndreas Gohr /** 493*f9e60319SAndreas Gohr * @return array 494*f9e60319SAndreas Gohr */ 495*f9e60319SAndreas 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" . 503*f9e60319SAndreas Gohr $this->limit; 504*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser']); 505b6632b6eSAndreas Gohr } 506b6632b6eSAndreas Gohr 507*f9e60319SAndreas Gohr /** 508*f9e60319SAndreas Gohr * @return array 509*f9e60319SAndreas Gohr */ 510*f9e60319SAndreas 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" . 519*f9e60319SAndreas Gohr $this->limit; 520*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', '']); 521b6632b6eSAndreas Gohr } 522b6632b6eSAndreas Gohr 523*f9e60319SAndreas Gohr /** 524*f9e60319SAndreas Gohr * @return array 525*f9e60319SAndreas Gohr */ 526*f9e60319SAndreas 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" . 534*f9e60319SAndreas Gohr $this->limit; 535*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, '']); 536b6632b6eSAndreas Gohr } 537b6632b6eSAndreas Gohr 538*f9e60319SAndreas Gohr /** 539*f9e60319SAndreas Gohr * @return array 540*f9e60319SAndreas Gohr */ 541*f9e60319SAndreas 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`" . 549*f9e60319SAndreas Gohr $this->limit; 550*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'view']); 551b6632b6eSAndreas Gohr } 552b6632b6eSAndreas Gohr 553*f9e60319SAndreas Gohr /** 554*f9e60319SAndreas Gohr * @return array 555*f9e60319SAndreas Gohr */ 556*f9e60319SAndreas 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`" . 564*f9e60319SAndreas Gohr $this->limit; 565*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'edit']); 566b6632b6eSAndreas Gohr } 567b6632b6eSAndreas Gohr 568b6632b6eSAndreas Gohr 569*f9e60319SAndreas Gohr /** 570*f9e60319SAndreas Gohr * @return array 571*f9e60319SAndreas Gohr */ 572*f9e60319SAndreas 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" . 585*f9e60319SAndreas Gohr $this->limit; 586*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', 0, 0]); 587b6632b6eSAndreas Gohr } 588b6632b6eSAndreas Gohr 589*f9e60319SAndreas Gohr /** 590*f9e60319SAndreas Gohr * @return array 591*f9e60319SAndreas Gohr */ 592*f9e60319SAndreas 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" . 605*f9e60319SAndreas Gohr $this->limit; 606b6632b6eSAndreas Gohr 607*f9e60319SAndreas Gohr return $this->db->queryAll($sql, [$this->from, $this->to, 'browser', 0, 0]); 608b6632b6eSAndreas Gohr } 609b6632b6eSAndreas Gohr 610*f9e60319SAndreas Gohr /** 611*f9e60319SAndreas Gohr * @return array 612*f9e60319SAndreas Gohr */ 613*f9e60319SAndreas 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" . 618*f9e60319SAndreas Gohr $this->limit; 619b6632b6eSAndreas Gohr 620*f9e60319SAndreas Gohr return $this->db->queryAll($sql); 621b6632b6eSAndreas Gohr } 622b6632b6eSAndreas Gohr 623b6632b6eSAndreas Gohr} 624