11878f16fSAndreas Gohr<?php 21878f16fSAndreas Gohr/** 31878f16fSAndreas Gohr * statistics plugin 41878f16fSAndreas Gohr * 51878f16fSAndreas Gohr * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 61878f16fSAndreas Gohr * @author Andreas Gohr <gohr@cosmocode.de> 71878f16fSAndreas Gohr */ 81878f16fSAndreas Gohr 91878f16fSAndreas Gohr// must be run within Dokuwiki 101878f16fSAndreas Gohrif(!defined('DOKU_INC')) die(); 111878f16fSAndreas Gohr 121878f16fSAndreas Gohrif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 131878f16fSAndreas Gohrrequire_once(DOKU_PLUGIN.'admin.php'); 141878f16fSAndreas Gohr 151878f16fSAndreas Gohr/** 161878f16fSAndreas Gohr * All DokuWiki plugins to extend the admin function 171878f16fSAndreas Gohr * need to inherit from this class 181878f16fSAndreas Gohr */ 191878f16fSAndreas Gohrclass admin_plugin_statistics extends DokuWiki_Admin_Plugin { 201878f16fSAndreas Gohr var $dblink = null; 21264f1744SAndreas Gohr var $opt = ''; 22264f1744SAndreas Gohr var $from = ''; 23264f1744SAndreas Gohr var $to = ''; 2495eb68e6SAndreas Gohr var $start = ''; 25264f1744SAndreas Gohr var $tlimit = ''; 261878f16fSAndreas Gohr 271878f16fSAndreas Gohr /** 281878f16fSAndreas Gohr * return some info 291878f16fSAndreas Gohr */ 301878f16fSAndreas Gohr function getInfo(){ 311878f16fSAndreas Gohr return confToHash(dirname(__FILE__).'/info.txt'); 321878f16fSAndreas Gohr } 331878f16fSAndreas Gohr 341878f16fSAndreas Gohr /** 351878f16fSAndreas Gohr * Access for managers allowed 361878f16fSAndreas Gohr */ 371878f16fSAndreas Gohr function forAdminOnly(){ 381878f16fSAndreas Gohr return false; 391878f16fSAndreas Gohr } 401878f16fSAndreas Gohr 411878f16fSAndreas Gohr /** 421878f16fSAndreas Gohr * return sort order for position in admin menu 431878f16fSAndreas Gohr */ 441878f16fSAndreas Gohr function getMenuSort() { 4514d99ec0SAndreas Gohr return 150; 461878f16fSAndreas Gohr } 471878f16fSAndreas Gohr 481878f16fSAndreas Gohr /** 491878f16fSAndreas Gohr * handle user request 501878f16fSAndreas Gohr */ 511878f16fSAndreas Gohr function handle() { 52264f1744SAndreas Gohr $this->opt = preg_replace('/[^a-z]+/','',$_REQUEST['opt']); 5395eb68e6SAndreas Gohr 5495eb68e6SAndreas Gohr $this->start = (int) $_REQUEST['s']; 5595eb68e6SAndreas Gohr 56264f1744SAndreas Gohr // fixme add better sanity checking here: 57264f1744SAndreas Gohr $this->from = preg_replace('/[^\d\-]+/','',$_REQUEST['f']); 58264f1744SAndreas Gohr $this->to = preg_replace('/[^\d\-]+/','',$_REQUEST['t']); 59264f1744SAndreas Gohr if(!$this->from) $this->from = date('Y-m-d'); 60264f1744SAndreas Gohr if(!$this->to) $this->to = date('Y-m-d'); 61264f1744SAndreas Gohr 62264f1744SAndreas Gohr //setup limit clause 63264f1744SAndreas Gohr if($this->from != $this->to){ 64264f1744SAndreas Gohr $this->tlimit = "DATE(A.dt) >= DATE('".$this->from."') AND DATE(A.dt) <= DATE('".$this->to."')"; 65264f1744SAndreas Gohr }else{ 66264f1744SAndreas Gohr $this->tlimit = "DATE(A.dt) = DATE('".$this->from."')"; 67264f1744SAndreas Gohr } 681878f16fSAndreas Gohr } 691878f16fSAndreas Gohr 701878f16fSAndreas Gohr /** 7194171ff3SAndreas Gohr * fixme build statistics here 721878f16fSAndreas Gohr */ 731878f16fSAndreas Gohr function html() { 749da6395dSAndreas Gohr $this->html_toc(); 75264f1744SAndreas Gohr echo '<h1>Access Statistics</h1>'; 76264f1744SAndreas Gohr $this->html_timeselect(); 77264f1744SAndreas Gohr 78264f1744SAndreas Gohr switch($this->opt){ 799da6395dSAndreas Gohr case 'country': 809da6395dSAndreas Gohr $this->html_country(); 819da6395dSAndreas Gohr break; 829da6395dSAndreas Gohr case 'page': 839da6395dSAndreas Gohr $this->html_page(); 849da6395dSAndreas Gohr break; 8575fa767dSAndreas Gohr case 'browser': 8675fa767dSAndreas Gohr $this->html_browser(); 8775fa767dSAndreas Gohr break; 88bd4217d3SAndreas Gohr case 'os': 89bd4217d3SAndreas Gohr $this->html_os(); 90bd4217d3SAndreas Gohr break; 919da6395dSAndreas Gohr case 'referer': 929da6395dSAndreas Gohr $this->html_referer(); 939da6395dSAndreas Gohr break; 94e7a2f1e0SAndreas Gohr case 'newreferer': 95e7a2f1e0SAndreas Gohr $this->html_newreferer(); 96e7a2f1e0SAndreas Gohr break; 97e25286daSAndreas Gohr case 'outlinks': 98e25286daSAndreas Gohr $this->html_outlinks(); 99e25286daSAndreas Gohr break; 100c73e16f1SAndreas Gohr case 'resolution': 101c73e16f1SAndreas Gohr $this->html_resolution(); 102c73e16f1SAndreas Gohr break; 10314d99ec0SAndreas Gohr default: 1049da6395dSAndreas Gohr $this->html_dashboard(); 10514d99ec0SAndreas Gohr } 10614d99ec0SAndreas Gohr } 10714d99ec0SAndreas Gohr 1089da6395dSAndreas Gohr function html_toc(){ 1099da6395dSAndreas Gohr echo '<div class="toc">'; 1109da6395dSAndreas Gohr echo '<div class="tocheader toctoggle" id="toc__header">'; 1119da6395dSAndreas Gohr echo 'Detailed Statistics'; 1129da6395dSAndreas Gohr echo '</div>'; 1139da6395dSAndreas Gohr echo '<div id="toc__inside">'; 1149da6395dSAndreas Gohr echo '<ul class="toc">'; 1159da6395dSAndreas Gohr 1169da6395dSAndreas Gohr echo '<li><div class="li">'; 1172507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=&f='.$this->from.'&t='.$this->to.'">Dashboard</a>'; 1189da6395dSAndreas Gohr echo '</div></li>'; 1199da6395dSAndreas Gohr 1209da6395dSAndreas Gohr echo '<li><div class="li">'; 1212507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=page&f='.$this->from.'&t='.$this->to.'">Pages</a>'; 1229da6395dSAndreas Gohr echo '</div></li>'; 1239da6395dSAndreas Gohr 1249da6395dSAndreas Gohr echo '<li><div class="li">'; 1252507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=referer&f='.$this->from.'&t='.$this->to.'">Incoming Links</a>'; 1269da6395dSAndreas Gohr echo '</div></li>'; 1279da6395dSAndreas Gohr 1289da6395dSAndreas Gohr echo '<li><div class="li">'; 1292507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=newreferer&f='.$this->from.'&t='.$this->to.'">New Incoming Links</a>'; 130e7a2f1e0SAndreas Gohr echo '</div></li>'; 131e7a2f1e0SAndreas Gohr 132e7a2f1e0SAndreas Gohr echo '<li><div class="li">'; 133e25286daSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=outlinks&f='.$this->from.'&t='.$this->to.'">Outgoing Links</a>'; 134e25286daSAndreas Gohr echo '</div></li>'; 135e25286daSAndreas Gohr 136e25286daSAndreas Gohr echo '<li><div class="li">'; 1372507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=browser&f='.$this->from.'&t='.$this->to.'">Browsers</a>'; 13875fa767dSAndreas Gohr echo '</div></li>'; 13975fa767dSAndreas Gohr 14075fa767dSAndreas Gohr echo '<li><div class="li">'; 1412507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=os&f='.$this->from.'&t='.$this->to.'">Operating Systems</a>'; 142bd4217d3SAndreas Gohr echo '</div></li>'; 143bd4217d3SAndreas Gohr 144bd4217d3SAndreas Gohr echo '<li><div class="li">'; 1452507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=country&f='.$this->from.'&t='.$this->to.'">Countries</a>'; 1469da6395dSAndreas Gohr echo '</div></li>'; 1479da6395dSAndreas Gohr 148c73e16f1SAndreas Gohr echo '<li><div class="li">'; 149c73e16f1SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=resolution&f='.$this->from.'&t='.$this->to.'">Resolution</a>'; 150c73e16f1SAndreas Gohr echo '</div></li>'; 151c73e16f1SAndreas Gohr 1529da6395dSAndreas Gohr echo '</ul>'; 1539da6395dSAndreas Gohr echo '</div>'; 1549da6395dSAndreas Gohr echo '</div>'; 1559da6395dSAndreas Gohr } 1569da6395dSAndreas Gohr 1572507f8e0SAndreas Gohr function html_pager($limit,$next){ 1582507f8e0SAndreas Gohr echo '<div class="plg_stats_pager">'; 1592507f8e0SAndreas Gohr 1602507f8e0SAndreas Gohr if($this->start > 0){ 1612507f8e0SAndreas Gohr $go = max($this->start - $limit, 0); 1622507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$this->from.'&t='.$this->to.'&s='.$go.'" class="prev">previous page</a>'; 1632507f8e0SAndreas Gohr } 1642507f8e0SAndreas Gohr 1652507f8e0SAndreas Gohr if($next){ 1662507f8e0SAndreas Gohr $go = $this->start + $limit; 1672507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$this->from.'&t='.$this->to.'&s='.$go.'" class="next">next page</a>'; 1682507f8e0SAndreas Gohr } 1692507f8e0SAndreas Gohr echo '</div>'; 1702507f8e0SAndreas Gohr } 1712507f8e0SAndreas Gohr 172264f1744SAndreas Gohr /** 173264f1744SAndreas Gohr * Print the time selection menu 174264f1744SAndreas Gohr */ 17514d99ec0SAndreas Gohr function html_timeselect(){ 176264f1744SAndreas Gohr $now = date('Y-m-d'); 177264f1744SAndreas Gohr $yday = date('Y-m-d',time()-(60*60*24)); 178264f1744SAndreas Gohr $week = date('Y-m-d',time()-(60*60*24*7)); 179264f1744SAndreas Gohr $month = date('Y-m-d',time()-(60*60*24*30)); 18014d99ec0SAndreas Gohr 181264f1744SAndreas Gohr echo '<div class="plg_stats_timeselect">'; 182264f1744SAndreas Gohr echo '<span>Select the timeframe:</span>'; 183264f1744SAndreas Gohr echo '<ul>'; 184264f1744SAndreas Gohr 185264f1744SAndreas Gohr echo '<li>'; 1862507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$now.'&t='.$now.'">'; 187264f1744SAndreas Gohr echo 'today'; 188264f1744SAndreas Gohr echo '</a>'; 189264f1744SAndreas Gohr echo '</li>'; 190264f1744SAndreas Gohr 191264f1744SAndreas Gohr echo '<li>'; 1922507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$yday.'&t='.$yday.'">'; 193264f1744SAndreas Gohr echo 'yesterday'; 194264f1744SAndreas Gohr echo '</a>'; 195264f1744SAndreas Gohr echo '</li>'; 196264f1744SAndreas Gohr 197264f1744SAndreas Gohr echo '<li>'; 1982507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$week.'&t='.$now.'">'; 199264f1744SAndreas Gohr echo 'last 7 days'; 200264f1744SAndreas Gohr echo '</a>'; 201264f1744SAndreas Gohr echo '</li>'; 202264f1744SAndreas Gohr 203264f1744SAndreas Gohr echo '<li>'; 2042507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$month.'&t='.$now.'">'; 205264f1744SAndreas Gohr echo 'last 30 days'; 206264f1744SAndreas Gohr echo '</a>'; 207264f1744SAndreas Gohr echo '</li>'; 208264f1744SAndreas Gohr 209264f1744SAndreas Gohr echo '</ul>'; 210264f1744SAndreas Gohr 211264f1744SAndreas Gohr 212264f1744SAndreas Gohr echo '<form action="" method="get">'; 213264f1744SAndreas Gohr echo '<input type="hidden" name="do" value="admin" />'; 214264f1744SAndreas Gohr echo '<input type="hidden" name="page" value="statistics" />'; 215264f1744SAndreas Gohr echo '<input type="hidden" name="opt" value="'.$this->opt.'" />'; 216264f1744SAndreas Gohr echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />'; 217264f1744SAndreas Gohr echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />'; 218264f1744SAndreas Gohr echo '<input type="submit" value="go" class="button" />'; 21914d99ec0SAndreas Gohr echo '</form>'; 220264f1744SAndreas Gohr 221264f1744SAndreas Gohr echo '</div>'; 22214d99ec0SAndreas Gohr } 22314d99ec0SAndreas Gohr 22414d99ec0SAndreas Gohr 225f5f32cbfSAndreas Gohr /** 226f5f32cbfSAndreas Gohr * Print an introductionary screen 227f5f32cbfSAndreas Gohr */ 22814d99ec0SAndreas Gohr function html_dashboard(){ 2292812a751SAndreas Gohr echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists 2302812a751SAndreas Gohr choose a topic from the list.</p>'; 2312812a751SAndreas Gohr 2322812a751SAndreas Gohr 233264f1744SAndreas Gohr echo '<div class="plg_stats_dashboard">'; 234264f1744SAndreas Gohr 2352812a751SAndreas Gohr // general info 2362812a751SAndreas Gohr echo '<div class="plg_stats_top">'; 2372812a751SAndreas Gohr $result = $this->sql_aggregate($this->tlimit); 2382812a751SAndreas Gohr echo '<ul>'; 2392812a751SAndreas Gohr echo '<li><span>'.$result['pageviews'].'</span> page views </li>'; 2403c0acc14SAndreas Gohr echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>'; 2413c0acc14SAndreas Gohr echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>'; 2422812a751SAndreas Gohr echo '<li><span>'.$result['users'].'</span> logged in users</li>'; 2432812a751SAndreas Gohr 2442812a751SAndreas Gohr echo '</ul>'; 2452812a751SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&f='.$this->from.'&t='.$this->to.'" />'; 2462812a751SAndreas Gohr echo '</div>'; 2472812a751SAndreas Gohr 24814d99ec0SAndreas Gohr 24987d5e44bSAndreas Gohr // top pages today 250264f1744SAndreas Gohr echo '<div>'; 251264f1744SAndreas Gohr echo '<h2>Most popular pages</h2>'; 25295eb68e6SAndreas Gohr $result = $this->sql_pages($this->tlimit,$this->start,15); 2532812a751SAndreas Gohr $this->html_resulttable($result); 2542507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=page&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 255264f1744SAndreas Gohr echo '</div>'; 25687d5e44bSAndreas Gohr 25787d5e44bSAndreas Gohr // top referer today 258264f1744SAndreas Gohr echo '<div>'; 259e7a2f1e0SAndreas Gohr echo '<h2>Newest incoming links</h2>'; 260e7a2f1e0SAndreas Gohr $result = $this->sql_newreferer($this->tlimit,$this->start,15); 2612812a751SAndreas Gohr $this->html_resulttable($result); 2622507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=newreferer&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 263264f1744SAndreas Gohr echo '</div>'; 26454f6c432SAndreas Gohr 26554f6c432SAndreas Gohr // top countries today 266264f1744SAndreas Gohr echo '<div>'; 267264f1744SAndreas Gohr echo '<h2>Visitor\'s top countries</h2>'; 26895eb68e6SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&f='.$this->from.'&t='.$this->to.'" />'; 2692507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=country&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 270264f1744SAndreas Gohr echo '</div>'; 271264f1744SAndreas Gohr 272264f1744SAndreas Gohr echo '</div>'; 27314d99ec0SAndreas Gohr } 27414d99ec0SAndreas Gohr 2759da6395dSAndreas Gohr function html_country(){ 2769da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 2779da6395dSAndreas Gohr echo '<h2>Visitor\'s Countries</h2>'; 278bd4217d3SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&f='.$this->from.'&t='.$this->to.'" />'; 2799da6395dSAndreas Gohr $result = $this->sql_countries($this->tlimit,$this->start,150); 2802507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 2819da6395dSAndreas Gohr echo '</div>'; 2829da6395dSAndreas Gohr } 2839da6395dSAndreas Gohr 2849da6395dSAndreas Gohr function html_page(){ 2859da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 2869da6395dSAndreas Gohr echo '<h2>Popular Pages</h2>'; 2879da6395dSAndreas Gohr $result = $this->sql_pages($this->tlimit,$this->start,150); 2882507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 2899da6395dSAndreas Gohr echo '</div>'; 2909da6395dSAndreas Gohr } 2919da6395dSAndreas Gohr 29275fa767dSAndreas Gohr function html_browser(){ 29375fa767dSAndreas Gohr echo '<div class="plg_stats_full">'; 29475fa767dSAndreas Gohr echo '<h2>Browser Shootout</h2>'; 29575fa767dSAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&f='.$this->from.'&t='.$this->to.'" />'; 29675fa767dSAndreas Gohr $result = $this->sql_browsers($this->tlimit,$this->start,150,true); 2972507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 29875fa767dSAndreas Gohr echo '</div>'; 29975fa767dSAndreas Gohr } 30075fa767dSAndreas Gohr 301bd4217d3SAndreas Gohr function html_os(){ 302bd4217d3SAndreas Gohr echo '<div class="plg_stats_full">'; 303bd4217d3SAndreas Gohr echo '<h2>Operating Systems</h2>'; 304bd4217d3SAndreas Gohr $result = $this->sql_os($this->tlimit,$this->start,150,true); 3052507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 306bd4217d3SAndreas Gohr echo '</div>'; 307bd4217d3SAndreas Gohr } 308bd4217d3SAndreas Gohr 3099da6395dSAndreas Gohr function html_referer(){ 3109da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 3119da6395dSAndreas Gohr echo '<h2>Incoming Links</h2>'; 3122812a751SAndreas Gohr $result = $this->sql_aggregate($this->tlimit); 3132812a751SAndreas Gohr 3142812a751SAndreas Gohr $all = $result['search']+$result['external']+$result['direct']; 3152812a751SAndreas Gohr 31694023548SAndreas Gohr if($all){ 3172812a751SAndreas Gohr printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses, 3182812a751SAndreas Gohr %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through 3192812a751SAndreas Gohr links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all), 3202812a751SAndreas Gohr $result['search'],(100*$result['search']/$all),$result['external'], 3212812a751SAndreas Gohr (100*$result['external']/$all)); 32294023548SAndreas Gohr } 3232812a751SAndreas Gohr 3249da6395dSAndreas Gohr $result = $this->sql_referer($this->tlimit,$this->start,150); 3252507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 3269da6395dSAndreas Gohr echo '</div>'; 3279da6395dSAndreas Gohr } 3289da6395dSAndreas Gohr 329e7a2f1e0SAndreas Gohr function html_newreferer(){ 330e7a2f1e0SAndreas Gohr echo '<div class="plg_stats_full">'; 331e7a2f1e0SAndreas Gohr echo '<h2>New Incoming Links</h2>'; 332e7a2f1e0SAndreas Gohr echo '<p>The following incoming links where first logged in the selected time frame, 333e7a2f1e0SAndreas Gohr and have never been seen before.</p>'; 334e7a2f1e0SAndreas Gohr 335e7a2f1e0SAndreas Gohr $result = $this->sql_newreferer($this->tlimit,$this->start,150); 3362507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 337e7a2f1e0SAndreas Gohr echo '</div>'; 338e7a2f1e0SAndreas Gohr } 339e7a2f1e0SAndreas Gohr 340e25286daSAndreas Gohr function html_outlinks(){ 341e25286daSAndreas Gohr echo '<div class="plg_stats_full">'; 342e25286daSAndreas Gohr echo '<h2>Outgoing Links</h2>'; 343e25286daSAndreas Gohr 344e25286daSAndreas Gohr $result = $this->sql_outlinks($this->tlimit,$this->start,150); 345e25286daSAndreas Gohr $this->html_resulttable($result,'',150); 346e25286daSAndreas Gohr echo '</div>'; 347e25286daSAndreas Gohr } 348e25286daSAndreas Gohr 349e25286daSAndreas Gohr 350c73e16f1SAndreas Gohr function html_resolution(){ 351c73e16f1SAndreas Gohr echo '<div class="plg_stats_full">'; 352c73e16f1SAndreas Gohr echo '<h2>Resolution</h2>'; 353c73e16f1SAndreas Gohr $result = $this->sql_resolution($this->tlimit,$this->start,150); 354c73e16f1SAndreas Gohr $this->html_resulttable($result,'',150); 355c73e16f1SAndreas Gohr 356c73e16f1SAndreas Gohr echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you 357c73e16f1SAndreas Gohr much about about the real size of their browser windows. The graphic below shows the size distribution of 358c73e16f1SAndreas Gohr the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged 359c73e16f1SAndreas Gohr in all browsers. Because users may resize their browser window while browsing your site the statistics may 360c73e16f1SAndreas Gohr be flawed. Take it with a grain of salt.</p>'; 361c73e16f1SAndreas Gohr 362c73e16f1SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&f='.$this->from.'&t='.$this->to.'" />'; 363c73e16f1SAndreas Gohr echo '</div>'; 364c73e16f1SAndreas Gohr } 3659da6395dSAndreas Gohr 3669da6395dSAndreas Gohr 36714d99ec0SAndreas Gohr /** 36814d99ec0SAndreas Gohr * Display a result in a HTML table 36914d99ec0SAndreas Gohr */ 3702507f8e0SAndreas Gohr function html_resulttable($result,$header='',$pager=0){ 37114d99ec0SAndreas Gohr echo '<table>'; 3722812a751SAndreas Gohr if(is_array($header)){ 37314d99ec0SAndreas Gohr echo '<tr>'; 37414d99ec0SAndreas Gohr foreach($header as $h){ 37514d99ec0SAndreas Gohr echo '<th>'.hsc($h).'</th>'; 37614d99ec0SAndreas Gohr } 37714d99ec0SAndreas Gohr echo '</tr>'; 3782812a751SAndreas Gohr } 37914d99ec0SAndreas Gohr 3802507f8e0SAndreas Gohr $count = 0; 38114d99ec0SAndreas Gohr foreach($result as $row){ 38214d99ec0SAndreas Gohr echo '<tr>'; 38314d99ec0SAndreas Gohr foreach($row as $k => $v){ 3842812a751SAndreas Gohr echo '<td class="plg_stats_X'.$k.'">'; 38514d99ec0SAndreas Gohr if($k == 'page'){ 38614d99ec0SAndreas Gohr echo '<a href="'.wl($v).'" class="wikilink1">'; 38714d99ec0SAndreas Gohr echo hsc($v); 38814d99ec0SAndreas Gohr echo '</a>'; 38914d99ec0SAndreas Gohr }elseif($k == 'url'){ 39054f6c432SAndreas Gohr $url = hsc($v); 39183b63546SAndreas Gohr $url = preg_replace('/^https?:\/\/(www\.)?/','',$url); 3922812a751SAndreas Gohr if(strlen($url) > 45){ 3932812a751SAndreas Gohr $url = substr($url,0,30).' … '.substr($url,-15); 39454f6c432SAndreas Gohr } 39514d99ec0SAndreas Gohr echo '<a href="'.$v.'" class="urlextern">'; 39654f6c432SAndreas Gohr echo $url; 39714d99ec0SAndreas Gohr echo '</a>'; 39875fa767dSAndreas Gohr }elseif($k == 'browser'){ 39975fa767dSAndreas Gohr include_once(dirname(__FILE__).'/inc/browsers.php'); 40075fa767dSAndreas Gohr echo $BrowsersHashIDLib[$v]; 40175fa767dSAndreas Gohr }elseif($k == 'bflag'){ 40275fa767dSAndreas Gohr include_once(dirname(__FILE__).'/inc/browsers.php'); 40375fa767dSAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />'; 404bd4217d3SAndreas Gohr }elseif($k == 'os'){ 405bd4217d3SAndreas Gohr if(empty($v)){ 406bd4217d3SAndreas Gohr echo 'unknown'; 407bd4217d3SAndreas Gohr }else{ 408bd4217d3SAndreas Gohr include_once(dirname(__FILE__).'/inc/operating_systems.php'); 409bd4217d3SAndreas Gohr echo $OSHashLib[$v]; 410bd4217d3SAndreas Gohr } 411bd4217d3SAndreas Gohr }elseif($k == 'osflag'){ 412bd4217d3SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />'; 41375fa767dSAndreas Gohr }elseif($k == 'cflag'){ 41475fa767dSAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />'; 41514d99ec0SAndreas Gohr }elseif($k == 'html'){ 41614d99ec0SAndreas Gohr echo $v; 41714d99ec0SAndreas Gohr }else{ 41814d99ec0SAndreas Gohr echo hsc($v); 41914d99ec0SAndreas Gohr } 42014d99ec0SAndreas Gohr echo '</td>'; 42114d99ec0SAndreas Gohr } 42214d99ec0SAndreas Gohr echo '</tr>'; 4232507f8e0SAndreas Gohr 4242507f8e0SAndreas Gohr if($pager && ($count == $pager)) break; 4252507f8e0SAndreas Gohr $count++; 42614d99ec0SAndreas Gohr } 42714d99ec0SAndreas Gohr echo '</table>'; 4282507f8e0SAndreas Gohr 4292507f8e0SAndreas Gohr if($pager) $this->html_pager($pager,count($result) > $pager); 4301878f16fSAndreas Gohr } 4311878f16fSAndreas Gohr 43295eb68e6SAndreas Gohr /** 43395eb68e6SAndreas Gohr * Create an image 43495eb68e6SAndreas Gohr */ 43595eb68e6SAndreas Gohr function img_build($img){ 43695eb68e6SAndreas Gohr include(dirname(__FILE__).'/inc/AGC.class.php'); 43795eb68e6SAndreas Gohr 43895eb68e6SAndreas Gohr switch($img){ 43995eb68e6SAndreas Gohr case 'country': 44095eb68e6SAndreas Gohr // build top countries + other 44195eb68e6SAndreas Gohr $result = $this->sql_countries($this->tlimit,$this->start,0); 44295eb68e6SAndreas Gohr $data = array(); 44395eb68e6SAndreas Gohr $top = 0; 44495eb68e6SAndreas Gohr foreach($result as $row){ 44595eb68e6SAndreas Gohr if($top < 7){ 44695eb68e6SAndreas Gohr $data[$row['country']] = $row['cnt']; 44795eb68e6SAndreas Gohr }else{ 44895eb68e6SAndreas Gohr $data['other'] += $row['cnt']; 44995eb68e6SAndreas Gohr } 45095eb68e6SAndreas Gohr $top++; 45195eb68e6SAndreas Gohr } 45295eb68e6SAndreas Gohr $pie = new AGC(300, 200); 45395eb68e6SAndreas Gohr $pie->setProp("showkey",true); 45495eb68e6SAndreas Gohr $pie->setProp("showval",false); 45595eb68e6SAndreas Gohr $pie->setProp("showgrid",false); 45695eb68e6SAndreas Gohr $pie->setProp("type","pie"); 45795eb68e6SAndreas Gohr $pie->setProp("keyinfo",1); 45895eb68e6SAndreas Gohr $pie->setProp("keysize",8); 45995eb68e6SAndreas Gohr $pie->setProp("keywidspc",-50); 46095eb68e6SAndreas Gohr $pie->setProp("key",array_keys($data)); 46195eb68e6SAndreas Gohr $pie->addBulkPoints(array_values($data)); 46295eb68e6SAndreas Gohr @$pie->graph(); 46395eb68e6SAndreas Gohr $pie->showGraph(); 46495eb68e6SAndreas Gohr break; 46575fa767dSAndreas Gohr case 'browser': 46675fa767dSAndreas Gohr // build top browsers + other 46775fa767dSAndreas Gohr include_once(dirname(__FILE__).'/inc/browsers.php'); 46875fa767dSAndreas Gohr 46975fa767dSAndreas Gohr $result = $this->sql_browsers($this->tlimit,$this->start,0,false); 47075fa767dSAndreas Gohr $data = array(); 47175fa767dSAndreas Gohr $top = 0; 47275fa767dSAndreas Gohr foreach($result as $row){ 47375fa767dSAndreas Gohr if($top < 5){ 47475fa767dSAndreas Gohr $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt']; 47575fa767dSAndreas Gohr }else{ 47675fa767dSAndreas Gohr $data['other'] += $row['cnt']; 47775fa767dSAndreas Gohr } 47875fa767dSAndreas Gohr $top++; 47975fa767dSAndreas Gohr } 48075fa767dSAndreas Gohr $pie = new AGC(300, 200); 48175fa767dSAndreas Gohr $pie->setProp("showkey",true); 48275fa767dSAndreas Gohr $pie->setProp("showval",false); 48375fa767dSAndreas Gohr $pie->setProp("showgrid",false); 48475fa767dSAndreas Gohr $pie->setProp("type","pie"); 48575fa767dSAndreas Gohr $pie->setProp("keyinfo",1); 48675fa767dSAndreas Gohr $pie->setProp("keysize",8); 48775fa767dSAndreas Gohr $pie->setProp("keywidspc",-50); 48875fa767dSAndreas Gohr $pie->setProp("key",array_keys($data)); 48975fa767dSAndreas Gohr $pie->addBulkPoints(array_values($data)); 49075fa767dSAndreas Gohr @$pie->graph(); 49175fa767dSAndreas Gohr $pie->showGraph(); 49275fa767dSAndreas Gohr break; 493c73e16f1SAndreas Gohr case 'view': 494c73e16f1SAndreas Gohr 495c73e16f1SAndreas Gohr $graph = new AGC(400, 200); 496c73e16f1SAndreas Gohr $graph->setColor('color',0,'blue'); 497c73e16f1SAndreas Gohr $graph->setColor('color',1,'red'); 498c73e16f1SAndreas Gohr $graph->setProp("showkey",true); 499c73e16f1SAndreas Gohr $graph->setProp("key",'view port width',0); 500c73e16f1SAndreas Gohr $graph->setProp("key",'view port height',1); 501c73e16f1SAndreas Gohr 502c73e16f1SAndreas Gohr $result = $this->sql_viewport($this->tlimit,0,0,true); 503c73e16f1SAndreas Gohr foreach($result as $row){ 504c73e16f1SAndreas Gohr $graph->addPoint($row['cnt'],$row['res_x'],0); 505c73e16f1SAndreas Gohr } 506c73e16f1SAndreas Gohr 507c73e16f1SAndreas Gohr $result = $this->sql_viewport($this->tlimit,0,0,false); 508c73e16f1SAndreas Gohr foreach($result as $row){ 509c73e16f1SAndreas Gohr $graph->addPoint($row['cnt'],$row['res_y'],1); 510c73e16f1SAndreas Gohr } 511c73e16f1SAndreas Gohr 512c73e16f1SAndreas Gohr @$graph->graph(); 513c73e16f1SAndreas Gohr $graph->showGraph(); 514c73e16f1SAndreas Gohr 515c73e16f1SAndreas Gohr break; 5162812a751SAndreas Gohr case 'trend': 5172812a751SAndreas Gohr $hours = ($this->from == $this->to); 5182812a751SAndreas Gohr $result = $this->sql_trend($this->tlimit,$hours); 5192812a751SAndreas Gohr $data1 = array(); 5202812a751SAndreas Gohr $data2 = array(); 5212812a751SAndreas Gohr 5222812a751SAndreas Gohr $graph = new AGC(400, 150); 5232812a751SAndreas Gohr $graph->setProp("type","bar"); 5242812a751SAndreas Gohr $graph->setProp("showgrid",false); 5252812a751SAndreas Gohr $graph->setProp("barwidth",.8); 52675fa767dSAndreas Gohr 5272812a751SAndreas Gohr $graph->setColor('color',0,'blue'); 5282812a751SAndreas Gohr $graph->setColor('color',1,'red'); 5293c0acc14SAndreas Gohr $graph->setColor('color',2,'yellow'); 5302812a751SAndreas Gohr 5312812a751SAndreas Gohr if($hours){ 5322812a751SAndreas Gohr //preset $hours 5332812a751SAndreas Gohr for($i=0;$i<24;$i++){ 5342812a751SAndreas Gohr $data1[$i] = 0; 5352812a751SAndreas Gohr $data2[$i] = 0; 5363c0acc14SAndreas Gohr $data3[$i] = 0; 5372812a751SAndreas Gohr $graph->setProp("scale",array(' 0h',' 4h',' 8h',' 12h',' 16h',' 20h',' 24h')); 5382812a751SAndreas Gohr } 5392812a751SAndreas Gohr }else{ 5402812a751SAndreas Gohr $graph->setProp("scale",array(next(array_keys($data1)),$this->to)); 5412812a751SAndreas Gohr } 5422812a751SAndreas Gohr 5432812a751SAndreas Gohr foreach($result as $row){ 5442812a751SAndreas Gohr $data1[$row['time']] = $row['pageviews']; 5452812a751SAndreas Gohr $data2[$row['time']] = $row['sessions']; 5463c0acc14SAndreas Gohr $data3[$row['time']] = $row['visitors']; 5472812a751SAndreas Gohr } 5482812a751SAndreas Gohr 5492812a751SAndreas Gohr foreach($data1 as $key => $val){ 5502812a751SAndreas Gohr $graph->addPoint($val,$key,0); 5512812a751SAndreas Gohr } 5522812a751SAndreas Gohr foreach($data2 as $key => $val){ 5532812a751SAndreas Gohr $graph->addPoint($val,$key,1); 5542812a751SAndreas Gohr } 5553c0acc14SAndreas Gohr foreach($data3 as $key => $val){ 5563c0acc14SAndreas Gohr $graph->addPoint($val,$key,2); 5573c0acc14SAndreas Gohr } 5582812a751SAndreas Gohr 5592812a751SAndreas Gohr @$graph->graph(); 5602812a751SAndreas Gohr $graph->showGraph(); 5612812a751SAndreas Gohr 56295eb68e6SAndreas Gohr default: 56395eb68e6SAndreas Gohr $this->sendGIF(); 56495eb68e6SAndreas Gohr } 56595eb68e6SAndreas Gohr } 56695eb68e6SAndreas Gohr 56795eb68e6SAndreas Gohr 5682812a751SAndreas Gohr /** 5692812a751SAndreas Gohr * Return some aggregated statistics 5702812a751SAndreas Gohr */ 5712812a751SAndreas Gohr function sql_aggregate($tlimit){ 5722812a751SAndreas Gohr $data = array(); 5732812a751SAndreas Gohr 5742812a751SAndreas Gohr $sql = "SELECT ref_type, COUNT(*) as cnt 5752812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5762812a751SAndreas Gohr WHERE $tlimit 5772812a751SAndreas Gohr AND ua_type = 'browser' 5782812a751SAndreas Gohr GROUP BY ref_type"; 5792812a751SAndreas Gohr $result = $this->runSQL($sql); 5802812a751SAndreas Gohr 5812812a751SAndreas Gohr foreach($result as $row){ 5822812a751SAndreas Gohr if($row['ref_type'] == 'search') $data['search'] = $row['cnt']; 5832812a751SAndreas Gohr if($row['ref_type'] == 'external') $data['external'] = $row['cnt']; 5842812a751SAndreas Gohr if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt']; 5852812a751SAndreas Gohr if($row['ref_type'] == '') $data['direct'] = $row['cnt']; 5862812a751SAndreas Gohr } 5872812a751SAndreas Gohr 5882812a751SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as sessions, 5892812a751SAndreas Gohr COUNT(session) as views, 5903c0acc14SAndreas Gohr COUNT(DISTINCT user) as users, 5913c0acc14SAndreas Gohr COUNT(DISTINCT uid) as visitors 5922812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5932812a751SAndreas Gohr WHERE $tlimit 5942812a751SAndreas Gohr AND ua_type = 'browser'"; 5952812a751SAndreas Gohr $result = $this->runSQL($sql); 5962812a751SAndreas Gohr 59775fa767dSAndreas Gohr $data['users'] = max($result[0]['users'] - 1,0); // subtract empty user 5982812a751SAndreas Gohr $data['sessions'] = $result[0]['sessions']; 5992812a751SAndreas Gohr $data['pageviews'] = $result[0]['views']; 6003c0acc14SAndreas Gohr $data['visitors'] = $result[0]['visitors']; 6012812a751SAndreas Gohr 6022812a751SAndreas Gohr $sql = "SELECT COUNT(id) as robots 6032812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 6042812a751SAndreas Gohr WHERE $tlimit 6052812a751SAndreas Gohr AND ua_type = 'robot'"; 6062812a751SAndreas Gohr $result = $this->runSQL($sql); 6072812a751SAndreas Gohr $data['robots'] = $result[0]['robots']; 6082812a751SAndreas Gohr 6092812a751SAndreas Gohr return $data; 6102812a751SAndreas Gohr } 6112812a751SAndreas Gohr 612bd4217d3SAndreas Gohr /** 613bd4217d3SAndreas Gohr * standard statistics follow, only accesses made by browsers are counted 614bd4217d3SAndreas Gohr * for general stats like browser or OS only visitors not pageviews are counted 615bd4217d3SAndreas Gohr */ 6162812a751SAndreas Gohr function sql_trend($tlimit,$hours=false){ 6172812a751SAndreas Gohr if($hours){ 6182812a751SAndreas Gohr $sql = "SELECT HOUR(dt) as time, 6192812a751SAndreas Gohr COUNT(DISTINCT session) as sessions, 6203c0acc14SAndreas Gohr COUNT(session) as pageviews, 6213c0acc14SAndreas Gohr COUNT(DISTINCT uid) as visitors 6222812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 6232812a751SAndreas Gohr WHERE $tlimit 6242812a751SAndreas Gohr AND ua_type = 'browser' 6252812a751SAndreas Gohr GROUP BY HOUR(dt) 6262812a751SAndreas Gohr ORDER BY time"; 6272812a751SAndreas Gohr }else{ 6282812a751SAndreas Gohr $sql = "SELECT DATE(dt) as time, 6292812a751SAndreas Gohr COUNT(DISTINCT session) as sessions, 6303c0acc14SAndreas Gohr COUNT(session) as pageviews, 6313c0acc14SAndreas Gohr COUNT(DISTINCT uid) as visitors 6322812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 6332812a751SAndreas Gohr WHERE $tlimit 6342812a751SAndreas Gohr AND ua_type = 'browser' 6352812a751SAndreas Gohr GROUP BY DATE(dt) 6362812a751SAndreas Gohr ORDER BY time"; 6372812a751SAndreas Gohr } 6382812a751SAndreas Gohr return $this->runSQL($sql); 6392812a751SAndreas Gohr } 6402812a751SAndreas Gohr 641e25286daSAndreas Gohr function sql_outlinks($tlimit,$start=0,$limit=20){ 642e25286daSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, link as url 643e25286daSAndreas Gohr FROM ".$this->getConf('db_prefix')."outlinks as A 644e25286daSAndreas Gohr WHERE $tlimit 645e25286daSAndreas Gohr GROUP BY link 646e25286daSAndreas Gohr ORDER BY cnt DESC, link". 647e25286daSAndreas Gohr $this->sql_limit($start,$limit); 648e25286daSAndreas Gohr return $this->runSQL($sql); 649e25286daSAndreas Gohr } 650e25286daSAndreas Gohr 65195eb68e6SAndreas Gohr function sql_pages($tlimit,$start=0,$limit=20){ 6522812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, page 65395eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 65495eb68e6SAndreas Gohr WHERE $tlimit 65595eb68e6SAndreas Gohr AND ua_type = 'browser' 65695eb68e6SAndreas Gohr GROUP BY page 65795eb68e6SAndreas Gohr ORDER BY cnt DESC, page". 65895eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 65995eb68e6SAndreas Gohr return $this->runSQL($sql); 66095eb68e6SAndreas Gohr } 66195eb68e6SAndreas Gohr 66295eb68e6SAndreas Gohr function sql_referer($tlimit,$start=0,$limit=20){ 6632812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 66495eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 66595eb68e6SAndreas Gohr WHERE $tlimit 66695eb68e6SAndreas Gohr AND ua_type = 'browser' 66795eb68e6SAndreas Gohr AND ref_type = 'external' 66895eb68e6SAndreas Gohr GROUP BY ref_md5 66995eb68e6SAndreas Gohr ORDER BY cnt DESC, url". 67095eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 67195eb68e6SAndreas Gohr return $this->runSQL($sql); 67295eb68e6SAndreas Gohr } 67395eb68e6SAndreas Gohr 674e7a2f1e0SAndreas Gohr function sql_newreferer($tlimit,$start=0,$limit=20){ 675e7a2f1e0SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 676e7a2f1e0SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 677e7a2f1e0SAndreas Gohr WHERE ua_type = 'browser' 678e7a2f1e0SAndreas Gohr AND ref_type = 'external' 679e7a2f1e0SAndreas Gohr GROUP BY ref_md5 680e7a2f1e0SAndreas Gohr HAVING DATE(MIN(dt)) >= DATE('".$this->from."') 681e7a2f1e0SAndreas Gohr AND DATE(MIN(dt)) <= DATE('".$this->to."') 682e7a2f1e0SAndreas Gohr ORDER BY cnt DESC, url". 683e7a2f1e0SAndreas Gohr $this->sql_limit($start,$limit); 684e7a2f1e0SAndreas Gohr return $this->runSQL($sql); 685e7a2f1e0SAndreas Gohr } 686e7a2f1e0SAndreas Gohr 68795eb68e6SAndreas Gohr function sql_countries($tlimit,$start=0,$limit=20){ 688bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country 68995eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A, 69095eb68e6SAndreas Gohr ".$this->getConf('db_prefix')."iplocation as B 69195eb68e6SAndreas Gohr WHERE $tlimit 69295eb68e6SAndreas Gohr AND A.ip = B.ip 69395eb68e6SAndreas Gohr GROUP BY B.country 69495eb68e6SAndreas Gohr ORDER BY cnt DESC, B.country". 69595eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 69695eb68e6SAndreas Gohr return $this->runSQL($sql); 69795eb68e6SAndreas Gohr } 69895eb68e6SAndreas Gohr 69975fa767dSAndreas Gohr function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){ 70075fa767dSAndreas Gohr if($ext){ 70175fa767dSAndreas Gohr $sel = 'ua_info as bflag, ua_info as browser, ua_ver'; 70275fa767dSAndreas Gohr $grp = 'ua_info, ua_ver'; 70375fa767dSAndreas Gohr }else{ 70475fa767dSAndreas Gohr $grp = 'ua_info'; 70575fa767dSAndreas Gohr $sel = 'ua_info'; 70675fa767dSAndreas Gohr } 70775fa767dSAndreas Gohr 708bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel 70975fa767dSAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 71075fa767dSAndreas Gohr WHERE $tlimit 71175fa767dSAndreas Gohr AND ua_type = 'browser' 71275fa767dSAndreas Gohr GROUP BY $grp 71375fa767dSAndreas Gohr ORDER BY cnt DESC, ua_info". 71475fa767dSAndreas Gohr $this->sql_limit($start,$limit); 71575fa767dSAndreas Gohr return $this->runSQL($sql); 71675fa767dSAndreas Gohr } 71775fa767dSAndreas Gohr 718bd4217d3SAndreas Gohr function sql_os($tlimit,$start=0,$limit=20){ 719bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os 720bd4217d3SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 721bd4217d3SAndreas Gohr WHERE $tlimit 722bd4217d3SAndreas Gohr AND ua_type = 'browser' 723bd4217d3SAndreas Gohr GROUP BY os 724bd4217d3SAndreas Gohr ORDER BY cnt DESC, os". 725bd4217d3SAndreas Gohr $this->sql_limit($start,$limit); 726bd4217d3SAndreas Gohr return $this->runSQL($sql); 727bd4217d3SAndreas Gohr } 728bd4217d3SAndreas Gohr 729c73e16f1SAndreas Gohr function sql_resolution($tlimit,$start=0,$limit=20){ 730c73e16f1SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res 731c73e16f1SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 732c73e16f1SAndreas Gohr WHERE $tlimit 733c73e16f1SAndreas Gohr AND ua_type = 'browser' 734c73e16f1SAndreas Gohr AND screen_x != 0 735c73e16f1SAndreas Gohr GROUP BY screen_x, screen_y 736c73e16f1SAndreas Gohr ORDER BY cnt DESC, screen_x". 737c73e16f1SAndreas Gohr $this->sql_limit($start,$limit); 738c73e16f1SAndreas Gohr return $this->runSQL($sql); 739c73e16f1SAndreas Gohr } 740c73e16f1SAndreas Gohr 741c73e16f1SAndreas Gohr function sql_viewport($tlimit,$start=0,$limit=20,$x=true){ 742c73e16f1SAndreas Gohr if($x){ 743c73e16f1SAndreas Gohr $col = 'view_x'; 744c73e16f1SAndreas Gohr $res = 'res_x'; 745c73e16f1SAndreas Gohr }else{ 746c73e16f1SAndreas Gohr $col = 'view_y'; 747c73e16f1SAndreas Gohr $res = 'res_y'; 748c73e16f1SAndreas Gohr } 749c73e16f1SAndreas Gohr 750c73e16f1SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, 751c73e16f1SAndreas Gohr ROUND($col/10)*10 as $res 752c73e16f1SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 753c73e16f1SAndreas Gohr WHERE $tlimit 754c73e16f1SAndreas Gohr AND ua_type = 'browser' 755c73e16f1SAndreas Gohr AND $col != 0 756c73e16f1SAndreas Gohr GROUP BY $res 757c73e16f1SAndreas Gohr ORDER BY cnt DESC, $res". 758c73e16f1SAndreas Gohr $this->sql_limit($start,$limit); 759c73e16f1SAndreas Gohr return $this->runSQL($sql); 760c73e16f1SAndreas Gohr } 761c73e16f1SAndreas Gohr 76275fa767dSAndreas Gohr 76395eb68e6SAndreas Gohr /** 76495eb68e6SAndreas Gohr * Builds a limit clause 76595eb68e6SAndreas Gohr */ 76695eb68e6SAndreas Gohr function sql_limit($start,$limit){ 76795eb68e6SAndreas Gohr $start = (int) $start; 76895eb68e6SAndreas Gohr $limit = (int) $limit; 76995eb68e6SAndreas Gohr if($limit){ 7702507f8e0SAndreas Gohr $limit += 1; 77195eb68e6SAndreas Gohr return " LIMIT $start,$limit"; 77295eb68e6SAndreas Gohr }elseif($start){ 77395eb68e6SAndreas Gohr return " OFFSET $start"; 77495eb68e6SAndreas Gohr } 77595eb68e6SAndreas Gohr return ''; 77695eb68e6SAndreas Gohr } 7771878f16fSAndreas Gohr 7781878f16fSAndreas Gohr /** 77914d99ec0SAndreas Gohr * Return a link to the DB, opening the connection if needed 7801878f16fSAndreas Gohr */ 78114d99ec0SAndreas Gohr function dbLink(){ 7821878f16fSAndreas Gohr // connect to DB if needed 7831878f16fSAndreas Gohr if(!$this->dblink){ 7841878f16fSAndreas Gohr $this->dblink = mysql_connect($this->getConf('db_server'), 7851878f16fSAndreas Gohr $this->getConf('db_user'), 7861878f16fSAndreas Gohr $this->getConf('db_password')); 7871878f16fSAndreas Gohr if(!$this->dblink){ 7881878f16fSAndreas Gohr msg('DB Error: connection failed',-1); 7891878f16fSAndreas Gohr return null; 7901878f16fSAndreas Gohr } 7911878f16fSAndreas Gohr // set utf-8 7921878f16fSAndreas Gohr if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){ 7931878f16fSAndreas Gohr msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1); 7941878f16fSAndreas Gohr return null; 7951878f16fSAndreas Gohr } 7961878f16fSAndreas Gohr } 79714d99ec0SAndreas Gohr return $this->dblink; 79814d99ec0SAndreas Gohr } 7991878f16fSAndreas Gohr 80014d99ec0SAndreas Gohr /** 80114d99ec0SAndreas Gohr * Simple function to run a DB query 80214d99ec0SAndreas Gohr */ 80314d99ec0SAndreas Gohr function runSQL($sql_string) { 80414d99ec0SAndreas Gohr $link = $this->dbLink(); 80514d99ec0SAndreas Gohr 80614d99ec0SAndreas Gohr $result = mysql_db_query($this->conf['db_database'],$sql_string,$link); 80794171ff3SAndreas Gohr if(!$result){ 8082812a751SAndreas Gohr msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1); 8091878f16fSAndreas Gohr return null; 8101878f16fSAndreas Gohr } 8111878f16fSAndreas Gohr 8121878f16fSAndreas Gohr $resultarray = array(); 8131878f16fSAndreas Gohr 8141878f16fSAndreas Gohr //mysql_db_query returns 1 on a insert statement -> no need to ask for results 8151878f16fSAndreas Gohr if ($result != 1) { 8161878f16fSAndreas Gohr for($i=0; $i< mysql_num_rows($result); $i++) { 8171878f16fSAndreas Gohr $temparray = mysql_fetch_assoc($result); 8181878f16fSAndreas Gohr $resultarray[]=$temparray; 8191878f16fSAndreas Gohr } 8201878f16fSAndreas Gohr mysql_free_result($result); 8211878f16fSAndreas Gohr } 8221878f16fSAndreas Gohr 82314d99ec0SAndreas Gohr if (mysql_insert_id($link)) { 82414d99ec0SAndreas Gohr $resultarray = mysql_insert_id($link); //give back ID on insert 8251878f16fSAndreas Gohr } 8261878f16fSAndreas Gohr 8271878f16fSAndreas Gohr return $resultarray; 8281878f16fSAndreas Gohr } 8291878f16fSAndreas Gohr 8301878f16fSAndreas Gohr /** 83114d99ec0SAndreas Gohr * Returns a short name for a User Agent and sets type, version and os info 8321878f16fSAndreas Gohr */ 83314d99ec0SAndreas Gohr function ua_info($ua,&$type,&$ver,&$os){ 83414d99ec0SAndreas Gohr $ua = strtr($ua,' +','__'); 83514d99ec0SAndreas Gohr $ua = strtolower($ua); 83614d99ec0SAndreas Gohr 83714d99ec0SAndreas Gohr // common browsers 83814d99ec0SAndreas Gohr $regvermsie = '/msie([+_ ]|)([\d\.]*)/i'; 83914d99ec0SAndreas Gohr $regvernetscape = '/netscape.?\/([\d\.]*)/i'; 84014d99ec0SAndreas Gohr $regverfirefox = '/firefox\/([\d\.]*)/i'; 84114d99ec0SAndreas Gohr $regversvn = '/svn\/([\d\.]*)/i'; 84214d99ec0SAndreas Gohr $regvermozilla = '/mozilla(\/|)([\d\.]*)/i'; 84314d99ec0SAndreas Gohr $regnotie = '/webtv|omniweb|opera/i'; 84414d99ec0SAndreas Gohr $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i'; 84514d99ec0SAndreas Gohr 84614d99ec0SAndreas Gohr $name = ''; 84714d99ec0SAndreas Gohr # IE ? 84814d99ec0SAndreas Gohr if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){ 84914d99ec0SAndreas Gohr $type = 'browser'; 85014d99ec0SAndreas Gohr $ver = $m[2]; 85114d99ec0SAndreas Gohr $name = 'msie'; 85214d99ec0SAndreas Gohr } 85314d99ec0SAndreas Gohr # Firefox ? 85414d99ec0SAndreas Gohr elseif (preg_match($regverfirefox,$ua,$m)){ 85514d99ec0SAndreas Gohr $type = 'browser'; 85614d99ec0SAndreas Gohr $ver = $m[1]; 85714d99ec0SAndreas Gohr $name = 'firefox'; 85814d99ec0SAndreas Gohr } 85914d99ec0SAndreas Gohr # Subversion ? 86014d99ec0SAndreas Gohr elseif (preg_match($regversvn,$ua,$m)){ 86114d99ec0SAndreas Gohr $type = 'rcs'; 86214d99ec0SAndreas Gohr $ver = $m[1]; 86314d99ec0SAndreas Gohr $name = 'svn'; 86414d99ec0SAndreas Gohr } 86514d99ec0SAndreas Gohr # Netscape 6.x, 7.x ... ? 86614d99ec0SAndreas Gohr elseif (preg_match($regvernetscape,$ua,$m)){ 86714d99ec0SAndreas Gohr $type = 'browser'; 86814d99ec0SAndreas Gohr $ver = $m[1]; 86914d99ec0SAndreas Gohr $name = 'netscape'; 87014d99ec0SAndreas Gohr } 87114d99ec0SAndreas Gohr # Netscape 3.x, 4.x ... ? 87214d99ec0SAndreas Gohr elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){ 87314d99ec0SAndreas Gohr $type = 'browser'; 87414d99ec0SAndreas Gohr $ver = $m[2]; 87514d99ec0SAndreas Gohr $name = 'netscape'; 87614d99ec0SAndreas Gohr }else{ 87714d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/browsers.php'); 87814d99ec0SAndreas Gohr foreach($BrowsersSearchIDOrder as $regex){ 87914d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 88014d99ec0SAndreas Gohr // it's a browser! 88114d99ec0SAndreas Gohr $type = 'browser'; 88214d99ec0SAndreas Gohr $name = strtolower($regex); 88314d99ec0SAndreas Gohr break; 88414d99ec0SAndreas Gohr } 88514d99ec0SAndreas Gohr } 88614d99ec0SAndreas Gohr } 88714d99ec0SAndreas Gohr 88875fa767dSAndreas Gohr // check versions for Safari and Opera 88975fa767dSAndreas Gohr if($name == 'safari'){ 89075fa767dSAndreas Gohr if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){ 89175fa767dSAndreas Gohr $ver = $BrowsersSafariBuildToVersionHash[$match[1]]; 89275fa767dSAndreas Gohr } 89375fa767dSAndreas Gohr }elseif($name == 'opera'){ 89475fa767dSAndreas Gohr if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){ 89575fa767dSAndreas Gohr $ver = $match[1]; 89675fa767dSAndreas Gohr } 89775fa767dSAndreas Gohr } 89875fa767dSAndreas Gohr 89975fa767dSAndreas Gohr 90014d99ec0SAndreas Gohr // check OS for browsers 90114d99ec0SAndreas Gohr if($type == 'browser'){ 90214d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/operating_systems.php'); 90314d99ec0SAndreas Gohr foreach($OSSearchIDOrder as $regex){ 90414d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 90514d99ec0SAndreas Gohr $os = $OSHashID[$regex]; 90614d99ec0SAndreas Gohr break; 90714d99ec0SAndreas Gohr } 90814d99ec0SAndreas Gohr } 90914d99ec0SAndreas Gohr 91014d99ec0SAndreas Gohr } 91114d99ec0SAndreas Gohr 91214d99ec0SAndreas Gohr // are we done now? 91314d99ec0SAndreas Gohr if($name) return $name; 91414d99ec0SAndreas Gohr 91514d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/robots.php'); 91614d99ec0SAndreas Gohr foreach($RobotsSearchIDOrder as $regex){ 91714d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 91814d99ec0SAndreas Gohr // it's a robot! 91914d99ec0SAndreas Gohr $type = 'robot'; 92014d99ec0SAndreas Gohr return strtolower($regex); 92114d99ec0SAndreas Gohr } 92214d99ec0SAndreas Gohr } 92314d99ec0SAndreas Gohr 92414d99ec0SAndreas Gohr // dunno 9251878f16fSAndreas Gohr return ''; 9261878f16fSAndreas Gohr } 9271878f16fSAndreas Gohr 9281878f16fSAndreas Gohr /** 92914d99ec0SAndreas Gohr * 93014d99ec0SAndreas Gohr * @fixme: put search engine queries in seperate table here 93114d99ec0SAndreas Gohr */ 93214d99ec0SAndreas Gohr function log_search($referer,&$type){ 93314d99ec0SAndreas Gohr $referer = strtr($referer,' +','__'); 93414d99ec0SAndreas Gohr $referer = strtolower($referer); 93514d99ec0SAndreas Gohr 93614d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/search_engines.php'); 93714d99ec0SAndreas Gohr 93814d99ec0SAndreas Gohr foreach($SearchEnginesSearchIDOrder as $regex){ 93914d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$referer)){ 94014d99ec0SAndreas Gohr if(!$NotSearchEnginesKeys[$regex] || 94114d99ec0SAndreas Gohr !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){ 94214d99ec0SAndreas Gohr // it's a search engine! 94314d99ec0SAndreas Gohr $type = 'search'; 94414d99ec0SAndreas Gohr break; 94514d99ec0SAndreas Gohr } 94614d99ec0SAndreas Gohr } 94714d99ec0SAndreas Gohr } 94814d99ec0SAndreas Gohr if($type != 'search') return; // we're done here 94914d99ec0SAndreas Gohr 95014d99ec0SAndreas Gohr #fixme now do the keyword magic! 95114d99ec0SAndreas Gohr } 95214d99ec0SAndreas Gohr 95314d99ec0SAndreas Gohr /** 95414d99ec0SAndreas Gohr * Resolve IP to country/city 95514d99ec0SAndreas Gohr */ 95614d99ec0SAndreas Gohr function log_ip($ip){ 95714d99ec0SAndreas Gohr // check if IP already known and up-to-date 95814d99ec0SAndreas Gohr $sql = "SELECT ip 95914d99ec0SAndreas Gohr FROM ".$this->getConf('db_prefix')."iplocation 96014d99ec0SAndreas Gohr WHERE ip ='".addslashes($ip)."' 96114d99ec0SAndreas Gohr AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)"; 96214d99ec0SAndreas Gohr $result = $this->runSQL($sql); 96314d99ec0SAndreas Gohr if($result[0]['ip']) return; 96414d99ec0SAndreas Gohr 96514d99ec0SAndreas Gohr $http = new DokuHTTPClient(); 96614d99ec0SAndreas Gohr $http->timeout = 10; 96714d99ec0SAndreas Gohr $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip); 96814d99ec0SAndreas Gohr 96914d99ec0SAndreas Gohr if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){ 97014d99ec0SAndreas Gohr $country = addslashes(trim($match[1])); 97114d99ec0SAndreas Gohr $code = addslashes(strtolower(trim($match[2]))); 97214d99ec0SAndreas Gohr $city = addslashes(trim($match[3])); 97314d99ec0SAndreas Gohr $host = addslashes(gethostbyaddr($ip)); 97414d99ec0SAndreas Gohr $ip = addslashes($ip); 97514d99ec0SAndreas Gohr 97614d99ec0SAndreas Gohr $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation 97714d99ec0SAndreas Gohr SET ip = '$ip', 97814d99ec0SAndreas Gohr country = '$country', 97914d99ec0SAndreas Gohr code = '$code', 98014d99ec0SAndreas Gohr city = '$city', 98114d99ec0SAndreas Gohr host = '$host'"; 98214d99ec0SAndreas Gohr $this->runSQL($sql); 98314d99ec0SAndreas Gohr } 98414d99ec0SAndreas Gohr } 98514d99ec0SAndreas Gohr 98614d99ec0SAndreas Gohr /** 987e25286daSAndreas Gohr * log a click on an external link 988e25286daSAndreas Gohr * 989e25286daSAndreas Gohr * called from log.php 990e25286daSAndreas Gohr */ 991e25286daSAndreas Gohr function log_outgoing(){ 992e25286daSAndreas Gohr if(!$_REQUEST['ol']) return; 993e25286daSAndreas Gohr 994e25286daSAndreas Gohr $link_md5 = md5($link); 995e25286daSAndreas Gohr $link = addslashes($_REQUEST['ol']); 996e25286daSAndreas Gohr $session = addslashes(session_id()); 997*d8c4d85eSAndreas Gohr $page = addslashes($_REQUEST['p']); 998e25286daSAndreas Gohr 999e25286daSAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks 1000e25286daSAndreas Gohr SET dt = NOW(), 1001e25286daSAndreas Gohr session = '$session', 1002*d8c4d85eSAndreas Gohr page = '$page', 1003e25286daSAndreas Gohr link_md5 = '$link_md5', 1004e25286daSAndreas Gohr link = '$link'"; 1005e25286daSAndreas Gohr $ok = $this->runSQL($sql); 1006e25286daSAndreas Gohr if(is_null($ok)){ 1007e25286daSAndreas Gohr global $MSG; 1008e25286daSAndreas Gohr print_r($MSG); 1009e25286daSAndreas Gohr } 1010e25286daSAndreas Gohr } 1011e25286daSAndreas Gohr 1012e25286daSAndreas Gohr /** 10131878f16fSAndreas Gohr * log a page access 10141878f16fSAndreas Gohr * 10151878f16fSAndreas Gohr * called from log.php 10161878f16fSAndreas Gohr */ 10171878f16fSAndreas Gohr function log_access(){ 101894171ff3SAndreas Gohr if(!$_REQUEST['p']) return; 101994171ff3SAndreas Gohr 102014d99ec0SAndreas Gohr # FIXME check referer against blacklist and drop logging for bad boys 102114d99ec0SAndreas Gohr 102214d99ec0SAndreas Gohr // handle referer 102314d99ec0SAndreas Gohr $referer = trim($_REQUEST['r']); 102414d99ec0SAndreas Gohr if($referer){ 102514d99ec0SAndreas Gohr $ref = addslashes($referer); 102614d99ec0SAndreas Gohr $ref_md5 = ($ref) ? md5($referer) : ''; 102714d99ec0SAndreas Gohr if(strpos($referer,DOKU_URL) === 0){ 102814d99ec0SAndreas Gohr $ref_type = 'internal'; 102914d99ec0SAndreas Gohr }else{ 103014d99ec0SAndreas Gohr $ref_type = 'external'; 103114d99ec0SAndreas Gohr $this->log_search($referer,$ref_type); 103214d99ec0SAndreas Gohr } 103314d99ec0SAndreas Gohr }else{ 103414d99ec0SAndreas Gohr $ref = ''; 103514d99ec0SAndreas Gohr $ref_md5 = ''; 103614d99ec0SAndreas Gohr $ref_type = ''; 103714d99ec0SAndreas Gohr } 103814d99ec0SAndreas Gohr 103914d99ec0SAndreas Gohr // handle user agent 104014d99ec0SAndreas Gohr $agent = trim($_SERVER['HTTP_USER_AGENT']); 104114d99ec0SAndreas Gohr 104214d99ec0SAndreas Gohr $ua = addslashes($agent); 104314d99ec0SAndreas Gohr $ua_type = ''; 104414d99ec0SAndreas Gohr $ua_ver = ''; 104514d99ec0SAndreas Gohr $os = ''; 104614d99ec0SAndreas Gohr $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os)); 104714d99ec0SAndreas Gohr 10481878f16fSAndreas Gohr $page = addslashes($_REQUEST['p']); 10491878f16fSAndreas Gohr $ip = addslashes($_SERVER['REMOTE_ADDR']); 10501878f16fSAndreas Gohr $sx = (int) $_REQUEST['sx']; 10511878f16fSAndreas Gohr $sy = (int) $_REQUEST['sy']; 10521878f16fSAndreas Gohr $vx = (int) $_REQUEST['vx']; 10531878f16fSAndreas Gohr $vy = (int) $_REQUEST['vy']; 105475fa767dSAndreas Gohr $js = (int) $_REQUEST['js']; 10553c0acc14SAndreas Gohr $uid = addslashes($_REQUEST['uid']); 10561878f16fSAndreas Gohr $user = addslashes($_SERVER['REMOTE_USER']); 10571878f16fSAndreas Gohr $session = addslashes(session_id()); 10583c0acc14SAndreas Gohr if(!$uid) $uid = $session; 10591878f16fSAndreas Gohr 106094171ff3SAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access 106175fa767dSAndreas Gohr SET dt = NOW(), 106275fa767dSAndreas Gohr page = '$page', 10631878f16fSAndreas Gohr ip = '$ip', 10641878f16fSAndreas Gohr ua = '$ua', 10651878f16fSAndreas Gohr ua_info = '$ua_info', 106614d99ec0SAndreas Gohr ua_type = '$ua_type', 106714d99ec0SAndreas Gohr ua_ver = '$ua_ver', 106814d99ec0SAndreas Gohr os = '$os', 10691878f16fSAndreas Gohr ref = '$ref', 107094171ff3SAndreas Gohr ref_md5 = '$ref_md5', 107114d99ec0SAndreas Gohr ref_type = '$ref_type', 10721878f16fSAndreas Gohr screen_x = '$sx', 10731878f16fSAndreas Gohr screen_y = '$sy', 10741878f16fSAndreas Gohr view_x = '$vx', 10751878f16fSAndreas Gohr view_y = '$vy', 107675fa767dSAndreas Gohr js = '$js', 10771878f16fSAndreas Gohr user = '$user', 10783c0acc14SAndreas Gohr session = '$session', 10793c0acc14SAndreas Gohr uid = '$uid'"; 10801878f16fSAndreas Gohr $ok = $this->runSQL($sql); 10811878f16fSAndreas Gohr if(is_null($ok)){ 10821878f16fSAndreas Gohr global $MSG; 10831878f16fSAndreas Gohr print_r($MSG); 10841878f16fSAndreas Gohr } 108514d99ec0SAndreas Gohr 108614d99ec0SAndreas Gohr // resolve the IP 108714d99ec0SAndreas Gohr $this->log_ip($_SERVER['REMOTE_ADDR']); 10881878f16fSAndreas Gohr } 10891878f16fSAndreas Gohr 10901878f16fSAndreas Gohr /** 10911878f16fSAndreas Gohr * Just send a 1x1 pixel blank gif to the browser 10921878f16fSAndreas Gohr * 10931878f16fSAndreas Gohr * @called from log.php 10941878f16fSAndreas Gohr * 10951878f16fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 10961878f16fSAndreas Gohr * @author Harry Fuecks <fuecks@gmail.com> 10971878f16fSAndreas Gohr */ 10981878f16fSAndreas Gohr function sendGIF(){ 10991878f16fSAndreas Gohr $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7'); 11001878f16fSAndreas Gohr header('Content-Type: image/gif'); 11011878f16fSAndreas Gohr header('Content-Length: '.strlen($img)); 11021878f16fSAndreas Gohr header('Connection: Close'); 11031878f16fSAndreas Gohr print $img; 11041878f16fSAndreas Gohr flush(); 11051878f16fSAndreas Gohr // Browser should drop connection after this 11061878f16fSAndreas Gohr // Thinks it's got the whole image 11071878f16fSAndreas Gohr } 11081878f16fSAndreas Gohr 11091878f16fSAndreas Gohr} 1110