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; 21*264f1744SAndreas Gohr var $opt = ''; 22*264f1744SAndreas Gohr var $from = ''; 23*264f1744SAndreas Gohr var $to = ''; 24*264f1744SAndreas Gohr var $tlimit = ''; 251878f16fSAndreas Gohr 261878f16fSAndreas Gohr /** 271878f16fSAndreas Gohr * return some info 281878f16fSAndreas Gohr */ 291878f16fSAndreas Gohr function getInfo(){ 301878f16fSAndreas Gohr return confToHash(dirname(__FILE__).'/info.txt'); 311878f16fSAndreas Gohr } 321878f16fSAndreas Gohr 331878f16fSAndreas Gohr /** 341878f16fSAndreas Gohr * Access for managers allowed 351878f16fSAndreas Gohr */ 361878f16fSAndreas Gohr function forAdminOnly(){ 371878f16fSAndreas Gohr return false; 381878f16fSAndreas Gohr } 391878f16fSAndreas Gohr 401878f16fSAndreas Gohr /** 411878f16fSAndreas Gohr * return sort order for position in admin menu 421878f16fSAndreas Gohr */ 431878f16fSAndreas Gohr function getMenuSort() { 4414d99ec0SAndreas Gohr return 150; 451878f16fSAndreas Gohr } 461878f16fSAndreas Gohr 471878f16fSAndreas Gohr /** 481878f16fSAndreas Gohr * handle user request 491878f16fSAndreas Gohr */ 501878f16fSAndreas Gohr function handle() { 51*264f1744SAndreas Gohr $this->opt = preg_replace('/[^a-z]+/','',$_REQUEST['opt']); 52*264f1744SAndreas Gohr // fixme add better sanity checking here: 53*264f1744SAndreas Gohr $this->from = preg_replace('/[^\d\-]+/','',$_REQUEST['f']); 54*264f1744SAndreas Gohr $this->to = preg_replace('/[^\d\-]+/','',$_REQUEST['t']); 55*264f1744SAndreas Gohr 56*264f1744SAndreas Gohr if(!$this->from) $this->from = date('Y-m-d'); 57*264f1744SAndreas Gohr if(!$this->to) $this->to = date('Y-m-d'); 58*264f1744SAndreas Gohr 59*264f1744SAndreas Gohr //setup limit clause 60*264f1744SAndreas Gohr if($this->from != $this->to){ 61*264f1744SAndreas Gohr $this->tlimit = "DATE(A.dt) >= DATE('".$this->from."') AND DATE(A.dt) <= DATE('".$this->to."')"; 62*264f1744SAndreas Gohr }else{ 63*264f1744SAndreas Gohr $this->tlimit = "DATE(A.dt) = DATE('".$this->from."')"; 64*264f1744SAndreas Gohr } 651878f16fSAndreas Gohr } 661878f16fSAndreas Gohr 671878f16fSAndreas Gohr /** 6894171ff3SAndreas Gohr * fixme build statistics here 691878f16fSAndreas Gohr */ 701878f16fSAndreas Gohr function html() { 7114d99ec0SAndreas Gohr // fixme build a navigation menu in a TOC here 7214d99ec0SAndreas Gohr 73*264f1744SAndreas Gohr echo '<h1>Access Statistics</h1>'; 74*264f1744SAndreas Gohr $this->html_timeselect(); 75*264f1744SAndreas Gohr 76*264f1744SAndreas Gohr switch($this->opt){ 7714d99ec0SAndreas Gohr 7814d99ec0SAndreas Gohr default: 7914d99ec0SAndreas Gohr echo $this->html_dashboard(); 8014d99ec0SAndreas Gohr } 8114d99ec0SAndreas Gohr } 8214d99ec0SAndreas Gohr 83*264f1744SAndreas Gohr /** 84*264f1744SAndreas Gohr * Print the time selection menu 85*264f1744SAndreas Gohr */ 8614d99ec0SAndreas Gohr function html_timeselect(){ 87*264f1744SAndreas Gohr $now = date('Y-m-d'); 88*264f1744SAndreas Gohr $yday = date('Y-m-d',time()-(60*60*24)); 89*264f1744SAndreas Gohr $week = date('Y-m-d',time()-(60*60*24*7)); 90*264f1744SAndreas Gohr $month = date('Y-m-d',time()-(60*60*24*30)); 9114d99ec0SAndreas Gohr 92*264f1744SAndreas Gohr echo '<div class="plg_stats_timeselect">'; 93*264f1744SAndreas Gohr echo '<span>Select the timeframe:</span>'; 94*264f1744SAndreas Gohr echo '<ul>'; 95*264f1744SAndreas Gohr 96*264f1744SAndreas Gohr echo '<li>'; 97*264f1744SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$now.'&t='.$now.'">'; 98*264f1744SAndreas Gohr echo 'today'; 99*264f1744SAndreas Gohr echo '</a>'; 100*264f1744SAndreas Gohr echo '</li>'; 101*264f1744SAndreas Gohr 102*264f1744SAndreas Gohr echo '<li>'; 103*264f1744SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$yday.'&t='.$yday.'">'; 104*264f1744SAndreas Gohr echo 'yesterday'; 105*264f1744SAndreas Gohr echo '</a>'; 106*264f1744SAndreas Gohr echo '</li>'; 107*264f1744SAndreas Gohr 108*264f1744SAndreas Gohr echo '<li>'; 109*264f1744SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$week.'&t='.$now.'">'; 110*264f1744SAndreas Gohr echo 'last 7 days'; 111*264f1744SAndreas Gohr echo '</a>'; 112*264f1744SAndreas Gohr echo '</li>'; 113*264f1744SAndreas Gohr 114*264f1744SAndreas Gohr echo '<li>'; 115*264f1744SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$month.'&t='.$now.'">'; 116*264f1744SAndreas Gohr echo 'last 30 days'; 117*264f1744SAndreas Gohr echo '</a>'; 118*264f1744SAndreas Gohr echo '</li>'; 119*264f1744SAndreas Gohr 120*264f1744SAndreas Gohr echo '</ul>'; 121*264f1744SAndreas Gohr 122*264f1744SAndreas Gohr 123*264f1744SAndreas Gohr echo '<form action="" method="get">'; 124*264f1744SAndreas Gohr echo '<input type="hidden" name="do" value="admin" />'; 125*264f1744SAndreas Gohr echo '<input type="hidden" name="page" value="statistics" />'; 126*264f1744SAndreas Gohr echo '<input type="hidden" name="opt" value="'.$this->opt.'" />'; 127*264f1744SAndreas Gohr echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />'; 128*264f1744SAndreas Gohr echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />'; 129*264f1744SAndreas Gohr echo '<input type="submit" value="go" class="button" />'; 13014d99ec0SAndreas Gohr echo '</form>'; 131*264f1744SAndreas Gohr 132*264f1744SAndreas Gohr echo '</div>'; 13314d99ec0SAndreas Gohr } 13414d99ec0SAndreas Gohr 13514d99ec0SAndreas Gohr 13614d99ec0SAndreas Gohr function html_dashboard(){ 137*264f1744SAndreas Gohr echo '<div class="plg_stats_dashboard">'; 138*264f1744SAndreas Gohr 13914d99ec0SAndreas Gohr 14087d5e44bSAndreas Gohr // top pages today 141*264f1744SAndreas Gohr echo '<div>'; 142*264f1744SAndreas Gohr echo '<h2>Most popular pages</h2>'; 14314d99ec0SAndreas Gohr $sql = "SELECT page, COUNT(*) as cnt 144*264f1744SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 145*264f1744SAndreas Gohr WHERE ".$this->tlimit." 14687d5e44bSAndreas Gohr AND ua_type = 'browser' 14714d99ec0SAndreas Gohr GROUP BY page 14814d99ec0SAndreas Gohr ORDER BY cnt DESC, page 14914d99ec0SAndreas Gohr LIMIT 20"; 15014d99ec0SAndreas Gohr $result = $this->runSQL($sql); 15187d5e44bSAndreas Gohr $this->html_resulttable($result,array('Pages','Count')); 152*264f1744SAndreas Gohr echo '</div>'; 15387d5e44bSAndreas Gohr 15487d5e44bSAndreas Gohr // top referer today 155*264f1744SAndreas Gohr echo '<div>'; 156*264f1744SAndreas Gohr echo '<h2>Top incoming links</h2>'; 15787d5e44bSAndreas Gohr $sql = "SELECT ref as url, COUNT(*) as cnt 158*264f1744SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 159*264f1744SAndreas Gohr WHERE ".$this->tlimit." 16087d5e44bSAndreas Gohr AND ua_type = 'browser' 16187d5e44bSAndreas Gohr AND ref_type = 'external' 16287d5e44bSAndreas Gohr GROUP BY ref_md5 16387d5e44bSAndreas Gohr ORDER BY cnt DESC, url 16487d5e44bSAndreas Gohr LIMIT 20"; 16587d5e44bSAndreas Gohr $result = $this->runSQL($sql); 16687d5e44bSAndreas Gohr $this->html_resulttable($result,array('Incoming Links','Count')); 167*264f1744SAndreas Gohr echo '</div>'; 16854f6c432SAndreas Gohr 16954f6c432SAndreas Gohr // top countries today 170*264f1744SAndreas Gohr echo '<div>'; 171*264f1744SAndreas Gohr echo '<h2>Visitor\'s top countries</h2>'; 17254f6c432SAndreas Gohr $sql = "SELECT B.country, COUNT(*) as cnt 17354f6c432SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A, 17454f6c432SAndreas Gohr ".$this->getConf('db_prefix')."iplocation as B 175*264f1744SAndreas Gohr WHERE ".$this->tlimit." 17654f6c432SAndreas Gohr AND A.ip = B.ip 17754f6c432SAndreas Gohr GROUP BY B.country 17854f6c432SAndreas Gohr ORDER BY cnt DESC, B.country 17954f6c432SAndreas Gohr LIMIT 20"; 18054f6c432SAndreas Gohr $result = $this->runSQL($sql); 18154f6c432SAndreas Gohr $this->html_resulttable($result,array('Countries','Count')); 182*264f1744SAndreas Gohr echo '</div>'; 183*264f1744SAndreas Gohr 184*264f1744SAndreas Gohr echo '</div>'; 18514d99ec0SAndreas Gohr } 18614d99ec0SAndreas Gohr 18714d99ec0SAndreas Gohr /** 18814d99ec0SAndreas Gohr * Display a result in a HTML table 18914d99ec0SAndreas Gohr */ 19014d99ec0SAndreas Gohr function html_resulttable($result,$header){ 19114d99ec0SAndreas Gohr echo '<table>'; 19214d99ec0SAndreas Gohr echo '<tr>'; 19314d99ec0SAndreas Gohr foreach($header as $h){ 19414d99ec0SAndreas Gohr echo '<th>'.hsc($h).'</th>'; 19514d99ec0SAndreas Gohr } 19614d99ec0SAndreas Gohr echo '</tr>'; 19714d99ec0SAndreas Gohr 19814d99ec0SAndreas Gohr foreach($result as $row){ 19914d99ec0SAndreas Gohr echo '<tr>'; 20014d99ec0SAndreas Gohr foreach($row as $k => $v){ 20114d99ec0SAndreas Gohr echo '<td class="stats_'.$k.'">'; 20214d99ec0SAndreas Gohr if($k == 'page'){ 20314d99ec0SAndreas Gohr echo '<a href="'.wl($v).'" class="wikilink1">'; 20414d99ec0SAndreas Gohr echo hsc($v); 20514d99ec0SAndreas Gohr echo '</a>'; 20614d99ec0SAndreas Gohr }elseif($k == 'url'){ 20754f6c432SAndreas Gohr $url = hsc($v); 20854f6c432SAndreas Gohr if(strlen($url) > 50){ 20954f6c432SAndreas Gohr $url = substr($url,0,30).' … '.substr($url,-20); 21054f6c432SAndreas Gohr } 21114d99ec0SAndreas Gohr echo '<a href="'.$v.'" class="urlextern">'; 21254f6c432SAndreas Gohr echo $url; 21314d99ec0SAndreas Gohr echo '</a>'; 21414d99ec0SAndreas Gohr }elseif($k == 'html'){ 21514d99ec0SAndreas Gohr echo $v; 21614d99ec0SAndreas Gohr }else{ 21714d99ec0SAndreas Gohr echo hsc($v); 21814d99ec0SAndreas Gohr } 21914d99ec0SAndreas Gohr echo '</td>'; 22014d99ec0SAndreas Gohr } 22114d99ec0SAndreas Gohr echo '</tr>'; 22214d99ec0SAndreas Gohr } 22314d99ec0SAndreas Gohr echo '</table>'; 2241878f16fSAndreas Gohr } 2251878f16fSAndreas Gohr 2261878f16fSAndreas Gohr 2271878f16fSAndreas Gohr /** 22814d99ec0SAndreas Gohr * Return a link to the DB, opening the connection if needed 2291878f16fSAndreas Gohr */ 23014d99ec0SAndreas Gohr function dbLink(){ 2311878f16fSAndreas Gohr // connect to DB if needed 2321878f16fSAndreas Gohr if(!$this->dblink){ 2331878f16fSAndreas Gohr $this->dblink = mysql_connect($this->getConf('db_server'), 2341878f16fSAndreas Gohr $this->getConf('db_user'), 2351878f16fSAndreas Gohr $this->getConf('db_password')); 2361878f16fSAndreas Gohr if(!$this->dblink){ 2371878f16fSAndreas Gohr msg('DB Error: connection failed',-1); 2381878f16fSAndreas Gohr return null; 2391878f16fSAndreas Gohr } 2401878f16fSAndreas Gohr // set utf-8 2411878f16fSAndreas Gohr if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){ 2421878f16fSAndreas Gohr msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1); 2431878f16fSAndreas Gohr return null; 2441878f16fSAndreas Gohr } 2451878f16fSAndreas Gohr } 24614d99ec0SAndreas Gohr return $this->dblink; 24714d99ec0SAndreas Gohr } 2481878f16fSAndreas Gohr 24914d99ec0SAndreas Gohr /** 25014d99ec0SAndreas Gohr * Simple function to run a DB query 25114d99ec0SAndreas Gohr */ 25214d99ec0SAndreas Gohr function runSQL($sql_string) { 25314d99ec0SAndreas Gohr $link = $this->dbLink(); 25414d99ec0SAndreas Gohr 25514d99ec0SAndreas Gohr $result = mysql_db_query($this->conf['db_database'],$sql_string,$link); 25694171ff3SAndreas Gohr if(!$result){ 25714d99ec0SAndreas Gohr msg('DB Error: '.mysql_error($link),-1); 2581878f16fSAndreas Gohr return null; 2591878f16fSAndreas Gohr } 2601878f16fSAndreas Gohr 2611878f16fSAndreas Gohr $resultarray = array(); 2621878f16fSAndreas Gohr 2631878f16fSAndreas Gohr //mysql_db_query returns 1 on a insert statement -> no need to ask for results 2641878f16fSAndreas Gohr if ($result != 1) { 2651878f16fSAndreas Gohr for($i=0; $i< mysql_num_rows($result); $i++) { 2661878f16fSAndreas Gohr $temparray = mysql_fetch_assoc($result); 2671878f16fSAndreas Gohr $resultarray[]=$temparray; 2681878f16fSAndreas Gohr } 2691878f16fSAndreas Gohr mysql_free_result($result); 2701878f16fSAndreas Gohr } 2711878f16fSAndreas Gohr 27214d99ec0SAndreas Gohr if (mysql_insert_id($link)) { 27314d99ec0SAndreas Gohr $resultarray = mysql_insert_id($link); //give back ID on insert 2741878f16fSAndreas Gohr } 2751878f16fSAndreas Gohr 2761878f16fSAndreas Gohr return $resultarray; 2771878f16fSAndreas Gohr } 2781878f16fSAndreas Gohr 2791878f16fSAndreas Gohr /** 28014d99ec0SAndreas Gohr * Returns a short name for a User Agent and sets type, version and os info 2811878f16fSAndreas Gohr */ 28214d99ec0SAndreas Gohr function ua_info($ua,&$type,&$ver,&$os){ 28314d99ec0SAndreas Gohr $ua = strtr($ua,' +','__'); 28414d99ec0SAndreas Gohr $ua = strtolower($ua); 28514d99ec0SAndreas Gohr 28614d99ec0SAndreas Gohr // common browsers 28714d99ec0SAndreas Gohr $regvermsie = '/msie([+_ ]|)([\d\.]*)/i'; 28814d99ec0SAndreas Gohr $regvernetscape = '/netscape.?\/([\d\.]*)/i'; 28914d99ec0SAndreas Gohr $regverfirefox = '/firefox\/([\d\.]*)/i'; 29014d99ec0SAndreas Gohr $regversvn = '/svn\/([\d\.]*)/i'; 29114d99ec0SAndreas Gohr $regvermozilla = '/mozilla(\/|)([\d\.]*)/i'; 29214d99ec0SAndreas Gohr $regnotie = '/webtv|omniweb|opera/i'; 29314d99ec0SAndreas Gohr $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i'; 29414d99ec0SAndreas Gohr 29514d99ec0SAndreas Gohr $name = ''; 29614d99ec0SAndreas Gohr # IE ? 29714d99ec0SAndreas Gohr if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){ 29814d99ec0SAndreas Gohr $type = 'browser'; 29914d99ec0SAndreas Gohr $ver = $m[2]; 30014d99ec0SAndreas Gohr $name = 'msie'; 30114d99ec0SAndreas Gohr } 30214d99ec0SAndreas Gohr # Firefox ? 30314d99ec0SAndreas Gohr elseif (preg_match($regverfirefox,$ua,$m)){ 30414d99ec0SAndreas Gohr $type = 'browser'; 30514d99ec0SAndreas Gohr $ver = $m[1]; 30614d99ec0SAndreas Gohr $name = 'firefox'; 30714d99ec0SAndreas Gohr } 30814d99ec0SAndreas Gohr # Subversion ? 30914d99ec0SAndreas Gohr elseif (preg_match($regversvn,$ua,$m)){ 31014d99ec0SAndreas Gohr $type = 'rcs'; 31114d99ec0SAndreas Gohr $ver = $m[1]; 31214d99ec0SAndreas Gohr $name = 'svn'; 31314d99ec0SAndreas Gohr } 31414d99ec0SAndreas Gohr # Netscape 6.x, 7.x ... ? 31514d99ec0SAndreas Gohr elseif (preg_match($regvernetscape,$ua,$m)){ 31614d99ec0SAndreas Gohr $type = 'browser'; 31714d99ec0SAndreas Gohr $ver = $m[1]; 31814d99ec0SAndreas Gohr $name = 'netscape'; 31914d99ec0SAndreas Gohr } 32014d99ec0SAndreas Gohr # Netscape 3.x, 4.x ... ? 32114d99ec0SAndreas Gohr elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){ 32214d99ec0SAndreas Gohr $type = 'browser'; 32314d99ec0SAndreas Gohr $ver = $m[2]; 32414d99ec0SAndreas Gohr $name = 'netscape'; 32514d99ec0SAndreas Gohr }else{ 32614d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/browsers.php'); 32714d99ec0SAndreas Gohr foreach($BrowsersSearchIDOrder as $regex){ 32814d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 32914d99ec0SAndreas Gohr // it's a browser! 33014d99ec0SAndreas Gohr $type = 'browser'; 33114d99ec0SAndreas Gohr $name = strtolower($regex); 33214d99ec0SAndreas Gohr break; 33314d99ec0SAndreas Gohr } 33414d99ec0SAndreas Gohr } 33514d99ec0SAndreas Gohr } 33614d99ec0SAndreas Gohr 33714d99ec0SAndreas Gohr // check OS for browsers 33814d99ec0SAndreas Gohr if($type == 'browser'){ 33914d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/operating_systems.php'); 34014d99ec0SAndreas Gohr foreach($OSSearchIDOrder as $regex){ 34114d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 34214d99ec0SAndreas Gohr $os = $OSHashID[$regex]; 34314d99ec0SAndreas Gohr break; 34414d99ec0SAndreas Gohr } 34514d99ec0SAndreas Gohr } 34614d99ec0SAndreas Gohr 34714d99ec0SAndreas Gohr } 34814d99ec0SAndreas Gohr 34914d99ec0SAndreas Gohr // are we done now? 35014d99ec0SAndreas Gohr if($name) return $name; 35114d99ec0SAndreas Gohr 35214d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/robots.php'); 35314d99ec0SAndreas Gohr foreach($RobotsSearchIDOrder as $regex){ 35414d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 35514d99ec0SAndreas Gohr // it's a robot! 35614d99ec0SAndreas Gohr $type = 'robot'; 35714d99ec0SAndreas Gohr return strtolower($regex); 35814d99ec0SAndreas Gohr } 35914d99ec0SAndreas Gohr } 36014d99ec0SAndreas Gohr 36114d99ec0SAndreas Gohr // dunno 3621878f16fSAndreas Gohr return ''; 3631878f16fSAndreas Gohr } 3641878f16fSAndreas Gohr 3651878f16fSAndreas Gohr /** 36614d99ec0SAndreas Gohr * 36714d99ec0SAndreas Gohr * @fixme: put search engine queries in seperate table here 36814d99ec0SAndreas Gohr */ 36914d99ec0SAndreas Gohr function log_search($referer,&$type){ 37014d99ec0SAndreas Gohr $referer = strtr($referer,' +','__'); 37114d99ec0SAndreas Gohr $referer = strtolower($referer); 37214d99ec0SAndreas Gohr 37314d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/search_engines.php'); 37414d99ec0SAndreas Gohr 37514d99ec0SAndreas Gohr foreach($SearchEnginesSearchIDOrder as $regex){ 37614d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$referer)){ 37714d99ec0SAndreas Gohr if(!$NotSearchEnginesKeys[$regex] || 37814d99ec0SAndreas Gohr !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){ 37914d99ec0SAndreas Gohr // it's a search engine! 38014d99ec0SAndreas Gohr $type = 'search'; 38114d99ec0SAndreas Gohr break; 38214d99ec0SAndreas Gohr } 38314d99ec0SAndreas Gohr } 38414d99ec0SAndreas Gohr } 38514d99ec0SAndreas Gohr if($type != 'search') return; // we're done here 38614d99ec0SAndreas Gohr 38714d99ec0SAndreas Gohr #fixme now do the keyword magic! 38814d99ec0SAndreas Gohr } 38914d99ec0SAndreas Gohr 39014d99ec0SAndreas Gohr /** 39114d99ec0SAndreas Gohr * Resolve IP to country/city 39214d99ec0SAndreas Gohr */ 39314d99ec0SAndreas Gohr function log_ip($ip){ 39414d99ec0SAndreas Gohr // check if IP already known and up-to-date 39514d99ec0SAndreas Gohr $sql = "SELECT ip 39614d99ec0SAndreas Gohr FROM ".$this->getConf('db_prefix')."iplocation 39714d99ec0SAndreas Gohr WHERE ip ='".addslashes($ip)."' 39814d99ec0SAndreas Gohr AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)"; 39914d99ec0SAndreas Gohr $result = $this->runSQL($sql); 40014d99ec0SAndreas Gohr if($result[0]['ip']) return; 40114d99ec0SAndreas Gohr 40214d99ec0SAndreas Gohr $http = new DokuHTTPClient(); 40314d99ec0SAndreas Gohr $http->timeout = 10; 40414d99ec0SAndreas Gohr $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip); 40514d99ec0SAndreas Gohr 40614d99ec0SAndreas Gohr if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){ 40714d99ec0SAndreas Gohr $country = addslashes(trim($match[1])); 40814d99ec0SAndreas Gohr $code = addslashes(strtolower(trim($match[2]))); 40914d99ec0SAndreas Gohr $city = addslashes(trim($match[3])); 41014d99ec0SAndreas Gohr $host = addslashes(gethostbyaddr($ip)); 41114d99ec0SAndreas Gohr $ip = addslashes($ip); 41214d99ec0SAndreas Gohr 41314d99ec0SAndreas Gohr $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation 41414d99ec0SAndreas Gohr SET ip = '$ip', 41514d99ec0SAndreas Gohr country = '$country', 41614d99ec0SAndreas Gohr code = '$code', 41714d99ec0SAndreas Gohr city = '$city', 41814d99ec0SAndreas Gohr host = '$host'"; 41914d99ec0SAndreas Gohr $this->runSQL($sql); 42014d99ec0SAndreas Gohr } 42114d99ec0SAndreas Gohr } 42214d99ec0SAndreas Gohr 42314d99ec0SAndreas Gohr /** 4241878f16fSAndreas Gohr * log a page access 4251878f16fSAndreas Gohr * 4261878f16fSAndreas Gohr * called from log.php 4271878f16fSAndreas Gohr */ 4281878f16fSAndreas Gohr function log_access(){ 42994171ff3SAndreas Gohr if(!$_REQUEST['p']) return; 43094171ff3SAndreas Gohr 43114d99ec0SAndreas Gohr # FIXME check referer against blacklist and drop logging for bad boys 43214d99ec0SAndreas Gohr 43314d99ec0SAndreas Gohr // handle referer 43414d99ec0SAndreas Gohr $referer = trim($_REQUEST['r']); 43514d99ec0SAndreas Gohr if($referer){ 43614d99ec0SAndreas Gohr $ref = addslashes($referer); 43714d99ec0SAndreas Gohr $ref_md5 = ($ref) ? md5($referer) : ''; 43814d99ec0SAndreas Gohr if(strpos($referer,DOKU_URL) === 0){ 43914d99ec0SAndreas Gohr $ref_type = 'internal'; 44014d99ec0SAndreas Gohr }else{ 44114d99ec0SAndreas Gohr $ref_type = 'external'; 44214d99ec0SAndreas Gohr $this->log_search($referer,$ref_type); 44314d99ec0SAndreas Gohr } 44414d99ec0SAndreas Gohr }else{ 44514d99ec0SAndreas Gohr $ref = ''; 44614d99ec0SAndreas Gohr $ref_md5 = ''; 44714d99ec0SAndreas Gohr $ref_type = ''; 44814d99ec0SAndreas Gohr } 44914d99ec0SAndreas Gohr 45014d99ec0SAndreas Gohr // handle user agent 45114d99ec0SAndreas Gohr $agent = trim($_SERVER['HTTP_USER_AGENT']); 45214d99ec0SAndreas Gohr 45314d99ec0SAndreas Gohr $ua = addslashes($agent); 45414d99ec0SAndreas Gohr $ua_type = ''; 45514d99ec0SAndreas Gohr $ua_ver = ''; 45614d99ec0SAndreas Gohr $os = ''; 45714d99ec0SAndreas Gohr $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os)); 45814d99ec0SAndreas Gohr 4591878f16fSAndreas Gohr $page = addslashes($_REQUEST['p']); 4601878f16fSAndreas Gohr $ip = addslashes($_SERVER['REMOTE_ADDR']); 4611878f16fSAndreas Gohr $sx = (int) $_REQUEST['sx']; 4621878f16fSAndreas Gohr $sy = (int) $_REQUEST['sy']; 4631878f16fSAndreas Gohr $vx = (int) $_REQUEST['vx']; 4641878f16fSAndreas Gohr $vy = (int) $_REQUEST['vy']; 4651878f16fSAndreas Gohr $user = addslashes($_SERVER['REMOTE_USER']); 4661878f16fSAndreas Gohr $session = addslashes(session_id()); 4671878f16fSAndreas Gohr 46894171ff3SAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access 4691878f16fSAndreas Gohr SET page = '$page', 4701878f16fSAndreas Gohr ip = '$ip', 4711878f16fSAndreas Gohr ua = '$ua', 4721878f16fSAndreas Gohr ua_info = '$ua_info', 47314d99ec0SAndreas Gohr ua_type = '$ua_type', 47414d99ec0SAndreas Gohr ua_ver = '$ua_ver', 47514d99ec0SAndreas Gohr os = '$os', 4761878f16fSAndreas Gohr ref = '$ref', 47794171ff3SAndreas Gohr ref_md5 = '$ref_md5', 47814d99ec0SAndreas Gohr ref_type = '$ref_type', 4791878f16fSAndreas Gohr screen_x = '$sx', 4801878f16fSAndreas Gohr screen_y = '$sy', 4811878f16fSAndreas Gohr view_x = '$vx', 4821878f16fSAndreas Gohr view_y = '$vy', 4831878f16fSAndreas Gohr user = '$user', 4841878f16fSAndreas Gohr session = '$session'"; 4851878f16fSAndreas Gohr $ok = $this->runSQL($sql); 4861878f16fSAndreas Gohr if(is_null($ok)){ 4871878f16fSAndreas Gohr global $MSG; 4881878f16fSAndreas Gohr print_r($MSG); 4891878f16fSAndreas Gohr } 49014d99ec0SAndreas Gohr 49114d99ec0SAndreas Gohr // resolve the IP 49214d99ec0SAndreas Gohr $this->log_ip($_SERVER['REMOTE_ADDR']); 4931878f16fSAndreas Gohr } 4941878f16fSAndreas Gohr 4951878f16fSAndreas Gohr /** 4961878f16fSAndreas Gohr * Just send a 1x1 pixel blank gif to the browser 4971878f16fSAndreas Gohr * 4981878f16fSAndreas Gohr * @called from log.php 4991878f16fSAndreas Gohr * 5001878f16fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 5011878f16fSAndreas Gohr * @author Harry Fuecks <fuecks@gmail.com> 5021878f16fSAndreas Gohr */ 5031878f16fSAndreas Gohr function sendGIF(){ 5041878f16fSAndreas Gohr $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7'); 5051878f16fSAndreas Gohr header('Content-Type: image/gif'); 5061878f16fSAndreas Gohr header('Content-Length: '.strlen($img)); 5071878f16fSAndreas Gohr header('Connection: Close'); 5081878f16fSAndreas Gohr print $img; 5091878f16fSAndreas Gohr flush(); 5101878f16fSAndreas Gohr // Browser should drop connection after this 5111878f16fSAndreas Gohr // Thinks it's got the whole image 5121878f16fSAndreas Gohr } 5131878f16fSAndreas Gohr 5141878f16fSAndreas Gohr} 515