11878f16fSAndreas Gohr<?php 2a8acb244SAndreas Gohr 3*211caa5dSAndreas Gohr// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps 4a8acb244SAndreas Gohruse dokuwiki\Extension\AdminPlugin; 5a8acb244SAndreas Gohr 61878f16fSAndreas Gohr/** 71878f16fSAndreas Gohr * statistics plugin 81878f16fSAndreas Gohr * 91878f16fSAndreas Gohr * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 106b6f8822SAndreas Gohr * @author Andreas Gohr <gohr@splitbrain.org> 111878f16fSAndreas Gohr */ 12a8acb244SAndreas Gohrclass admin_plugin_statistics extends AdminPlugin 13a8acb244SAndreas Gohr{ 1433a136e5SAndreas Gohr /** @var string the currently selected page */ 15a901d721SAndreas Gohr protected $opt = ''; 1633a136e5SAndreas Gohr 1733a136e5SAndreas Gohr /** @var string from date in YYYY-MM-DD */ 18a901d721SAndreas Gohr protected $from = ''; 1933a136e5SAndreas Gohr /** @var string to date in YYYY-MM-DD */ 20a901d721SAndreas Gohr protected $to = ''; 2133a136e5SAndreas Gohr /** @var int Offset to use when displaying paged data */ 2233a136e5SAndreas Gohr protected $start = 0; 2333a136e5SAndreas Gohr 2433a136e5SAndreas Gohr /** @var helper_plugin_statistics */ 2533a136e5SAndreas Gohr protected $hlp; 2633a136e5SAndreas Gohr 27a901d721SAndreas Gohr /** 28a901d721SAndreas Gohr * Available statistic pages 29a901d721SAndreas Gohr */ 30483101d3SAndreas Gohr protected $pages = [ 31483101d3SAndreas Gohr 'dashboard' => 1, 32483101d3SAndreas Gohr 'content' => ['page', 'edits', 'images', 'downloads', 'history'], 33483101d3SAndreas Gohr 'users' => ['topuser', 'topeditor', 'topgroup', 'topgroupedit', 'seenusers'], 34483101d3SAndreas Gohr 'links' => ['referer', 'newreferer', 'outlinks'], 35483101d3SAndreas Gohr 'search' => ['searchengines', 'searchphrases', 'searchwords', 'internalsearchphrases', 'internalsearchwords'], 36483101d3SAndreas Gohr 'technology' => ['browsers', 'os', 'countries', 'resolution', 'viewport'] 37483101d3SAndreas Gohr ]; 381878f16fSAndreas Gohr 3981ff4c3aSAndreas Gohr /** @var array keeps a list of all real content pages, generated from above array */ 40a8acb244SAndreas Gohr protected $allowedpages = []; 4181ff4c3aSAndreas Gohr 421878f16fSAndreas Gohr /** 436b6f8822SAndreas Gohr * Initialize the helper 446b6f8822SAndreas Gohr */ 45a8acb244SAndreas Gohr public function __construct() 46a8acb244SAndreas Gohr { 476b6f8822SAndreas Gohr $this->hlp = plugin_load('helper', 'statistics'); 4881ff4c3aSAndreas Gohr 4981ff4c3aSAndreas Gohr // build a list of pages 5081ff4c3aSAndreas Gohr foreach ($this->pages as $key => $val) { 5181ff4c3aSAndreas Gohr if (is_array($val)) { 5281ff4c3aSAndreas Gohr $this->allowedpages = array_merge($this->allowedpages, $val); 5381ff4c3aSAndreas Gohr } else { 5481ff4c3aSAndreas Gohr $this->allowedpages[] = $key; 5581ff4c3aSAndreas Gohr } 5681ff4c3aSAndreas Gohr } 576b6f8822SAndreas Gohr } 586b6f8822SAndreas Gohr 596b6f8822SAndreas Gohr /** 601878f16fSAndreas Gohr * Access for managers allowed 611878f16fSAndreas Gohr */ 62a8acb244SAndreas Gohr public function forAdminOnly() 63a8acb244SAndreas Gohr { 641878f16fSAndreas Gohr return false; 651878f16fSAndreas Gohr } 661878f16fSAndreas Gohr 671878f16fSAndreas Gohr /** 681878f16fSAndreas Gohr * return sort order for position in admin menu 691878f16fSAndreas Gohr */ 70a8acb244SAndreas Gohr public function getMenuSort() 71a8acb244SAndreas Gohr { 726b6f8822SAndreas Gohr return 350; 731878f16fSAndreas Gohr } 741878f16fSAndreas Gohr 751878f16fSAndreas Gohr /** 761878f16fSAndreas Gohr * handle user request 771878f16fSAndreas Gohr */ 78a8acb244SAndreas Gohr public function handle() 79a8acb244SAndreas Gohr { 80483101d3SAndreas Gohr global $INPUT; 81483101d3SAndreas Gohr $this->opt = preg_replace('/[^a-z]+/', '', $INPUT->str('opt')); 8281ff4c3aSAndreas Gohr if (!in_array($this->opt, $this->allowedpages)) $this->opt = 'dashboard'; 83a901d721SAndreas Gohr 84483101d3SAndreas Gohr $this->start = $INPUT->int('s'); 85483101d3SAndreas Gohr $this->setTimeframe($INPUT->str('f', date('Y-m-d')), $INPUT->str('t', date('Y-m-d'))); 86e8699bceSAndreas Gohr } 8795eb68e6SAndreas Gohr 88e8699bceSAndreas Gohr /** 89e8699bceSAndreas Gohr * set limit clause 90e8699bceSAndreas Gohr */ 91a8acb244SAndreas Gohr public function setTimeframe($from, $to) 92a8acb244SAndreas Gohr { 93047fcb0fSAndreas Gohr // swap if wrong order 94a8acb244SAndreas Gohr if ($from > $to) [$from, $to] = [$to, $from]; 95047fcb0fSAndreas Gohr 96*211caa5dSAndreas Gohr $this->hlp->getQuery()->setTimeFrame($from, $to); 97e8699bceSAndreas Gohr $this->from = $from; 98e8699bceSAndreas Gohr $this->to = $to; 991878f16fSAndreas Gohr } 1001878f16fSAndreas Gohr 1011878f16fSAndreas Gohr /** 10279b4a855SAndreas Gohr * Output the Statistics 1031878f16fSAndreas Gohr */ 104a8acb244SAndreas Gohr public function html() 105a8acb244SAndreas Gohr { 106b0cf2118SAnna Dabrowska echo '<script src="' . DOKU_BASE . 'lib/plugins/statistics/lib/chart.js"></script>'; 107b0cf2118SAnna Dabrowska echo '<script src="' . DOKU_BASE . 'lib/plugins/statistics/lib/chartjs-plugin-datalabels.js"></script>'; 108b0cf2118SAnna Dabrowska 1091d2d78ccSAndreas Gohr echo '<div id="plugin__statistics">'; 1100c3b1e44SAndreas Gohr echo '<h1>' . $this->getLang('menu') . '</h1>'; 111264f1744SAndreas Gohr $this->html_timeselect(); 112441bfb8eSAndreas Gohr tpl_flush(); 113264f1744SAndreas Gohr 11479b4a855SAndreas Gohr $method = 'html_' . $this->opt; 11579b4a855SAndreas Gohr if (method_exists($this, $method)) { 116a901d721SAndreas Gohr echo '<div class="plg_stats_' . $this->opt . '">'; 117a901d721SAndreas Gohr echo '<h2>' . $this->getLang($this->opt) . '</h2>'; 11879b4a855SAndreas Gohr $this->$method(); 119a901d721SAndreas Gohr echo '</div>'; 12014d99ec0SAndreas Gohr } 1211d2d78ccSAndreas Gohr echo '</div>'; 12214d99ec0SAndreas Gohr } 12314d99ec0SAndreas Gohr 1246b6f8822SAndreas Gohr /** 1256b6f8822SAndreas Gohr * Return the TOC 1266b6f8822SAndreas Gohr * 1276b6f8822SAndreas Gohr * @return array 1286b6f8822SAndreas Gohr */ 129a8acb244SAndreas Gohr public function getTOC() 130a8acb244SAndreas Gohr { 131a8acb244SAndreas Gohr $toc = []; 13281ff4c3aSAndreas Gohr foreach ($this->pages as $key => $info) { 13381ff4c3aSAndreas Gohr if (is_array($info)) { 13481ff4c3aSAndreas Gohr $toc[] = html_mktocitem( 13581ff4c3aSAndreas Gohr '', 13681ff4c3aSAndreas Gohr $this->getLang($key), 13781ff4c3aSAndreas Gohr 1, 13881ff4c3aSAndreas Gohr '' 13947ffcf7dSAndreas Gohr ); 14081ff4c3aSAndreas Gohr 14181ff4c3aSAndreas Gohr foreach ($info as $page) { 14281ff4c3aSAndreas Gohr $toc[] = html_mktocitem( 143*211caa5dSAndreas Gohr '?do=admin&page=statistics&opt=' . $page . 144*211caa5dSAndreas Gohr '&f=' . $this->from . 145*211caa5dSAndreas Gohr '&t=' . $this->to, 14681ff4c3aSAndreas Gohr $this->getLang($page), 14781ff4c3aSAndreas Gohr 2, 14881ff4c3aSAndreas Gohr '' 14981ff4c3aSAndreas Gohr ); 15081ff4c3aSAndreas Gohr } 15181ff4c3aSAndreas Gohr } else { 15281ff4c3aSAndreas Gohr $toc[] = html_mktocitem( 153*211caa5dSAndreas Gohr '?do=admin&page=statistics&opt=' . $key . 154*211caa5dSAndreas Gohr '&f=' . $this->from . 155*211caa5dSAndreas Gohr '&t=' . $this->to, 15681ff4c3aSAndreas Gohr $this->getLang($key), 15781ff4c3aSAndreas Gohr 1, 15881ff4c3aSAndreas Gohr '' 15981ff4c3aSAndreas Gohr ); 16081ff4c3aSAndreas Gohr } 16147ffcf7dSAndreas Gohr } 16247ffcf7dSAndreas Gohr return $toc; 1639da6395dSAndreas Gohr } 1649da6395dSAndreas Gohr 165a8acb244SAndreas Gohr public function html_graph($name, $width, $height) 166a8acb244SAndreas Gohr { 167*211caa5dSAndreas Gohr $this->hlp->getGraph($this->from, $this->to, $width, $height)->$name(); 168dc7b1e5eSAndreas Gohr } 169dc7b1e5eSAndreas Gohr 1706b6f8822SAndreas Gohr /** 1716b6f8822SAndreas Gohr * Outputs pagination links 1726b6f8822SAndreas Gohr * 17333a136e5SAndreas Gohr * @param int $limit 17433a136e5SAndreas Gohr * @param int $next 1756b6f8822SAndreas Gohr */ 176a8acb244SAndreas Gohr public function html_pager($limit, $next) 177a8acb244SAndreas Gohr { 178*211caa5dSAndreas Gohr $params = [ 179*211caa5dSAndreas Gohr 'do' => 'admin', 180*211caa5dSAndreas Gohr 'page' => 'statistics', 181*211caa5dSAndreas Gohr 'opt' => $this->opt, 182*211caa5dSAndreas Gohr 'f' => $this->from, 183*211caa5dSAndreas Gohr 't' => $this->to, 184*211caa5dSAndreas Gohr ]; 1852507f8e0SAndreas Gohr 186*211caa5dSAndreas Gohr echo '<div class="plg_stats_pager">'; 1872507f8e0SAndreas Gohr if ($this->start > 0) { 1882507f8e0SAndreas Gohr $go = max($this->start - $limit, 0); 189*211caa5dSAndreas Gohr $params['s'] = $go; 190*211caa5dSAndreas Gohr echo '<a href="?' . buildURLparams($params) . '" class="prev button">' . $this->getLang('prev') . '</a>'; 1912507f8e0SAndreas Gohr } 1922507f8e0SAndreas Gohr 1932507f8e0SAndreas Gohr if ($next) { 1942507f8e0SAndreas Gohr $go = $this->start + $limit; 195*211caa5dSAndreas Gohr $params['s'] = $go; 196*211caa5dSAndreas Gohr echo '<a href="?' . buildURLparams($params) . '" class="next button">' . $this->getLang('next') . '</a>'; 1972507f8e0SAndreas Gohr } 1982507f8e0SAndreas Gohr echo '</div>'; 1992507f8e0SAndreas Gohr } 2002507f8e0SAndreas Gohr 201264f1744SAndreas Gohr /** 202264f1744SAndreas Gohr * Print the time selection menu 203264f1744SAndreas Gohr */ 204a8acb244SAndreas Gohr public function html_timeselect() 205a8acb244SAndreas Gohr { 206483101d3SAndreas Gohr $quick = [ 207483101d3SAndreas Gohr 'today' => date('Y-m-d'), 208483101d3SAndreas Gohr 'last1' => date('Y-m-d', time() - (60 * 60 * 24)), 209483101d3SAndreas Gohr 'last7' => date('Y-m-d', time() - (60 * 60 * 24 * 7)), 210483101d3SAndreas Gohr 'last30' => date('Y-m-d', time() - (60 * 60 * 24 * 30)), 211483101d3SAndreas Gohr ]; 212483101d3SAndreas Gohr 21314d99ec0SAndreas Gohr 214264f1744SAndreas Gohr echo '<div class="plg_stats_timeselect">'; 2156985b606SAndreas Gohr echo '<span>' . $this->getLang('time_select') . '</span> '; 216264f1744SAndreas Gohr 217047fcb0fSAndreas Gohr echo '<form action="' . DOKU_SCRIPT . '" method="get">'; 218264f1744SAndreas Gohr echo '<input type="hidden" name="do" value="admin" />'; 219264f1744SAndreas Gohr echo '<input type="hidden" name="page" value="statistics" />'; 220264f1744SAndreas Gohr echo '<input type="hidden" name="opt" value="' . $this->opt . '" />'; 221483101d3SAndreas Gohr echo '<input type="date" name="f" value="' . $this->from . '" class="edit" />'; 222483101d3SAndreas Gohr echo '<input type="date" name="t" value="' . $this->to . '" class="edit" />'; 223264f1744SAndreas Gohr echo '<input type="submit" value="go" class="button" />'; 22414d99ec0SAndreas Gohr echo '</form>'; 225264f1744SAndreas Gohr 2266985b606SAndreas Gohr echo '<ul>'; 227483101d3SAndreas Gohr foreach ($quick as $name => $time) { 228*211caa5dSAndreas Gohr $url = buildURLparams([ 229*211caa5dSAndreas Gohr 'do' => 'admin', 230*211caa5dSAndreas Gohr 'page' => 'statistics', 231*211caa5dSAndreas Gohr 'opt' => $this->opt, 232*211caa5dSAndreas Gohr 'f' => $time, 233*211caa5dSAndreas Gohr 't' => $quick['today'], 234*211caa5dSAndreas Gohr ]); 235*211caa5dSAndreas Gohr 2366985b606SAndreas Gohr echo '<li>'; 237*211caa5dSAndreas Gohr echo '<a href="?' . $url . '">'; 238483101d3SAndreas Gohr echo $this->getLang('time_' . $name); 2396985b606SAndreas Gohr echo '</a>'; 2406985b606SAndreas Gohr echo '</li>'; 2416985b606SAndreas Gohr } 2426985b606SAndreas Gohr echo '</ul>'; 2436985b606SAndreas Gohr 244264f1744SAndreas Gohr echo '</div>'; 24514d99ec0SAndreas Gohr } 24614d99ec0SAndreas Gohr 247f5f32cbfSAndreas Gohr /** 248f5f32cbfSAndreas Gohr * Print an introductionary screen 249f5f32cbfSAndreas Gohr */ 250a8acb244SAndreas Gohr public function html_dashboard() 251a8acb244SAndreas Gohr { 252878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_dashboard') . '</p>'; 2532812a751SAndreas Gohr 2542812a751SAndreas Gohr // general info 2552812a751SAndreas Gohr echo '<div class="plg_stats_top">'; 256*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->aggregate(); 2571d2d78ccSAndreas Gohr 2581d2d78ccSAndreas Gohr echo '<ul class="left">'; 259a8acb244SAndreas Gohr foreach (['pageviews', 'sessions', 'visitors', 'users', 'logins', 'current'] as $name) { 260eabe0d07SAndreas Gohr echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>'; 261eabe0d07SAndreas Gohr } 2622812a751SAndreas Gohr echo '</ul>'; 2631d2d78ccSAndreas Gohr 2641d2d78ccSAndreas Gohr echo '<ul class="left">'; 265a8acb244SAndreas Gohr foreach (['bouncerate', 'timespent', 'avgpages', 'newvisitors', 'registrations'] as $name) { 2661d2d78ccSAndreas Gohr echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>'; 2671d2d78ccSAndreas Gohr } 2681d2d78ccSAndreas Gohr echo '</ul>'; 2691d2d78ccSAndreas Gohr 27056f647ddSAndreas Gohr echo '<br style="clear: left" />'; 27156f647ddSAndreas Gohr 272259897e1SAndreas Gohr $this->html_graph('dashboardviews', 700, 280); 273259897e1SAndreas Gohr $this->html_graph('dashboardwiki', 700, 280); 2742812a751SAndreas Gohr echo '</div>'; 2752812a751SAndreas Gohr 276*211caa5dSAndreas Gohr $quickgraphs = [ 277*211caa5dSAndreas Gohr ['lbl' => 'dash_mostpopular', 'query' => 'pages', 'opt' => 'page'], 278*211caa5dSAndreas Gohr ['lbl' => 'dash_newincoming', 'query' => 'newreferer', 'opt' => 'newreferer'], 279*211caa5dSAndreas Gohr ['lbl' => 'dash_topsearch', 'query' => 'searchphrases', 'opt' => 'internalsearchphrases'], 280*211caa5dSAndreas Gohr ]; 28187d5e44bSAndreas Gohr 282*211caa5dSAndreas Gohr foreach ($quickgraphs as $graph) { 283*211caa5dSAndreas Gohr $params = [ 284*211caa5dSAndreas Gohr 'do' => 'admin', 285*211caa5dSAndreas Gohr 'page' => 'statistics', 286*211caa5dSAndreas Gohr 'f' => $this->from, 287*211caa5dSAndreas Gohr 't' => $this->to, 288*211caa5dSAndreas Gohr 'opt' => $graph['opt'], 289*211caa5dSAndreas Gohr ]; 29054f6c432SAndreas Gohr 291264f1744SAndreas Gohr echo '<div>'; 292*211caa5dSAndreas Gohr echo '<h2>' . $this->getLang($graph['lbl']) . '</h2>'; 293*211caa5dSAndreas Gohr $result = call_user_func([$this->hlp->getQuery(), $graph['query']]); 29429dea504SAndreas Gohr $this->html_resulttable($result); 295*211caa5dSAndreas Gohr echo '<a href="?' . buildURLparams($params) . '" class="more button">' . $this->getLang('more') . '</a>'; 296264f1744SAndreas Gohr echo '</div>'; 29714d99ec0SAndreas Gohr } 298*211caa5dSAndreas Gohr } 29914d99ec0SAndreas Gohr 300a8acb244SAndreas Gohr public function html_history() 301a8acb244SAndreas Gohr { 302cae4a1c5SAndreas Gohr echo '<p>' . $this->getLang('intro_history') . '</p>'; 303338987f5SAndreas Gohr $this->html_graph('history_page_count', 600, 200); 304338987f5SAndreas Gohr $this->html_graph('history_page_size', 600, 200); 305338987f5SAndreas Gohr $this->html_graph('history_media_count', 600, 200); 306338987f5SAndreas Gohr $this->html_graph('history_media_size', 600, 200); 307cae4a1c5SAndreas Gohr } 308cae4a1c5SAndreas Gohr 309a8acb244SAndreas Gohr public function html_countries() 310a8acb244SAndreas Gohr { 311878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_countries') . '</p>'; 3121d379254SAnna Dabrowska $this->html_graph('countries', 300, 300); 313*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->countries(); 3142507f8e0SAndreas Gohr $this->html_resulttable($result, '', 150); 3159da6395dSAndreas Gohr } 3169da6395dSAndreas Gohr 317a8acb244SAndreas Gohr public function html_page() 318a8acb244SAndreas Gohr { 319878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_page') . '</p>'; 320*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->pages(); 3212507f8e0SAndreas Gohr $this->html_resulttable($result, '', 150); 3229da6395dSAndreas Gohr } 3239da6395dSAndreas Gohr 324a8acb244SAndreas Gohr public function html_edits() 325a8acb244SAndreas Gohr { 3261664ba1dSAndreas Gohr echo '<p>' . $this->getLang('intro_edits') . '</p>'; 327*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->edits(); 3281664ba1dSAndreas Gohr $this->html_resulttable($result, '', 150); 3291664ba1dSAndreas Gohr } 3301664ba1dSAndreas Gohr 331a8acb244SAndreas Gohr public function html_images() 332a8acb244SAndreas Gohr { 3331664ba1dSAndreas Gohr echo '<p>' . $this->getLang('intro_images') . '</p>'; 334616c1e8bSAndreas Gohr 335*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->imagessum(); 336616c1e8bSAndreas Gohr echo '<p>'; 337616c1e8bSAndreas Gohr echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize'])); 338616c1e8bSAndreas Gohr echo '</p>'; 339616c1e8bSAndreas Gohr 340*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->images(); 3411664ba1dSAndreas Gohr $this->html_resulttable($result, '', 150); 3421664ba1dSAndreas Gohr } 3431664ba1dSAndreas Gohr 344a8acb244SAndreas Gohr public function html_downloads() 345a8acb244SAndreas Gohr { 3461664ba1dSAndreas Gohr echo '<p>' . $this->getLang('intro_downloads') . '</p>'; 347616c1e8bSAndreas Gohr 348*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->downloadssum(); 349616c1e8bSAndreas Gohr echo '<p>'; 350616c1e8bSAndreas Gohr echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize'])); 351616c1e8bSAndreas Gohr echo '</p>'; 352616c1e8bSAndreas Gohr 353*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->downloads(); 3541664ba1dSAndreas Gohr $this->html_resulttable($result, '', 150); 3551664ba1dSAndreas Gohr } 3561664ba1dSAndreas Gohr 357a8acb244SAndreas Gohr public function html_browsers() 358a8acb244SAndreas Gohr { 359878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_browsers') . '</p>'; 3601d379254SAnna Dabrowska $this->html_graph('browsers', 300, 300); 361*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->browsers(false); 3622507f8e0SAndreas Gohr $this->html_resulttable($result, '', 150); 36375fa767dSAndreas Gohr } 36475fa767dSAndreas Gohr 365a8acb244SAndreas Gohr public function html_topuser() 366a8acb244SAndreas Gohr { 36781ff4c3aSAndreas Gohr echo '<p>' . $this->getLang('intro_topuser') . '</p>'; 3681d379254SAnna Dabrowska $this->html_graph('topuser', 300, 300); 369*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->topuser(); 37081ff4c3aSAndreas Gohr $this->html_resulttable($result, '', 150); 37181ff4c3aSAndreas Gohr } 37281ff4c3aSAndreas Gohr 373a8acb244SAndreas Gohr public function html_topeditor() 374a8acb244SAndreas Gohr { 37581ff4c3aSAndreas Gohr echo '<p>' . $this->getLang('intro_topeditor') . '</p>'; 3761d379254SAnna Dabrowska $this->html_graph('topeditor', 300, 300); 377*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->topeditor(); 37881ff4c3aSAndreas Gohr $this->html_resulttable($result, '', 150); 37981ff4c3aSAndreas Gohr } 38081ff4c3aSAndreas Gohr 381a8acb244SAndreas Gohr public function html_topgroup() 382a8acb244SAndreas Gohr { 38381ff4c3aSAndreas Gohr echo '<p>' . $this->getLang('intro_topgroup') . '</p>'; 3841d379254SAnna Dabrowska $this->html_graph('topgroup', 300, 300); 385*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->topgroup(); 38681ff4c3aSAndreas Gohr $this->html_resulttable($result, '', 150); 38781ff4c3aSAndreas Gohr } 38881ff4c3aSAndreas Gohr 389a8acb244SAndreas Gohr public function html_topgroupedit() 390a8acb244SAndreas Gohr { 39181ff4c3aSAndreas Gohr echo '<p>' . $this->getLang('intro_topgroupedit') . '</p>'; 3921d379254SAnna Dabrowska $this->html_graph('topgroupedit', 300, 300); 393*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->topgroupedit(); 39481ff4c3aSAndreas Gohr $this->html_resulttable($result, '', 150); 39581ff4c3aSAndreas Gohr } 39681ff4c3aSAndreas Gohr 397a8acb244SAndreas Gohr public function html_os() 398a8acb244SAndreas Gohr { 399878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_os') . '</p>'; 4001d379254SAnna Dabrowska $this->html_graph('os', 300, 300); 401*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->os(); 4022507f8e0SAndreas Gohr $this->html_resulttable($result, '', 150); 403bd4217d3SAndreas Gohr } 404bd4217d3SAndreas Gohr 405a8acb244SAndreas Gohr public function html_referer() 406a8acb244SAndreas Gohr { 407*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->aggregate(); 4082812a751SAndreas Gohr 4092812a751SAndreas Gohr $all = $result['search'] + $result['external'] + $result['direct']; 4102812a751SAndreas Gohr 41194023548SAndreas Gohr if ($all) { 4120863c19cSAndreas Gohr printf( 4130863c19cSAndreas Gohr '<p>' . $this->getLang('intro_referer') . '</p>', 414a8acb244SAndreas Gohr $all, 415a8acb244SAndreas Gohr $result['direct'], 416a8acb244SAndreas Gohr (100 * $result['direct'] / $all), 417a8acb244SAndreas Gohr $result['search'], 418a8acb244SAndreas Gohr (100 * $result['search'] / $all), 419a8acb244SAndreas Gohr $result['external'], 4200863c19cSAndreas Gohr (100 * $result['external'] / $all) 4210863c19cSAndreas Gohr ); 42294023548SAndreas Gohr } 4232812a751SAndreas Gohr 424*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->referer(); 4252507f8e0SAndreas Gohr $this->html_resulttable($result, '', 150); 4269da6395dSAndreas Gohr } 4279da6395dSAndreas Gohr 428a8acb244SAndreas Gohr public function html_newreferer() 429a8acb244SAndreas Gohr { 430878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_newreferer') . '</p>'; 431e7a2f1e0SAndreas Gohr 432*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->newreferer(); 4332507f8e0SAndreas Gohr $this->html_resulttable($result, '', 150); 434e7a2f1e0SAndreas Gohr } 435e7a2f1e0SAndreas Gohr 436a8acb244SAndreas Gohr public function html_outlinks() 437a8acb244SAndreas Gohr { 438878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_outlinks') . '</p>'; 439*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->outlinks(); 440e25286daSAndreas Gohr $this->html_resulttable($result, '', 150); 441e25286daSAndreas Gohr } 442e25286daSAndreas Gohr 443a8acb244SAndreas Gohr public function html_searchphrases() 444a8acb244SAndreas Gohr { 445878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_searchphrases') . '</p>'; 446*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->searchphrases(true); 44712dcdeccSAndreas Gohr $this->html_resulttable($result, '', 150); 44812dcdeccSAndreas Gohr } 44912dcdeccSAndreas Gohr 450a8acb244SAndreas Gohr public function html_searchwords() 451a8acb244SAndreas Gohr { 452878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_searchwords') . '</p>'; 453*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->searchwords(true); 4545bccfe87SAndreas Gohr $this->html_resulttable($result, '', 150); 4555bccfe87SAndreas Gohr } 4565bccfe87SAndreas Gohr 457a8acb244SAndreas Gohr public function html_internalsearchphrases() 458a8acb244SAndreas Gohr { 459878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_internalsearchphrases') . '</p>'; 460*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->searchphrases(false); 4615bccfe87SAndreas Gohr $this->html_resulttable($result, '', 150); 4625bccfe87SAndreas Gohr } 4635bccfe87SAndreas Gohr 464a8acb244SAndreas Gohr public function html_internalsearchwords() 465a8acb244SAndreas Gohr { 466878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_internalsearchwords') . '</p>'; 467*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->searchwords(false); 46812dcdeccSAndreas Gohr $this->html_resulttable($result, '', 150); 46912dcdeccSAndreas Gohr } 47012dcdeccSAndreas Gohr 471a8acb244SAndreas Gohr public function html_searchengines() 472a8acb244SAndreas Gohr { 473878be5c9SAndreas Gohr echo '<p>' . $this->getLang('intro_searchengines') . '</p>'; 47425b71d4bSAndreas Gohr $this->html_graph('searchengines', 400, 200); 475*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->searchengines(); 47612dcdeccSAndreas Gohr $this->html_resulttable($result, '', 150); 47712dcdeccSAndreas Gohr } 47812dcdeccSAndreas Gohr 479a8acb244SAndreas Gohr public function html_resolution() 480a8acb244SAndreas Gohr { 48125446aa2SAndreas Gohr echo '<p>' . $this->getLang('intro_resolution') . '</p>'; 48225446aa2SAndreas Gohr $this->html_graph('resolution', 650, 490); 483*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->resolution(); 484307baf3fSAndreas Gohr $this->html_resulttable($result, '', 150); 48525446aa2SAndreas Gohr } 486307baf3fSAndreas Gohr 487a8acb244SAndreas Gohr public function html_viewport() 488a8acb244SAndreas Gohr { 48925446aa2SAndreas Gohr echo '<p>' . $this->getLang('intro_viewport') . '</p>'; 49025446aa2SAndreas Gohr $this->html_graph('viewport', 650, 490); 491*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->viewport(); 49225446aa2SAndreas Gohr $this->html_resulttable($result, '', 150); 493c73e16f1SAndreas Gohr } 4949da6395dSAndreas Gohr 495a8acb244SAndreas Gohr public function html_seenusers() 496a8acb244SAndreas Gohr { 49733a136e5SAndreas Gohr echo '<p>' . $this->getLang('intro_seenusers') . '</p>'; 498*211caa5dSAndreas Gohr $result = $this->hlp->getQuery()->seenusers(); 49933a136e5SAndreas Gohr $this->html_resulttable($result, '', 150); 50033a136e5SAndreas Gohr } 50133a136e5SAndreas Gohr 50214d99ec0SAndreas Gohr /** 50314d99ec0SAndreas Gohr * Display a result in a HTML table 50414d99ec0SAndreas Gohr */ 505a8acb244SAndreas Gohr public function html_resulttable($result, $header = '', $pager = 0) 506a8acb244SAndreas Gohr { 50756f647ddSAndreas Gohr echo '<table class="inline">'; 5082812a751SAndreas Gohr if (is_array($header)) { 50914d99ec0SAndreas Gohr echo '<tr>'; 51014d99ec0SAndreas Gohr foreach ($header as $h) { 51114d99ec0SAndreas Gohr echo '<th>' . hsc($h) . '</th>'; 51214d99ec0SAndreas Gohr } 51314d99ec0SAndreas Gohr echo '</tr>'; 5142812a751SAndreas Gohr } 51514d99ec0SAndreas Gohr 5162507f8e0SAndreas Gohr $count = 0; 5172ee939eeSAndreas Gohr if (is_array($result)) foreach ($result as $row) { 51814d99ec0SAndreas Gohr echo '<tr>'; 51914d99ec0SAndreas Gohr foreach ($row as $k => $v) { 520f3818071SAndreas Gohr if ($k == 'res_x') continue; 521f3818071SAndreas Gohr if ($k == 'res_y') continue; 522f3818071SAndreas Gohr 5232812a751SAndreas Gohr echo '<td class="plg_stats_X' . $k . '">'; 52414d99ec0SAndreas Gohr if ($k == 'page') { 52514d99ec0SAndreas Gohr echo '<a href="' . wl($v) . '" class="wikilink1">'; 52614d99ec0SAndreas Gohr echo hsc($v); 52714d99ec0SAndreas Gohr echo '</a>'; 5281664ba1dSAndreas Gohr } elseif ($k == 'media') { 5291664ba1dSAndreas Gohr echo '<a href="' . ml($v) . '" class="wikilink1">'; 5301664ba1dSAndreas Gohr echo hsc($v); 5311664ba1dSAndreas Gohr echo '</a>'; 5321664ba1dSAndreas Gohr } elseif ($k == 'filesize') { 5331664ba1dSAndreas Gohr echo filesize_h($v); 53414d99ec0SAndreas Gohr } elseif ($k == 'url') { 53554f6c432SAndreas Gohr $url = hsc($v); 53683b63546SAndreas Gohr $url = preg_replace('/^https?:\/\/(www\.)?/', '', $url); 5372812a751SAndreas Gohr if (strlen($url) > 45) { 5382812a751SAndreas Gohr $url = substr($url, 0, 30) . ' … ' . substr($url, -15); 53954f6c432SAndreas Gohr } 54014d99ec0SAndreas Gohr echo '<a href="' . $v . '" class="urlextern">'; 54154f6c432SAndreas Gohr echo $url; 54214d99ec0SAndreas Gohr echo '</a>'; 5435bccfe87SAndreas Gohr } elseif ($k == 'ilookup') { 544a8acb244SAndreas Gohr echo '<a href="' . wl('', ['id' => $v, 'do' => 'search']) . '">Search</a>'; 54529dea504SAndreas Gohr } elseif ($k == 'lookup') { 54629dea504SAndreas Gohr echo '<a href="http://www.google.com/search?q=' . rawurlencode($v) . '">'; 547*211caa5dSAndreas Gohr echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/google.png" alt="Google" />'; 54829dea504SAndreas Gohr echo '</a> '; 54929dea504SAndreas Gohr 55029dea504SAndreas Gohr echo '<a href="http://search.yahoo.com/search?p=' . rawurlencode($v) . '">'; 551*211caa5dSAndreas Gohr echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/yahoo.png" alt="Yahoo!" />'; 55229dea504SAndreas Gohr echo '</a> '; 55329dea504SAndreas Gohr 55413a86c14SAndreas Gohr echo '<a href="http://www.bing.com/search?q=' . rawurlencode($v) . '">'; 555*211caa5dSAndreas Gohr echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/bing.png" alt="Bing" />'; 55629dea504SAndreas Gohr echo '</a> '; 55712dcdeccSAndreas Gohr } elseif ($k == 'engine') { 558*211caa5dSAndreas Gohr // FIXME thhis is not correct anymore 55913a86c14SAndreas Gohr if (isset($SEARCHENGINEINFO[$v])) { 56013a86c14SAndreas Gohr echo '<a href="' . $SEARCHENGINEINFO[$v][1] . '">' . $SEARCHENGINEINFO[$v][0] . '</a>'; 56113a86c14SAndreas Gohr } else { 56213a86c14SAndreas Gohr echo hsc(ucwords($v)); 56313a86c14SAndreas Gohr } 56413a86c14SAndreas Gohr } elseif ($k == 'eflag') { 56513a86c14SAndreas Gohr $this->html_icon('search', $v); 56675fa767dSAndreas Gohr } elseif ($k == 'bflag') { 56713a86c14SAndreas Gohr $this->html_icon('browser', $v); 568bd4217d3SAndreas Gohr } elseif ($k == 'osflag') { 56913a86c14SAndreas Gohr $this->html_icon('os', $v); 57075fa767dSAndreas Gohr } elseif ($k == 'cflag') { 57113a86c14SAndreas Gohr $this->html_icon('flags', $v); 57214d99ec0SAndreas Gohr } elseif ($k == 'html') { 57314d99ec0SAndreas Gohr echo $v; 57414d99ec0SAndreas Gohr } else { 57514d99ec0SAndreas Gohr echo hsc($v); 57614d99ec0SAndreas Gohr } 57714d99ec0SAndreas Gohr echo '</td>'; 57814d99ec0SAndreas Gohr } 57914d99ec0SAndreas Gohr echo '</tr>'; 5802507f8e0SAndreas Gohr 5812507f8e0SAndreas Gohr if ($pager && ($count == $pager)) break; 5822507f8e0SAndreas Gohr $count++; 58314d99ec0SAndreas Gohr } 58414d99ec0SAndreas Gohr echo '</table>'; 5852507f8e0SAndreas Gohr 5862507f8e0SAndreas Gohr if ($pager) $this->html_pager($pager, count($result) > $pager); 5871878f16fSAndreas Gohr } 5881878f16fSAndreas Gohr 589a8acb244SAndreas Gohr public function html_icon($type, $value) 590a8acb244SAndreas Gohr { 59113a86c14SAndreas Gohr $value = strtolower(preg_replace('/[^\w]+/', '', $value)); 5929bb008afSAndreas Gohr $value = str_replace(' ', '_', $value); 593a8acb244SAndreas Gohr 59413a86c14SAndreas Gohr $file = 'lib/plugins/statistics/ico/' . $type . '/' . $value . '.png'; 595dffb869bSAndreas Gohr if ($type == 'flags') { 596dffb869bSAndreas Gohr $w = 18; 597dffb869bSAndreas Gohr $h = 12; 598dffb869bSAndreas Gohr } else { 599dffb869bSAndreas Gohr $w = 16; 600dffb869bSAndreas Gohr $h = 16; 601dffb869bSAndreas Gohr } 602*211caa5dSAndreas Gohr if (!file_exists(DOKU_INC . $file)) return; 603*211caa5dSAndreas Gohr 604dffb869bSAndreas Gohr echo '<img src="' . DOKU_BASE . $file . '" alt="' . hsc($value) . '" width="' . $w . '" height="' . $h . '" />'; 60513a86c14SAndreas Gohr } 60613a86c14SAndreas Gohr} 607