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','searchphrases','searchwords', 30 'searchengines','browsers','os','countries', 31 'resolution'); 32 33 /** 34 * Initialize the helper 35 */ 36 public function __construct() { 37 $this->hlp = plugin_load('helper','statistics'); 38 } 39 40 /** 41 * Access for managers allowed 42 */ 43 public function forAdminOnly(){ 44 return false; 45 } 46 47 /** 48 * return sort order for position in admin menu 49 */ 50 public function getMenuSort() { 51 return 350; 52 } 53 54 /** 55 * handle user request 56 */ 57 public function handle() { 58 $this->opt = preg_replace('/[^a-z]+/','',$_REQUEST['opt']); 59 if(!in_array($this->opt,$this->pages)) $this->opt = 'dashboard'; 60 61 $this->start = (int) $_REQUEST['s']; 62 $this->setTimeframe($_REQUEST['f'],$_REQUEST['t']); 63 } 64 65 /** 66 * set limit clause 67 */ 68 public function setTimeframe($from,$to){ 69 // fixme add better sanity checking here: 70 $from = preg_replace('/[^\d\-]+/','',$from); 71 $to = preg_replace('/[^\d\-]+/','',$to); 72 if(!$from) $from = date('Y-m-d'); 73 if(!$to) $to = date('Y-m-d'); 74 75 //setup limit clause 76 $tlimit = "A.dt >= '$from 00:00:00' AND A.dt <= '$to 23:59:59'"; 77 $this->tlimit = $tlimit; 78 $this->from = $from; 79 $this->to = $to; 80 } 81 82 /** 83 * Output the Statistics 84 */ 85 function html() { 86 echo '<h1>Access Statistics</h1>'; 87 $this->html_timeselect(); 88 89 $method = 'html_'.$this->opt; 90 if(method_exists($this,$method)){ 91 echo '<div class="plg_stats_'.$this->opt.'">'; 92 echo '<h2>'.$this->getLang($this->opt).'</h2>'; 93 $this->$method(); 94 echo '</div>'; 95 } 96 } 97 98 /** 99 * Return the TOC 100 * 101 * @return array 102 */ 103 function getTOC(){ 104 $toc = array(); 105 foreach($this->pages as $page){ 106 $toc[] = array( 107 'link' => '?do=admin&page=statistics&opt='.$page.'&f='.$this->from.'&t='.$this->to, 108 'title' => $this->getLang($page), 109 'level' => 1, 110 'type' => 'ul' 111 ); 112 } 113 return $toc; 114 } 115 116 /** 117 * Outputs pagination links 118 * 119 * @fixme does this still work? 120 * 121 * @param type $limit 122 * @param type $next 123 */ 124 function html_pager($limit,$next){ 125 echo '<div class="plg_stats_pager">'; 126 127 if($this->start > 0){ 128 $go = max($this->start - $limit, 0); 129 echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$this->from.'&t='.$this->to.'&s='.$go.'" class="prev">previous page</a>'; 130 } 131 132 if($next){ 133 $go = $this->start + $limit; 134 echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$this->from.'&t='.$this->to.'&s='.$go.'" class="next">next page</a>'; 135 } 136 echo '</div>'; 137 } 138 139 /** 140 * Print the time selection menu 141 */ 142 function html_timeselect(){ 143 $now = date('Y-m-d'); 144 $yday = date('Y-m-d',time()-(60*60*24)); 145 $week = date('Y-m-d',time()-(60*60*24*7)); 146 $month = date('Y-m-d',time()-(60*60*24*30)); 147 148 echo '<div class="plg_stats_timeselect">'; 149 echo '<span>Select the timeframe:</span>'; 150 echo '<ul>'; 151 152 echo '<li>'; 153 echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$now.'&t='.$now.'">'; 154 echo 'today'; 155 echo '</a>'; 156 echo '</li>'; 157 158 echo '<li>'; 159 echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$yday.'&t='.$yday.'">'; 160 echo 'yesterday'; 161 echo '</a>'; 162 echo '</li>'; 163 164 echo '<li>'; 165 echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$week.'&t='.$now.'">'; 166 echo 'last 7 days'; 167 echo '</a>'; 168 echo '</li>'; 169 170 echo '<li>'; 171 echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$month.'&t='.$now.'">'; 172 echo 'last 30 days'; 173 echo '</a>'; 174 echo '</li>'; 175 176 echo '</ul>'; 177 178 179 echo '<form action="" method="get">'; 180 echo '<input type="hidden" name="do" value="admin" />'; 181 echo '<input type="hidden" name="page" value="statistics" />'; 182 echo '<input type="hidden" name="opt" value="'.$this->opt.'" />'; 183 echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />'; 184 echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />'; 185 echo '<input type="submit" value="go" class="button" />'; 186 echo '</form>'; 187 188 echo '</div>'; 189 } 190 191 192 /** 193 * Print an introductionary screen 194 */ 195 function html_dashboard(){ 196 echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists 197 choose a topic from the list.</p>'; 198 199 // general info 200 echo '<div class="plg_stats_top">'; 201 $result = $this->hlp->Query()->aggregate($this->tlimit); 202 echo '<ul>'; 203 echo '<li><span>'.$result['pageviews'].'</span> page views </li>'; 204 echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>'; 205 echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>'; 206 echo '<li><span>'.$result['users'].'</span> logged in users</li>'; 207 208 echo '</ul>'; 209 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&f='.$this->from.'&t='.$this->to.'" />'; 210 echo '</div>'; 211 212 213 // top pages today 214 echo '<div>'; 215 echo '<h2>Most popular pages</h2>'; 216 $result = $this->hlp->Query()->pages($this->tlimit,$this->start,15); 217 $this->html_resulttable($result); 218 echo '<a href="?do=admin&page=statistics&opt=page&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 219 echo '</div>'; 220 221 // top referer today 222 echo '<div>'; 223 echo '<h2>Newest incoming links</h2>'; 224 $result = $this->hlp->Query()->newreferer($this->tlimit,$this->start,15); 225 $this->html_resulttable($result); 226 echo '<a href="?do=admin&page=statistics&opt=newreferer&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 227 echo '</div>'; 228 229 // top searches today 230 echo '<div>'; 231 echo '<h2>Top search phrases</h2>'; 232 $result = $this->hlp->Query()->searchphrases($this->tlimit,$this->start,15); 233 $this->html_resulttable($result); 234 echo '<a href="?do=admin&page=statistics&opt=searchphrases&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 235 echo '</div>'; 236 } 237 238 function html_countries(){ 239 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=countries&f='.$this->from.'&t='.$this->to.'" />'; 240 $result = $this->hlp->Query()->countries($this->tlimit,$this->start,150); 241 $this->html_resulttable($result,'',150); 242 } 243 244 function html_page(){ 245 $result = $this->hlp->Query()->pages($this->tlimit,$this->start,150); 246 $this->html_resulttable($result,'',150); 247 } 248 249 function html_browsers(){ 250 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browsers&f='.$this->from.'&t='.$this->to.'" />'; 251 $result = $this->hlp->Query()->browsers($this->tlimit,$this->start,150,true); 252 $this->html_resulttable($result,'',150); 253 } 254 255 function html_os(){ 256 $result = $this->hlp->Query()->os($this->tlimit,$this->start,150,true); 257 $this->html_resulttable($result,'',150); 258 } 259 260 function html_referer(){ 261 $result = $this->hlp->Query()->aggregate($this->tlimit); 262 263 $all = $result['search']+$result['external']+$result['direct']; 264 265 if($all){ 266 printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses, 267 %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through 268 links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all), 269 $result['search'],(100*$result['search']/$all),$result['external'], 270 (100*$result['external']/$all)); 271 } 272 273 $result = $this->hlp->Query()->referer($this->tlimit,$this->start,150); 274 $this->html_resulttable($result,'',150); 275 } 276 277 function html_newreferer(){ 278 echo '<p>The following incoming links where first logged in the selected time frame, 279 and have never been seen before.</p>'; 280 281 $result = $this->hlp->Query()->newreferer($this->tlimit,$this->start,150); 282 $this->html_resulttable($result,'',150); 283 } 284 285 function html_outlinks(){ 286 $result = $this->hlp->Query()->outlinks($this->tlimit,$this->start,150); 287 $this->html_resulttable($result,'',150); 288 } 289 290 function html_searchphrases(){ 291 $result = $this->hlp->Query()->searchphrases($this->tlimit,$this->start,150); 292 $this->html_resulttable($result,'',150); 293 } 294 295 function html_searchwords(){ 296 $result = $this->hlp->Query()->searchwords($this->tlimit,$this->start,150); 297 $this->html_resulttable($result,'',150); 298 } 299 300 function html_searchengines(){ 301 $result = $this->hlp->Query()->searchengines($this->tlimit,$this->start,150); 302 $this->html_resulttable($result,'',150); 303 } 304 305 306 function html_resolution(){ 307 $result = $this->hlp->Query()->resolution($this->tlimit,$this->start,150); 308 $this->html_resulttable($result,'',150); 309 310 echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you 311 much about about the real size of their browser windows. The graphic below shows the size distribution of 312 the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged 313 in all browsers. Because users may resize their browser window while browsing your site the statistics may 314 be flawed. Take it with a grain of salt.</p>'; 315 316 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&f='.$this->from.'&t='.$this->to.'" />'; 317 } 318 319 320 /** 321 * Display a result in a HTML table 322 */ 323 function html_resulttable($result,$header='',$pager=0){ 324 echo '<table>'; 325 if(is_array($header)){ 326 echo '<tr>'; 327 foreach($header as $h){ 328 echo '<th>'.hsc($h).'</th>'; 329 } 330 echo '</tr>'; 331 } 332 333 $count = 0; 334 if(is_array($result)) foreach($result as $row){ 335 echo '<tr>'; 336 foreach($row as $k => $v){ 337 echo '<td class="plg_stats_X'.$k.'">'; 338 if($k == 'page'){ 339 echo '<a href="'.wl($v).'" class="wikilink1">'; 340 echo hsc($v); 341 echo '</a>'; 342 }elseif($k == 'url'){ 343 $url = hsc($v); 344 $url = preg_replace('/^https?:\/\/(www\.)?/','',$url); 345 if(strlen($url) > 45){ 346 $url = substr($url,0,30).' … '.substr($url,-15); 347 } 348 echo '<a href="'.$v.'" class="urlextern">'; 349 echo $url; 350 echo '</a>'; 351 }elseif($k == 'lookup'){ 352 echo '<a href="http://www.google.com/search?q='.rawurlencode($v).'">'; 353 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/google.png" alt="lookup in Google" border="0" />'; 354 echo '</a> '; 355 356 echo '<a href="http://search.yahoo.com/search?p='.rawurlencode($v).'">'; 357 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/yahoo.png" alt="lookup in Yahoo" border="0" />'; 358 echo '</a> '; 359 360 echo '<a href="http://search.msn.com/results.aspx?q='.rawurlencode($v).'">'; 361 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/msn.png" alt="lookup in MSN Live" border="0" />'; 362 echo '</a> '; 363 364 }elseif($k == 'engine'){ 365 include_once(dirname(__FILE__).'/inc/search_engines.php'); 366 echo $SearchEnginesHashLib[$v]; 367 }elseif($k == 'bflag'){ 368 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.strtolower(preg_replace('/[^\w]+/','',$v)).'.png" alt="'.hsc($v).'" />'; 369 }elseif($k == 'osflag'){ 370 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.strtolower(preg_replace('/[^\w]+/','',$v)).'.png" alt="'.hsc($v).'" />'; 371 }elseif($k == 'cflag'){ 372 echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />'; 373 }elseif($k == 'html'){ 374 echo $v; 375 }else{ 376 echo hsc($v); 377 } 378 echo '</td>'; 379 } 380 echo '</tr>'; 381 382 if($pager && ($count == $pager)) break; 383 $count++; 384 } 385 echo '</table>'; 386 387 if($pager) $this->html_pager($pager,count($result) > $pager); 388 } 389 390} 391