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&page=statistics&opt='.$page.'&f='.$this->from.'&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 '&f='.$this->from.'&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&page=statistics&opt='.$this->opt.'&f='.$this->from.'&t='.$this->to.'&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&page=statistics&opt='.$this->opt.'&f='.$this->from.'&t='.$this->to.'&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&page=statistics&opt='.$this->opt.'&f='.$$time.'&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&page=statistics&opt=page&f='.$this->from.'&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&page=statistics&opt=newreferer&f='.$this->from.'&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&page=statistics&opt=searchphrases&f='.$this->from.'&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).' … '.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(file_exists(DOKU_INC.$file)){ 416 echo '<img src="'.DOKU_BASE.$file.'" alt="'.hsc($value).'" width="16" height="16" />'; 417 } 418 } 419} 420