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