xref: /plugin/statistics/admin.php (revision 0863c19c7bf8b95c6f464efd1fa1fd2c4f9b4e94)
1<?php
2/**
3 * statistics plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Andreas Gohr <gohr@splitbrain.org>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12/**
13 * All DokuWiki plugins to extend the admin function
14 * need to inherit from this class
15 */
16class admin_plugin_statistics extends DokuWiki_Admin_Plugin {
17    public $dblink = null;
18    protected $opt = '';
19    protected $from = '';
20    protected $to = '';
21    protected $start = '';
22    protected $tlimit = '';
23
24    /**
25     * Available statistic pages
26     */
27    protected $pages = array(
28        'dashboard', 'page', 'referer', 'newreferer',
29        'outlinks', 'searchengines', 'searchphrases',
30        'searchwords', 'internalsearchphrases',
31        'internalsearchwords', 'browsers', 'os',
32        'countries', 'resolution', 'viewport'
33    );
34
35    /**
36     * Initialize the helper
37     */
38    public function __construct() {
39        $this->hlp = plugin_load('helper', 'statistics');
40    }
41
42    /**
43     * Access for managers allowed
44     */
45    public function forAdminOnly() {
46        return false;
47    }
48
49    /**
50     * return sort order for position in admin menu
51     */
52    public function getMenuSort() {
53        return 350;
54    }
55
56    /**
57     * handle user request
58     */
59    public function handle() {
60        $this->opt = preg_replace('/[^a-z]+/', '', $_REQUEST['opt']);
61        if(!in_array($this->opt, $this->pages)) $this->opt = 'dashboard';
62
63        $this->start = (int) $_REQUEST['s'];
64        $this->setTimeframe($_REQUEST['f'], $_REQUEST['t']);
65    }
66
67    /**
68     * set limit clause
69     */
70    public function setTimeframe($from, $to) {
71        $this->tlimit = $this->hlp->Query()->mktlimit($from, $to);
72        $this->from   = $from;
73        $this->to     = $to;
74    }
75
76    /**
77     * Output the Statistics
78     */
79    function html() {
80        echo '<div id="plugin__statistics">';
81        echo '<h1>' . $this->getLang('menu') . '</h1>';
82        $this->html_timeselect();
83        tpl_flush();
84
85        $method = 'html_' . $this->opt;
86        if(method_exists($this, $method)) {
87            echo '<div class="plg_stats_' . $this->opt . '">';
88            echo '<h2>' . $this->getLang($this->opt) . '</h2>';
89            $this->$method();
90            echo '</div>';
91        }
92        echo '</div>';
93    }
94
95    /**
96     * Return the TOC
97     *
98     * @return array
99     */
100    function getTOC() {
101        $toc = array();
102        foreach($this->pages as $page) {
103            $toc[] = array(
104                'link'  => '?do=admin&amp;page=statistics&amp;opt=' . $page . '&amp;f=' . $this->from . '&amp;t=' . $this->to,
105                'title' => $this->getLang($page),
106                'level' => 1,
107                'type'  => 'ul'
108            );
109        }
110        return $toc;
111    }
112
113    function html_graph($name, $width, $height) {
114        $url = DOKU_BASE . 'lib/plugins/statistics/img.php?img=' . $name .
115            '&amp;f=' . $this->from . '&amp;t=' . $this->to;
116        echo '<img src="' . $url . '" class="graph" width="' . $width . '" height="' . $height . '"/>';
117    }
118
119    /**
120     * Outputs pagination links
121     *
122     * @param type $limit
123     * @param type $next
124     */
125    function html_pager($limit, $next) {
126        echo '<div class="plg_stats_pager">';
127
128        if($this->start > 0) {
129            $go = max($this->start - $limit, 0);
130            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>';
131        }
132
133        if($next) {
134            $go = $this->start + $limit;
135            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>';
136        }
137        echo '</div>';
138    }
139
140    /**
141     * Print the time selection menu
142     */
143    function html_timeselect() {
144        $today  = date('Y-m-d');
145        $last1  = date('Y-m-d', time() - (60 * 60 * 24));
146        $last7  = date('Y-m-d', time() - (60 * 60 * 24 * 7));
147        $last30 = date('Y-m-d', time() - (60 * 60 * 24 * 30));
148
149        echo '<div class="plg_stats_timeselect">';
150        echo '<span>' . $this->getLang('time_select') . '</span> ';
151
152        echo '<form action="" method="get">';
153        echo '<input type="hidden" name="do" value="admin" />';
154        echo '<input type="hidden" name="page" value="statistics" />';
155        echo '<input type="hidden" name="opt" value="' . $this->opt . '" />';
156        echo '<input type="text" name="f" value="' . $this->from . '" class="edit" />';
157        echo '<input type="text" name="t" value="' . $this->to . '" class="edit" />';
158        echo '<input type="submit" value="go" class="button" />';
159        echo '</form>';
160
161        echo '<ul>';
162        foreach(array('today', 'last1', 'last7', 'last30') as $time) {
163            echo '<li>';
164            echo '<a href="?do=admin&amp;page=statistics&amp;opt=' . $this->opt . '&amp;f=' . $$time . '&amp;t=' . $today . '">';
165            echo $this->getLang('time_' . $time);
166            echo '</a>';
167            echo '</li>';
168        }
169        echo '</ul>';
170
171        echo '</div>';
172    }
173
174    /**
175     * Print an introductionary screen
176     */
177    function html_dashboard() {
178        echo '<p>' . $this->getLang('intro_dashboard') . '</p>';
179
180        // general info
181        echo '<div class="plg_stats_top">';
182        $result = $this->hlp->Query()->aggregate($this->tlimit);
183
184        echo '<ul class="left">';
185        foreach(array('pageviews', 'sessions', 'visitors', 'users', 'logins') as $name) {
186            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
187        }
188        echo '</ul>';
189
190        echo '<ul class="left">';
191        foreach(array('bouncerate', 'timespent', 'avgpages', 'newvisitors', 'registrations') as $name) {
192            echo '<li><div class="li">' . sprintf($this->getLang('dash_' . $name), $result[$name]) . '</div></li>';
193        }
194        echo '</ul>';
195
196        $this->html_graph('dashboardviews', 700, 280);
197        $this->html_graph('dashboardwiki', 700, 280);
198        echo '</div>';
199
200        // top pages today
201        echo '<div>';
202        echo '<h2>' . $this->getLang('dash_mostpopular') . '</h2>';
203        $result = $this->hlp->Query()->pages($this->tlimit, $this->start, 15);
204        $this->html_resulttable($result);
205        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>';
206        echo '</div>';
207
208        // top referer today
209        echo '<div>';
210        echo '<h2>' . $this->getLang('dash_newincoming') . '</h2>';
211        $result = $this->hlp->Query()->newreferer($this->tlimit, $this->start, 15);
212        $this->html_resulttable($result);
213        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>';
214        echo '</div>';
215
216        // top searches today
217        echo '<div>';
218        echo '<h2>' . $this->getLang('dash_topsearch') . '</h2>';
219        $result = $this->hlp->Query()->searchphrases(true, $this->tlimit, $this->start, 15);
220        $this->html_resulttable($result);
221        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>';
222        echo '</div>';
223    }
224
225    function html_countries() {
226        echo '<p>' . $this->getLang('intro_countries') . '</p>';
227        $this->html_graph('countries', 400, 200);
228        $result = $this->hlp->Query()->countries($this->tlimit, $this->start, 150);
229        $this->html_resulttable($result, '', 150);
230    }
231
232    function html_page() {
233        echo '<p>' . $this->getLang('intro_page') . '</p>';
234        $result = $this->hlp->Query()->pages($this->tlimit, $this->start, 150);
235        $this->html_resulttable($result, '', 150);
236    }
237
238    function html_browsers() {
239        echo '<p>' . $this->getLang('intro_browsers') . '</p>';
240        $this->html_graph('browsers', 400, 200);
241        $result = $this->hlp->Query()->browsers($this->tlimit, $this->start, 150, true);
242        $this->html_resulttable($result, '', 150);
243    }
244
245    function html_os() {
246        echo '<p>' . $this->getLang('intro_os') . '</p>';
247        $this->html_graph('os', 400, 200);
248        $result = $this->hlp->Query()->os($this->tlimit, $this->start, 150, true);
249        $this->html_resulttable($result, '', 150);
250    }
251
252    function html_referer() {
253        $result = $this->hlp->Query()->aggregate($this->tlimit);
254
255        $all = $result['search'] + $result['external'] + $result['direct'];
256
257        if($all) {
258            printf(
259                '<p>' . $this->getLang('intro_referer') . '</p>',
260                $all, $result['direct'], (100 * $result['direct'] / $all),
261                $result['search'], (100 * $result['search'] / $all), $result['external'],
262                (100 * $result['external'] / $all)
263            );
264        }
265
266        $result = $this->hlp->Query()->referer($this->tlimit, $this->start, 150);
267        $this->html_resulttable($result, '', 150);
268    }
269
270    function html_newreferer() {
271        echo '<p>' . $this->getLang('intro_newreferer') . '</p>';
272
273        $result = $this->hlp->Query()->newreferer($this->tlimit, $this->start, 150);
274        $this->html_resulttable($result, '', 150);
275    }
276
277    function html_outlinks() {
278        echo '<p>' . $this->getLang('intro_outlinks') . '</p>';
279        $result = $this->hlp->Query()->outlinks($this->tlimit, $this->start, 150);
280        $this->html_resulttable($result, '', 150);
281    }
282
283    function html_searchphrases() {
284        echo '<p>' . $this->getLang('intro_searchphrases') . '</p>';
285        $result = $this->hlp->Query()->searchphrases(true, $this->tlimit, $this->start, 150);
286        $this->html_resulttable($result, '', 150);
287    }
288
289    function html_searchwords() {
290        echo '<p>' . $this->getLang('intro_searchwords') . '</p>';
291        $result = $this->hlp->Query()->searchwords(true, $this->tlimit, $this->start, 150);
292        $this->html_resulttable($result, '', 150);
293    }
294
295    function html_internalsearchphrases() {
296        echo '<p>' . $this->getLang('intro_internalsearchphrases') . '</p>';
297        $result = $this->hlp->Query()->searchphrases(false, $this->tlimit, $this->start, 150);
298        $this->html_resulttable($result, '', 150);
299    }
300
301    function html_internalsearchwords() {
302        echo '<p>' . $this->getLang('intro_internalsearchwords') . '</p>';
303        $result = $this->hlp->Query()->searchwords(false, $this->tlimit, $this->start, 150);
304        $this->html_resulttable($result, '', 150);
305    }
306
307    function html_searchengines() {
308        echo '<p>' . $this->getLang('intro_searchengines') . '</p>';
309        $this->html_graph('searchengines', 400, 200);
310        $result = $this->hlp->Query()->searchengines($this->tlimit, $this->start, 150);
311        $this->html_resulttable($result, '', 150);
312    }
313
314    function html_resolution() {
315        echo '<p>' . $this->getLang('intro_resolution') . '</p>';
316        $this->html_graph('resolution', 650, 490);
317        $result = $this->hlp->Query()->resolution($this->tlimit, $this->start, 150);
318        $this->html_resulttable($result, '', 150);
319    }
320
321    function html_viewport() {
322        echo '<p>' . $this->getLang('intro_viewport') . '</p>';
323        $this->html_graph('viewport', 650, 490);
324        $result = $this->hlp->Query()->viewport($this->tlimit, $this->start, 150);
325        $this->html_resulttable($result, '', 150);
326    }
327
328    /**
329     * Display a result in a HTML table
330     */
331    function html_resulttable($result, $header = '', $pager = 0) {
332        echo '<table>';
333        if(is_array($header)) {
334            echo '<tr>';
335            foreach($header as $h) {
336                echo '<th>' . hsc($h) . '</th>';
337            }
338            echo '</tr>';
339        }
340
341        $count = 0;
342        if(is_array($result)) foreach($result as $row) {
343            echo '<tr>';
344            foreach($row as $k => $v) {
345                if($k == 'res_x') continue;
346                if($k == 'res_y') continue;
347
348                echo '<td class="plg_stats_X' . $k . '">';
349                if($k == 'page') {
350                    echo '<a href="' . wl($v) . '" class="wikilink1">';
351                    echo hsc($v);
352                    echo '</a>';
353                } elseif($k == 'url') {
354                    $url = hsc($v);
355                    $url = preg_replace('/^https?:\/\/(www\.)?/', '', $url);
356                    if(strlen($url) > 45) {
357                        $url = substr($url, 0, 30) . ' &hellip; ' . substr($url, -15);
358                    }
359                    echo '<a href="' . $v . '" class="urlextern">';
360                    echo $url;
361                    echo '</a>';
362                } elseif($k == 'ilookup') {
363                    echo '<a href="' . wl('', array('id' => $v, 'do' => 'search')) . '">Search</a>';
364                } elseif($k == 'lookup') {
365                    echo '<a href="http://www.google.com/search?q=' . rawurlencode($v) . '">';
366                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/google.png" alt="Google" border="0" />';
367                    echo '</a> ';
368
369                    echo '<a href="http://search.yahoo.com/search?p=' . rawurlencode($v) . '">';
370                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/yahoo.png" alt="Yahoo!" border="0" />';
371                    echo '</a> ';
372
373                    echo '<a href="http://www.bing.com/search?q=' . rawurlencode($v) . '">';
374                    echo '<img src="' . DOKU_BASE . 'lib/plugins/statistics/ico/search/bing.png" alt="Bing" border="0" />';
375                    echo '</a> ';
376
377                } elseif($k == 'engine') {
378                    include_once(dirname(__FILE__) . '/inc/searchengines.php');
379                    if(isset($SEARCHENGINEINFO[$v])) {
380                        echo '<a href="' . $SEARCHENGINEINFO[$v][1] . '">' . $SEARCHENGINEINFO[$v][0] . '</a>';
381                    } else {
382                        echo hsc(ucwords($v));
383                    }
384                } elseif($k == 'eflag') {
385                    $this->html_icon('search', $v);
386                } elseif($k == 'bflag') {
387                    $this->html_icon('browser', $v);
388                } elseif($k == 'osflag') {
389                    $this->html_icon('os', $v);
390                } elseif($k == 'cflag') {
391                    $this->html_icon('flags', $v);
392                } elseif($k == 'html') {
393                    echo $v;
394                } else {
395                    echo hsc($v);
396                }
397                echo '</td>';
398            }
399            echo '</tr>';
400
401            if($pager && ($count == $pager)) break;
402            $count++;
403        }
404        echo '</table>';
405
406        if($pager) $this->html_pager($pager, count($result) > $pager);
407    }
408
409    function html_icon($type, $value) {
410        $value = strtolower(preg_replace('/[^\w]+/', '', $value));
411        $value = str_replace(' ', '_', $value);
412        $file  = 'lib/plugins/statistics/ico/' . $type . '/' . $value . '.png';
413        if($type == 'flags') {
414            $w = 18;
415            $h = 12;
416        } else {
417            $w = 16;
418            $h = 16;
419        }
420        if(file_exists(DOKU_INC . $file)) {
421            echo '<img src="' . DOKU_BASE . $file . '" alt="' . hsc($value) . '" width="' . $w . '" height="' . $h . '" />';
422        }
423    }
424}
425