xref: /plugin/statistics/admin.php (revision ba6b3b10263c8439a170c848fb8e0ce174e4f468)
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
50*ba6b3b10SAndreas Gohr        // remove pages that are not available because logging its data is disabled
51*ba6b3b10SAndreas Gohr        if($this->getConf('nolocation')) {
52*ba6b3b10SAndreas Gohr            $this->pages['technology'] = array_diff($this->pages['technology'], ['countries']);
53*ba6b3b10SAndreas Gohr        }
54*ba6b3b10SAndreas Gohr
5581ff4c3aSAndreas Gohr        // build a list of pages
5681ff4c3aSAndreas Gohr        foreach ($this->pages as $key => $val) {
5781ff4c3aSAndreas Gohr            if (is_array($val)) {
5881ff4c3aSAndreas Gohr                $this->allowedpages = array_merge($this->allowedpages, $val);
5981ff4c3aSAndreas Gohr            } else {
6081ff4c3aSAndreas Gohr                $this->allowedpages[] = $key;
6181ff4c3aSAndreas Gohr            }
6281ff4c3aSAndreas Gohr        }
636b6f8822SAndreas Gohr    }
646b6f8822SAndreas Gohr
656b6f8822SAndreas Gohr    /**
661878f16fSAndreas Gohr     * Access for managers allowed
671878f16fSAndreas Gohr     */
68a8acb244SAndreas Gohr    public function forAdminOnly()
69a8acb244SAndreas Gohr    {
701878f16fSAndreas Gohr        return false;
711878f16fSAndreas Gohr    }
721878f16fSAndreas Gohr
731878f16fSAndreas Gohr    /**
741878f16fSAndreas Gohr     * return sort order for position in admin menu
751878f16fSAndreas Gohr     */
76a8acb244SAndreas Gohr    public function getMenuSort()
77a8acb244SAndreas Gohr    {
786b6f8822SAndreas Gohr        return 350;
791878f16fSAndreas Gohr    }
801878f16fSAndreas Gohr
811878f16fSAndreas Gohr    /**
821878f16fSAndreas Gohr     * handle user request
831878f16fSAndreas Gohr     */
84a8acb244SAndreas Gohr    public function handle()
85a8acb244SAndreas Gohr    {
86483101d3SAndreas Gohr        global $INPUT;
87483101d3SAndreas Gohr        $this->opt = preg_replace('/[^a-z]+/', '', $INPUT->str('opt'));
8881ff4c3aSAndreas Gohr        if (!in_array($this->opt, $this->allowedpages)) $this->opt = 'dashboard';
89a901d721SAndreas Gohr
90483101d3SAndreas Gohr        $this->start = $INPUT->int('s');
91483101d3SAndreas Gohr        $this->setTimeframe($INPUT->str('f', date('Y-m-d')), $INPUT->str('t', date('Y-m-d')));
92e8699bceSAndreas Gohr    }
9395eb68e6SAndreas Gohr
94e8699bceSAndreas Gohr    /**
95e8699bceSAndreas Gohr     * set limit clause
96e8699bceSAndreas Gohr     */
97a8acb244SAndreas Gohr    public function setTimeframe($from, $to)
98a8acb244SAndreas Gohr    {
99047fcb0fSAndreas Gohr        // swap if wrong order
100a8acb244SAndreas Gohr        if ($from > $to) [$from, $to] = [$to, $from];
101047fcb0fSAndreas Gohr
102211caa5dSAndreas Gohr        $this->hlp->getQuery()->setTimeFrame($from, $to);
103e8699bceSAndreas Gohr        $this->from = $from;
104e8699bceSAndreas Gohr        $this->to = $to;
1051878f16fSAndreas Gohr    }
1061878f16fSAndreas Gohr
1071878f16fSAndreas Gohr    /**
10879b4a855SAndreas Gohr     * Output the Statistics
1091878f16fSAndreas Gohr     */
110a8acb244SAndreas Gohr    public function html()
111a8acb244SAndreas Gohr    {
112b0cf2118SAnna Dabrowska        echo '<script src="' . DOKU_BASE . 'lib/plugins/statistics/lib/chart.js"></script>';
113b0cf2118SAnna Dabrowska        echo '<script src="' . DOKU_BASE . 'lib/plugins/statistics/lib/chartjs-plugin-datalabels.js"></script>';
114b0cf2118SAnna Dabrowska
1151d2d78ccSAndreas Gohr        echo '<div id="plugin__statistics">';
1160c3b1e44SAndreas Gohr        echo '<h1>' . $this->getLang('menu') . '</h1>';
117264f1744SAndreas Gohr        $this->html_timeselect();
118441bfb8eSAndreas Gohr        tpl_flush();
119264f1744SAndreas Gohr
12079b4a855SAndreas Gohr        $method = 'html_' . $this->opt;
12179b4a855SAndreas Gohr        if (method_exists($this, $method)) {
122a901d721SAndreas Gohr            echo '<div class="plg_stats_' . $this->opt . '">';
123a901d721SAndreas Gohr            echo '<h2>' . $this->getLang($this->opt) . '</h2>';
12479b4a855SAndreas Gohr            $this->$method();
125a901d721SAndreas Gohr            echo '</div>';
12614d99ec0SAndreas Gohr        }
1271d2d78ccSAndreas Gohr        echo '</div>';
12814d99ec0SAndreas Gohr    }
12914d99ec0SAndreas Gohr
1306b6f8822SAndreas Gohr    /**
1316b6f8822SAndreas Gohr     * Return the TOC
1326b6f8822SAndreas Gohr     *
1336b6f8822SAndreas Gohr     * @return array
1346b6f8822SAndreas Gohr     */
135a8acb244SAndreas Gohr    public function getTOC()
136a8acb244SAndreas Gohr    {
137a8acb244SAndreas Gohr        $toc = [];
13881ff4c3aSAndreas Gohr        foreach ($this->pages as $key => $info) {
13981ff4c3aSAndreas Gohr            if (is_array($info)) {
14081ff4c3aSAndreas Gohr                $toc[] = html_mktocitem(
14181ff4c3aSAndreas Gohr                    '',
14281ff4c3aSAndreas Gohr                    $this->getLang($key),
14381ff4c3aSAndreas Gohr                    1,
14481ff4c3aSAndreas Gohr                    ''
14547ffcf7dSAndreas Gohr                );
14681ff4c3aSAndreas Gohr
14781ff4c3aSAndreas Gohr                foreach ($info as $page) {
14881ff4c3aSAndreas Gohr                    $toc[] = html_mktocitem(
149211caa5dSAndreas Gohr                        '?do=admin&amp;page=statistics&amp;opt=' . $page .
150211caa5dSAndreas Gohr                        '&amp;f=' . $this->from .
151211caa5dSAndreas Gohr                        '&amp;t=' . $this->to,
15281ff4c3aSAndreas Gohr                        $this->getLang($page),
15381ff4c3aSAndreas Gohr                        2,
15481ff4c3aSAndreas Gohr                        ''
15581ff4c3aSAndreas Gohr                    );
15681ff4c3aSAndreas Gohr                }
15781ff4c3aSAndreas Gohr            } else {
15881ff4c3aSAndreas Gohr                $toc[] = html_mktocitem(
159211caa5dSAndreas Gohr                    '?do=admin&amp;page=statistics&amp;opt=' . $key .
160211caa5dSAndreas Gohr                    '&amp;f=' . $this->from .
161211caa5dSAndreas Gohr                    '&amp;t=' . $this->to,
16281ff4c3aSAndreas Gohr                    $this->getLang($key),
16381ff4c3aSAndreas Gohr                    1,
16481ff4c3aSAndreas Gohr                    ''
16581ff4c3aSAndreas Gohr                );
16681ff4c3aSAndreas Gohr            }
16747ffcf7dSAndreas Gohr        }
16847ffcf7dSAndreas Gohr        return $toc;
1699da6395dSAndreas Gohr    }
1709da6395dSAndreas Gohr
171a8acb244SAndreas Gohr    public function html_graph($name, $width, $height)
172a8acb244SAndreas Gohr    {
173211caa5dSAndreas Gohr        $this->hlp->getGraph($this->from, $this->to, $width, $height)->$name();
174dc7b1e5eSAndreas Gohr    }
175dc7b1e5eSAndreas Gohr
1766b6f8822SAndreas Gohr    /**
1776b6f8822SAndreas Gohr     * Outputs pagination links
1786b6f8822SAndreas Gohr     *
17933a136e5SAndreas Gohr     * @param int $limit
18033a136e5SAndreas Gohr     * @param int $next
1816b6f8822SAndreas Gohr     */
182a8acb244SAndreas Gohr    public function html_pager($limit, $next)
183a8acb244SAndreas Gohr    {
184211caa5dSAndreas Gohr        $params = [
185211caa5dSAndreas Gohr            'do' => 'admin',
186211caa5dSAndreas Gohr            'page' => 'statistics',
187211caa5dSAndreas Gohr            'opt' => $this->opt,
188211caa5dSAndreas Gohr            'f' => $this->from,
189211caa5dSAndreas Gohr            't' => $this->to,
190211caa5dSAndreas Gohr        ];
1912507f8e0SAndreas Gohr
192211caa5dSAndreas Gohr        echo '<div class="plg_stats_pager">';
1932507f8e0SAndreas Gohr        if ($this->start > 0) {
1942507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
195211caa5dSAndreas Gohr            $params['s'] = $go;
196211caa5dSAndreas Gohr            echo '<a href="?' . buildURLparams($params) . '" class="prev button">' . $this->getLang('prev') . '</a>';
1972507f8e0SAndreas Gohr        }
1982507f8e0SAndreas Gohr
1992507f8e0SAndreas Gohr        if ($next) {
2002507f8e0SAndreas Gohr            $go = $this->start + $limit;
201211caa5dSAndreas Gohr            $params['s'] = $go;
202211caa5dSAndreas Gohr            echo '<a href="?' . buildURLparams($params) . '" class="next button">' . $this->getLang('next') . '</a>';
2032507f8e0SAndreas Gohr        }
2042507f8e0SAndreas Gohr        echo '</div>';
2052507f8e0SAndreas Gohr    }
2062507f8e0SAndreas Gohr
207264f1744SAndreas Gohr    /**
208264f1744SAndreas Gohr     * Print the time selection menu
209264f1744SAndreas Gohr     */
210a8acb244SAndreas Gohr    public function html_timeselect()
211a8acb244SAndreas Gohr    {
212483101d3SAndreas Gohr        $quick = [
213483101d3SAndreas Gohr            'today' => date('Y-m-d'),
214483101d3SAndreas Gohr            'last1' => date('Y-m-d', time() - (60 * 60 * 24)),
215483101d3SAndreas Gohr            'last7' => date('Y-m-d', time() - (60 * 60 * 24 * 7)),
216483101d3SAndreas Gohr            'last30' => date('Y-m-d', time() - (60 * 60 * 24 * 30)),
217483101d3SAndreas Gohr        ];
218483101d3SAndreas Gohr
21914d99ec0SAndreas Gohr
220264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
2216985b606SAndreas Gohr        echo '<span>' . $this->getLang('time_select') . '</span> ';
222264f1744SAndreas Gohr
223047fcb0fSAndreas Gohr        echo '<form action="' . DOKU_SCRIPT . '" method="get">';
224264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
225264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
226264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="' . $this->opt . '" />';
227483101d3SAndreas Gohr        echo '<input type="date" name="f" value="' . $this->from . '" class="edit" />';
228483101d3SAndreas Gohr        echo '<input type="date" name="t" value="' . $this->to . '" class="edit" />';
229264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
23014d99ec0SAndreas Gohr        echo '</form>';
231264f1744SAndreas Gohr
2326985b606SAndreas Gohr        echo '<ul>';
233483101d3SAndreas Gohr        foreach ($quick as $name => $time) {
234eaa05ffcSAndreas Gohr            // today is included only today
235eaa05ffcSAndreas Gohr            $to = $name == 'today' ? $quick['today'] : $quick['last1'];
236eaa05ffcSAndreas Gohr
237211caa5dSAndreas Gohr            $url = buildURLparams([
238211caa5dSAndreas Gohr                'do' => 'admin',
239211caa5dSAndreas Gohr                'page' => 'statistics',
240211caa5dSAndreas Gohr                'opt' => $this->opt,
241211caa5dSAndreas Gohr                'f' => $time,
242eaa05ffcSAndreas Gohr                't' => $to,
243211caa5dSAndreas Gohr            ]);
244211caa5dSAndreas Gohr
2456985b606SAndreas Gohr            echo '<li>';
246211caa5dSAndreas Gohr            echo '<a href="?' . $url . '">';
247483101d3SAndreas Gohr            echo $this->getLang('time_' . $name);
2486985b606SAndreas Gohr            echo '</a>';
2496985b606SAndreas Gohr            echo '</li>';
2506985b606SAndreas Gohr        }
2516985b606SAndreas Gohr        echo '</ul>';
2526985b606SAndreas Gohr
253264f1744SAndreas Gohr        echo '</div>';
25414d99ec0SAndreas Gohr    }
25514d99ec0SAndreas Gohr
256f5f32cbfSAndreas Gohr    /**
257f5f32cbfSAndreas Gohr     * Print an introductionary screen
258f5f32cbfSAndreas Gohr     */
259a8acb244SAndreas Gohr    public function html_dashboard()
260a8acb244SAndreas Gohr    {
261878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_dashboard') . '</p>';
2622812a751SAndreas Gohr
2632812a751SAndreas Gohr        // general info
2642812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
265211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->aggregate();
2661d2d78ccSAndreas Gohr
2671fd51258SAndreas Gohr        echo '<ul>';
268a8acb244SAndreas Gohr        foreach (['pageviews', 'sessions', 'visitors', 'users', 'logins', 'current'] as $name) {
269eabe0d07SAndreas Gohr            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
270eabe0d07SAndreas Gohr        }
2712812a751SAndreas Gohr        echo '</ul>';
2721d2d78ccSAndreas Gohr
2731fd51258SAndreas Gohr        echo '<ul>';
274a8acb244SAndreas Gohr        foreach (['bouncerate', 'timespent', 'avgpages', 'newvisitors', 'registrations'] as $name) {
2751d2d78ccSAndreas Gohr            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
2761d2d78ccSAndreas Gohr        }
2771d2d78ccSAndreas Gohr        echo '</ul>';
2781d2d78ccSAndreas Gohr
279259897e1SAndreas Gohr        $this->html_graph('dashboardviews', 700, 280);
280259897e1SAndreas Gohr        $this->html_graph('dashboardwiki', 700, 280);
2812812a751SAndreas Gohr        echo '</div>';
2822812a751SAndreas Gohr
283211caa5dSAndreas Gohr        $quickgraphs = [
284211caa5dSAndreas Gohr            ['lbl' => 'dash_mostpopular', 'query' => 'pages', 'opt' => 'page'],
285211caa5dSAndreas Gohr            ['lbl' => 'dash_newincoming', 'query' => 'newreferer', 'opt' => 'newreferer'],
286211caa5dSAndreas Gohr            ['lbl' => 'dash_topsearch', 'query' => 'searchphrases', 'opt' => 'internalsearchphrases'],
287211caa5dSAndreas Gohr        ];
28887d5e44bSAndreas Gohr
289211caa5dSAndreas Gohr        foreach ($quickgraphs as $graph) {
290211caa5dSAndreas Gohr            $params = [
291211caa5dSAndreas Gohr                'do' => 'admin',
292211caa5dSAndreas Gohr                'page' => 'statistics',
293211caa5dSAndreas Gohr                'f' => $this->from,
294211caa5dSAndreas Gohr                't' => $this->to,
295211caa5dSAndreas Gohr                'opt' => $graph['opt'],
296211caa5dSAndreas Gohr            ];
29754f6c432SAndreas Gohr
298264f1744SAndreas Gohr            echo '<div>';
299211caa5dSAndreas Gohr            echo '<h2>' . $this->getLang($graph['lbl']) . '</h2>';
300211caa5dSAndreas Gohr            $result = call_user_func([$this->hlp->getQuery(), $graph['query']]);
30129dea504SAndreas Gohr            $this->html_resulttable($result);
3021fd51258SAndreas Gohr            echo '<p><a href="?' . buildURLparams($params) . '" class="more">' . $this->getLang('more') . '…</a></p>';
303264f1744SAndreas Gohr            echo '</div>';
30414d99ec0SAndreas Gohr        }
305211caa5dSAndreas Gohr    }
30614d99ec0SAndreas Gohr
307a8acb244SAndreas Gohr    public function html_history()
308a8acb244SAndreas Gohr    {
309cae4a1c5SAndreas Gohr        echo '<p>' . $this->getLang('intro_history') . '</p>';
310338987f5SAndreas Gohr        $this->html_graph('history_page_count', 600, 200);
311338987f5SAndreas Gohr        $this->html_graph('history_page_size', 600, 200);
312338987f5SAndreas Gohr        $this->html_graph('history_media_count', 600, 200);
313338987f5SAndreas Gohr        $this->html_graph('history_media_size', 600, 200);
314cae4a1c5SAndreas Gohr    }
315cae4a1c5SAndreas Gohr
316a8acb244SAndreas Gohr    public function html_countries()
317a8acb244SAndreas Gohr    {
318878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_countries') . '</p>';
3191d379254SAnna Dabrowska        $this->html_graph('countries', 300, 300);
320211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->countries();
3212507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
3229da6395dSAndreas Gohr    }
3239da6395dSAndreas Gohr
324a8acb244SAndreas Gohr    public function html_page()
325a8acb244SAndreas Gohr    {
326878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_page') . '</p>';
327211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->pages();
3282507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
3299da6395dSAndreas Gohr    }
3309da6395dSAndreas Gohr
331a8acb244SAndreas Gohr    public function html_edits()
332a8acb244SAndreas Gohr    {
3331664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_edits') . '</p>';
334211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->edits();
3351664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3361664ba1dSAndreas Gohr    }
3371664ba1dSAndreas Gohr
338a8acb244SAndreas Gohr    public function html_images()
339a8acb244SAndreas Gohr    {
3401664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_images') . '</p>';
341616c1e8bSAndreas Gohr
342211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->imagessum();
343616c1e8bSAndreas Gohr        echo '<p>';
344616c1e8bSAndreas Gohr        echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize']));
345616c1e8bSAndreas Gohr        echo '</p>';
346616c1e8bSAndreas Gohr
347211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->images();
3481664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3491664ba1dSAndreas Gohr    }
3501664ba1dSAndreas Gohr
351a8acb244SAndreas Gohr    public function html_downloads()
352a8acb244SAndreas Gohr    {
3531664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_downloads') . '</p>';
354616c1e8bSAndreas Gohr
355211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->downloadssum();
356616c1e8bSAndreas Gohr        echo '<p>';
357616c1e8bSAndreas Gohr        echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize']));
358616c1e8bSAndreas Gohr        echo '</p>';
359616c1e8bSAndreas Gohr
360211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->downloads();
3611664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3621664ba1dSAndreas Gohr    }
3631664ba1dSAndreas Gohr
364a8acb244SAndreas Gohr    public function html_browsers()
365a8acb244SAndreas Gohr    {
366878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_browsers') . '</p>';
3671d379254SAnna Dabrowska        $this->html_graph('browsers', 300, 300);
368211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->browsers(false);
3692507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
37075fa767dSAndreas Gohr    }
37175fa767dSAndreas Gohr
3729fdd7e51SAndreas Gohr    public function html_topdomain()
3739fdd7e51SAndreas Gohr    {
3749fdd7e51SAndreas Gohr        echo '<p>' . $this->getLang('intro_topdomain') . '</p>';
3759fdd7e51SAndreas Gohr        $this->html_graph('topdomain', 300, 300);
3769fdd7e51SAndreas Gohr        $result = $this->hlp->getQuery()->topdomain();
3779fdd7e51SAndreas Gohr        $this->html_resulttable($result, '', 150);
3789fdd7e51SAndreas Gohr    }
3799fdd7e51SAndreas Gohr
380a8acb244SAndreas Gohr    public function html_topuser()
381a8acb244SAndreas Gohr    {
38281ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topuser') . '</p>';
3831d379254SAnna Dabrowska        $this->html_graph('topuser', 300, 300);
384211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topuser();
38581ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
38681ff4c3aSAndreas Gohr    }
38781ff4c3aSAndreas Gohr
388a8acb244SAndreas Gohr    public function html_topeditor()
389a8acb244SAndreas Gohr    {
39081ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topeditor') . '</p>';
3911d379254SAnna Dabrowska        $this->html_graph('topeditor', 300, 300);
392211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topeditor();
39381ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
39481ff4c3aSAndreas Gohr    }
39581ff4c3aSAndreas Gohr
396a8acb244SAndreas Gohr    public function html_topgroup()
397a8acb244SAndreas Gohr    {
39881ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topgroup') . '</p>';
3991d379254SAnna Dabrowska        $this->html_graph('topgroup', 300, 300);
400211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topgroup();
40181ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
40281ff4c3aSAndreas Gohr    }
40381ff4c3aSAndreas Gohr
404a8acb244SAndreas Gohr    public function html_topgroupedit()
405a8acb244SAndreas Gohr    {
40681ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topgroupedit') . '</p>';
4071d379254SAnna Dabrowska        $this->html_graph('topgroupedit', 300, 300);
408211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->topgroupedit();
40981ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
41081ff4c3aSAndreas Gohr    }
41181ff4c3aSAndreas Gohr
412a8acb244SAndreas Gohr    public function html_os()
413a8acb244SAndreas Gohr    {
414878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_os') . '</p>';
4151d379254SAnna Dabrowska        $this->html_graph('os', 300, 300);
416211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->os();
4172507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
418bd4217d3SAndreas Gohr    }
419bd4217d3SAndreas Gohr
420a8acb244SAndreas Gohr    public function html_referer()
421a8acb244SAndreas Gohr    {
422211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->aggregate();
4232812a751SAndreas Gohr
4242a30f557SAndreas Gohr        if ($result['referers']) {
4250863c19cSAndreas Gohr            printf(
4260863c19cSAndreas Gohr                '<p>' . $this->getLang('intro_referer') . '</p>',
4272a30f557SAndreas Gohr                $result['referers'],
428a8acb244SAndreas Gohr                $result['direct'],
4292a30f557SAndreas Gohr                (100 * $result['direct'] / $result['referers']),
430a8acb244SAndreas Gohr                $result['search'],
4312a30f557SAndreas Gohr                (100 * $result['search'] / $result['referers']),
432a8acb244SAndreas Gohr                $result['external'],
4332a30f557SAndreas Gohr                (100 * $result['external'] / $result['referers'])
4340863c19cSAndreas Gohr            );
43594023548SAndreas Gohr        }
4362812a751SAndreas Gohr
437211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->referer();
4382507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
4399da6395dSAndreas Gohr    }
4409da6395dSAndreas Gohr
441a8acb244SAndreas Gohr    public function html_newreferer()
442a8acb244SAndreas Gohr    {
443878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_newreferer') . '</p>';
444e7a2f1e0SAndreas Gohr
445211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->newreferer();
4462507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
447e7a2f1e0SAndreas Gohr    }
448e7a2f1e0SAndreas Gohr
449a8acb244SAndreas Gohr    public function html_outlinks()
450a8acb244SAndreas Gohr    {
451878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_outlinks') . '</p>';
452211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->outlinks();
453e25286daSAndreas Gohr        $this->html_resulttable($result, '', 150);
454e25286daSAndreas Gohr    }
455e25286daSAndreas Gohr
456a8acb244SAndreas Gohr    public function html_searchphrases()
457a8acb244SAndreas Gohr    {
458878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchphrases') . '</p>';
459211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchphrases(true);
46012dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
46112dcdeccSAndreas Gohr    }
46212dcdeccSAndreas Gohr
463a8acb244SAndreas Gohr    public function html_searchwords()
464a8acb244SAndreas Gohr    {
465878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchwords') . '</p>';
466211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchwords(true);
4675bccfe87SAndreas Gohr        $this->html_resulttable($result, '', 150);
4685bccfe87SAndreas Gohr    }
4695bccfe87SAndreas Gohr
470a8acb244SAndreas Gohr    public function html_internalsearchphrases()
471a8acb244SAndreas Gohr    {
472878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_internalsearchphrases') . '</p>';
473211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchphrases(false);
4745bccfe87SAndreas Gohr        $this->html_resulttable($result, '', 150);
4755bccfe87SAndreas Gohr    }
4765bccfe87SAndreas Gohr
477a8acb244SAndreas Gohr    public function html_internalsearchwords()
478a8acb244SAndreas Gohr    {
479878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_internalsearchwords') . '</p>';
480211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchwords(false);
48112dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
48212dcdeccSAndreas Gohr    }
48312dcdeccSAndreas Gohr
484a8acb244SAndreas Gohr    public function html_searchengines()
485a8acb244SAndreas Gohr    {
486878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchengines') . '</p>';
48725b71d4bSAndreas Gohr        $this->html_graph('searchengines', 400, 200);
488211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->searchengines();
48912dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
49012dcdeccSAndreas Gohr    }
49112dcdeccSAndreas Gohr
492a8acb244SAndreas Gohr    public function html_resolution()
493a8acb244SAndreas Gohr    {
49425446aa2SAndreas Gohr        echo '<p>' . $this->getLang('intro_resolution') . '</p>';
49525446aa2SAndreas Gohr        $this->html_graph('resolution', 650, 490);
496211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->resolution();
497307baf3fSAndreas Gohr        $this->html_resulttable($result, '', 150);
49825446aa2SAndreas Gohr    }
499307baf3fSAndreas Gohr
500a8acb244SAndreas Gohr    public function html_viewport()
501a8acb244SAndreas Gohr    {
50225446aa2SAndreas Gohr        echo '<p>' . $this->getLang('intro_viewport') . '</p>';
50325446aa2SAndreas Gohr        $this->html_graph('viewport', 650, 490);
504211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->viewport();
50525446aa2SAndreas Gohr        $this->html_resulttable($result, '', 150);
506c73e16f1SAndreas Gohr    }
5079da6395dSAndreas Gohr
508a8acb244SAndreas Gohr    public function html_seenusers()
509a8acb244SAndreas Gohr    {
51033a136e5SAndreas Gohr        echo '<p>' . $this->getLang('intro_seenusers') . '</p>';
511211caa5dSAndreas Gohr        $result = $this->hlp->getQuery()->seenusers();
51233a136e5SAndreas Gohr        $this->html_resulttable($result, '', 150);
51333a136e5SAndreas Gohr    }
51433a136e5SAndreas Gohr
51514d99ec0SAndreas Gohr    /**
51614d99ec0SAndreas Gohr     * Display a result in a HTML table
51714d99ec0SAndreas Gohr     */
518a8acb244SAndreas Gohr    public function html_resulttable($result, $header = '', $pager = 0)
519a8acb244SAndreas Gohr    {
52056f647ddSAndreas Gohr        echo '<table class="inline">';
5212812a751SAndreas Gohr        if (is_array($header)) {
52214d99ec0SAndreas Gohr            echo '<tr>';
52314d99ec0SAndreas Gohr            foreach ($header as $h) {
52414d99ec0SAndreas Gohr                echo '<th>' . hsc($h) . '</th>';
52514d99ec0SAndreas Gohr            }
52614d99ec0SAndreas Gohr            echo '</tr>';
5272812a751SAndreas Gohr        }
52814d99ec0SAndreas Gohr
5292507f8e0SAndreas Gohr        $count = 0;
5302ee939eeSAndreas Gohr        if (is_array($result)) foreach ($result as $row) {
53114d99ec0SAndreas Gohr            echo '<tr>';
53214d99ec0SAndreas Gohr            foreach ($row as $k => $v) {
533f3818071SAndreas Gohr                if ($k == 'res_x') continue;
534f3818071SAndreas Gohr                if ($k == 'res_y') continue;
535f3818071SAndreas Gohr
5362812a751SAndreas Gohr                echo '<td class="plg_stats_X' . $k . '">';
53714d99ec0SAndreas Gohr                if ($k == 'page') {
53814d99ec0SAndreas Gohr                    echo '<a href="' . wl($v) . '" class="wikilink1">';
53914d99ec0SAndreas Gohr                    echo hsc($v);
54014d99ec0SAndreas Gohr                    echo '</a>';
5411664ba1dSAndreas Gohr                } elseif ($k == 'media') {
5421664ba1dSAndreas Gohr                    echo '<a href="' . ml($v) . '" class="wikilink1">';
5431664ba1dSAndreas Gohr                    echo hsc($v);
5441664ba1dSAndreas Gohr                    echo '</a>';
5451664ba1dSAndreas Gohr                } elseif ($k == 'filesize') {
5461664ba1dSAndreas Gohr                    echo filesize_h($v);
54714d99ec0SAndreas Gohr                } elseif ($k == 'url') {
54854f6c432SAndreas Gohr                    $url = hsc($v);
54983b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/', '', $url);
5502812a751SAndreas Gohr                    if (strlen($url) > 45) {
5512812a751SAndreas Gohr                        $url = substr($url, 0, 30) . ' &hellip; ' . substr($url, -15);
55254f6c432SAndreas Gohr                    }
55314d99ec0SAndreas Gohr                    echo '<a href="' . $v . '" class="urlextern">';
55454f6c432SAndreas Gohr                    echo $url;
55514d99ec0SAndreas Gohr                    echo '</a>';
5565bccfe87SAndreas Gohr                } elseif ($k == 'ilookup') {
557a8acb244SAndreas Gohr                    echo '<a href="' . wl('', ['id' => $v, 'do' => 'search']) . '">Search</a>';
55829dea504SAndreas Gohr                } elseif ($k == 'lookup') {
55929dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q=' . rawurlencode($v) . '">';
560211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/google.png" alt="Google" />';
56129dea504SAndreas Gohr                    echo '</a> ';
56229dea504SAndreas Gohr
56329dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p=' . rawurlencode($v) . '">';
564211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/yahoo.png" alt="Yahoo!" />';
56529dea504SAndreas Gohr                    echo '</a> ';
56629dea504SAndreas Gohr
56713a86c14SAndreas Gohr                    echo '<a href="http://www.bing.com/search?q=' . rawurlencode($v) . '">';
568211caa5dSAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/bing.png" alt="Bing" />';
56929dea504SAndreas Gohr                    echo '</a> ';
57012dcdeccSAndreas Gohr                } elseif ($k == 'engine') {
571c4c84f98SAndreas Gohr                    $name = SearchEngines::getName($v);
572c4c84f98SAndreas Gohr                    $url = SearchEngines::getURL($v);
573c4c84f98SAndreas Gohr                    if ($url) {
574c4c84f98SAndreas Gohr                        echo '<a href="' . $url . '">' . hsc($name) . '</a>';
57513a86c14SAndreas Gohr                    } else {
576c4c84f98SAndreas Gohr                        echo hsc($name);
57713a86c14SAndreas Gohr                    }
57814d99ec0SAndreas Gohr                } elseif ($k == 'html') {
57914d99ec0SAndreas Gohr                    echo $v;
58014d99ec0SAndreas Gohr                } else {
58114d99ec0SAndreas Gohr                    echo hsc($v);
58214d99ec0SAndreas Gohr                }
58314d99ec0SAndreas Gohr                echo '</td>';
58414d99ec0SAndreas Gohr            }
58514d99ec0SAndreas Gohr            echo '</tr>';
5862507f8e0SAndreas Gohr
5872507f8e0SAndreas Gohr            if ($pager && ($count == $pager)) break;
5882507f8e0SAndreas Gohr            $count++;
58914d99ec0SAndreas Gohr        }
59014d99ec0SAndreas Gohr        echo '</table>';
5912507f8e0SAndreas Gohr
5922507f8e0SAndreas Gohr        if ($pager) $this->html_pager($pager, count($result) > $pager);
5931878f16fSAndreas Gohr    }
59413a86c14SAndreas Gohr}
595