xref: /plugin/statistics/admin.php (revision d550a4ad772c00d30c3bead8fc22362f3d1bec7a)
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'],
349fdd7e51SAndreas Gohr        'users' => ['topdomain', 'topuser', 'topeditor', 'topgroup', 'topgroupedit', 'seenusers'],
35483101d3SAndreas Gohr        'links' => ['referer', 'newreferer', 'outlinks'],
362a30f557SAndreas Gohr        'search' => ['searchengines', '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
50ba6b3b10SAndreas Gohr        // remove pages that are not available because logging its data is disabled
51ba6b3b10SAndreas Gohr        if($this->getConf('nolocation')) {
52ba6b3b10SAndreas Gohr            $this->pages['technology'] = array_diff($this->pages['technology'], ['countries']);
53ba6b3b10SAndreas Gohr        }
54*d550a4adSAndreas Gohr        if($this->getConf('nousers')) {
55*d550a4adSAndreas Gohr            unset($this->pages['users']);
56*d550a4adSAndreas Gohr        }
57ba6b3b10SAndreas Gohr
5881ff4c3aSAndreas Gohr        // build a list of pages
5981ff4c3aSAndreas Gohr        foreach ($this->pages as $key => $val) {
6081ff4c3aSAndreas Gohr            if (is_array($val)) {
6181ff4c3aSAndreas Gohr                $this->allowedpages = array_merge($this->allowedpages, $val);
6281ff4c3aSAndreas Gohr            } else {
6381ff4c3aSAndreas Gohr                $this->allowedpages[] = $key;
6481ff4c3aSAndreas Gohr            }
6581ff4c3aSAndreas Gohr        }
666b6f8822SAndreas Gohr    }
676b6f8822SAndreas Gohr
686b6f8822SAndreas Gohr    /**
691878f16fSAndreas Gohr     * Access for managers allowed
701878f16fSAndreas Gohr     */
71a8acb244SAndreas Gohr    public function forAdminOnly()
72a8acb244SAndreas Gohr    {
731878f16fSAndreas Gohr        return false;
741878f16fSAndreas Gohr    }
751878f16fSAndreas Gohr
761878f16fSAndreas Gohr    /**
771878f16fSAndreas Gohr     * return sort order for position in admin menu
781878f16fSAndreas Gohr     */
79a8acb244SAndreas Gohr    public function getMenuSort()
80a8acb244SAndreas Gohr    {
816b6f8822SAndreas Gohr        return 350;
821878f16fSAndreas Gohr    }
831878f16fSAndreas Gohr
841878f16fSAndreas Gohr    /**
851878f16fSAndreas Gohr     * handle user request
861878f16fSAndreas Gohr     */
87a8acb244SAndreas Gohr    public function handle()
88a8acb244SAndreas Gohr    {
89483101d3SAndreas Gohr        global $INPUT;
90483101d3SAndreas Gohr        $this->opt = preg_replace('/[^a-z]+/', '', $INPUT->str('opt'));
9181ff4c3aSAndreas Gohr        if (!in_array($this->opt, $this->allowedpages)) $this->opt = 'dashboard';
92a901d721SAndreas Gohr
93483101d3SAndreas Gohr        $this->start = $INPUT->int('s');
94483101d3SAndreas Gohr        $this->setTimeframe($INPUT->str('f', date('Y-m-d')), $INPUT->str('t', date('Y-m-d')));
95e8699bceSAndreas Gohr    }
9695eb68e6SAndreas Gohr
97e8699bceSAndreas Gohr    /**
98e8699bceSAndreas Gohr     * set limit clause
99e8699bceSAndreas Gohr     */
100a8acb244SAndreas Gohr    public function setTimeframe($from, $to)
101a8acb244SAndreas Gohr    {
102047fcb0fSAndreas Gohr        // swap if wrong order
103a8acb244SAndreas Gohr        if ($from > $to) [$from, $to] = [$to, $from];
104047fcb0fSAndreas Gohr
105211caa5dSAndreas Gohr        $this->hlp->getQuery()->setTimeFrame($from, $to);
106e8699bceSAndreas Gohr        $this->from = $from;
107e8699bceSAndreas Gohr        $this->to = $to;
1081878f16fSAndreas Gohr    }
1091878f16fSAndreas Gohr
1101878f16fSAndreas Gohr    /**
11179b4a855SAndreas Gohr     * Output the Statistics
1121878f16fSAndreas Gohr     */
113a8acb244SAndreas Gohr    public function html()
114a8acb244SAndreas Gohr    {
115b0cf2118SAnna Dabrowska        echo '<script src="' . DOKU_BASE . 'lib/plugins/statistics/lib/chart.js"></script>';
116b0cf2118SAnna Dabrowska        echo '<script src="' . DOKU_BASE . 'lib/plugins/statistics/lib/chartjs-plugin-datalabels.js"></script>';
117b0cf2118SAnna Dabrowska
1181d2d78ccSAndreas Gohr        echo '<div id="plugin__statistics">';
1190c3b1e44SAndreas Gohr        echo '<h1>' . $this->getLang('menu') . '</h1>';
120264f1744SAndreas Gohr        $this->html_timeselect();
121441bfb8eSAndreas Gohr        tpl_flush();
122264f1744SAndreas Gohr
12379b4a855SAndreas Gohr        $method = 'html_' . $this->opt;
12479b4a855SAndreas Gohr        if (method_exists($this, $method)) {
125a901d721SAndreas Gohr            echo '<div class="plg_stats_' . $this->opt . '">';
126a901d721SAndreas Gohr            echo '<h2>' . $this->getLang($this->opt) . '</h2>';
12779b4a855SAndreas Gohr            $this->$method();
128a901d721SAndreas Gohr            echo '</div>';
12914d99ec0SAndreas Gohr        }
1301d2d78ccSAndreas Gohr        echo '</div>';
13114d99ec0SAndreas Gohr    }
13214d99ec0SAndreas Gohr
1336b6f8822SAndreas Gohr    /**
1346b6f8822SAndreas Gohr     * Return the TOC
1356b6f8822SAndreas Gohr     *
1366b6f8822SAndreas Gohr     * @return array
1376b6f8822SAndreas Gohr     */
138a8acb244SAndreas Gohr    public function getTOC()
139a8acb244SAndreas Gohr    {
140a8acb244SAndreas Gohr        $toc = [];
14181ff4c3aSAndreas Gohr        foreach ($this->pages as $key => $info) {
14281ff4c3aSAndreas Gohr            if (is_array($info)) {
14381ff4c3aSAndreas Gohr                $toc[] = html_mktocitem(
14481ff4c3aSAndreas Gohr                    '',
14581ff4c3aSAndreas Gohr                    $this->getLang($key),
14681ff4c3aSAndreas Gohr                    1,
14781ff4c3aSAndreas Gohr                    ''
14847ffcf7dSAndreas Gohr                );
14981ff4c3aSAndreas Gohr
15081ff4c3aSAndreas Gohr                foreach ($info as $page) {
15181ff4c3aSAndreas Gohr                    $toc[] = html_mktocitem(
152211caa5dSAndreas Gohr                        '?do=admin&amp;page=statistics&amp;opt=' . $page .
153211caa5dSAndreas Gohr                        '&amp;f=' . $this->from .
154211caa5dSAndreas Gohr                        '&amp;t=' . $this->to,
15581ff4c3aSAndreas Gohr                        $this->getLang($page),
15681ff4c3aSAndreas Gohr                        2,
15781ff4c3aSAndreas Gohr                        ''
15881ff4c3aSAndreas Gohr                    );
15981ff4c3aSAndreas Gohr                }
16081ff4c3aSAndreas Gohr            } else {
16181ff4c3aSAndreas Gohr                $toc[] = html_mktocitem(
162211caa5dSAndreas Gohr                    '?do=admin&amp;page=statistics&amp;opt=' . $key .
163211caa5dSAndreas Gohr                    '&amp;f=' . $this->from .
164211caa5dSAndreas Gohr                    '&amp;t=' . $this->to,
16581ff4c3aSAndreas Gohr                    $this->getLang($key),
16681ff4c3aSAndreas Gohr                    1,
16781ff4c3aSAndreas Gohr                    ''
16881ff4c3aSAndreas Gohr                );
16981ff4c3aSAndreas Gohr            }
17047ffcf7dSAndreas Gohr        }
17147ffcf7dSAndreas Gohr        return $toc;
1729da6395dSAndreas Gohr    }
1739da6395dSAndreas Gohr
174a8acb244SAndreas Gohr    public function html_graph($name, $width, $height)
175a8acb244SAndreas Gohr    {
176211caa5dSAndreas Gohr        $this->hlp->getGraph($this->from, $this->to, $width, $height)->$name();
177dc7b1e5eSAndreas Gohr    }
178dc7b1e5eSAndreas Gohr
1796b6f8822SAndreas Gohr    /**
1806b6f8822SAndreas Gohr     * Outputs pagination links
1816b6f8822SAndreas Gohr     *
18233a136e5SAndreas Gohr     * @param int $limit
18333a136e5SAndreas Gohr     * @param int $next
1846b6f8822SAndreas Gohr     */
185a8acb244SAndreas Gohr    public function html_pager($limit, $next)
186a8acb244SAndreas Gohr    {
187211caa5dSAndreas Gohr        $params = [
188211caa5dSAndreas Gohr            'do' => 'admin',
189211caa5dSAndreas Gohr            'page' => 'statistics',
190211caa5dSAndreas Gohr            'opt' => $this->opt,
191211caa5dSAndreas Gohr            'f' => $this->from,
192211caa5dSAndreas Gohr            't' => $this->to,
193211caa5dSAndreas Gohr        ];
1942507f8e0SAndreas Gohr
195211caa5dSAndreas Gohr        echo '<div class="plg_stats_pager">';
1962507f8e0SAndreas Gohr        if ($this->start > 0) {
1972507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
198211caa5dSAndreas Gohr            $params['s'] = $go;
199211caa5dSAndreas Gohr            echo '<a href="?' . buildURLparams($params) . '" class="prev button">' . $this->getLang('prev') . '</a>';
2002507f8e0SAndreas Gohr        }
2012507f8e0SAndreas Gohr
2022507f8e0SAndreas Gohr        if ($next) {
2032507f8e0SAndreas Gohr            $go = $this->start + $limit;
204211caa5dSAndreas Gohr            $params['s'] = $go;
205211caa5dSAndreas Gohr            echo '<a href="?' . buildURLparams($params) . '" class="next button">' . $this->getLang('next') . '</a>';
2062507f8e0SAndreas Gohr        }
2072507f8e0SAndreas Gohr        echo '</div>';
2082507f8e0SAndreas Gohr    }
2092507f8e0SAndreas Gohr
210264f1744SAndreas Gohr    /**
211264f1744SAndreas Gohr     * Print the time selection menu
212264f1744SAndreas Gohr     */
213a8acb244SAndreas Gohr    public function html_timeselect()
214a8acb244SAndreas Gohr    {
215483101d3SAndreas Gohr        $quick = [
216483101d3SAndreas Gohr            'today' => date('Y-m-d'),
217483101d3SAndreas Gohr            'last1' => date('Y-m-d', time() - (60 * 60 * 24)),
218483101d3SAndreas Gohr            'last7' => date('Y-m-d', time() - (60 * 60 * 24 * 7)),
219483101d3SAndreas Gohr            'last30' => date('Y-m-d', time() - (60 * 60 * 24 * 30)),
220483101d3SAndreas Gohr        ];
221483101d3SAndreas Gohr
22214d99ec0SAndreas Gohr
223264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
2246985b606SAndreas Gohr        echo '<span>' . $this->getLang('time_select') . '</span> ';
225264f1744SAndreas Gohr
226047fcb0fSAndreas Gohr        echo '<form action="' . DOKU_SCRIPT . '" method="get">';
227264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
228264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
229264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="' . $this->opt . '" />';
230483101d3SAndreas Gohr        echo '<input type="date" name="f" value="' . $this->from . '" class="edit" />';
231483101d3SAndreas Gohr        echo '<input type="date" name="t" value="' . $this->to . '" class="edit" />';
232264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
23314d99ec0SAndreas Gohr        echo '</form>';
234264f1744SAndreas Gohr
2356985b606SAndreas Gohr        echo '<ul>';
236483101d3SAndreas Gohr        foreach ($quick as $name => $time) {
237eaa05ffcSAndreas Gohr            // today is included only today
238eaa05ffcSAndreas Gohr            $to = $name == 'today' ? $quick['today'] : $quick['last1'];
239eaa05ffcSAndreas Gohr
240211caa5dSAndreas Gohr            $url = buildURLparams([
241211caa5dSAndreas Gohr                'do' => 'admin',
242211caa5dSAndreas Gohr                'page' => 'statistics',
243211caa5dSAndreas Gohr                'opt' => $this->opt,
244211caa5dSAndreas Gohr                'f' => $time,
245eaa05ffcSAndreas Gohr                't' => $to,
246211caa5dSAndreas Gohr            ]);
247211caa5dSAndreas Gohr
2486985b606SAndreas Gohr            echo '<li>';
249211caa5dSAndreas Gohr            echo '<a href="?' . $url . '">';
250483101d3SAndreas Gohr            echo $this->getLang('time_' . $name);
2516985b606SAndreas Gohr            echo '</a>';
2526985b606SAndreas Gohr            echo '</li>';
2536985b606SAndreas Gohr        }
2546985b606SAndreas Gohr        echo '</ul>';
2556985b606SAndreas Gohr
256264f1744SAndreas Gohr        echo '</div>';
25714d99ec0SAndreas Gohr    }
25814d99ec0SAndreas Gohr
259f5f32cbfSAndreas Gohr    /**
260f5f32cbfSAndreas Gohr     * Print an introductionary screen
261f5f32cbfSAndreas Gohr     */
262a8acb244SAndreas Gohr    public function html_dashboard()
263a8acb244SAndreas Gohr    {
264878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_dashboard') . '</p>';
2652812a751SAndreas Gohr
2662812a751SAndreas Gohr        // general info
2672812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
268211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->aggregate();
2691d2d78ccSAndreas Gohr
2701fd51258SAndreas Gohr        echo '<ul>';
271a8acb244SAndreas Gohr        foreach (['pageviews', 'sessions', 'visitors', 'users', 'logins', 'current'] as $name) {
272eabe0d07SAndreas Gohr            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
273eabe0d07SAndreas Gohr        }
2742812a751SAndreas Gohr        echo '</ul>';
2751d2d78ccSAndreas Gohr
2761fd51258SAndreas Gohr        echo '<ul>';
277a8acb244SAndreas Gohr        foreach (['bouncerate', 'timespent', 'avgpages', 'newvisitors', 'registrations'] as $name) {
2781d2d78ccSAndreas Gohr            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
2791d2d78ccSAndreas Gohr        }
2801d2d78ccSAndreas Gohr        echo '</ul>';
2811d2d78ccSAndreas Gohr
282259897e1SAndreas Gohr        $this->html_graph('dashboardviews', 700, 280);
283259897e1SAndreas Gohr        $this->html_graph('dashboardwiki', 700, 280);
2842812a751SAndreas Gohr        echo '</div>';
2852812a751SAndreas Gohr
286211caa5dSAndreas Gohr        $quickgraphs = [
287211caa5dSAndreas Gohr            ['lbl' => 'dash_mostpopular', 'query' => 'pages', 'opt' => 'page'],
288211caa5dSAndreas Gohr            ['lbl' => 'dash_newincoming', 'query' => 'newreferer', 'opt' => 'newreferer'],
289211caa5dSAndreas Gohr            ['lbl' => 'dash_topsearch', 'query' => 'searchphrases', 'opt' => 'internalsearchphrases'],
290211caa5dSAndreas Gohr        ];
29187d5e44bSAndreas Gohr
292211caa5dSAndreas Gohr        foreach ($quickgraphs as $graph) {
293211caa5dSAndreas Gohr            $params = [
294211caa5dSAndreas Gohr                'do' => 'admin',
295211caa5dSAndreas Gohr                'page' => 'statistics',
296211caa5dSAndreas Gohr                'f' => $this->from,
297211caa5dSAndreas Gohr                't' => $this->to,
298211caa5dSAndreas Gohr                'opt' => $graph['opt'],
299211caa5dSAndreas Gohr            ];
30054f6c432SAndreas Gohr
301264f1744SAndreas Gohr            echo '<div>';
302211caa5dSAndreas Gohr            echo '<h2>' . $this->getLang($graph['lbl']) . '</h2>';
303211caa5dSAndreas Gohr            $result = call_user_func([$this->hlp->getQuery(), $graph['query']]);
30429dea504SAndreas Gohr            $this->html_resulttable($result);
3051fd51258SAndreas Gohr            echo '<p><a href="?' . buildURLparams($params) . '" class="more">' . $this->getLang('more') . '…</a></p>';
306264f1744SAndreas Gohr            echo '</div>';
30714d99ec0SAndreas Gohr        }
308211caa5dSAndreas Gohr    }
30914d99ec0SAndreas Gohr
310a8acb244SAndreas Gohr    public function html_history()
311a8acb244SAndreas Gohr    {
312cae4a1c5SAndreas Gohr        echo '<p>' . $this->getLang('intro_history') . '</p>';
313338987f5SAndreas Gohr        $this->html_graph('history_page_count', 600, 200);
314338987f5SAndreas Gohr        $this->html_graph('history_page_size', 600, 200);
315338987f5SAndreas Gohr        $this->html_graph('history_media_count', 600, 200);
316338987f5SAndreas Gohr        $this->html_graph('history_media_size', 600, 200);
317cae4a1c5SAndreas Gohr    }
318cae4a1c5SAndreas Gohr
319a8acb244SAndreas Gohr    public function html_countries()
320a8acb244SAndreas Gohr    {
321878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_countries') . '</p>';
3221d379254SAnna Dabrowska        $this->html_graph('countries', 300, 300);
323211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->countries();
3242507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
3259da6395dSAndreas Gohr    }
3269da6395dSAndreas Gohr
327a8acb244SAndreas Gohr    public function html_page()
328a8acb244SAndreas Gohr    {
329878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_page') . '</p>';
330211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->pages();
3312507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
3329da6395dSAndreas Gohr    }
3339da6395dSAndreas Gohr
334a8acb244SAndreas Gohr    public function html_edits()
335a8acb244SAndreas Gohr    {
3361664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_edits') . '</p>';
337211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->edits();
3381664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3391664ba1dSAndreas Gohr    }
3401664ba1dSAndreas Gohr
341a8acb244SAndreas Gohr    public function html_images()
342a8acb244SAndreas Gohr    {
3431664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_images') . '</p>';
344616c1e8bSAndreas Gohr
345211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->imagessum();
346616c1e8bSAndreas Gohr        echo '<p>';
347616c1e8bSAndreas Gohr        echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize']));
348616c1e8bSAndreas Gohr        echo '</p>';
349616c1e8bSAndreas Gohr
350211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->images();
3511664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3521664ba1dSAndreas Gohr    }
3531664ba1dSAndreas Gohr
354a8acb244SAndreas Gohr    public function html_downloads()
355a8acb244SAndreas Gohr    {
3561664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_downloads') . '</p>';
357616c1e8bSAndreas Gohr
358211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->downloadssum();
359616c1e8bSAndreas Gohr        echo '<p>';
360616c1e8bSAndreas Gohr        echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize']));
361616c1e8bSAndreas Gohr        echo '</p>';
362616c1e8bSAndreas Gohr
363211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->downloads();
3641664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3651664ba1dSAndreas Gohr    }
3661664ba1dSAndreas Gohr
367a8acb244SAndreas Gohr    public function html_browsers()
368a8acb244SAndreas Gohr    {
369878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_browsers') . '</p>';
3701d379254SAnna Dabrowska        $this->html_graph('browsers', 300, 300);
371211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->browsers(false);
3722507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
37375fa767dSAndreas Gohr    }
37475fa767dSAndreas Gohr
3759fdd7e51SAndreas Gohr    public function html_topdomain()
3769fdd7e51SAndreas Gohr    {
3779fdd7e51SAndreas Gohr        echo '<p>' . $this->getLang('intro_topdomain') . '</p>';
3789fdd7e51SAndreas Gohr        $this->html_graph('topdomain', 300, 300);
3799fdd7e51SAndreas Gohr        $result = $this->hlp->getQuery()->topdomain();
3809fdd7e51SAndreas Gohr        $this->html_resulttable($result, '', 150);
3819fdd7e51SAndreas Gohr    }
3829fdd7e51SAndreas Gohr
383a8acb244SAndreas Gohr    public function html_topuser()
384a8acb244SAndreas Gohr    {
38581ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topuser') . '</p>';
3861d379254SAnna Dabrowska        $this->html_graph('topuser', 300, 300);
387211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topuser();
38881ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
38981ff4c3aSAndreas Gohr    }
39081ff4c3aSAndreas Gohr
391a8acb244SAndreas Gohr    public function html_topeditor()
392a8acb244SAndreas Gohr    {
39381ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topeditor') . '</p>';
3941d379254SAnna Dabrowska        $this->html_graph('topeditor', 300, 300);
395211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topeditor();
39681ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
39781ff4c3aSAndreas Gohr    }
39881ff4c3aSAndreas Gohr
399a8acb244SAndreas Gohr    public function html_topgroup()
400a8acb244SAndreas Gohr    {
40181ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topgroup') . '</p>';
4021d379254SAnna Dabrowska        $this->html_graph('topgroup', 300, 300);
403211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topgroup();
40481ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
40581ff4c3aSAndreas Gohr    }
40681ff4c3aSAndreas Gohr
407a8acb244SAndreas Gohr    public function html_topgroupedit()
408a8acb244SAndreas Gohr    {
40981ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topgroupedit') . '</p>';
4101d379254SAnna Dabrowska        $this->html_graph('topgroupedit', 300, 300);
411211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topgroupedit();
41281ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
41381ff4c3aSAndreas Gohr    }
41481ff4c3aSAndreas Gohr
415a8acb244SAndreas Gohr    public function html_os()
416a8acb244SAndreas Gohr    {
417878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_os') . '</p>';
4181d379254SAnna Dabrowska        $this->html_graph('os', 300, 300);
419211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->os();
4202507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
421bd4217d3SAndreas Gohr    }
422bd4217d3SAndreas Gohr
423a8acb244SAndreas Gohr    public function html_referer()
424a8acb244SAndreas Gohr    {
425211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->aggregate();
4262812a751SAndreas Gohr
4272a30f557SAndreas Gohr        if ($result['referers']) {
4280863c19cSAndreas Gohr            printf(
4290863c19cSAndreas Gohr                '<p>' . $this->getLang('intro_referer') . '</p>',
4302a30f557SAndreas Gohr                $result['referers'],
431a8acb244SAndreas Gohr                $result['direct'],
4322a30f557SAndreas Gohr                (100 * $result['direct'] / $result['referers']),
433a8acb244SAndreas Gohr                $result['search'],
4342a30f557SAndreas Gohr                (100 * $result['search'] / $result['referers']),
435a8acb244SAndreas Gohr                $result['external'],
4362a30f557SAndreas Gohr                (100 * $result['external'] / $result['referers'])
4370863c19cSAndreas Gohr            );
43894023548SAndreas Gohr        }
4392812a751SAndreas Gohr
440211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->referer();
4412507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
4429da6395dSAndreas Gohr    }
4439da6395dSAndreas Gohr
444a8acb244SAndreas Gohr    public function html_newreferer()
445a8acb244SAndreas Gohr    {
446878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_newreferer') . '</p>';
447e7a2f1e0SAndreas Gohr
448211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->newreferer();
4492507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
450e7a2f1e0SAndreas Gohr    }
451e7a2f1e0SAndreas Gohr
452a8acb244SAndreas Gohr    public function html_outlinks()
453a8acb244SAndreas Gohr    {
454878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_outlinks') . '</p>';
455211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->outlinks();
456e25286daSAndreas Gohr        $this->html_resulttable($result, '', 150);
457e25286daSAndreas Gohr    }
458e25286daSAndreas Gohr
459a8acb244SAndreas Gohr    public function html_searchphrases()
460a8acb244SAndreas Gohr    {
461878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchphrases') . '</p>';
462211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchphrases(true);
46312dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
46412dcdeccSAndreas Gohr    }
46512dcdeccSAndreas Gohr
466a8acb244SAndreas Gohr    public function html_searchwords()
467a8acb244SAndreas Gohr    {
468878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchwords') . '</p>';
469211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchwords(true);
4705bccfe87SAndreas Gohr        $this->html_resulttable($result, '', 150);
4715bccfe87SAndreas Gohr    }
4725bccfe87SAndreas Gohr
473a8acb244SAndreas Gohr    public function html_internalsearchphrases()
474a8acb244SAndreas Gohr    {
475878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_internalsearchphrases') . '</p>';
476211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchphrases(false);
4775bccfe87SAndreas Gohr        $this->html_resulttable($result, '', 150);
4785bccfe87SAndreas Gohr    }
4795bccfe87SAndreas Gohr
480a8acb244SAndreas Gohr    public function html_internalsearchwords()
481a8acb244SAndreas Gohr    {
482878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_internalsearchwords') . '</p>';
483211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchwords(false);
48412dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
48512dcdeccSAndreas Gohr    }
48612dcdeccSAndreas Gohr
487a8acb244SAndreas Gohr    public function html_searchengines()
488a8acb244SAndreas Gohr    {
489878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchengines') . '</p>';
49025b71d4bSAndreas Gohr        $this->html_graph('searchengines', 400, 200);
491211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchengines();
49212dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
49312dcdeccSAndreas Gohr    }
49412dcdeccSAndreas Gohr
495a8acb244SAndreas Gohr    public function html_resolution()
496a8acb244SAndreas Gohr    {
49725446aa2SAndreas Gohr        echo '<p>' . $this->getLang('intro_resolution') . '</p>';
49825446aa2SAndreas Gohr        $this->html_graph('resolution', 650, 490);
499211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->resolution();
500307baf3fSAndreas Gohr        $this->html_resulttable($result, '', 150);
50125446aa2SAndreas Gohr    }
502307baf3fSAndreas Gohr
503a8acb244SAndreas Gohr    public function html_viewport()
504a8acb244SAndreas Gohr    {
50525446aa2SAndreas Gohr        echo '<p>' . $this->getLang('intro_viewport') . '</p>';
50625446aa2SAndreas Gohr        $this->html_graph('viewport', 650, 490);
507211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->viewport();
50825446aa2SAndreas Gohr        $this->html_resulttable($result, '', 150);
509c73e16f1SAndreas Gohr    }
5109da6395dSAndreas Gohr
511a8acb244SAndreas Gohr    public function html_seenusers()
512a8acb244SAndreas Gohr    {
51333a136e5SAndreas Gohr        echo '<p>' . $this->getLang('intro_seenusers') . '</p>';
514211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->seenusers();
51533a136e5SAndreas Gohr        $this->html_resulttable($result, '', 150);
51633a136e5SAndreas Gohr    }
51733a136e5SAndreas Gohr
51814d99ec0SAndreas Gohr    /**
51914d99ec0SAndreas Gohr     * Display a result in a HTML table
52014d99ec0SAndreas Gohr     */
521a8acb244SAndreas Gohr    public function html_resulttable($result, $header = '', $pager = 0)
522a8acb244SAndreas Gohr    {
52356f647ddSAndreas Gohr        echo '<table class="inline">';
5242812a751SAndreas Gohr        if (is_array($header)) {
52514d99ec0SAndreas Gohr            echo '<tr>';
52614d99ec0SAndreas Gohr            foreach ($header as $h) {
52714d99ec0SAndreas Gohr                echo '<th>' . hsc($h) . '</th>';
52814d99ec0SAndreas Gohr            }
52914d99ec0SAndreas Gohr            echo '</tr>';
5302812a751SAndreas Gohr        }
53114d99ec0SAndreas Gohr
5322507f8e0SAndreas Gohr        $count = 0;
5332ee939eeSAndreas Gohr        if (is_array($result)) foreach ($result as $row) {
53414d99ec0SAndreas Gohr            echo '<tr>';
53514d99ec0SAndreas Gohr            foreach ($row as $k => $v) {
536f3818071SAndreas Gohr                if ($k == 'res_x') continue;
537f3818071SAndreas Gohr                if ($k == 'res_y') continue;
538f3818071SAndreas Gohr
5392812a751SAndreas Gohr                echo '<td class="plg_stats_X' . $k . '">';
54014d99ec0SAndreas Gohr                if ($k == 'page') {
54114d99ec0SAndreas Gohr                    echo '<a href="' . wl($v) . '" class="wikilink1">';
54214d99ec0SAndreas Gohr                    echo hsc($v);
54314d99ec0SAndreas Gohr                    echo '</a>';
5441664ba1dSAndreas Gohr                } elseif ($k == 'media') {
5451664ba1dSAndreas Gohr                    echo '<a href="' . ml($v) . '" class="wikilink1">';
5461664ba1dSAndreas Gohr                    echo hsc($v);
5471664ba1dSAndreas Gohr                    echo '</a>';
5481664ba1dSAndreas Gohr                } elseif ($k == 'filesize') {
5491664ba1dSAndreas Gohr                    echo filesize_h($v);
55014d99ec0SAndreas Gohr                } elseif ($k == 'url') {
55154f6c432SAndreas Gohr                    $url = hsc($v);
55283b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/', '', $url);
5532812a751SAndreas Gohr                    if (strlen($url) > 45) {
5542812a751SAndreas Gohr                        $url = substr($url, 0, 30) . ' &hellip; ' . substr($url, -15);
55554f6c432SAndreas Gohr                    }
55614d99ec0SAndreas Gohr                    echo '<a href="' . $v . '" class="urlextern">';
55754f6c432SAndreas Gohr                    echo $url;
55814d99ec0SAndreas Gohr                    echo '</a>';
5595bccfe87SAndreas Gohr                } elseif ($k == 'ilookup') {
560a8acb244SAndreas Gohr                    echo '<a href="' . wl('', ['id' => $v, 'do' => 'search']) . '">Search</a>';
56129dea504SAndreas Gohr                } elseif ($k == 'lookup') {
56229dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q=' . rawurlencode($v) . '">';
563211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/google.png" alt="Google" />';
56429dea504SAndreas Gohr                    echo '</a> ';
56529dea504SAndreas Gohr
56629dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p=' . rawurlencode($v) . '">';
567211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/yahoo.png" alt="Yahoo!" />';
56829dea504SAndreas Gohr                    echo '</a> ';
56929dea504SAndreas Gohr
57013a86c14SAndreas Gohr                    echo '<a href="http://www.bing.com/search?q=' . rawurlencode($v) . '">';
571211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/bing.png" alt="Bing" />';
57229dea504SAndreas Gohr                    echo '</a> ';
57312dcdeccSAndreas Gohr                } elseif ($k == 'engine') {
574c4c84f98SAndreas Gohr                    $name = SearchEngines::getName($v);
575c4c84f98SAndreas Gohr                    $url = SearchEngines::getURL($v);
576c4c84f98SAndreas Gohr                    if ($url) {
577c4c84f98SAndreas Gohr                        echo '<a href="' . $url . '">' . hsc($name) . '</a>';
57813a86c14SAndreas Gohr                    } else {
579c4c84f98SAndreas Gohr                        echo hsc($name);
58013a86c14SAndreas Gohr                    }
58114d99ec0SAndreas Gohr                } elseif ($k == 'html') {
58214d99ec0SAndreas Gohr                    echo $v;
58314d99ec0SAndreas Gohr                } else {
58414d99ec0SAndreas Gohr                    echo hsc($v);
58514d99ec0SAndreas Gohr                }
58614d99ec0SAndreas Gohr                echo '</td>';
58714d99ec0SAndreas Gohr            }
58814d99ec0SAndreas Gohr            echo '</tr>';
5892507f8e0SAndreas Gohr
5902507f8e0SAndreas Gohr            if ($pager && ($count == $pager)) break;
5912507f8e0SAndreas Gohr            $count++;
59214d99ec0SAndreas Gohr        }
59314d99ec0SAndreas Gohr        echo '</table>';
5942507f8e0SAndreas Gohr
5952507f8e0SAndreas Gohr        if ($pager) $this->html_pager($pager, count($result) > $pager);
5961878f16fSAndreas Gohr    }
59713a86c14SAndreas Gohr}
598