xref: /plugin/statistics/admin.php (revision eaa05ffc09b7f504c4fe7d1a21d31c18250c65b4)
11878f16fSAndreas Gohr<?php
2a8acb244SAndreas Gohr
3211caa5dSAndreas Gohr// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
4a8acb244SAndreas Gohruse dokuwiki\Extension\AdminPlugin;
5c4c84f98SAndreas Gohruse dokuwiki\plugin\statistics\SearchEngines;
6a8acb244SAndreas Gohr
71878f16fSAndreas Gohr/**
81878f16fSAndreas Gohr * statistics plugin
91878f16fSAndreas Gohr *
101878f16fSAndreas Gohr * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
116b6f8822SAndreas Gohr * @author     Andreas Gohr <gohr@splitbrain.org>
121878f16fSAndreas Gohr */
13a8acb244SAndreas Gohrclass admin_plugin_statistics extends AdminPlugin
14a8acb244SAndreas Gohr{
1533a136e5SAndreas Gohr    /** @var string the currently selected page */
16a901d721SAndreas Gohr    protected $opt = '';
1733a136e5SAndreas Gohr
1833a136e5SAndreas Gohr    /** @var string from date in YYYY-MM-DD */
19a901d721SAndreas Gohr    protected $from = '';
2033a136e5SAndreas Gohr    /** @var string to date in YYYY-MM-DD */
21a901d721SAndreas Gohr    protected $to = '';
2233a136e5SAndreas Gohr    /** @var int Offset to use when displaying paged data */
2333a136e5SAndreas Gohr    protected $start = 0;
2433a136e5SAndreas Gohr
2533a136e5SAndreas Gohr    /** @var helper_plugin_statistics */
2633a136e5SAndreas Gohr    protected $hlp;
2733a136e5SAndreas Gohr
28a901d721SAndreas Gohr    /**
29a901d721SAndreas Gohr     * Available statistic pages
30a901d721SAndreas Gohr     */
31483101d3SAndreas Gohr    protected $pages = [
32483101d3SAndreas Gohr        'dashboard' => 1,
33483101d3SAndreas Gohr        'content' => ['page', 'edits', 'images', 'downloads', 'history'],
34483101d3SAndreas Gohr        'users' => ['topuser', 'topeditor', 'topgroup', 'topgroupedit', 'seenusers'],
35483101d3SAndreas Gohr        'links' => ['referer', 'newreferer', 'outlinks'],
36483101d3SAndreas Gohr        'search' => ['searchengines', 'searchphrases', 'searchwords', 'internalsearchphrases', 'internalsearchwords'],
37483101d3SAndreas Gohr        'technology' => ['browsers', 'os', 'countries', 'resolution', 'viewport']
38483101d3SAndreas Gohr    ];
391878f16fSAndreas Gohr
4081ff4c3aSAndreas Gohr    /** @var array keeps a list of all real content pages, generated from above array */
41a8acb244SAndreas Gohr    protected $allowedpages = [];
4281ff4c3aSAndreas Gohr
431878f16fSAndreas Gohr    /**
446b6f8822SAndreas Gohr     * Initialize the helper
456b6f8822SAndreas Gohr     */
46a8acb244SAndreas Gohr    public function __construct()
47a8acb244SAndreas Gohr    {
486b6f8822SAndreas Gohr        $this->hlp = plugin_load('helper', 'statistics');
4981ff4c3aSAndreas Gohr
5081ff4c3aSAndreas Gohr        // build a list of pages
5181ff4c3aSAndreas Gohr        foreach ($this->pages as $key => $val) {
5281ff4c3aSAndreas Gohr            if (is_array($val)) {
5381ff4c3aSAndreas Gohr                $this->allowedpages = array_merge($this->allowedpages, $val);
5481ff4c3aSAndreas Gohr            } else {
5581ff4c3aSAndreas Gohr                $this->allowedpages[] = $key;
5681ff4c3aSAndreas Gohr            }
5781ff4c3aSAndreas Gohr        }
586b6f8822SAndreas Gohr    }
596b6f8822SAndreas Gohr
606b6f8822SAndreas Gohr    /**
611878f16fSAndreas Gohr     * Access for managers allowed
621878f16fSAndreas Gohr     */
63a8acb244SAndreas Gohr    public function forAdminOnly()
64a8acb244SAndreas Gohr    {
651878f16fSAndreas Gohr        return false;
661878f16fSAndreas Gohr    }
671878f16fSAndreas Gohr
681878f16fSAndreas Gohr    /**
691878f16fSAndreas Gohr     * return sort order for position in admin menu
701878f16fSAndreas Gohr     */
71a8acb244SAndreas Gohr    public function getMenuSort()
72a8acb244SAndreas Gohr    {
736b6f8822SAndreas Gohr        return 350;
741878f16fSAndreas Gohr    }
751878f16fSAndreas Gohr
761878f16fSAndreas Gohr    /**
771878f16fSAndreas Gohr     * handle user request
781878f16fSAndreas Gohr     */
79a8acb244SAndreas Gohr    public function handle()
80a8acb244SAndreas Gohr    {
81483101d3SAndreas Gohr        global $INPUT;
82483101d3SAndreas Gohr        $this->opt = preg_replace('/[^a-z]+/', '', $INPUT->str('opt'));
8381ff4c3aSAndreas Gohr        if (!in_array($this->opt, $this->allowedpages)) $this->opt = 'dashboard';
84a901d721SAndreas Gohr
85483101d3SAndreas Gohr        $this->start = $INPUT->int('s');
86483101d3SAndreas Gohr        $this->setTimeframe($INPUT->str('f', date('Y-m-d')), $INPUT->str('t', date('Y-m-d')));
87e8699bceSAndreas Gohr    }
8895eb68e6SAndreas Gohr
89e8699bceSAndreas Gohr    /**
90e8699bceSAndreas Gohr     * set limit clause
91e8699bceSAndreas Gohr     */
92a8acb244SAndreas Gohr    public function setTimeframe($from, $to)
93a8acb244SAndreas Gohr    {
94047fcb0fSAndreas Gohr        // swap if wrong order
95a8acb244SAndreas Gohr        if ($from > $to) [$from, $to] = [$to, $from];
96047fcb0fSAndreas Gohr
97211caa5dSAndreas Gohr        $this->hlp->getQuery()->setTimeFrame($from, $to);
98e8699bceSAndreas Gohr        $this->from = $from;
99e8699bceSAndreas Gohr        $this->to = $to;
1001878f16fSAndreas Gohr    }
1011878f16fSAndreas Gohr
1021878f16fSAndreas Gohr    /**
10379b4a855SAndreas Gohr     * Output the Statistics
1041878f16fSAndreas Gohr     */
105a8acb244SAndreas Gohr    public function html()
106a8acb244SAndreas Gohr    {
107b0cf2118SAnna Dabrowska        echo '<script src="' . DOKU_BASE . 'lib/plugins/statistics/lib/chart.js"></script>';
108b0cf2118SAnna Dabrowska        echo '<script src="' . DOKU_BASE . 'lib/plugins/statistics/lib/chartjs-plugin-datalabels.js"></script>';
109b0cf2118SAnna Dabrowska
1101d2d78ccSAndreas Gohr        echo '<div id="plugin__statistics">';
1110c3b1e44SAndreas Gohr        echo '<h1>' . $this->getLang('menu') . '</h1>';
112264f1744SAndreas Gohr        $this->html_timeselect();
113441bfb8eSAndreas Gohr        tpl_flush();
114264f1744SAndreas Gohr
11579b4a855SAndreas Gohr        $method = 'html_' . $this->opt;
11679b4a855SAndreas Gohr        if (method_exists($this, $method)) {
117a901d721SAndreas Gohr            echo '<div class="plg_stats_' . $this->opt . '">';
118a901d721SAndreas Gohr            echo '<h2>' . $this->getLang($this->opt) . '</h2>';
11979b4a855SAndreas Gohr            $this->$method();
120a901d721SAndreas Gohr            echo '</div>';
12114d99ec0SAndreas Gohr        }
1221d2d78ccSAndreas Gohr        echo '</div>';
12314d99ec0SAndreas Gohr    }
12414d99ec0SAndreas Gohr
1256b6f8822SAndreas Gohr    /**
1266b6f8822SAndreas Gohr     * Return the TOC
1276b6f8822SAndreas Gohr     *
1286b6f8822SAndreas Gohr     * @return array
1296b6f8822SAndreas Gohr     */
130a8acb244SAndreas Gohr    public function getTOC()
131a8acb244SAndreas Gohr    {
132a8acb244SAndreas Gohr        $toc = [];
13381ff4c3aSAndreas Gohr        foreach ($this->pages as $key => $info) {
13481ff4c3aSAndreas Gohr            if (is_array($info)) {
13581ff4c3aSAndreas Gohr                $toc[] = html_mktocitem(
13681ff4c3aSAndreas Gohr                    '',
13781ff4c3aSAndreas Gohr                    $this->getLang($key),
13881ff4c3aSAndreas Gohr                    1,
13981ff4c3aSAndreas Gohr                    ''
14047ffcf7dSAndreas Gohr                );
14181ff4c3aSAndreas Gohr
14281ff4c3aSAndreas Gohr                foreach ($info as $page) {
14381ff4c3aSAndreas Gohr                    $toc[] = html_mktocitem(
144211caa5dSAndreas Gohr                        '?do=admin&amp;page=statistics&amp;opt=' . $page .
145211caa5dSAndreas Gohr                        '&amp;f=' . $this->from .
146211caa5dSAndreas Gohr                        '&amp;t=' . $this->to,
14781ff4c3aSAndreas Gohr                        $this->getLang($page),
14881ff4c3aSAndreas Gohr                        2,
14981ff4c3aSAndreas Gohr                        ''
15081ff4c3aSAndreas Gohr                    );
15181ff4c3aSAndreas Gohr                }
15281ff4c3aSAndreas Gohr            } else {
15381ff4c3aSAndreas Gohr                $toc[] = html_mktocitem(
154211caa5dSAndreas Gohr                    '?do=admin&amp;page=statistics&amp;opt=' . $key .
155211caa5dSAndreas Gohr                    '&amp;f=' . $this->from .
156211caa5dSAndreas Gohr                    '&amp;t=' . $this->to,
15781ff4c3aSAndreas Gohr                    $this->getLang($key),
15881ff4c3aSAndreas Gohr                    1,
15981ff4c3aSAndreas Gohr                    ''
16081ff4c3aSAndreas Gohr                );
16181ff4c3aSAndreas Gohr            }
16247ffcf7dSAndreas Gohr        }
16347ffcf7dSAndreas Gohr        return $toc;
1649da6395dSAndreas Gohr    }
1659da6395dSAndreas Gohr
166a8acb244SAndreas Gohr    public function html_graph($name, $width, $height)
167a8acb244SAndreas Gohr    {
168211caa5dSAndreas Gohr        $this->hlp->getGraph($this->from, $this->to, $width, $height)->$name();
169dc7b1e5eSAndreas Gohr    }
170dc7b1e5eSAndreas Gohr
1716b6f8822SAndreas Gohr    /**
1726b6f8822SAndreas Gohr     * Outputs pagination links
1736b6f8822SAndreas Gohr     *
17433a136e5SAndreas Gohr     * @param int $limit
17533a136e5SAndreas Gohr     * @param int $next
1766b6f8822SAndreas Gohr     */
177a8acb244SAndreas Gohr    public function html_pager($limit, $next)
178a8acb244SAndreas Gohr    {
179211caa5dSAndreas Gohr        $params = [
180211caa5dSAndreas Gohr            'do' => 'admin',
181211caa5dSAndreas Gohr            'page' => 'statistics',
182211caa5dSAndreas Gohr            'opt' => $this->opt,
183211caa5dSAndreas Gohr            'f' => $this->from,
184211caa5dSAndreas Gohr            't' => $this->to,
185211caa5dSAndreas Gohr        ];
1862507f8e0SAndreas Gohr
187211caa5dSAndreas Gohr        echo '<div class="plg_stats_pager">';
1882507f8e0SAndreas Gohr        if ($this->start > 0) {
1892507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
190211caa5dSAndreas Gohr            $params['s'] = $go;
191211caa5dSAndreas Gohr            echo '<a href="?' . buildURLparams($params) . '" class="prev button">' . $this->getLang('prev') . '</a>';
1922507f8e0SAndreas Gohr        }
1932507f8e0SAndreas Gohr
1942507f8e0SAndreas Gohr        if ($next) {
1952507f8e0SAndreas Gohr            $go = $this->start + $limit;
196211caa5dSAndreas Gohr            $params['s'] = $go;
197211caa5dSAndreas Gohr            echo '<a href="?' . buildURLparams($params) . '" class="next button">' . $this->getLang('next') . '</a>';
1982507f8e0SAndreas Gohr        }
1992507f8e0SAndreas Gohr        echo '</div>';
2002507f8e0SAndreas Gohr    }
2012507f8e0SAndreas Gohr
202264f1744SAndreas Gohr    /**
203264f1744SAndreas Gohr     * Print the time selection menu
204264f1744SAndreas Gohr     */
205a8acb244SAndreas Gohr    public function html_timeselect()
206a8acb244SAndreas Gohr    {
207483101d3SAndreas Gohr        $quick = [
208483101d3SAndreas Gohr            'today' => date('Y-m-d'),
209483101d3SAndreas Gohr            'last1' => date('Y-m-d', time() - (60 * 60 * 24)),
210483101d3SAndreas Gohr            'last7' => date('Y-m-d', time() - (60 * 60 * 24 * 7)),
211483101d3SAndreas Gohr            'last30' => date('Y-m-d', time() - (60 * 60 * 24 * 30)),
212483101d3SAndreas Gohr        ];
213483101d3SAndreas Gohr
21414d99ec0SAndreas Gohr
215264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
2166985b606SAndreas Gohr        echo '<span>' . $this->getLang('time_select') . '</span> ';
217264f1744SAndreas Gohr
218047fcb0fSAndreas Gohr        echo '<form action="' . DOKU_SCRIPT . '" method="get">';
219264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
220264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
221264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="' . $this->opt . '" />';
222483101d3SAndreas Gohr        echo '<input type="date" name="f" value="' . $this->from . '" class="edit" />';
223483101d3SAndreas Gohr        echo '<input type="date" name="t" value="' . $this->to . '" class="edit" />';
224264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
22514d99ec0SAndreas Gohr        echo '</form>';
226264f1744SAndreas Gohr
2276985b606SAndreas Gohr        echo '<ul>';
228483101d3SAndreas Gohr        foreach ($quick as $name => $time) {
229*eaa05ffcSAndreas Gohr            // today is included only today
230*eaa05ffcSAndreas Gohr            $to = $name == 'today' ? $quick['today'] : $quick['last1'];
231*eaa05ffcSAndreas Gohr
232211caa5dSAndreas Gohr            $url = buildURLparams([
233211caa5dSAndreas Gohr                'do' => 'admin',
234211caa5dSAndreas Gohr                'page' => 'statistics',
235211caa5dSAndreas Gohr                'opt' => $this->opt,
236211caa5dSAndreas Gohr                'f' => $time,
237*eaa05ffcSAndreas Gohr                't' => $to,
238211caa5dSAndreas Gohr            ]);
239211caa5dSAndreas Gohr
2406985b606SAndreas Gohr            echo '<li>';
241211caa5dSAndreas Gohr            echo '<a href="?' . $url . '">';
242483101d3SAndreas Gohr            echo $this->getLang('time_' . $name);
2436985b606SAndreas Gohr            echo '</a>';
2446985b606SAndreas Gohr            echo '</li>';
2456985b606SAndreas Gohr        }
2466985b606SAndreas Gohr        echo '</ul>';
2476985b606SAndreas Gohr
248264f1744SAndreas Gohr        echo '</div>';
24914d99ec0SAndreas Gohr    }
25014d99ec0SAndreas Gohr
251f5f32cbfSAndreas Gohr    /**
252f5f32cbfSAndreas Gohr     * Print an introductionary screen
253f5f32cbfSAndreas Gohr     */
254a8acb244SAndreas Gohr    public function html_dashboard()
255a8acb244SAndreas Gohr    {
256878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_dashboard') . '</p>';
2572812a751SAndreas Gohr
2582812a751SAndreas Gohr        // general info
2592812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
260211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->aggregate();
2611d2d78ccSAndreas Gohr
2621fd51258SAndreas Gohr        echo '<ul>';
263a8acb244SAndreas Gohr        foreach (['pageviews', 'sessions', 'visitors', 'users', 'logins', 'current'] as $name) {
264eabe0d07SAndreas Gohr            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
265eabe0d07SAndreas Gohr        }
2662812a751SAndreas Gohr        echo '</ul>';
2671d2d78ccSAndreas Gohr
2681fd51258SAndreas Gohr        echo '<ul>';
269a8acb244SAndreas Gohr        foreach (['bouncerate', 'timespent', 'avgpages', 'newvisitors', 'registrations'] as $name) {
2701d2d78ccSAndreas Gohr            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
2711d2d78ccSAndreas Gohr        }
2721d2d78ccSAndreas Gohr        echo '</ul>';
2731d2d78ccSAndreas Gohr
274259897e1SAndreas Gohr        $this->html_graph('dashboardviews', 700, 280);
275259897e1SAndreas Gohr        $this->html_graph('dashboardwiki', 700, 280);
2762812a751SAndreas Gohr        echo '</div>';
2772812a751SAndreas Gohr
278211caa5dSAndreas Gohr        $quickgraphs = [
279211caa5dSAndreas Gohr            ['lbl' => 'dash_mostpopular', 'query' => 'pages', 'opt' => 'page'],
280211caa5dSAndreas Gohr            ['lbl' => 'dash_newincoming', 'query' => 'newreferer', 'opt' => 'newreferer'],
281211caa5dSAndreas Gohr            ['lbl' => 'dash_topsearch', 'query' => 'searchphrases', 'opt' => 'internalsearchphrases'],
282211caa5dSAndreas Gohr        ];
28387d5e44bSAndreas Gohr
284211caa5dSAndreas Gohr        foreach ($quickgraphs as $graph) {
285211caa5dSAndreas Gohr            $params = [
286211caa5dSAndreas Gohr                'do' => 'admin',
287211caa5dSAndreas Gohr                'page' => 'statistics',
288211caa5dSAndreas Gohr                'f' => $this->from,
289211caa5dSAndreas Gohr                't' => $this->to,
290211caa5dSAndreas Gohr                'opt' => $graph['opt'],
291211caa5dSAndreas Gohr            ];
29254f6c432SAndreas Gohr
293264f1744SAndreas Gohr            echo '<div>';
294211caa5dSAndreas Gohr            echo '<h2>' . $this->getLang($graph['lbl']) . '</h2>';
295211caa5dSAndreas Gohr            $result = call_user_func([$this->hlp->getQuery(), $graph['query']]);
29629dea504SAndreas Gohr            $this->html_resulttable($result);
2971fd51258SAndreas Gohr            echo '<p><a href="?' . buildURLparams($params) . '" class="more">' . $this->getLang('more') . '…</a></p>';
298264f1744SAndreas Gohr            echo '</div>';
29914d99ec0SAndreas Gohr        }
300211caa5dSAndreas Gohr    }
30114d99ec0SAndreas Gohr
302a8acb244SAndreas Gohr    public function html_history()
303a8acb244SAndreas Gohr    {
304cae4a1c5SAndreas Gohr        echo '<p>' . $this->getLang('intro_history') . '</p>';
305338987f5SAndreas Gohr        $this->html_graph('history_page_count', 600, 200);
306338987f5SAndreas Gohr        $this->html_graph('history_page_size', 600, 200);
307338987f5SAndreas Gohr        $this->html_graph('history_media_count', 600, 200);
308338987f5SAndreas Gohr        $this->html_graph('history_media_size', 600, 200);
309cae4a1c5SAndreas Gohr    }
310cae4a1c5SAndreas Gohr
311a8acb244SAndreas Gohr    public function html_countries()
312a8acb244SAndreas Gohr    {
313878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_countries') . '</p>';
3141d379254SAnna Dabrowska        $this->html_graph('countries', 300, 300);
315211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->countries();
3162507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
3179da6395dSAndreas Gohr    }
3189da6395dSAndreas Gohr
319a8acb244SAndreas Gohr    public function html_page()
320a8acb244SAndreas Gohr    {
321878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_page') . '</p>';
322211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->pages();
3232507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
3249da6395dSAndreas Gohr    }
3259da6395dSAndreas Gohr
326a8acb244SAndreas Gohr    public function html_edits()
327a8acb244SAndreas Gohr    {
3281664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_edits') . '</p>';
329211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->edits();
3301664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3311664ba1dSAndreas Gohr    }
3321664ba1dSAndreas Gohr
333a8acb244SAndreas Gohr    public function html_images()
334a8acb244SAndreas Gohr    {
3351664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_images') . '</p>';
336616c1e8bSAndreas Gohr
337211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->imagessum();
338616c1e8bSAndreas Gohr        echo '<p>';
339616c1e8bSAndreas Gohr        echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize']));
340616c1e8bSAndreas Gohr        echo '</p>';
341616c1e8bSAndreas Gohr
342211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->images();
3431664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3441664ba1dSAndreas Gohr    }
3451664ba1dSAndreas Gohr
346a8acb244SAndreas Gohr    public function html_downloads()
347a8acb244SAndreas Gohr    {
3481664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_downloads') . '</p>';
349616c1e8bSAndreas Gohr
350211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->downloadssum();
351616c1e8bSAndreas Gohr        echo '<p>';
352616c1e8bSAndreas Gohr        echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize']));
353616c1e8bSAndreas Gohr        echo '</p>';
354616c1e8bSAndreas Gohr
355211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->downloads();
3561664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3571664ba1dSAndreas Gohr    }
3581664ba1dSAndreas Gohr
359a8acb244SAndreas Gohr    public function html_browsers()
360a8acb244SAndreas Gohr    {
361878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_browsers') . '</p>';
3621d379254SAnna Dabrowska        $this->html_graph('browsers', 300, 300);
363211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->browsers(false);
3642507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
36575fa767dSAndreas Gohr    }
36675fa767dSAndreas Gohr
367a8acb244SAndreas Gohr    public function html_topuser()
368a8acb244SAndreas Gohr    {
36981ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topuser') . '</p>';
3701d379254SAnna Dabrowska        $this->html_graph('topuser', 300, 300);
371211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topuser();
37281ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
37381ff4c3aSAndreas Gohr    }
37481ff4c3aSAndreas Gohr
375a8acb244SAndreas Gohr    public function html_topeditor()
376a8acb244SAndreas Gohr    {
37781ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topeditor') . '</p>';
3781d379254SAnna Dabrowska        $this->html_graph('topeditor', 300, 300);
379211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topeditor();
38081ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
38181ff4c3aSAndreas Gohr    }
38281ff4c3aSAndreas Gohr
383a8acb244SAndreas Gohr    public function html_topgroup()
384a8acb244SAndreas Gohr    {
38581ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topgroup') . '</p>';
3861d379254SAnna Dabrowska        $this->html_graph('topgroup', 300, 300);
387211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topgroup();
38881ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
38981ff4c3aSAndreas Gohr    }
39081ff4c3aSAndreas Gohr
391a8acb244SAndreas Gohr    public function html_topgroupedit()
392a8acb244SAndreas Gohr    {
39381ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topgroupedit') . '</p>';
3941d379254SAnna Dabrowska        $this->html_graph('topgroupedit', 300, 300);
395211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topgroupedit();
39681ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
39781ff4c3aSAndreas Gohr    }
39881ff4c3aSAndreas Gohr
399a8acb244SAndreas Gohr    public function html_os()
400a8acb244SAndreas Gohr    {
401878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_os') . '</p>';
4021d379254SAnna Dabrowska        $this->html_graph('os', 300, 300);
403211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->os();
4042507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
405bd4217d3SAndreas Gohr    }
406bd4217d3SAndreas Gohr
407a8acb244SAndreas Gohr    public function html_referer()
408a8acb244SAndreas Gohr    {
409211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->aggregate();
4102812a751SAndreas Gohr
4112812a751SAndreas Gohr        $all = $result['search'] + $result['external'] + $result['direct'];
4122812a751SAndreas Gohr
41394023548SAndreas Gohr        if ($all) {
4140863c19cSAndreas Gohr            printf(
4150863c19cSAndreas Gohr                '<p>' . $this->getLang('intro_referer') . '</p>',
416a8acb244SAndreas Gohr                $all,
417a8acb244SAndreas Gohr                $result['direct'],
418a8acb244SAndreas Gohr                (100 * $result['direct'] / $all),
419a8acb244SAndreas Gohr                $result['search'],
420a8acb244SAndreas Gohr                (100 * $result['search'] / $all),
421a8acb244SAndreas Gohr                $result['external'],
4220863c19cSAndreas Gohr                (100 * $result['external'] / $all)
4230863c19cSAndreas Gohr            );
42494023548SAndreas Gohr        }
4252812a751SAndreas Gohr
426211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->referer();
4272507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
4289da6395dSAndreas Gohr    }
4299da6395dSAndreas Gohr
430a8acb244SAndreas Gohr    public function html_newreferer()
431a8acb244SAndreas Gohr    {
432878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_newreferer') . '</p>';
433e7a2f1e0SAndreas Gohr
434211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->newreferer();
4352507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
436e7a2f1e0SAndreas Gohr    }
437e7a2f1e0SAndreas Gohr
438a8acb244SAndreas Gohr    public function html_outlinks()
439a8acb244SAndreas Gohr    {
440878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_outlinks') . '</p>';
441211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->outlinks();
442e25286daSAndreas Gohr        $this->html_resulttable($result, '', 150);
443e25286daSAndreas Gohr    }
444e25286daSAndreas Gohr
445a8acb244SAndreas Gohr    public function html_searchphrases()
446a8acb244SAndreas Gohr    {
447878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchphrases') . '</p>';
448211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchphrases(true);
44912dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
45012dcdeccSAndreas Gohr    }
45112dcdeccSAndreas Gohr
452a8acb244SAndreas Gohr    public function html_searchwords()
453a8acb244SAndreas Gohr    {
454878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchwords') . '</p>';
455211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchwords(true);
4565bccfe87SAndreas Gohr        $this->html_resulttable($result, '', 150);
4575bccfe87SAndreas Gohr    }
4585bccfe87SAndreas Gohr
459a8acb244SAndreas Gohr    public function html_internalsearchphrases()
460a8acb244SAndreas Gohr    {
461878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_internalsearchphrases') . '</p>';
462211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchphrases(false);
4635bccfe87SAndreas Gohr        $this->html_resulttable($result, '', 150);
4645bccfe87SAndreas Gohr    }
4655bccfe87SAndreas Gohr
466a8acb244SAndreas Gohr    public function html_internalsearchwords()
467a8acb244SAndreas Gohr    {
468878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_internalsearchwords') . '</p>';
469211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchwords(false);
47012dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
47112dcdeccSAndreas Gohr    }
47212dcdeccSAndreas Gohr
473a8acb244SAndreas Gohr    public function html_searchengines()
474a8acb244SAndreas Gohr    {
475878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchengines') . '</p>';
47625b71d4bSAndreas Gohr        $this->html_graph('searchengines', 400, 200);
477211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchengines();
47812dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
47912dcdeccSAndreas Gohr    }
48012dcdeccSAndreas Gohr
481a8acb244SAndreas Gohr    public function html_resolution()
482a8acb244SAndreas Gohr    {
48325446aa2SAndreas Gohr        echo '<p>' . $this->getLang('intro_resolution') . '</p>';
48425446aa2SAndreas Gohr        $this->html_graph('resolution', 650, 490);
485211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->resolution();
486307baf3fSAndreas Gohr        $this->html_resulttable($result, '', 150);
48725446aa2SAndreas Gohr    }
488307baf3fSAndreas Gohr
489a8acb244SAndreas Gohr    public function html_viewport()
490a8acb244SAndreas Gohr    {
49125446aa2SAndreas Gohr        echo '<p>' . $this->getLang('intro_viewport') . '</p>';
49225446aa2SAndreas Gohr        $this->html_graph('viewport', 650, 490);
493211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->viewport();
49425446aa2SAndreas Gohr        $this->html_resulttable($result, '', 150);
495c73e16f1SAndreas Gohr    }
4969da6395dSAndreas Gohr
497a8acb244SAndreas Gohr    public function html_seenusers()
498a8acb244SAndreas Gohr    {
49933a136e5SAndreas Gohr        echo '<p>' . $this->getLang('intro_seenusers') . '</p>';
500211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->seenusers();
50133a136e5SAndreas Gohr        $this->html_resulttable($result, '', 150);
50233a136e5SAndreas Gohr    }
50333a136e5SAndreas Gohr
50414d99ec0SAndreas Gohr    /**
50514d99ec0SAndreas Gohr     * Display a result in a HTML table
50614d99ec0SAndreas Gohr     */
507a8acb244SAndreas Gohr    public function html_resulttable($result, $header = '', $pager = 0)
508a8acb244SAndreas Gohr    {
50956f647ddSAndreas Gohr        echo '<table class="inline">';
5102812a751SAndreas Gohr        if (is_array($header)) {
51114d99ec0SAndreas Gohr            echo '<tr>';
51214d99ec0SAndreas Gohr            foreach ($header as $h) {
51314d99ec0SAndreas Gohr                echo '<th>' . hsc($h) . '</th>';
51414d99ec0SAndreas Gohr            }
51514d99ec0SAndreas Gohr            echo '</tr>';
5162812a751SAndreas Gohr        }
51714d99ec0SAndreas Gohr
5182507f8e0SAndreas Gohr        $count = 0;
5192ee939eeSAndreas Gohr        if (is_array($result)) foreach ($result as $row) {
52014d99ec0SAndreas Gohr            echo '<tr>';
52114d99ec0SAndreas Gohr            foreach ($row as $k => $v) {
522f3818071SAndreas Gohr                if ($k == 'res_x') continue;
523f3818071SAndreas Gohr                if ($k == 'res_y') continue;
524f3818071SAndreas Gohr
5252812a751SAndreas Gohr                echo '<td class="plg_stats_X' . $k . '">';
52614d99ec0SAndreas Gohr                if ($k == 'page') {
52714d99ec0SAndreas Gohr                    echo '<a href="' . wl($v) . '" class="wikilink1">';
52814d99ec0SAndreas Gohr                    echo hsc($v);
52914d99ec0SAndreas Gohr                    echo '</a>';
5301664ba1dSAndreas Gohr                } elseif ($k == 'media') {
5311664ba1dSAndreas Gohr                    echo '<a href="' . ml($v) . '" class="wikilink1">';
5321664ba1dSAndreas Gohr                    echo hsc($v);
5331664ba1dSAndreas Gohr                    echo '</a>';
5341664ba1dSAndreas Gohr                } elseif ($k == 'filesize') {
5351664ba1dSAndreas Gohr                    echo filesize_h($v);
53614d99ec0SAndreas Gohr                } elseif ($k == 'url') {
53754f6c432SAndreas Gohr                    $url = hsc($v);
53883b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/', '', $url);
5392812a751SAndreas Gohr                    if (strlen($url) > 45) {
5402812a751SAndreas Gohr                        $url = substr($url, 0, 30) . ' &hellip; ' . substr($url, -15);
54154f6c432SAndreas Gohr                    }
54214d99ec0SAndreas Gohr                    echo '<a href="' . $v . '" class="urlextern">';
54354f6c432SAndreas Gohr                    echo $url;
54414d99ec0SAndreas Gohr                    echo '</a>';
5455bccfe87SAndreas Gohr                } elseif ($k == 'ilookup') {
546a8acb244SAndreas Gohr                    echo '<a href="' . wl('', ['id' => $v, 'do' => 'search']) . '">Search</a>';
54729dea504SAndreas Gohr                } elseif ($k == 'lookup') {
54829dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q=' . rawurlencode($v) . '">';
549211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/google.png" alt="Google" />';
55029dea504SAndreas Gohr                    echo '</a> ';
55129dea504SAndreas Gohr
55229dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p=' . rawurlencode($v) . '">';
553211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/yahoo.png" alt="Yahoo!" />';
55429dea504SAndreas Gohr                    echo '</a> ';
55529dea504SAndreas Gohr
55613a86c14SAndreas Gohr                    echo '<a href="http://www.bing.com/search?q=' . rawurlencode($v) . '">';
557211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/bing.png" alt="Bing" />';
55829dea504SAndreas Gohr                    echo '</a> ';
55912dcdeccSAndreas Gohr                } elseif ($k == 'engine') {
560c4c84f98SAndreas Gohr                    $name = SearchEngines::getName($v);
561c4c84f98SAndreas Gohr                    $url = SearchEngines::getURL($v);
562c4c84f98SAndreas Gohr                    if ($url) {
563c4c84f98SAndreas Gohr                        echo '<a href="' . $url . '">' . hsc($name) . '</a>';
56413a86c14SAndreas Gohr                    } else {
565c4c84f98SAndreas Gohr                        echo hsc($name);
56613a86c14SAndreas Gohr                    }
56714d99ec0SAndreas Gohr                } elseif ($k == 'html') {
56814d99ec0SAndreas Gohr                    echo $v;
56914d99ec0SAndreas Gohr                } else {
57014d99ec0SAndreas Gohr                    echo hsc($v);
57114d99ec0SAndreas Gohr                }
57214d99ec0SAndreas Gohr                echo '</td>';
57314d99ec0SAndreas Gohr            }
57414d99ec0SAndreas Gohr            echo '</tr>';
5752507f8e0SAndreas Gohr
5762507f8e0SAndreas Gohr            if ($pager && ($count == $pager)) break;
5772507f8e0SAndreas Gohr            $count++;
57814d99ec0SAndreas Gohr        }
57914d99ec0SAndreas Gohr        echo '</table>';
5802507f8e0SAndreas Gohr
5812507f8e0SAndreas Gohr        if ($pager) $this->html_pager($pager, count($result) > $pager);
5821878f16fSAndreas Gohr    }
58313a86c14SAndreas Gohr}
584