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; 859da6395dSAndreas Gohr case 'referer': 869da6395dSAndreas Gohr $this->html_referer(); 879da6395dSAndreas Gohr break; 8814d99ec0SAndreas Gohr default: 899da6395dSAndreas Gohr $this->html_dashboard(); 9014d99ec0SAndreas Gohr } 9114d99ec0SAndreas Gohr } 9214d99ec0SAndreas Gohr 939da6395dSAndreas Gohr function html_toc(){ 949da6395dSAndreas Gohr echo '<div class="toc">'; 959da6395dSAndreas Gohr echo '<div class="tocheader toctoggle" id="toc__header">'; 969da6395dSAndreas Gohr echo 'Detailed Statistics'; 979da6395dSAndreas Gohr echo '</div>'; 989da6395dSAndreas Gohr echo '<div id="toc__inside">'; 999da6395dSAndreas Gohr echo '<ul class="toc">'; 1009da6395dSAndreas Gohr 1019da6395dSAndreas Gohr echo '<li><div class="li">'; 1029da6395dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Dashboard</a>'; 1039da6395dSAndreas Gohr echo '</div></li>'; 1049da6395dSAndreas Gohr 1059da6395dSAndreas Gohr echo '<li><div class="li">'; 1069da6395dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=page&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Pages</a>'; 1079da6395dSAndreas Gohr echo '</div></li>'; 1089da6395dSAndreas Gohr 1099da6395dSAndreas Gohr echo '<li><div class="li">'; 1109da6395dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=referer&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Incoming Links</a>'; 1119da6395dSAndreas Gohr echo '</div></li>'; 1129da6395dSAndreas Gohr 1139da6395dSAndreas Gohr echo '<li><div class="li">'; 1149da6395dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=country&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Countries</a>'; 1159da6395dSAndreas Gohr echo '</div></li>'; 1169da6395dSAndreas Gohr 1179da6395dSAndreas Gohr echo '</ul>'; 1189da6395dSAndreas Gohr echo '</div>'; 1199da6395dSAndreas Gohr echo '</div>'; 1209da6395dSAndreas Gohr } 1219da6395dSAndreas Gohr 122264f1744SAndreas Gohr /** 123264f1744SAndreas Gohr * Print the time selection menu 124264f1744SAndreas Gohr */ 12514d99ec0SAndreas Gohr function html_timeselect(){ 126264f1744SAndreas Gohr $now = date('Y-m-d'); 127264f1744SAndreas Gohr $yday = date('Y-m-d',time()-(60*60*24)); 128264f1744SAndreas Gohr $week = date('Y-m-d',time()-(60*60*24*7)); 129264f1744SAndreas Gohr $month = date('Y-m-d',time()-(60*60*24*30)); 13014d99ec0SAndreas Gohr 131264f1744SAndreas Gohr echo '<div class="plg_stats_timeselect">'; 132264f1744SAndreas Gohr echo '<span>Select the timeframe:</span>'; 133264f1744SAndreas Gohr echo '<ul>'; 134264f1744SAndreas Gohr 135264f1744SAndreas Gohr echo '<li>'; 13695eb68e6SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$now.'&t='.$now.'&s='.$this->start.'">'; 137264f1744SAndreas Gohr echo 'today'; 138264f1744SAndreas Gohr echo '</a>'; 139264f1744SAndreas Gohr echo '</li>'; 140264f1744SAndreas Gohr 141264f1744SAndreas Gohr echo '<li>'; 14295eb68e6SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$yday.'&t='.$yday.'&s='.$this->start.'">'; 143264f1744SAndreas Gohr echo 'yesterday'; 144264f1744SAndreas Gohr echo '</a>'; 145264f1744SAndreas Gohr echo '</li>'; 146264f1744SAndreas Gohr 147264f1744SAndreas Gohr echo '<li>'; 14895eb68e6SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$week.'&t='.$now.'&s='.$this->start.'">'; 149264f1744SAndreas Gohr echo 'last 7 days'; 150264f1744SAndreas Gohr echo '</a>'; 151264f1744SAndreas Gohr echo '</li>'; 152264f1744SAndreas Gohr 153264f1744SAndreas Gohr echo '<li>'; 15495eb68e6SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$month.'&t='.$now.'&s='.$this->start.'">'; 155264f1744SAndreas Gohr echo 'last 30 days'; 156264f1744SAndreas Gohr echo '</a>'; 157264f1744SAndreas Gohr echo '</li>'; 158264f1744SAndreas Gohr 159264f1744SAndreas Gohr echo '</ul>'; 160264f1744SAndreas Gohr 161264f1744SAndreas Gohr 162264f1744SAndreas Gohr echo '<form action="" method="get">'; 163264f1744SAndreas Gohr echo '<input type="hidden" name="do" value="admin" />'; 164264f1744SAndreas Gohr echo '<input type="hidden" name="page" value="statistics" />'; 165264f1744SAndreas Gohr echo '<input type="hidden" name="opt" value="'.$this->opt.'" />'; 16695eb68e6SAndreas Gohr echo '<input type="hidden" name="s" value="'.$this->start.'" />'; 167264f1744SAndreas Gohr echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />'; 168264f1744SAndreas Gohr echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />'; 169264f1744SAndreas Gohr echo '<input type="submit" value="go" class="button" />'; 17014d99ec0SAndreas Gohr echo '</form>'; 171264f1744SAndreas Gohr 172264f1744SAndreas Gohr echo '</div>'; 17314d99ec0SAndreas Gohr } 17414d99ec0SAndreas Gohr 17514d99ec0SAndreas Gohr 176f5f32cbfSAndreas Gohr /** 177f5f32cbfSAndreas Gohr * Print an introductionary screen 178f5f32cbfSAndreas Gohr */ 17914d99ec0SAndreas Gohr function html_dashboard(){ 180*2812a751SAndreas Gohr echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists 181*2812a751SAndreas Gohr choose a topic from the list.</p>'; 182*2812a751SAndreas Gohr 183*2812a751SAndreas Gohr 184264f1744SAndreas Gohr echo '<div class="plg_stats_dashboard">'; 185264f1744SAndreas Gohr 186*2812a751SAndreas Gohr // general info 187*2812a751SAndreas Gohr echo '<div class="plg_stats_top">'; 188*2812a751SAndreas Gohr $result = $this->sql_aggregate($this->tlimit); 189*2812a751SAndreas Gohr echo '<ul>'; 190*2812a751SAndreas Gohr echo '<li><span>'.$result['pageviews'].'</span> page views</li>'; 191*2812a751SAndreas Gohr echo '<li><span>'.$result['sessions'].'</span> visitors (sessions)</li>'; 192*2812a751SAndreas Gohr echo '<li><span>'.$result['users'].'</span> logged in users</li>'; 193*2812a751SAndreas Gohr 194*2812a751SAndreas Gohr echo '</ul>'; 195*2812a751SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&f='.$this->from.'&t='.$this->to.'" />'; 196*2812a751SAndreas Gohr echo '</div>'; 197*2812a751SAndreas Gohr 19814d99ec0SAndreas Gohr 19987d5e44bSAndreas Gohr // top pages today 200264f1744SAndreas Gohr echo '<div>'; 201264f1744SAndreas Gohr echo '<h2>Most popular pages</h2>'; 20295eb68e6SAndreas Gohr $result = $this->sql_pages($this->tlimit,$this->start,15); 203*2812a751SAndreas Gohr $this->html_resulttable($result); 204264f1744SAndreas Gohr echo '</div>'; 20587d5e44bSAndreas Gohr 20687d5e44bSAndreas Gohr // top referer today 207264f1744SAndreas Gohr echo '<div>'; 208264f1744SAndreas Gohr echo '<h2>Top incoming links</h2>'; 20995eb68e6SAndreas Gohr $result = $this->sql_referer($this->tlimit,$this->start,15); 210*2812a751SAndreas Gohr $this->html_resulttable($result); 211264f1744SAndreas Gohr echo '</div>'; 21254f6c432SAndreas Gohr 21354f6c432SAndreas Gohr // top countries today 214264f1744SAndreas Gohr echo '<div>'; 215264f1744SAndreas Gohr echo '<h2>Visitor\'s top countries</h2>'; 21695eb68e6SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&f='.$this->from.'&t='.$this->to.'" />'; 21795eb68e6SAndreas Gohr// $result = $this->sql_countries($this->tlimit,$this->start,15); 21895eb68e6SAndreas Gohr// $this->html_resulttable($result,array('','Countries','Count')); 219264f1744SAndreas Gohr echo '</div>'; 220264f1744SAndreas Gohr 221264f1744SAndreas Gohr echo '</div>'; 22214d99ec0SAndreas Gohr } 22314d99ec0SAndreas Gohr 2249da6395dSAndreas Gohr function html_country(){ 2259da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 2269da6395dSAndreas Gohr echo '<h2>Visitor\'s Countries</h2>'; 2279da6395dSAndreas Gohr $result = $this->sql_countries($this->tlimit,$this->start,150); 228*2812a751SAndreas Gohr $this->html_resulttable($result); 2299da6395dSAndreas Gohr echo '</div>'; 2309da6395dSAndreas Gohr } 2319da6395dSAndreas Gohr 2329da6395dSAndreas Gohr function html_page(){ 2339da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 2349da6395dSAndreas Gohr echo '<h2>Popular Pages</h2>'; 2359da6395dSAndreas Gohr $result = $this->sql_pages($this->tlimit,$this->start,150); 236*2812a751SAndreas Gohr $this->html_resulttable($result); 2379da6395dSAndreas Gohr echo '</div>'; 2389da6395dSAndreas Gohr } 2399da6395dSAndreas Gohr 2409da6395dSAndreas Gohr function html_referer(){ 2419da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 2429da6395dSAndreas Gohr echo '<h2>Incoming Links</h2>'; 243*2812a751SAndreas Gohr $result = $this->sql_aggregate($this->tlimit); 244*2812a751SAndreas Gohr 245*2812a751SAndreas Gohr $all = $result['search']+$result['external']+$result['direct']; 246*2812a751SAndreas Gohr 247*2812a751SAndreas Gohr printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses, 248*2812a751SAndreas Gohr %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through 249*2812a751SAndreas Gohr links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all), 250*2812a751SAndreas Gohr $result['search'],(100*$result['search']/$all),$result['external'], 251*2812a751SAndreas Gohr (100*$result['external']/$all)); 252*2812a751SAndreas Gohr 2539da6395dSAndreas Gohr $result = $this->sql_referer($this->tlimit,$this->start,150); 254*2812a751SAndreas Gohr $this->html_resulttable($result); 2559da6395dSAndreas Gohr echo '</div>'; 2569da6395dSAndreas Gohr } 2579da6395dSAndreas Gohr 2589da6395dSAndreas Gohr 2599da6395dSAndreas Gohr 26014d99ec0SAndreas Gohr /** 26114d99ec0SAndreas Gohr * Display a result in a HTML table 26214d99ec0SAndreas Gohr */ 263*2812a751SAndreas Gohr function html_resulttable($result,$header=''){ 26414d99ec0SAndreas Gohr echo '<table>'; 265*2812a751SAndreas Gohr if(is_array($header)){ 26614d99ec0SAndreas Gohr echo '<tr>'; 26714d99ec0SAndreas Gohr foreach($header as $h){ 26814d99ec0SAndreas Gohr echo '<th>'.hsc($h).'</th>'; 26914d99ec0SAndreas Gohr } 27014d99ec0SAndreas Gohr echo '</tr>'; 271*2812a751SAndreas Gohr } 27214d99ec0SAndreas Gohr 27314d99ec0SAndreas Gohr foreach($result as $row){ 27414d99ec0SAndreas Gohr echo '<tr>'; 27514d99ec0SAndreas Gohr foreach($row as $k => $v){ 276*2812a751SAndreas Gohr echo '<td class="plg_stats_X'.$k.'">'; 27714d99ec0SAndreas Gohr if($k == 'page'){ 27814d99ec0SAndreas Gohr echo '<a href="'.wl($v).'" class="wikilink1">'; 27914d99ec0SAndreas Gohr echo hsc($v); 28014d99ec0SAndreas Gohr echo '</a>'; 28114d99ec0SAndreas Gohr }elseif($k == 'url'){ 28254f6c432SAndreas Gohr $url = hsc($v); 283*2812a751SAndreas Gohr if(strlen($url) > 45){ 284*2812a751SAndreas Gohr $url = substr($url,0,30).' … '.substr($url,-15); 28554f6c432SAndreas Gohr } 28614d99ec0SAndreas Gohr echo '<a href="'.$v.'" class="urlextern">'; 28754f6c432SAndreas Gohr echo $url; 28814d99ec0SAndreas Gohr echo '</a>'; 28914d99ec0SAndreas Gohr }elseif($k == 'html'){ 29014d99ec0SAndreas Gohr echo $v; 291f5f32cbfSAndreas Gohr }elseif($k == 'cflag'){ 29295eb68e6SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12"/>'; 29314d99ec0SAndreas Gohr }else{ 29414d99ec0SAndreas Gohr echo hsc($v); 29514d99ec0SAndreas Gohr } 29614d99ec0SAndreas Gohr echo '</td>'; 29714d99ec0SAndreas Gohr } 29814d99ec0SAndreas Gohr echo '</tr>'; 29914d99ec0SAndreas Gohr } 30014d99ec0SAndreas Gohr echo '</table>'; 3011878f16fSAndreas Gohr } 3021878f16fSAndreas Gohr 30395eb68e6SAndreas Gohr /** 30495eb68e6SAndreas Gohr * Create an image 30595eb68e6SAndreas Gohr */ 30695eb68e6SAndreas Gohr function img_build($img){ 30795eb68e6SAndreas Gohr include(dirname(__FILE__).'/inc/AGC.class.php'); 30895eb68e6SAndreas Gohr 30995eb68e6SAndreas Gohr switch($img){ 31095eb68e6SAndreas Gohr case 'country': 31195eb68e6SAndreas Gohr // build top countries + other 31295eb68e6SAndreas Gohr $result = $this->sql_countries($this->tlimit,$this->start,0); 31395eb68e6SAndreas Gohr $data = array(); 31495eb68e6SAndreas Gohr $top = 0; 31595eb68e6SAndreas Gohr foreach($result as $row){ 31695eb68e6SAndreas Gohr if($top < 7){ 31795eb68e6SAndreas Gohr $data[$row['country']] = $row['cnt']; 31895eb68e6SAndreas Gohr }else{ 31995eb68e6SAndreas Gohr $data['other'] += $row['cnt']; 32095eb68e6SAndreas Gohr } 32195eb68e6SAndreas Gohr $top++; 32295eb68e6SAndreas Gohr } 32395eb68e6SAndreas Gohr $pie = new AGC(300, 200); 32495eb68e6SAndreas Gohr $pie->setProp("showkey",true); 32595eb68e6SAndreas Gohr $pie->setProp("showval",false); 32695eb68e6SAndreas Gohr $pie->setProp("showgrid",false); 32795eb68e6SAndreas Gohr $pie->setProp("type","pie"); 32895eb68e6SAndreas Gohr $pie->setProp("keyinfo",1); 32995eb68e6SAndreas Gohr $pie->setProp("keysize",8); 33095eb68e6SAndreas Gohr $pie->setProp("keywidspc",-50); 33195eb68e6SAndreas Gohr $pie->setProp("key",array_keys($data)); 33295eb68e6SAndreas Gohr $pie->addBulkPoints(array_values($data)); 33395eb68e6SAndreas Gohr @$pie->graph(); 33495eb68e6SAndreas Gohr $pie->showGraph(); 33595eb68e6SAndreas Gohr break; 336*2812a751SAndreas Gohr case 'trend': 337*2812a751SAndreas Gohr $hours = ($this->from == $this->to); 338*2812a751SAndreas Gohr $result = $this->sql_trend($this->tlimit,$hours); 339*2812a751SAndreas Gohr $data1 = array(); 340*2812a751SAndreas Gohr $data2 = array(); 341*2812a751SAndreas Gohr 342*2812a751SAndreas Gohr $graph = new AGC(400, 150); 343*2812a751SAndreas Gohr $graph->setProp("type","bar"); 344*2812a751SAndreas Gohr $graph->setProp("showgrid",false); 345*2812a751SAndreas Gohr $graph->setProp("barwidth",.8); 346*2812a751SAndreas Gohr $graph->setColor('color',0,'blue'); 347*2812a751SAndreas Gohr $graph->setColor('color',1,'red'); 348*2812a751SAndreas Gohr 349*2812a751SAndreas Gohr if($hours){ 350*2812a751SAndreas Gohr //preset $hours 351*2812a751SAndreas Gohr for($i=0;$i<24;$i++){ 352*2812a751SAndreas Gohr $data1[$i] = 0; 353*2812a751SAndreas Gohr $data2[$i] = 0; 354*2812a751SAndreas Gohr $graph->setProp("scale",array(' 0h',' 4h',' 8h',' 12h',' 16h',' 20h',' 24h')); 355*2812a751SAndreas Gohr } 356*2812a751SAndreas Gohr }else{ 357*2812a751SAndreas Gohr $graph->setProp("scale",array(next(array_keys($data1)),$this->to)); 358*2812a751SAndreas Gohr } 359*2812a751SAndreas Gohr 360*2812a751SAndreas Gohr foreach($result as $row){ 361*2812a751SAndreas Gohr $data1[$row['time']] = $row['pageviews']; 362*2812a751SAndreas Gohr $data2[$row['time']] = $row['sessions']; 363*2812a751SAndreas Gohr } 364*2812a751SAndreas Gohr 365*2812a751SAndreas Gohr foreach($data1 as $key => $val){ 366*2812a751SAndreas Gohr $graph->addPoint($val,$key,0); 367*2812a751SAndreas Gohr } 368*2812a751SAndreas Gohr foreach($data2 as $key => $val){ 369*2812a751SAndreas Gohr $graph->addPoint($val,$key,1); 370*2812a751SAndreas Gohr } 371*2812a751SAndreas Gohr 372*2812a751SAndreas Gohr @$graph->graph(); 373*2812a751SAndreas Gohr $graph->showGraph(); 374*2812a751SAndreas Gohr 37595eb68e6SAndreas Gohr default: 37695eb68e6SAndreas Gohr $this->sendGIF(); 37795eb68e6SAndreas Gohr } 37895eb68e6SAndreas Gohr } 37995eb68e6SAndreas Gohr 38095eb68e6SAndreas Gohr 381*2812a751SAndreas Gohr /** 382*2812a751SAndreas Gohr * Return some aggregated statistics 383*2812a751SAndreas Gohr */ 384*2812a751SAndreas Gohr function sql_aggregate($tlimit){ 385*2812a751SAndreas Gohr $data = array(); 386*2812a751SAndreas Gohr 387*2812a751SAndreas Gohr $sql = "SELECT ref_type, COUNT(*) as cnt 388*2812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 389*2812a751SAndreas Gohr WHERE $tlimit 390*2812a751SAndreas Gohr AND ua_type = 'browser' 391*2812a751SAndreas Gohr GROUP BY ref_type"; 392*2812a751SAndreas Gohr $result = $this->runSQL($sql); 393*2812a751SAndreas Gohr 394*2812a751SAndreas Gohr foreach($result as $row){ 395*2812a751SAndreas Gohr if($row['ref_type'] == 'search') $data['search'] = $row['cnt']; 396*2812a751SAndreas Gohr if($row['ref_type'] == 'external') $data['external'] = $row['cnt']; 397*2812a751SAndreas Gohr if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt']; 398*2812a751SAndreas Gohr if($row['ref_type'] == '') $data['direct'] = $row['cnt']; 399*2812a751SAndreas Gohr } 400*2812a751SAndreas Gohr 401*2812a751SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as sessions, 402*2812a751SAndreas Gohr COUNT(session) as views, 403*2812a751SAndreas Gohr COUNT(DISTINCT user) as users 404*2812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 405*2812a751SAndreas Gohr WHERE $tlimit 406*2812a751SAndreas Gohr AND ua_type = 'browser'"; 407*2812a751SAndreas Gohr $result = $this->runSQL($sql); 408*2812a751SAndreas Gohr 409*2812a751SAndreas Gohr $data['users'] = $result[0]['users'] - 1; // subtract empty user 410*2812a751SAndreas Gohr $data['sessions'] = $result[0]['sessions']; 411*2812a751SAndreas Gohr $data['pageviews'] = $result[0]['views']; 412*2812a751SAndreas Gohr 413*2812a751SAndreas Gohr $sql = "SELECT COUNT(id) as robots 414*2812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 415*2812a751SAndreas Gohr WHERE $tlimit 416*2812a751SAndreas Gohr AND ua_type = 'robot'"; 417*2812a751SAndreas Gohr $result = $this->runSQL($sql); 418*2812a751SAndreas Gohr $data['robots'] = $result[0]['robots']; 419*2812a751SAndreas Gohr 420*2812a751SAndreas Gohr return $data; 421*2812a751SAndreas Gohr } 422*2812a751SAndreas Gohr 423*2812a751SAndreas Gohr function sql_trend($tlimit,$hours=false){ 424*2812a751SAndreas Gohr if($hours){ 425*2812a751SAndreas Gohr $sql = "SELECT HOUR(dt) as time, 426*2812a751SAndreas Gohr COUNT(DISTINCT session) as sessions, 427*2812a751SAndreas Gohr COUNT(session) as pageviews 428*2812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 429*2812a751SAndreas Gohr WHERE $tlimit 430*2812a751SAndreas Gohr AND ua_type = 'browser' 431*2812a751SAndreas Gohr GROUP BY HOUR(dt) 432*2812a751SAndreas Gohr ORDER BY time"; 433*2812a751SAndreas Gohr }else{ 434*2812a751SAndreas Gohr $sql = "SELECT DATE(dt) as time, 435*2812a751SAndreas Gohr COUNT(DISTINCT session) as sessions, 436*2812a751SAndreas Gohr COUNT(session) as pageviews 437*2812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 438*2812a751SAndreas Gohr WHERE $tlimit 439*2812a751SAndreas Gohr AND ua_type = 'browser' 440*2812a751SAndreas Gohr GROUP BY DATE(dt) 441*2812a751SAndreas Gohr ORDER BY time"; 442*2812a751SAndreas Gohr } 443*2812a751SAndreas Gohr return $this->runSQL($sql); 444*2812a751SAndreas Gohr } 445*2812a751SAndreas Gohr 44695eb68e6SAndreas Gohr function sql_pages($tlimit,$start=0,$limit=20){ 447*2812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, page 44895eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 44995eb68e6SAndreas Gohr WHERE $tlimit 45095eb68e6SAndreas Gohr AND ua_type = 'browser' 45195eb68e6SAndreas Gohr GROUP BY page 45295eb68e6SAndreas Gohr ORDER BY cnt DESC, page". 45395eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 45495eb68e6SAndreas Gohr return $this->runSQL($sql); 45595eb68e6SAndreas Gohr } 45695eb68e6SAndreas Gohr 45795eb68e6SAndreas Gohr function sql_referer($tlimit,$start=0,$limit=20){ 458*2812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 45995eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 46095eb68e6SAndreas Gohr WHERE $tlimit 46195eb68e6SAndreas Gohr AND ua_type = 'browser' 46295eb68e6SAndreas Gohr AND ref_type = 'external' 46395eb68e6SAndreas Gohr GROUP BY ref_md5 46495eb68e6SAndreas Gohr ORDER BY cnt DESC, url". 46595eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 46695eb68e6SAndreas Gohr return $this->runSQL($sql); 46795eb68e6SAndreas Gohr } 46895eb68e6SAndreas Gohr 46995eb68e6SAndreas Gohr function sql_countries($tlimit,$start=0,$limit=20){ 470*2812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, B.code AS cflag, B.country 47195eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A, 47295eb68e6SAndreas Gohr ".$this->getConf('db_prefix')."iplocation as B 47395eb68e6SAndreas Gohr WHERE $tlimit 47495eb68e6SAndreas Gohr AND A.ip = B.ip 47595eb68e6SAndreas Gohr GROUP BY B.country 47695eb68e6SAndreas Gohr ORDER BY cnt DESC, B.country". 47795eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 47895eb68e6SAndreas Gohr return $this->runSQL($sql); 47995eb68e6SAndreas Gohr } 48095eb68e6SAndreas Gohr 48195eb68e6SAndreas Gohr /** 48295eb68e6SAndreas Gohr * Builds a limit clause 48395eb68e6SAndreas Gohr */ 48495eb68e6SAndreas Gohr function sql_limit($start,$limit){ 48595eb68e6SAndreas Gohr $start = (int) $start; 48695eb68e6SAndreas Gohr $limit = (int) $limit; 48795eb68e6SAndreas Gohr if($limit){ 48895eb68e6SAndreas Gohr return " LIMIT $start,$limit"; 48995eb68e6SAndreas Gohr }elseif($start){ 49095eb68e6SAndreas Gohr return " OFFSET $start"; 49195eb68e6SAndreas Gohr } 49295eb68e6SAndreas Gohr return ''; 49395eb68e6SAndreas Gohr } 4941878f16fSAndreas Gohr 4951878f16fSAndreas Gohr /** 49614d99ec0SAndreas Gohr * Return a link to the DB, opening the connection if needed 4971878f16fSAndreas Gohr */ 49814d99ec0SAndreas Gohr function dbLink(){ 4991878f16fSAndreas Gohr // connect to DB if needed 5001878f16fSAndreas Gohr if(!$this->dblink){ 5011878f16fSAndreas Gohr $this->dblink = mysql_connect($this->getConf('db_server'), 5021878f16fSAndreas Gohr $this->getConf('db_user'), 5031878f16fSAndreas Gohr $this->getConf('db_password')); 5041878f16fSAndreas Gohr if(!$this->dblink){ 5051878f16fSAndreas Gohr msg('DB Error: connection failed',-1); 5061878f16fSAndreas Gohr return null; 5071878f16fSAndreas Gohr } 5081878f16fSAndreas Gohr // set utf-8 5091878f16fSAndreas Gohr if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){ 5101878f16fSAndreas Gohr msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1); 5111878f16fSAndreas Gohr return null; 5121878f16fSAndreas Gohr } 5131878f16fSAndreas Gohr } 51414d99ec0SAndreas Gohr return $this->dblink; 51514d99ec0SAndreas Gohr } 5161878f16fSAndreas Gohr 51714d99ec0SAndreas Gohr /** 51814d99ec0SAndreas Gohr * Simple function to run a DB query 51914d99ec0SAndreas Gohr */ 52014d99ec0SAndreas Gohr function runSQL($sql_string) { 52114d99ec0SAndreas Gohr $link = $this->dbLink(); 52214d99ec0SAndreas Gohr 52314d99ec0SAndreas Gohr $result = mysql_db_query($this->conf['db_database'],$sql_string,$link); 52494171ff3SAndreas Gohr if(!$result){ 525*2812a751SAndreas Gohr msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1); 5261878f16fSAndreas Gohr return null; 5271878f16fSAndreas Gohr } 5281878f16fSAndreas Gohr 5291878f16fSAndreas Gohr $resultarray = array(); 5301878f16fSAndreas Gohr 5311878f16fSAndreas Gohr //mysql_db_query returns 1 on a insert statement -> no need to ask for results 5321878f16fSAndreas Gohr if ($result != 1) { 5331878f16fSAndreas Gohr for($i=0; $i< mysql_num_rows($result); $i++) { 5341878f16fSAndreas Gohr $temparray = mysql_fetch_assoc($result); 5351878f16fSAndreas Gohr $resultarray[]=$temparray; 5361878f16fSAndreas Gohr } 5371878f16fSAndreas Gohr mysql_free_result($result); 5381878f16fSAndreas Gohr } 5391878f16fSAndreas Gohr 54014d99ec0SAndreas Gohr if (mysql_insert_id($link)) { 54114d99ec0SAndreas Gohr $resultarray = mysql_insert_id($link); //give back ID on insert 5421878f16fSAndreas Gohr } 5431878f16fSAndreas Gohr 5441878f16fSAndreas Gohr return $resultarray; 5451878f16fSAndreas Gohr } 5461878f16fSAndreas Gohr 5471878f16fSAndreas Gohr /** 54814d99ec0SAndreas Gohr * Returns a short name for a User Agent and sets type, version and os info 5491878f16fSAndreas Gohr */ 55014d99ec0SAndreas Gohr function ua_info($ua,&$type,&$ver,&$os){ 55114d99ec0SAndreas Gohr $ua = strtr($ua,' +','__'); 55214d99ec0SAndreas Gohr $ua = strtolower($ua); 55314d99ec0SAndreas Gohr 55414d99ec0SAndreas Gohr // common browsers 55514d99ec0SAndreas Gohr $regvermsie = '/msie([+_ ]|)([\d\.]*)/i'; 55614d99ec0SAndreas Gohr $regvernetscape = '/netscape.?\/([\d\.]*)/i'; 55714d99ec0SAndreas Gohr $regverfirefox = '/firefox\/([\d\.]*)/i'; 55814d99ec0SAndreas Gohr $regversvn = '/svn\/([\d\.]*)/i'; 55914d99ec0SAndreas Gohr $regvermozilla = '/mozilla(\/|)([\d\.]*)/i'; 56014d99ec0SAndreas Gohr $regnotie = '/webtv|omniweb|opera/i'; 56114d99ec0SAndreas Gohr $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i'; 56214d99ec0SAndreas Gohr 56314d99ec0SAndreas Gohr $name = ''; 56414d99ec0SAndreas Gohr # IE ? 56514d99ec0SAndreas Gohr if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){ 56614d99ec0SAndreas Gohr $type = 'browser'; 56714d99ec0SAndreas Gohr $ver = $m[2]; 56814d99ec0SAndreas Gohr $name = 'msie'; 56914d99ec0SAndreas Gohr } 57014d99ec0SAndreas Gohr # Firefox ? 57114d99ec0SAndreas Gohr elseif (preg_match($regverfirefox,$ua,$m)){ 57214d99ec0SAndreas Gohr $type = 'browser'; 57314d99ec0SAndreas Gohr $ver = $m[1]; 57414d99ec0SAndreas Gohr $name = 'firefox'; 57514d99ec0SAndreas Gohr } 57614d99ec0SAndreas Gohr # Subversion ? 57714d99ec0SAndreas Gohr elseif (preg_match($regversvn,$ua,$m)){ 57814d99ec0SAndreas Gohr $type = 'rcs'; 57914d99ec0SAndreas Gohr $ver = $m[1]; 58014d99ec0SAndreas Gohr $name = 'svn'; 58114d99ec0SAndreas Gohr } 58214d99ec0SAndreas Gohr # Netscape 6.x, 7.x ... ? 58314d99ec0SAndreas Gohr elseif (preg_match($regvernetscape,$ua,$m)){ 58414d99ec0SAndreas Gohr $type = 'browser'; 58514d99ec0SAndreas Gohr $ver = $m[1]; 58614d99ec0SAndreas Gohr $name = 'netscape'; 58714d99ec0SAndreas Gohr } 58814d99ec0SAndreas Gohr # Netscape 3.x, 4.x ... ? 58914d99ec0SAndreas Gohr elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){ 59014d99ec0SAndreas Gohr $type = 'browser'; 59114d99ec0SAndreas Gohr $ver = $m[2]; 59214d99ec0SAndreas Gohr $name = 'netscape'; 59314d99ec0SAndreas Gohr }else{ 59414d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/browsers.php'); 59514d99ec0SAndreas Gohr foreach($BrowsersSearchIDOrder as $regex){ 59614d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 59714d99ec0SAndreas Gohr // it's a browser! 59814d99ec0SAndreas Gohr $type = 'browser'; 59914d99ec0SAndreas Gohr $name = strtolower($regex); 60014d99ec0SAndreas Gohr break; 60114d99ec0SAndreas Gohr } 60214d99ec0SAndreas Gohr } 60314d99ec0SAndreas Gohr } 60414d99ec0SAndreas Gohr 60514d99ec0SAndreas Gohr // check OS for browsers 60614d99ec0SAndreas Gohr if($type == 'browser'){ 60714d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/operating_systems.php'); 60814d99ec0SAndreas Gohr foreach($OSSearchIDOrder as $regex){ 60914d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 61014d99ec0SAndreas Gohr $os = $OSHashID[$regex]; 61114d99ec0SAndreas Gohr break; 61214d99ec0SAndreas Gohr } 61314d99ec0SAndreas Gohr } 61414d99ec0SAndreas Gohr 61514d99ec0SAndreas Gohr } 61614d99ec0SAndreas Gohr 61714d99ec0SAndreas Gohr // are we done now? 61814d99ec0SAndreas Gohr if($name) return $name; 61914d99ec0SAndreas Gohr 62014d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/robots.php'); 62114d99ec0SAndreas Gohr foreach($RobotsSearchIDOrder as $regex){ 62214d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 62314d99ec0SAndreas Gohr // it's a robot! 62414d99ec0SAndreas Gohr $type = 'robot'; 62514d99ec0SAndreas Gohr return strtolower($regex); 62614d99ec0SAndreas Gohr } 62714d99ec0SAndreas Gohr } 62814d99ec0SAndreas Gohr 62914d99ec0SAndreas Gohr // dunno 6301878f16fSAndreas Gohr return ''; 6311878f16fSAndreas Gohr } 6321878f16fSAndreas Gohr 6331878f16fSAndreas Gohr /** 63414d99ec0SAndreas Gohr * 63514d99ec0SAndreas Gohr * @fixme: put search engine queries in seperate table here 63614d99ec0SAndreas Gohr */ 63714d99ec0SAndreas Gohr function log_search($referer,&$type){ 63814d99ec0SAndreas Gohr $referer = strtr($referer,' +','__'); 63914d99ec0SAndreas Gohr $referer = strtolower($referer); 64014d99ec0SAndreas Gohr 64114d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/search_engines.php'); 64214d99ec0SAndreas Gohr 64314d99ec0SAndreas Gohr foreach($SearchEnginesSearchIDOrder as $regex){ 64414d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$referer)){ 64514d99ec0SAndreas Gohr if(!$NotSearchEnginesKeys[$regex] || 64614d99ec0SAndreas Gohr !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){ 64714d99ec0SAndreas Gohr // it's a search engine! 64814d99ec0SAndreas Gohr $type = 'search'; 64914d99ec0SAndreas Gohr break; 65014d99ec0SAndreas Gohr } 65114d99ec0SAndreas Gohr } 65214d99ec0SAndreas Gohr } 65314d99ec0SAndreas Gohr if($type != 'search') return; // we're done here 65414d99ec0SAndreas Gohr 65514d99ec0SAndreas Gohr #fixme now do the keyword magic! 65614d99ec0SAndreas Gohr } 65714d99ec0SAndreas Gohr 65814d99ec0SAndreas Gohr /** 65914d99ec0SAndreas Gohr * Resolve IP to country/city 66014d99ec0SAndreas Gohr */ 66114d99ec0SAndreas Gohr function log_ip($ip){ 66214d99ec0SAndreas Gohr // check if IP already known and up-to-date 66314d99ec0SAndreas Gohr $sql = "SELECT ip 66414d99ec0SAndreas Gohr FROM ".$this->getConf('db_prefix')."iplocation 66514d99ec0SAndreas Gohr WHERE ip ='".addslashes($ip)."' 66614d99ec0SAndreas Gohr AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)"; 66714d99ec0SAndreas Gohr $result = $this->runSQL($sql); 66814d99ec0SAndreas Gohr if($result[0]['ip']) return; 66914d99ec0SAndreas Gohr 67014d99ec0SAndreas Gohr $http = new DokuHTTPClient(); 67114d99ec0SAndreas Gohr $http->timeout = 10; 67214d99ec0SAndreas Gohr $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip); 67314d99ec0SAndreas Gohr 67414d99ec0SAndreas Gohr if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){ 67514d99ec0SAndreas Gohr $country = addslashes(trim($match[1])); 67614d99ec0SAndreas Gohr $code = addslashes(strtolower(trim($match[2]))); 67714d99ec0SAndreas Gohr $city = addslashes(trim($match[3])); 67814d99ec0SAndreas Gohr $host = addslashes(gethostbyaddr($ip)); 67914d99ec0SAndreas Gohr $ip = addslashes($ip); 68014d99ec0SAndreas Gohr 68114d99ec0SAndreas Gohr $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation 68214d99ec0SAndreas Gohr SET ip = '$ip', 68314d99ec0SAndreas Gohr country = '$country', 68414d99ec0SAndreas Gohr code = '$code', 68514d99ec0SAndreas Gohr city = '$city', 68614d99ec0SAndreas Gohr host = '$host'"; 68714d99ec0SAndreas Gohr $this->runSQL($sql); 68814d99ec0SAndreas Gohr } 68914d99ec0SAndreas Gohr } 69014d99ec0SAndreas Gohr 69114d99ec0SAndreas Gohr /** 6921878f16fSAndreas Gohr * log a page access 6931878f16fSAndreas Gohr * 6941878f16fSAndreas Gohr * called from log.php 6951878f16fSAndreas Gohr */ 6961878f16fSAndreas Gohr function log_access(){ 69794171ff3SAndreas Gohr if(!$_REQUEST['p']) return; 69894171ff3SAndreas Gohr 69914d99ec0SAndreas Gohr # FIXME check referer against blacklist and drop logging for bad boys 70014d99ec0SAndreas Gohr 70114d99ec0SAndreas Gohr // handle referer 70214d99ec0SAndreas Gohr $referer = trim($_REQUEST['r']); 70314d99ec0SAndreas Gohr if($referer){ 70414d99ec0SAndreas Gohr $ref = addslashes($referer); 70514d99ec0SAndreas Gohr $ref_md5 = ($ref) ? md5($referer) : ''; 70614d99ec0SAndreas Gohr if(strpos($referer,DOKU_URL) === 0){ 70714d99ec0SAndreas Gohr $ref_type = 'internal'; 70814d99ec0SAndreas Gohr }else{ 70914d99ec0SAndreas Gohr $ref_type = 'external'; 71014d99ec0SAndreas Gohr $this->log_search($referer,$ref_type); 71114d99ec0SAndreas Gohr } 71214d99ec0SAndreas Gohr }else{ 71314d99ec0SAndreas Gohr $ref = ''; 71414d99ec0SAndreas Gohr $ref_md5 = ''; 71514d99ec0SAndreas Gohr $ref_type = ''; 71614d99ec0SAndreas Gohr } 71714d99ec0SAndreas Gohr 71814d99ec0SAndreas Gohr // handle user agent 71914d99ec0SAndreas Gohr $agent = trim($_SERVER['HTTP_USER_AGENT']); 72014d99ec0SAndreas Gohr 72114d99ec0SAndreas Gohr $ua = addslashes($agent); 72214d99ec0SAndreas Gohr $ua_type = ''; 72314d99ec0SAndreas Gohr $ua_ver = ''; 72414d99ec0SAndreas Gohr $os = ''; 72514d99ec0SAndreas Gohr $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os)); 72614d99ec0SAndreas Gohr 7271878f16fSAndreas Gohr $page = addslashes($_REQUEST['p']); 7281878f16fSAndreas Gohr $ip = addslashes($_SERVER['REMOTE_ADDR']); 7291878f16fSAndreas Gohr $sx = (int) $_REQUEST['sx']; 7301878f16fSAndreas Gohr $sy = (int) $_REQUEST['sy']; 7311878f16fSAndreas Gohr $vx = (int) $_REQUEST['vx']; 7321878f16fSAndreas Gohr $vy = (int) $_REQUEST['vy']; 7331878f16fSAndreas Gohr $user = addslashes($_SERVER['REMOTE_USER']); 7341878f16fSAndreas Gohr $session = addslashes(session_id()); 7351878f16fSAndreas Gohr 73694171ff3SAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access 7371878f16fSAndreas Gohr SET page = '$page', 7381878f16fSAndreas Gohr ip = '$ip', 7391878f16fSAndreas Gohr ua = '$ua', 7401878f16fSAndreas Gohr ua_info = '$ua_info', 74114d99ec0SAndreas Gohr ua_type = '$ua_type', 74214d99ec0SAndreas Gohr ua_ver = '$ua_ver', 74314d99ec0SAndreas Gohr os = '$os', 7441878f16fSAndreas Gohr ref = '$ref', 74594171ff3SAndreas Gohr ref_md5 = '$ref_md5', 74614d99ec0SAndreas Gohr ref_type = '$ref_type', 7471878f16fSAndreas Gohr screen_x = '$sx', 7481878f16fSAndreas Gohr screen_y = '$sy', 7491878f16fSAndreas Gohr view_x = '$vx', 7501878f16fSAndreas Gohr view_y = '$vy', 7511878f16fSAndreas Gohr user = '$user', 7521878f16fSAndreas Gohr session = '$session'"; 7531878f16fSAndreas Gohr $ok = $this->runSQL($sql); 7541878f16fSAndreas Gohr if(is_null($ok)){ 7551878f16fSAndreas Gohr global $MSG; 7561878f16fSAndreas Gohr print_r($MSG); 7571878f16fSAndreas Gohr } 75814d99ec0SAndreas Gohr 75914d99ec0SAndreas Gohr // resolve the IP 76014d99ec0SAndreas Gohr $this->log_ip($_SERVER['REMOTE_ADDR']); 7611878f16fSAndreas Gohr } 7621878f16fSAndreas Gohr 7631878f16fSAndreas Gohr /** 7641878f16fSAndreas Gohr * Just send a 1x1 pixel blank gif to the browser 7651878f16fSAndreas Gohr * 7661878f16fSAndreas Gohr * @called from log.php 7671878f16fSAndreas Gohr * 7681878f16fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 7691878f16fSAndreas Gohr * @author Harry Fuecks <fuecks@gmail.com> 7701878f16fSAndreas Gohr */ 7711878f16fSAndreas Gohr function sendGIF(){ 7721878f16fSAndreas Gohr $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7'); 7731878f16fSAndreas Gohr header('Content-Type: image/gif'); 7741878f16fSAndreas Gohr header('Content-Length: '.strlen($img)); 7751878f16fSAndreas Gohr header('Connection: Close'); 7761878f16fSAndreas Gohr print $img; 7771878f16fSAndreas Gohr flush(); 7781878f16fSAndreas Gohr // Browser should drop connection after this 7791878f16fSAndreas Gohr // Thinks it's got the whole image 7801878f16fSAndreas Gohr } 7811878f16fSAndreas Gohr 7821878f16fSAndreas Gohr} 783