xref: /plugin/statistics/admin.php (revision 7428e816a000a79987e124279d701cb1f094e3b3)
11878f16fSAndreas Gohr<?php
2a8acb244SAndreas Gohr
3a8acb244SAndreas Gohruse dokuwiki\Extension\AdminPlugin;
4a8acb244SAndreas Gohr
51878f16fSAndreas Gohr/**
61878f16fSAndreas Gohr * statistics plugin
71878f16fSAndreas Gohr *
81878f16fSAndreas Gohr * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
96b6f8822SAndreas Gohr * @author     Andreas Gohr <gohr@splitbrain.org>
101878f16fSAndreas Gohr */
111878f16fSAndreas Gohr
121878f16fSAndreas Gohr// must be run within Dokuwiki
131878f16fSAndreas Gohrif (!defined('DOKU_INC')) die();
141878f16fSAndreas Gohr
151878f16fSAndreas Gohr/**
161878f16fSAndreas Gohr * All DokuWiki plugins to extend the admin function
171878f16fSAndreas Gohr * need to inherit from this class
181878f16fSAndreas Gohr */
19a8acb244SAndreas Gohrclass admin_plugin_statistics extends AdminPlugin
20a8acb244SAndreas Gohr{
2133a136e5SAndreas Gohr    /** @var string the currently selected page */
22a901d721SAndreas Gohr    protected $opt = '';
2333a136e5SAndreas Gohr
2433a136e5SAndreas Gohr    /** @var string from date in YYYY-MM-DD */
25a901d721SAndreas Gohr    protected $from = '';
2633a136e5SAndreas Gohr    /** @var string to date in YYYY-MM-DD */
27a901d721SAndreas Gohr    protected $to = '';
2833a136e5SAndreas Gohr    /** @var int Offset to use when displaying paged data */
2933a136e5SAndreas Gohr    protected $start = 0;
3033a136e5SAndreas Gohr
3133a136e5SAndreas Gohr    /** @var helper_plugin_statistics  */
3233a136e5SAndreas Gohr    protected $hlp;
3333a136e5SAndreas Gohr
34a901d721SAndreas Gohr    /**
35a901d721SAndreas Gohr     * Available statistic pages
36a901d721SAndreas Gohr     */
37a8acb244SAndreas Gohr    protected $pages = ['dashboard' => 1, 'content' => ['page', 'edits', 'images', 'downloads', 'history'], 'users' => ['topuser', 'topeditor', 'topgroup', 'topgroupedit', 'seenusers'], 'links' => ['referer', 'newreferer', 'outlinks'], 'search' => ['searchengines', 'searchphrases', 'searchwords', 'internalsearchphrases', 'internalsearchwords'], 'technology' => ['browsers', 'os', 'countries', 'resolution', 'viewport']];
381878f16fSAndreas Gohr
3981ff4c3aSAndreas Gohr    /** @var array keeps a list of all real content pages, generated from above array */
40a8acb244SAndreas Gohr    protected $allowedpages = [];
4181ff4c3aSAndreas Gohr
421878f16fSAndreas Gohr    /**
436b6f8822SAndreas Gohr     * Initialize the helper
446b6f8822SAndreas Gohr     */
45a8acb244SAndreas Gohr    public function __construct()
46a8acb244SAndreas Gohr    {
476b6f8822SAndreas Gohr        $this->hlp = plugin_load('helper', 'statistics');
4881ff4c3aSAndreas Gohr
4981ff4c3aSAndreas Gohr        // build a list of pages
5081ff4c3aSAndreas Gohr        foreach ($this->pages as $key => $val) {
5181ff4c3aSAndreas Gohr            if (is_array($val)) {
5281ff4c3aSAndreas Gohr                $this->allowedpages = array_merge($this->allowedpages, $val);
5381ff4c3aSAndreas Gohr            } else {
5481ff4c3aSAndreas Gohr                $this->allowedpages[] = $key;
5581ff4c3aSAndreas Gohr            }
5681ff4c3aSAndreas Gohr        }
576b6f8822SAndreas Gohr    }
586b6f8822SAndreas Gohr
596b6f8822SAndreas Gohr    /**
601878f16fSAndreas Gohr     * Access for managers allowed
611878f16fSAndreas Gohr     */
62a8acb244SAndreas Gohr    public function forAdminOnly()
63a8acb244SAndreas Gohr    {
641878f16fSAndreas Gohr        return false;
651878f16fSAndreas Gohr    }
661878f16fSAndreas Gohr
671878f16fSAndreas Gohr    /**
681878f16fSAndreas Gohr     * return sort order for position in admin menu
691878f16fSAndreas Gohr     */
70a8acb244SAndreas Gohr    public function getMenuSort()
71a8acb244SAndreas Gohr    {
726b6f8822SAndreas Gohr        return 350;
731878f16fSAndreas Gohr    }
741878f16fSAndreas Gohr
751878f16fSAndreas Gohr    /**
761878f16fSAndreas Gohr     * handle user request
771878f16fSAndreas Gohr     */
78a8acb244SAndreas Gohr    public function handle()
79a8acb244SAndreas Gohr    {
80264f1744SAndreas Gohr        $this->opt = preg_replace('/[^a-z]+/', '', $_REQUEST['opt']);
8181ff4c3aSAndreas Gohr        if (!in_array($this->opt, $this->allowedpages)) $this->opt = 'dashboard';
82a901d721SAndreas Gohr
8395eb68e6SAndreas Gohr        $this->start = (int) $_REQUEST['s'];
84e8699bceSAndreas Gohr        $this->setTimeframe($_REQUEST['f'], $_REQUEST['t']);
85e8699bceSAndreas Gohr    }
8695eb68e6SAndreas Gohr
87e8699bceSAndreas Gohr    /**
88e8699bceSAndreas Gohr     * set limit clause
89e8699bceSAndreas Gohr     */
90a8acb244SAndreas Gohr    public function setTimeframe($from, $to)
91a8acb244SAndreas Gohr    {
92047fcb0fSAndreas Gohr        // swap if wrong order
93a8acb244SAndreas Gohr        if ($from > $to) [$from, $to] = [$to, $from];
94047fcb0fSAndreas Gohr
95*7428e816SAndreas Gohr        $this->hlp->Query()->setTimeFrame($from, $to);
96e8699bceSAndreas Gohr        $this->from   = $from;
97e8699bceSAndreas Gohr        $this->to     = $to;
981878f16fSAndreas Gohr    }
991878f16fSAndreas Gohr
1001878f16fSAndreas Gohr    /**
10179b4a855SAndreas Gohr     * Output the Statistics
1021878f16fSAndreas Gohr     */
103a8acb244SAndreas Gohr    public function html()
104a8acb244SAndreas Gohr    {
1051d2d78ccSAndreas Gohr        echo '<div id="plugin__statistics">';
1060c3b1e44SAndreas Gohr        echo '<h1>' . $this->getLang('menu') . '</h1>';
107264f1744SAndreas Gohr        $this->html_timeselect();
108441bfb8eSAndreas Gohr        tpl_flush();
109264f1744SAndreas Gohr
11079b4a855SAndreas Gohr        $method = 'html_' . $this->opt;
11179b4a855SAndreas Gohr        if (method_exists($this, $method)) {
112a901d721SAndreas Gohr            echo '<div class="plg_stats_' . $this->opt . '">';
113a901d721SAndreas Gohr            echo '<h2>' . $this->getLang($this->opt) . '</h2>';
11479b4a855SAndreas Gohr            $this->$method();
115a901d721SAndreas Gohr            echo '</div>';
11614d99ec0SAndreas Gohr        }
1171d2d78ccSAndreas Gohr        echo '</div>';
11814d99ec0SAndreas Gohr    }
11914d99ec0SAndreas Gohr
1206b6f8822SAndreas Gohr    /**
1216b6f8822SAndreas Gohr     * Return the TOC
1226b6f8822SAndreas Gohr     *
1236b6f8822SAndreas Gohr     * @return array
1246b6f8822SAndreas Gohr     */
125a8acb244SAndreas Gohr    public function getTOC()
126a8acb244SAndreas Gohr    {
127a8acb244SAndreas Gohr        $toc = [];
12881ff4c3aSAndreas Gohr        foreach ($this->pages as $key => $info) {
12981ff4c3aSAndreas Gohr            if (is_array($info)) {
13081ff4c3aSAndreas Gohr                $toc[] = html_mktocitem(
13181ff4c3aSAndreas Gohr                    '',
13281ff4c3aSAndreas Gohr                    $this->getLang($key),
13381ff4c3aSAndreas Gohr                    1,
13481ff4c3aSAndreas Gohr                    ''
13547ffcf7dSAndreas Gohr                );
13681ff4c3aSAndreas Gohr
13781ff4c3aSAndreas Gohr                foreach ($info as $page) {
13881ff4c3aSAndreas Gohr                    $toc[] = html_mktocitem(
13981ff4c3aSAndreas Gohr                        '?do=admin&amp;page=statistics&amp;opt=' . $page . '&amp;f=' . $this->from . '&amp;t=' . $this->to,
14081ff4c3aSAndreas Gohr                        $this->getLang($page),
14181ff4c3aSAndreas Gohr                        2,
14281ff4c3aSAndreas Gohr                        ''
14381ff4c3aSAndreas Gohr                    );
14481ff4c3aSAndreas Gohr                }
14581ff4c3aSAndreas Gohr            } else {
14681ff4c3aSAndreas Gohr                $toc[] = html_mktocitem(
14781ff4c3aSAndreas Gohr                    '?do=admin&amp;page=statistics&amp;opt=' . $key . '&amp;f=' . $this->from . '&amp;t=' . $this->to,
14881ff4c3aSAndreas Gohr                    $this->getLang($key),
14981ff4c3aSAndreas Gohr                    1,
15081ff4c3aSAndreas Gohr                    ''
15181ff4c3aSAndreas Gohr                );
15281ff4c3aSAndreas Gohr            }
15347ffcf7dSAndreas Gohr        }
15447ffcf7dSAndreas Gohr        return $toc;
1559da6395dSAndreas Gohr    }
1569da6395dSAndreas Gohr
157a8acb244SAndreas Gohr    public function html_graph($name, $width, $height)
158a8acb244SAndreas Gohr    {
159dc7b1e5eSAndreas Gohr        $url = DOKU_BASE . 'lib/plugins/statistics/img.php?img=' . $name .
160dc7b1e5eSAndreas Gohr            '&amp;f=' . $this->from . '&amp;t=' . $this->to;
161dc7b1e5eSAndreas Gohr        echo '<img src="' . $url . '" class="graph" width="' . $width . '" height="' . $height . '"/>';
162dc7b1e5eSAndreas Gohr    }
163dc7b1e5eSAndreas Gohr
1646b6f8822SAndreas Gohr    /**
1656b6f8822SAndreas Gohr     * Outputs pagination links
1666b6f8822SAndreas Gohr     *
16733a136e5SAndreas Gohr     * @param int $limit
16833a136e5SAndreas Gohr     * @param int $next
1696b6f8822SAndreas Gohr     */
170a8acb244SAndreas Gohr    public function html_pager($limit, $next)
171a8acb244SAndreas Gohr    {
1722507f8e0SAndreas Gohr        echo '<div class="plg_stats_pager">';
1732507f8e0SAndreas Gohr
1742507f8e0SAndreas Gohr        if ($this->start > 0) {
1752507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
176d43cd6e0SAndreas Gohr            echo '<a href="?do=admin&amp;page=statistics&amp;opt=' . $this->opt . '&amp;f=' . $this->from . '&amp;t=' . $this->to . '&amp;s=' . $go . '" class="prev button">' . $this->getLang('prev') . '</a>';
1772507f8e0SAndreas Gohr        }
1782507f8e0SAndreas Gohr
1792507f8e0SAndreas Gohr        if ($next) {
1802507f8e0SAndreas Gohr            $go = $this->start + $limit;
181d43cd6e0SAndreas Gohr            echo '<a href="?do=admin&amp;page=statistics&amp;opt=' . $this->opt . '&amp;f=' . $this->from . '&amp;t=' . $this->to . '&amp;s=' . $go . '" class="next button">' . $this->getLang('next') . '</a>';
1822507f8e0SAndreas Gohr        }
1832507f8e0SAndreas Gohr        echo '</div>';
1842507f8e0SAndreas Gohr    }
1852507f8e0SAndreas Gohr
186264f1744SAndreas Gohr    /**
187264f1744SAndreas Gohr     * Print the time selection menu
188264f1744SAndreas Gohr     */
189a8acb244SAndreas Gohr    public function html_timeselect()
190a8acb244SAndreas Gohr    {
1916985b606SAndreas Gohr        $today  = date('Y-m-d');
1926985b606SAndreas Gohr        $last1  = date('Y-m-d', time() - (60 * 60 * 24));
1936985b606SAndreas Gohr        $last7  = date('Y-m-d', time() - (60 * 60 * 24 * 7));
1946985b606SAndreas Gohr        $last30 = date('Y-m-d', time() - (60 * 60 * 24 * 30));
19514d99ec0SAndreas Gohr
196264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
1976985b606SAndreas Gohr        echo '<span>' . $this->getLang('time_select') . '</span> ';
198264f1744SAndreas Gohr
199047fcb0fSAndreas Gohr        echo '<form action="' . DOKU_SCRIPT . '" method="get">';
200264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
201264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
202264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="' . $this->opt . '" />';
203047fcb0fSAndreas Gohr        echo '<input type="text" name="f" value="' . $this->from . '" class="edit datepicker" />';
204047fcb0fSAndreas Gohr        echo '<input type="text" name="t" value="' . $this->to . '" class="edit datepicker" />';
205264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
20614d99ec0SAndreas Gohr        echo '</form>';
207264f1744SAndreas Gohr
2086985b606SAndreas Gohr        echo '<ul>';
209a8acb244SAndreas Gohr        foreach (['today', 'last1', 'last7', 'last30'] as $time) {
2106985b606SAndreas Gohr            echo '<li>';
211a8acb244SAndreas Gohr            echo '<a href="?do=admin&amp;page=statistics&amp;opt=' . $this->opt . '&amp;f=' . ${$time} . '&amp;t=' . $today . '">';
2126985b606SAndreas Gohr            echo $this->getLang('time_' . $time);
2136985b606SAndreas Gohr            echo '</a>';
2146985b606SAndreas Gohr            echo '</li>';
2156985b606SAndreas Gohr        }
2166985b606SAndreas Gohr        echo '</ul>';
2176985b606SAndreas Gohr
218264f1744SAndreas Gohr        echo '</div>';
21914d99ec0SAndreas Gohr    }
22014d99ec0SAndreas Gohr
221f5f32cbfSAndreas Gohr    /**
222f5f32cbfSAndreas Gohr     * Print an introductionary screen
223f5f32cbfSAndreas Gohr     */
224a8acb244SAndreas Gohr    public function html_dashboard()
225a8acb244SAndreas Gohr    {
226878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_dashboard') . '</p>';
2272812a751SAndreas Gohr
2282812a751SAndreas Gohr        // general info
2292812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
230*7428e816SAndreas Gohr        $result = $this->hlp->Query()->aggregate();
2311d2d78ccSAndreas Gohr
2321d2d78ccSAndreas Gohr        echo '<ul class="left">';
233a8acb244SAndreas Gohr        foreach (['pageviews', 'sessions', 'visitors', 'users', 'logins', 'current'] as $name) {
234eabe0d07SAndreas Gohr            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
235eabe0d07SAndreas Gohr        }
2362812a751SAndreas Gohr        echo '</ul>';
2371d2d78ccSAndreas Gohr
2381d2d78ccSAndreas Gohr        echo '<ul class="left">';
239a8acb244SAndreas Gohr        foreach (['bouncerate', 'timespent', 'avgpages', 'newvisitors', 'registrations'] as $name) {
2401d2d78ccSAndreas Gohr            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
2411d2d78ccSAndreas Gohr        }
2421d2d78ccSAndreas Gohr        echo '</ul>';
2431d2d78ccSAndreas Gohr
24456f647ddSAndreas Gohr        echo '<br style="clear: left" />';
24556f647ddSAndreas Gohr
246259897e1SAndreas Gohr        $this->html_graph('dashboardviews', 700, 280);
247259897e1SAndreas Gohr        $this->html_graph('dashboardwiki', 700, 280);
2482812a751SAndreas Gohr        echo '</div>';
2492812a751SAndreas Gohr
25087d5e44bSAndreas Gohr        // top pages today
251264f1744SAndreas Gohr        echo '<div>';
252dc7b1e5eSAndreas Gohr        echo '<h2>' . $this->getLang('dash_mostpopular') . '</h2>';
253*7428e816SAndreas Gohr        $result = $this->hlp->Query()->pages($this->start, 15);
2542812a751SAndreas Gohr        $this->html_resulttable($result);
255d43cd6e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f=' . $this->from . '&amp;t=' . $this->to . '" class="more button">' . $this->getLang('more') . '</a>';
256264f1744SAndreas Gohr        echo '</div>';
25787d5e44bSAndreas Gohr
25887d5e44bSAndreas Gohr        // top referer today
259264f1744SAndreas Gohr        echo '<div>';
260dc7b1e5eSAndreas Gohr        echo '<h2>' . $this->getLang('dash_newincoming') . '</h2>';
261*7428e816SAndreas Gohr        $result = $this->hlp->Query()->newreferer($this->start, 15);
2622812a751SAndreas Gohr        $this->html_resulttable($result);
263d43cd6e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f=' . $this->from . '&amp;t=' . $this->to . '" class="more button">' . $this->getLang('more') . '</a>';
264264f1744SAndreas Gohr        echo '</div>';
26554f6c432SAndreas Gohr
26629dea504SAndreas Gohr        // top searches today
267264f1744SAndreas Gohr        echo '<div>';
268dc7b1e5eSAndreas Gohr        echo '<h2>' . $this->getLang('dash_topsearch') . '</h2>';
269*7428e816SAndreas Gohr        $result = $this->hlp->Query()->searchphrases(true, $this->start, 15);
27029dea504SAndreas Gohr        $this->html_resulttable($result);
271d43cd6e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchphrases&amp;f=' . $this->from . '&amp;t=' . $this->to . '" class="more button">' . $this->getLang('more') . '</a>';
272264f1744SAndreas Gohr        echo '</div>';
27314d99ec0SAndreas Gohr    }
27414d99ec0SAndreas Gohr
275a8acb244SAndreas Gohr    public function html_history()
276a8acb244SAndreas Gohr    {
277cae4a1c5SAndreas Gohr        echo '<p>' . $this->getLang('intro_history') . '</p>';
278338987f5SAndreas Gohr        $this->html_graph('history_page_count', 600, 200);
279338987f5SAndreas Gohr        $this->html_graph('history_page_size', 600, 200);
280338987f5SAndreas Gohr        $this->html_graph('history_media_count', 600, 200);
281338987f5SAndreas Gohr        $this->html_graph('history_media_size', 600, 200);
282cae4a1c5SAndreas Gohr    }
283cae4a1c5SAndreas Gohr
284a8acb244SAndreas Gohr    public function html_countries()
285a8acb244SAndreas Gohr    {
286878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_countries') . '</p>';
287878be5c9SAndreas Gohr        $this->html_graph('countries', 400, 200);
288*7428e816SAndreas Gohr        $result = $this->hlp->Query()->countries($this->start, 150);
2892507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
2909da6395dSAndreas Gohr    }
2919da6395dSAndreas Gohr
292a8acb244SAndreas Gohr    public function html_page()
293a8acb244SAndreas Gohr    {
294878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_page') . '</p>';
295*7428e816SAndreas Gohr        $result = $this->hlp->Query()->pages($this->start, 150);
2962507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
2979da6395dSAndreas Gohr    }
2989da6395dSAndreas Gohr
299a8acb244SAndreas Gohr    public function html_edits()
300a8acb244SAndreas Gohr    {
3011664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_edits') . '</p>';
302*7428e816SAndreas Gohr        $result = $this->hlp->Query()->edits($this->start, 150);
3031664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3041664ba1dSAndreas Gohr    }
3051664ba1dSAndreas Gohr
306a8acb244SAndreas Gohr    public function html_images()
307a8acb244SAndreas Gohr    {
3081664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_images') . '</p>';
309616c1e8bSAndreas Gohr
310*7428e816SAndreas Gohr        $result = $this->hlp->Query()->imagessum();
311616c1e8bSAndreas Gohr        echo '<p>';
312616c1e8bSAndreas Gohr        echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize']));
313616c1e8bSAndreas Gohr        echo '</p>';
314616c1e8bSAndreas Gohr
315*7428e816SAndreas Gohr        $result = $this->hlp->Query()->images($this->start, 150);
3161664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3171664ba1dSAndreas Gohr    }
3181664ba1dSAndreas Gohr
319a8acb244SAndreas Gohr    public function html_downloads()
320a8acb244SAndreas Gohr    {
3211664ba1dSAndreas Gohr        echo '<p>' . $this->getLang('intro_downloads') . '</p>';
322616c1e8bSAndreas Gohr
323*7428e816SAndreas Gohr        $result = $this->hlp->Query()->downloadssum();
324616c1e8bSAndreas Gohr        echo '<p>';
325616c1e8bSAndreas Gohr        echo sprintf($this->getLang('trafficsum'), $result[0]['cnt'], filesize_h($result[0]['filesize']));
326616c1e8bSAndreas Gohr        echo '</p>';
327616c1e8bSAndreas Gohr
328*7428e816SAndreas Gohr        $result = $this->hlp->Query()->downloads($this->start, 150);
3291664ba1dSAndreas Gohr        $this->html_resulttable($result, '', 150);
3301664ba1dSAndreas Gohr    }
3311664ba1dSAndreas Gohr
332a8acb244SAndreas Gohr    public function html_browsers()
333a8acb244SAndreas Gohr    {
334878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_browsers') . '</p>';
335878be5c9SAndreas Gohr        $this->html_graph('browsers', 400, 200);
336*7428e816SAndreas Gohr        $result = $this->hlp->Query()->browsers($this->start, 150, true);
3372507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
33875fa767dSAndreas Gohr    }
33975fa767dSAndreas Gohr
340a8acb244SAndreas Gohr    public function html_topuser()
341a8acb244SAndreas Gohr    {
34281ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topuser') . '</p>';
34381ff4c3aSAndreas Gohr        $this->html_graph('topuser', 400, 200);
344*7428e816SAndreas Gohr        $result = $this->hlp->Query()->topuser($this->start, 150);
34581ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
34681ff4c3aSAndreas Gohr    }
34781ff4c3aSAndreas Gohr
348a8acb244SAndreas Gohr    public function html_topeditor()
349a8acb244SAndreas Gohr    {
35081ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topeditor') . '</p>';
35181ff4c3aSAndreas Gohr        $this->html_graph('topeditor', 400, 200);
352*7428e816SAndreas Gohr        $result = $this->hlp->Query()->topeditor($this->start, 150);
35381ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
35481ff4c3aSAndreas Gohr    }
35581ff4c3aSAndreas Gohr
356a8acb244SAndreas Gohr    public function html_topgroup()
357a8acb244SAndreas Gohr    {
35881ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topgroup') . '</p>';
35981ff4c3aSAndreas Gohr        $this->html_graph('topgroup', 400, 200);
360*7428e816SAndreas Gohr        $result = $this->hlp->Query()->topgroup($this->start, 150);
36181ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
36281ff4c3aSAndreas Gohr    }
36381ff4c3aSAndreas Gohr
364a8acb244SAndreas Gohr    public function html_topgroupedit()
365a8acb244SAndreas Gohr    {
36681ff4c3aSAndreas Gohr        echo '<p>' . $this->getLang('intro_topgroupedit') . '</p>';
36781ff4c3aSAndreas Gohr        $this->html_graph('topgroupedit', 400, 200);
368*7428e816SAndreas Gohr        $result = $this->hlp->Query()->topgroupedit($this->start, 150);
36981ff4c3aSAndreas Gohr        $this->html_resulttable($result, '', 150);
37081ff4c3aSAndreas Gohr    }
37181ff4c3aSAndreas Gohr
372a8acb244SAndreas Gohr    public function html_os()
373a8acb244SAndreas Gohr    {
374878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_os') . '</p>';
375878be5c9SAndreas Gohr        $this->html_graph('os', 400, 200);
376*7428e816SAndreas Gohr        $result = $this->hlp->Query()->os($this->start, 150);
3772507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
378bd4217d3SAndreas Gohr    }
379bd4217d3SAndreas Gohr
380a8acb244SAndreas Gohr    public function html_referer()
381a8acb244SAndreas Gohr    {
382*7428e816SAndreas Gohr        $result = $this->hlp->Query()->aggregate();
3832812a751SAndreas Gohr
3842812a751SAndreas Gohr        $all = $result['search'] + $result['external'] + $result['direct'];
3852812a751SAndreas Gohr
38694023548SAndreas Gohr        if ($all) {
3870863c19cSAndreas Gohr            printf(
3880863c19cSAndreas Gohr                '<p>' . $this->getLang('intro_referer') . '</p>',
389a8acb244SAndreas Gohr                $all,
390a8acb244SAndreas Gohr                $result['direct'],
391a8acb244SAndreas Gohr                (100 * $result['direct'] / $all),
392a8acb244SAndreas Gohr                $result['search'],
393a8acb244SAndreas Gohr                (100 * $result['search'] / $all),
394a8acb244SAndreas Gohr                $result['external'],
3950863c19cSAndreas Gohr                (100 * $result['external'] / $all)
3960863c19cSAndreas Gohr            );
39794023548SAndreas Gohr        }
3982812a751SAndreas Gohr
399*7428e816SAndreas Gohr        $result = $this->hlp->Query()->referer($this->start, 150);
4002507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
4019da6395dSAndreas Gohr    }
4029da6395dSAndreas Gohr
403a8acb244SAndreas Gohr    public function html_newreferer()
404a8acb244SAndreas Gohr    {
405878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_newreferer') . '</p>';
406e7a2f1e0SAndreas Gohr
407*7428e816SAndreas Gohr        $result = $this->hlp->Query()->newreferer($this->start, 150);
4082507f8e0SAndreas Gohr        $this->html_resulttable($result, '', 150);
409e7a2f1e0SAndreas Gohr    }
410e7a2f1e0SAndreas Gohr
411a8acb244SAndreas Gohr    public function html_outlinks()
412a8acb244SAndreas Gohr    {
413878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_outlinks') . '</p>';
414*7428e816SAndreas Gohr        $result = $this->hlp->Query()->outlinks($this->start, 150);
415e25286daSAndreas Gohr        $this->html_resulttable($result, '', 150);
416e25286daSAndreas Gohr    }
417e25286daSAndreas Gohr
418a8acb244SAndreas Gohr    public function html_searchphrases()
419a8acb244SAndreas Gohr    {
420878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchphrases') . '</p>';
421*7428e816SAndreas Gohr        $result = $this->hlp->Query()->searchphrases(true, $this->start, 150);
42212dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
42312dcdeccSAndreas Gohr    }
42412dcdeccSAndreas Gohr
425a8acb244SAndreas Gohr    public function html_searchwords()
426a8acb244SAndreas Gohr    {
427878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchwords') . '</p>';
428*7428e816SAndreas Gohr        $result = $this->hlp->Query()->searchwords(true, $this->start, 150);
4295bccfe87SAndreas Gohr        $this->html_resulttable($result, '', 150);
4305bccfe87SAndreas Gohr    }
4315bccfe87SAndreas Gohr
432a8acb244SAndreas Gohr    public function html_internalsearchphrases()
433a8acb244SAndreas Gohr    {
434878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_internalsearchphrases') . '</p>';
435*7428e816SAndreas Gohr        $result = $this->hlp->Query()->searchphrases(false, $this->start, 150);
4365bccfe87SAndreas Gohr        $this->html_resulttable($result, '', 150);
4375bccfe87SAndreas Gohr    }
4385bccfe87SAndreas Gohr
439a8acb244SAndreas Gohr    public function html_internalsearchwords()
440a8acb244SAndreas Gohr    {
441878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_internalsearchwords') . '</p>';
442*7428e816SAndreas Gohr        $result = $this->hlp->Query()->searchwords(false, $this->start, 150);
44312dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
44412dcdeccSAndreas Gohr    }
44512dcdeccSAndreas Gohr
446a8acb244SAndreas Gohr    public function html_searchengines()
447a8acb244SAndreas Gohr    {
448878be5c9SAndreas Gohr        echo '<p>' . $this->getLang('intro_searchengines') . '</p>';
44925b71d4bSAndreas Gohr        $this->html_graph('searchengines', 400, 200);
450*7428e816SAndreas Gohr        $result = $this->hlp->Query()->searchengines($this->start, 150);
45112dcdeccSAndreas Gohr        $this->html_resulttable($result, '', 150);
45212dcdeccSAndreas Gohr    }
45312dcdeccSAndreas Gohr
454a8acb244SAndreas Gohr    public function html_resolution()
455a8acb244SAndreas Gohr    {
45625446aa2SAndreas Gohr        echo '<p>' . $this->getLang('intro_resolution') . '</p>';
45725446aa2SAndreas Gohr        $this->html_graph('resolution', 650, 490);
458*7428e816SAndreas Gohr        $result = $this->hlp->Query()->resolution($this->start, 150);
459307baf3fSAndreas Gohr        $this->html_resulttable($result, '', 150);
46025446aa2SAndreas Gohr    }
461307baf3fSAndreas Gohr
462a8acb244SAndreas Gohr    public function html_viewport()
463a8acb244SAndreas Gohr    {
46425446aa2SAndreas Gohr        echo '<p>' . $this->getLang('intro_viewport') . '</p>';
46525446aa2SAndreas Gohr        $this->html_graph('viewport', 650, 490);
466*7428e816SAndreas Gohr        $result = $this->hlp->Query()->viewport($this->start, 150);
46725446aa2SAndreas Gohr        $this->html_resulttable($result, '', 150);
468c73e16f1SAndreas Gohr    }
4699da6395dSAndreas Gohr
470a8acb244SAndreas Gohr    public function html_seenusers()
471a8acb244SAndreas Gohr    {
47233a136e5SAndreas Gohr        echo '<p>' . $this->getLang('intro_seenusers') . '</p>';
473*7428e816SAndreas Gohr        $result = $this->hlp->Query()->seenusers($this->start, 150);
47433a136e5SAndreas Gohr        $this->html_resulttable($result, '', 150);
47533a136e5SAndreas Gohr    }
47633a136e5SAndreas Gohr
47714d99ec0SAndreas Gohr    /**
47814d99ec0SAndreas Gohr     * Display a result in a HTML table
47914d99ec0SAndreas Gohr     */
480a8acb244SAndreas Gohr    public function html_resulttable($result, $header = '', $pager = 0)
481a8acb244SAndreas Gohr    {
48256f647ddSAndreas Gohr        echo '<table class="inline">';
4832812a751SAndreas Gohr        if (is_array($header)) {
48414d99ec0SAndreas Gohr            echo '<tr>';
48514d99ec0SAndreas Gohr            foreach ($header as $h) {
48614d99ec0SAndreas Gohr                echo '<th>' . hsc($h) . '</th>';
48714d99ec0SAndreas Gohr            }
48814d99ec0SAndreas Gohr            echo '</tr>';
4892812a751SAndreas Gohr        }
49014d99ec0SAndreas Gohr
4912507f8e0SAndreas Gohr        $count = 0;
4922ee939eeSAndreas Gohr        if (is_array($result)) foreach ($result as $row) {
49314d99ec0SAndreas Gohr            echo '<tr>';
49414d99ec0SAndreas Gohr            foreach ($row as $k => $v) {
495f3818071SAndreas Gohr                if ($k == 'res_x') continue;
496f3818071SAndreas Gohr                if ($k == 'res_y') continue;
497f3818071SAndreas Gohr
4982812a751SAndreas Gohr                echo '<td class="plg_stats_X' . $k . '">';
49914d99ec0SAndreas Gohr                if ($k == 'page') {
50014d99ec0SAndreas Gohr                    echo '<a href="' . wl($v) . '" class="wikilink1">';
50114d99ec0SAndreas Gohr                    echo hsc($v);
50214d99ec0SAndreas Gohr                    echo '</a>';
5031664ba1dSAndreas Gohr                } elseif ($k == 'media') {
5041664ba1dSAndreas Gohr                        echo '<a href="' . ml($v) . '" class="wikilink1">';
5051664ba1dSAndreas Gohr                        echo hsc($v);
5061664ba1dSAndreas Gohr                        echo '</a>';
5071664ba1dSAndreas Gohr                } elseif ($k == 'filesize') {
5081664ba1dSAndreas Gohr                    echo filesize_h($v);
50914d99ec0SAndreas Gohr                } elseif ($k == 'url') {
51054f6c432SAndreas Gohr                    $url = hsc($v);
51183b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/', '', $url);
5122812a751SAndreas Gohr                    if (strlen($url) > 45) {
5132812a751SAndreas Gohr                        $url = substr($url, 0, 30) . ' &hellip; ' . substr($url, -15);
51454f6c432SAndreas Gohr                    }
51514d99ec0SAndreas Gohr                    echo '<a href="' . $v . '" class="urlextern">';
51654f6c432SAndreas Gohr                    echo $url;
51714d99ec0SAndreas Gohr                    echo '</a>';
5185bccfe87SAndreas Gohr                } elseif ($k == 'ilookup') {
519a8acb244SAndreas Gohr                    echo '<a href="' . wl('', ['id' => $v, 'do' => 'search']) . '">Search</a>';
52029dea504SAndreas Gohr                } elseif ($k == 'lookup') {
52129dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q=' . rawurlencode($v) . '">';
52213a86c14SAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/google.png" alt="Google" border="0" />';
52329dea504SAndreas Gohr                    echo '</a> ';
52429dea504SAndreas Gohr
52529dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p=' . rawurlencode($v) . '">';
52613a86c14SAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/yahoo.png" alt="Yahoo!" border="0" />';
52729dea504SAndreas Gohr                    echo '</a> ';
52829dea504SAndreas Gohr
52913a86c14SAndreas Gohr                    echo '<a href="http://www.bing.com/search?q=' . rawurlencode($v) . '">';
53013a86c14SAndreas Gohr                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/bing.png" alt="Bing" border="0" />';
53129dea504SAndreas Gohr                    echo '</a> ';
53212dcdeccSAndreas Gohr                } elseif ($k == 'engine') {
533a8acb244SAndreas Gohr                    include_once(__DIR__ . '/inc/searchengines.php');
53413a86c14SAndreas Gohr                    if (isset($SEARCHENGINEINFO[$v])) {
53513a86c14SAndreas Gohr                        echo '<a href="' . $SEARCHENGINEINFO[$v][1] . '">' . $SEARCHENGINEINFO[$v][0] . '</a>';
53613a86c14SAndreas Gohr                    } else {
53713a86c14SAndreas Gohr                        echo hsc(ucwords($v));
53813a86c14SAndreas Gohr                    }
53913a86c14SAndreas Gohr                } elseif ($k == 'eflag') {
54013a86c14SAndreas Gohr                    $this->html_icon('search', $v);
54175fa767dSAndreas Gohr                } elseif ($k == 'bflag') {
54213a86c14SAndreas Gohr                    $this->html_icon('browser', $v);
543bd4217d3SAndreas Gohr                } elseif ($k == 'osflag') {
54413a86c14SAndreas Gohr                    $this->html_icon('os', $v);
54575fa767dSAndreas Gohr                } elseif ($k == 'cflag') {
54613a86c14SAndreas Gohr                    $this->html_icon('flags', $v);
54714d99ec0SAndreas Gohr                } elseif ($k == 'html') {
54814d99ec0SAndreas Gohr                    echo $v;
54914d99ec0SAndreas Gohr                } else {
55014d99ec0SAndreas Gohr                    echo hsc($v);
55114d99ec0SAndreas Gohr                }
55214d99ec0SAndreas Gohr                echo '</td>';
55314d99ec0SAndreas Gohr            }
55414d99ec0SAndreas Gohr            echo '</tr>';
5552507f8e0SAndreas Gohr
5562507f8e0SAndreas Gohr            if ($pager && ($count == $pager)) break;
5572507f8e0SAndreas Gohr            $count++;
55814d99ec0SAndreas Gohr        }
55914d99ec0SAndreas Gohr        echo '</table>';
5602507f8e0SAndreas Gohr
5612507f8e0SAndreas Gohr        if ($pager) $this->html_pager($pager, count($result) > $pager);
5621878f16fSAndreas Gohr    }
5631878f16fSAndreas Gohr
564a8acb244SAndreas Gohr    public function html_icon($type, $value)
565a8acb244SAndreas Gohr    {
56613a86c14SAndreas Gohr        $value = strtolower(preg_replace('/[^\w]+/', '', $value));
5679bb008afSAndreas Gohr        $value = str_replace(' ', '_', $value);
568a8acb244SAndreas Gohr
56913a86c14SAndreas Gohr        $file  = 'lib/plugins/statistics/ico/' . $type . '/' . $value . '.png';
570dffb869bSAndreas Gohr        if ($type == 'flags') {
571dffb869bSAndreas Gohr            $w = 18;
572dffb869bSAndreas Gohr            $h = 12;
573dffb869bSAndreas Gohr        } else {
574dffb869bSAndreas Gohr            $w = 16;
575dffb869bSAndreas Gohr            $h = 16;
576dffb869bSAndreas Gohr        }
57713a86c14SAndreas Gohr        if (file_exists(DOKU_INC . $file)) {
578dffb869bSAndreas Gohr            echo '<img src="' . DOKU_BASE . $file . '" alt="' . hsc($value) . '" width="' . $w . '" height="' . $h . '" />';
57913a86c14SAndreas Gohr        }
58013a86c14SAndreas Gohr    }
5811878f16fSAndreas Gohr}
582