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 = ''; 24264f1744SAndreas 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() { 51264f1744SAndreas Gohr $this->opt = preg_replace('/[^a-z]+/','',$_REQUEST['opt']); 52264f1744SAndreas Gohr // fixme add better sanity checking here: 53264f1744SAndreas Gohr $this->from = preg_replace('/[^\d\-]+/','',$_REQUEST['f']); 54264f1744SAndreas Gohr $this->to = preg_replace('/[^\d\-]+/','',$_REQUEST['t']); 55264f1744SAndreas Gohr 56264f1744SAndreas Gohr if(!$this->from) $this->from = date('Y-m-d'); 57264f1744SAndreas Gohr if(!$this->to) $this->to = date('Y-m-d'); 58264f1744SAndreas Gohr 59264f1744SAndreas Gohr //setup limit clause 60264f1744SAndreas Gohr if($this->from != $this->to){ 61264f1744SAndreas Gohr $this->tlimit = "DATE(A.dt) >= DATE('".$this->from."') AND DATE(A.dt) <= DATE('".$this->to."')"; 62264f1744SAndreas Gohr }else{ 63264f1744SAndreas Gohr $this->tlimit = "DATE(A.dt) = DATE('".$this->from."')"; 64264f1744SAndreas 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 73264f1744SAndreas Gohr echo '<h1>Access Statistics</h1>'; 74264f1744SAndreas Gohr $this->html_timeselect(); 75264f1744SAndreas Gohr 76264f1744SAndreas Gohr switch($this->opt){ 7714d99ec0SAndreas Gohr 7814d99ec0SAndreas Gohr default: 7914d99ec0SAndreas Gohr echo $this->html_dashboard(); 8014d99ec0SAndreas Gohr } 8114d99ec0SAndreas Gohr } 8214d99ec0SAndreas Gohr 83264f1744SAndreas Gohr /** 84264f1744SAndreas Gohr * Print the time selection menu 85264f1744SAndreas Gohr */ 8614d99ec0SAndreas Gohr function html_timeselect(){ 87264f1744SAndreas Gohr $now = date('Y-m-d'); 88264f1744SAndreas Gohr $yday = date('Y-m-d',time()-(60*60*24)); 89264f1744SAndreas Gohr $week = date('Y-m-d',time()-(60*60*24*7)); 90264f1744SAndreas Gohr $month = date('Y-m-d',time()-(60*60*24*30)); 9114d99ec0SAndreas Gohr 92264f1744SAndreas Gohr echo '<div class="plg_stats_timeselect">'; 93264f1744SAndreas Gohr echo '<span>Select the timeframe:</span>'; 94264f1744SAndreas Gohr echo '<ul>'; 95264f1744SAndreas Gohr 96264f1744SAndreas Gohr echo '<li>'; 97264f1744SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$now.'&t='.$now.'">'; 98264f1744SAndreas Gohr echo 'today'; 99264f1744SAndreas Gohr echo '</a>'; 100264f1744SAndreas Gohr echo '</li>'; 101264f1744SAndreas Gohr 102264f1744SAndreas Gohr echo '<li>'; 103264f1744SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$yday.'&t='.$yday.'">'; 104264f1744SAndreas Gohr echo 'yesterday'; 105264f1744SAndreas Gohr echo '</a>'; 106264f1744SAndreas Gohr echo '</li>'; 107264f1744SAndreas Gohr 108264f1744SAndreas Gohr echo '<li>'; 109264f1744SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$week.'&t='.$now.'">'; 110264f1744SAndreas Gohr echo 'last 7 days'; 111264f1744SAndreas Gohr echo '</a>'; 112264f1744SAndreas Gohr echo '</li>'; 113264f1744SAndreas Gohr 114264f1744SAndreas Gohr echo '<li>'; 115264f1744SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$month.'&t='.$now.'">'; 116264f1744SAndreas Gohr echo 'last 30 days'; 117264f1744SAndreas Gohr echo '</a>'; 118264f1744SAndreas Gohr echo '</li>'; 119264f1744SAndreas Gohr 120264f1744SAndreas Gohr echo '</ul>'; 121264f1744SAndreas Gohr 122264f1744SAndreas Gohr 123264f1744SAndreas Gohr echo '<form action="" method="get">'; 124264f1744SAndreas Gohr echo '<input type="hidden" name="do" value="admin" />'; 125264f1744SAndreas Gohr echo '<input type="hidden" name="page" value="statistics" />'; 126264f1744SAndreas Gohr echo '<input type="hidden" name="opt" value="'.$this->opt.'" />'; 127264f1744SAndreas Gohr echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />'; 128264f1744SAndreas Gohr echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />'; 129264f1744SAndreas Gohr echo '<input type="submit" value="go" class="button" />'; 13014d99ec0SAndreas Gohr echo '</form>'; 131264f1744SAndreas Gohr 132264f1744SAndreas Gohr echo '</div>'; 13314d99ec0SAndreas Gohr } 13414d99ec0SAndreas Gohr 13514d99ec0SAndreas Gohr 136*f5f32cbfSAndreas Gohr /** 137*f5f32cbfSAndreas Gohr * Print an introductionary screen 138*f5f32cbfSAndreas Gohr * 139*f5f32cbfSAndreas Gohr * @fixme the sql statements probably need to go into their own functions 140*f5f32cbfSAndreas Gohr * to be reused in the syntax plugins to follow 141*f5f32cbfSAndreas Gohr */ 14214d99ec0SAndreas Gohr function html_dashboard(){ 143264f1744SAndreas Gohr echo '<div class="plg_stats_dashboard">'; 144264f1744SAndreas Gohr 14514d99ec0SAndreas Gohr 14687d5e44bSAndreas Gohr // top pages today 147264f1744SAndreas Gohr echo '<div>'; 148264f1744SAndreas Gohr echo '<h2>Most popular pages</h2>'; 14914d99ec0SAndreas Gohr $sql = "SELECT page, COUNT(*) as cnt 150264f1744SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 151264f1744SAndreas Gohr WHERE ".$this->tlimit." 15287d5e44bSAndreas Gohr AND ua_type = 'browser' 15314d99ec0SAndreas Gohr GROUP BY page 15414d99ec0SAndreas Gohr ORDER BY cnt DESC, page 15514d99ec0SAndreas Gohr LIMIT 20"; 15614d99ec0SAndreas Gohr $result = $this->runSQL($sql); 15787d5e44bSAndreas Gohr $this->html_resulttable($result,array('Pages','Count')); 158264f1744SAndreas Gohr echo '</div>'; 15987d5e44bSAndreas Gohr 16087d5e44bSAndreas Gohr // top referer today 161264f1744SAndreas Gohr echo '<div>'; 162264f1744SAndreas Gohr echo '<h2>Top incoming links</h2>'; 16387d5e44bSAndreas Gohr $sql = "SELECT ref as url, COUNT(*) as cnt 164264f1744SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 165264f1744SAndreas Gohr WHERE ".$this->tlimit." 16687d5e44bSAndreas Gohr AND ua_type = 'browser' 16787d5e44bSAndreas Gohr AND ref_type = 'external' 16887d5e44bSAndreas Gohr GROUP BY ref_md5 16987d5e44bSAndreas Gohr ORDER BY cnt DESC, url 17087d5e44bSAndreas Gohr LIMIT 20"; 17187d5e44bSAndreas Gohr $result = $this->runSQL($sql); 17287d5e44bSAndreas Gohr $this->html_resulttable($result,array('Incoming Links','Count')); 173264f1744SAndreas Gohr echo '</div>'; 17454f6c432SAndreas Gohr 17554f6c432SAndreas Gohr // top countries today 176264f1744SAndreas Gohr echo '<div>'; 177264f1744SAndreas Gohr echo '<h2>Visitor\'s top countries</h2>'; 178*f5f32cbfSAndreas Gohr $sql = "SELECT B.code AS cflag, B.country, COUNT(*) as cnt 17954f6c432SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A, 18054f6c432SAndreas Gohr ".$this->getConf('db_prefix')."iplocation as B 181264f1744SAndreas Gohr WHERE ".$this->tlimit." 18254f6c432SAndreas Gohr AND A.ip = B.ip 18354f6c432SAndreas Gohr GROUP BY B.country 18454f6c432SAndreas Gohr ORDER BY cnt DESC, B.country 18554f6c432SAndreas Gohr LIMIT 20"; 18654f6c432SAndreas Gohr $result = $this->runSQL($sql); 187*f5f32cbfSAndreas Gohr $this->html_resulttable($result,array('','Countries','Count')); 188264f1744SAndreas Gohr echo '</div>'; 189264f1744SAndreas Gohr 190264f1744SAndreas Gohr echo '</div>'; 19114d99ec0SAndreas Gohr } 19214d99ec0SAndreas Gohr 19314d99ec0SAndreas Gohr /** 19414d99ec0SAndreas Gohr * Display a result in a HTML table 19514d99ec0SAndreas Gohr */ 19614d99ec0SAndreas Gohr function html_resulttable($result,$header){ 19714d99ec0SAndreas Gohr echo '<table>'; 19814d99ec0SAndreas Gohr echo '<tr>'; 19914d99ec0SAndreas Gohr foreach($header as $h){ 20014d99ec0SAndreas Gohr echo '<th>'.hsc($h).'</th>'; 20114d99ec0SAndreas Gohr } 20214d99ec0SAndreas Gohr echo '</tr>'; 20314d99ec0SAndreas Gohr 20414d99ec0SAndreas Gohr foreach($result as $row){ 20514d99ec0SAndreas Gohr echo '<tr>'; 20614d99ec0SAndreas Gohr foreach($row as $k => $v){ 20714d99ec0SAndreas Gohr echo '<td class="stats_'.$k.'">'; 20814d99ec0SAndreas Gohr if($k == 'page'){ 20914d99ec0SAndreas Gohr echo '<a href="'.wl($v).'" class="wikilink1">'; 21014d99ec0SAndreas Gohr echo hsc($v); 21114d99ec0SAndreas Gohr echo '</a>'; 21214d99ec0SAndreas Gohr }elseif($k == 'url'){ 21354f6c432SAndreas Gohr $url = hsc($v); 21454f6c432SAndreas Gohr if(strlen($url) > 50){ 21554f6c432SAndreas Gohr $url = substr($url,0,30).' … '.substr($url,-20); 21654f6c432SAndreas Gohr } 21714d99ec0SAndreas Gohr echo '<a href="'.$v.'" class="urlextern">'; 21854f6c432SAndreas Gohr echo $url; 21914d99ec0SAndreas Gohr echo '</a>'; 22014d99ec0SAndreas Gohr }elseif($k == 'html'){ 22114d99ec0SAndreas Gohr echo $v; 222*f5f32cbfSAndreas Gohr }elseif($k == 'cflag'){ 223*f5f32cbfSAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugin/statistics/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12"/>'; 22414d99ec0SAndreas Gohr }else{ 22514d99ec0SAndreas Gohr echo hsc($v); 22614d99ec0SAndreas Gohr } 22714d99ec0SAndreas Gohr echo '</td>'; 22814d99ec0SAndreas Gohr } 22914d99ec0SAndreas Gohr echo '</tr>'; 23014d99ec0SAndreas Gohr } 23114d99ec0SAndreas Gohr echo '</table>'; 2321878f16fSAndreas Gohr } 2331878f16fSAndreas Gohr 2341878f16fSAndreas Gohr 2351878f16fSAndreas Gohr /** 23614d99ec0SAndreas Gohr * Return a link to the DB, opening the connection if needed 2371878f16fSAndreas Gohr */ 23814d99ec0SAndreas Gohr function dbLink(){ 2391878f16fSAndreas Gohr // connect to DB if needed 2401878f16fSAndreas Gohr if(!$this->dblink){ 2411878f16fSAndreas Gohr $this->dblink = mysql_connect($this->getConf('db_server'), 2421878f16fSAndreas Gohr $this->getConf('db_user'), 2431878f16fSAndreas Gohr $this->getConf('db_password')); 2441878f16fSAndreas Gohr if(!$this->dblink){ 2451878f16fSAndreas Gohr msg('DB Error: connection failed',-1); 2461878f16fSAndreas Gohr return null; 2471878f16fSAndreas Gohr } 2481878f16fSAndreas Gohr // set utf-8 2491878f16fSAndreas Gohr if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){ 2501878f16fSAndreas Gohr msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1); 2511878f16fSAndreas Gohr return null; 2521878f16fSAndreas Gohr } 2531878f16fSAndreas Gohr } 25414d99ec0SAndreas Gohr return $this->dblink; 25514d99ec0SAndreas Gohr } 2561878f16fSAndreas Gohr 25714d99ec0SAndreas Gohr /** 25814d99ec0SAndreas Gohr * Simple function to run a DB query 25914d99ec0SAndreas Gohr */ 26014d99ec0SAndreas Gohr function runSQL($sql_string) { 26114d99ec0SAndreas Gohr $link = $this->dbLink(); 26214d99ec0SAndreas Gohr 26314d99ec0SAndreas Gohr $result = mysql_db_query($this->conf['db_database'],$sql_string,$link); 26494171ff3SAndreas Gohr if(!$result){ 26514d99ec0SAndreas Gohr msg('DB Error: '.mysql_error($link),-1); 2661878f16fSAndreas Gohr return null; 2671878f16fSAndreas Gohr } 2681878f16fSAndreas Gohr 2691878f16fSAndreas Gohr $resultarray = array(); 2701878f16fSAndreas Gohr 2711878f16fSAndreas Gohr //mysql_db_query returns 1 on a insert statement -> no need to ask for results 2721878f16fSAndreas Gohr if ($result != 1) { 2731878f16fSAndreas Gohr for($i=0; $i< mysql_num_rows($result); $i++) { 2741878f16fSAndreas Gohr $temparray = mysql_fetch_assoc($result); 2751878f16fSAndreas Gohr $resultarray[]=$temparray; 2761878f16fSAndreas Gohr } 2771878f16fSAndreas Gohr mysql_free_result($result); 2781878f16fSAndreas Gohr } 2791878f16fSAndreas Gohr 28014d99ec0SAndreas Gohr if (mysql_insert_id($link)) { 28114d99ec0SAndreas Gohr $resultarray = mysql_insert_id($link); //give back ID on insert 2821878f16fSAndreas Gohr } 2831878f16fSAndreas Gohr 2841878f16fSAndreas Gohr return $resultarray; 2851878f16fSAndreas Gohr } 2861878f16fSAndreas Gohr 2871878f16fSAndreas Gohr /** 28814d99ec0SAndreas Gohr * Returns a short name for a User Agent and sets type, version and os info 2891878f16fSAndreas Gohr */ 29014d99ec0SAndreas Gohr function ua_info($ua,&$type,&$ver,&$os){ 29114d99ec0SAndreas Gohr $ua = strtr($ua,' +','__'); 29214d99ec0SAndreas Gohr $ua = strtolower($ua); 29314d99ec0SAndreas Gohr 29414d99ec0SAndreas Gohr // common browsers 29514d99ec0SAndreas Gohr $regvermsie = '/msie([+_ ]|)([\d\.]*)/i'; 29614d99ec0SAndreas Gohr $regvernetscape = '/netscape.?\/([\d\.]*)/i'; 29714d99ec0SAndreas Gohr $regverfirefox = '/firefox\/([\d\.]*)/i'; 29814d99ec0SAndreas Gohr $regversvn = '/svn\/([\d\.]*)/i'; 29914d99ec0SAndreas Gohr $regvermozilla = '/mozilla(\/|)([\d\.]*)/i'; 30014d99ec0SAndreas Gohr $regnotie = '/webtv|omniweb|opera/i'; 30114d99ec0SAndreas Gohr $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i'; 30214d99ec0SAndreas Gohr 30314d99ec0SAndreas Gohr $name = ''; 30414d99ec0SAndreas Gohr # IE ? 30514d99ec0SAndreas Gohr if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){ 30614d99ec0SAndreas Gohr $type = 'browser'; 30714d99ec0SAndreas Gohr $ver = $m[2]; 30814d99ec0SAndreas Gohr $name = 'msie'; 30914d99ec0SAndreas Gohr } 31014d99ec0SAndreas Gohr # Firefox ? 31114d99ec0SAndreas Gohr elseif (preg_match($regverfirefox,$ua,$m)){ 31214d99ec0SAndreas Gohr $type = 'browser'; 31314d99ec0SAndreas Gohr $ver = $m[1]; 31414d99ec0SAndreas Gohr $name = 'firefox'; 31514d99ec0SAndreas Gohr } 31614d99ec0SAndreas Gohr # Subversion ? 31714d99ec0SAndreas Gohr elseif (preg_match($regversvn,$ua,$m)){ 31814d99ec0SAndreas Gohr $type = 'rcs'; 31914d99ec0SAndreas Gohr $ver = $m[1]; 32014d99ec0SAndreas Gohr $name = 'svn'; 32114d99ec0SAndreas Gohr } 32214d99ec0SAndreas Gohr # Netscape 6.x, 7.x ... ? 32314d99ec0SAndreas Gohr elseif (preg_match($regvernetscape,$ua,$m)){ 32414d99ec0SAndreas Gohr $type = 'browser'; 32514d99ec0SAndreas Gohr $ver = $m[1]; 32614d99ec0SAndreas Gohr $name = 'netscape'; 32714d99ec0SAndreas Gohr } 32814d99ec0SAndreas Gohr # Netscape 3.x, 4.x ... ? 32914d99ec0SAndreas Gohr elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){ 33014d99ec0SAndreas Gohr $type = 'browser'; 33114d99ec0SAndreas Gohr $ver = $m[2]; 33214d99ec0SAndreas Gohr $name = 'netscape'; 33314d99ec0SAndreas Gohr }else{ 33414d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/browsers.php'); 33514d99ec0SAndreas Gohr foreach($BrowsersSearchIDOrder as $regex){ 33614d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 33714d99ec0SAndreas Gohr // it's a browser! 33814d99ec0SAndreas Gohr $type = 'browser'; 33914d99ec0SAndreas Gohr $name = strtolower($regex); 34014d99ec0SAndreas Gohr break; 34114d99ec0SAndreas Gohr } 34214d99ec0SAndreas Gohr } 34314d99ec0SAndreas Gohr } 34414d99ec0SAndreas Gohr 34514d99ec0SAndreas Gohr // check OS for browsers 34614d99ec0SAndreas Gohr if($type == 'browser'){ 34714d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/operating_systems.php'); 34814d99ec0SAndreas Gohr foreach($OSSearchIDOrder as $regex){ 34914d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 35014d99ec0SAndreas Gohr $os = $OSHashID[$regex]; 35114d99ec0SAndreas Gohr break; 35214d99ec0SAndreas Gohr } 35314d99ec0SAndreas Gohr } 35414d99ec0SAndreas Gohr 35514d99ec0SAndreas Gohr } 35614d99ec0SAndreas Gohr 35714d99ec0SAndreas Gohr // are we done now? 35814d99ec0SAndreas Gohr if($name) return $name; 35914d99ec0SAndreas Gohr 36014d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/robots.php'); 36114d99ec0SAndreas Gohr foreach($RobotsSearchIDOrder as $regex){ 36214d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 36314d99ec0SAndreas Gohr // it's a robot! 36414d99ec0SAndreas Gohr $type = 'robot'; 36514d99ec0SAndreas Gohr return strtolower($regex); 36614d99ec0SAndreas Gohr } 36714d99ec0SAndreas Gohr } 36814d99ec0SAndreas Gohr 36914d99ec0SAndreas Gohr // dunno 3701878f16fSAndreas Gohr return ''; 3711878f16fSAndreas Gohr } 3721878f16fSAndreas Gohr 3731878f16fSAndreas Gohr /** 37414d99ec0SAndreas Gohr * 37514d99ec0SAndreas Gohr * @fixme: put search engine queries in seperate table here 37614d99ec0SAndreas Gohr */ 37714d99ec0SAndreas Gohr function log_search($referer,&$type){ 37814d99ec0SAndreas Gohr $referer = strtr($referer,' +','__'); 37914d99ec0SAndreas Gohr $referer = strtolower($referer); 38014d99ec0SAndreas Gohr 38114d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/search_engines.php'); 38214d99ec0SAndreas Gohr 38314d99ec0SAndreas Gohr foreach($SearchEnginesSearchIDOrder as $regex){ 38414d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$referer)){ 38514d99ec0SAndreas Gohr if(!$NotSearchEnginesKeys[$regex] || 38614d99ec0SAndreas Gohr !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){ 38714d99ec0SAndreas Gohr // it's a search engine! 38814d99ec0SAndreas Gohr $type = 'search'; 38914d99ec0SAndreas Gohr break; 39014d99ec0SAndreas Gohr } 39114d99ec0SAndreas Gohr } 39214d99ec0SAndreas Gohr } 39314d99ec0SAndreas Gohr if($type != 'search') return; // we're done here 39414d99ec0SAndreas Gohr 39514d99ec0SAndreas Gohr #fixme now do the keyword magic! 39614d99ec0SAndreas Gohr } 39714d99ec0SAndreas Gohr 39814d99ec0SAndreas Gohr /** 39914d99ec0SAndreas Gohr * Resolve IP to country/city 40014d99ec0SAndreas Gohr */ 40114d99ec0SAndreas Gohr function log_ip($ip){ 40214d99ec0SAndreas Gohr // check if IP already known and up-to-date 40314d99ec0SAndreas Gohr $sql = "SELECT ip 40414d99ec0SAndreas Gohr FROM ".$this->getConf('db_prefix')."iplocation 40514d99ec0SAndreas Gohr WHERE ip ='".addslashes($ip)."' 40614d99ec0SAndreas Gohr AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)"; 40714d99ec0SAndreas Gohr $result = $this->runSQL($sql); 40814d99ec0SAndreas Gohr if($result[0]['ip']) return; 40914d99ec0SAndreas Gohr 41014d99ec0SAndreas Gohr $http = new DokuHTTPClient(); 41114d99ec0SAndreas Gohr $http->timeout = 10; 41214d99ec0SAndreas Gohr $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip); 41314d99ec0SAndreas Gohr 41414d99ec0SAndreas Gohr if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){ 41514d99ec0SAndreas Gohr $country = addslashes(trim($match[1])); 41614d99ec0SAndreas Gohr $code = addslashes(strtolower(trim($match[2]))); 41714d99ec0SAndreas Gohr $city = addslashes(trim($match[3])); 41814d99ec0SAndreas Gohr $host = addslashes(gethostbyaddr($ip)); 41914d99ec0SAndreas Gohr $ip = addslashes($ip); 42014d99ec0SAndreas Gohr 42114d99ec0SAndreas Gohr $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation 42214d99ec0SAndreas Gohr SET ip = '$ip', 42314d99ec0SAndreas Gohr country = '$country', 42414d99ec0SAndreas Gohr code = '$code', 42514d99ec0SAndreas Gohr city = '$city', 42614d99ec0SAndreas Gohr host = '$host'"; 42714d99ec0SAndreas Gohr $this->runSQL($sql); 42814d99ec0SAndreas Gohr } 42914d99ec0SAndreas Gohr } 43014d99ec0SAndreas Gohr 43114d99ec0SAndreas Gohr /** 4321878f16fSAndreas Gohr * log a page access 4331878f16fSAndreas Gohr * 4341878f16fSAndreas Gohr * called from log.php 4351878f16fSAndreas Gohr */ 4361878f16fSAndreas Gohr function log_access(){ 43794171ff3SAndreas Gohr if(!$_REQUEST['p']) return; 43894171ff3SAndreas Gohr 43914d99ec0SAndreas Gohr # FIXME check referer against blacklist and drop logging for bad boys 44014d99ec0SAndreas Gohr 44114d99ec0SAndreas Gohr // handle referer 44214d99ec0SAndreas Gohr $referer = trim($_REQUEST['r']); 44314d99ec0SAndreas Gohr if($referer){ 44414d99ec0SAndreas Gohr $ref = addslashes($referer); 44514d99ec0SAndreas Gohr $ref_md5 = ($ref) ? md5($referer) : ''; 44614d99ec0SAndreas Gohr if(strpos($referer,DOKU_URL) === 0){ 44714d99ec0SAndreas Gohr $ref_type = 'internal'; 44814d99ec0SAndreas Gohr }else{ 44914d99ec0SAndreas Gohr $ref_type = 'external'; 45014d99ec0SAndreas Gohr $this->log_search($referer,$ref_type); 45114d99ec0SAndreas Gohr } 45214d99ec0SAndreas Gohr }else{ 45314d99ec0SAndreas Gohr $ref = ''; 45414d99ec0SAndreas Gohr $ref_md5 = ''; 45514d99ec0SAndreas Gohr $ref_type = ''; 45614d99ec0SAndreas Gohr } 45714d99ec0SAndreas Gohr 45814d99ec0SAndreas Gohr // handle user agent 45914d99ec0SAndreas Gohr $agent = trim($_SERVER['HTTP_USER_AGENT']); 46014d99ec0SAndreas Gohr 46114d99ec0SAndreas Gohr $ua = addslashes($agent); 46214d99ec0SAndreas Gohr $ua_type = ''; 46314d99ec0SAndreas Gohr $ua_ver = ''; 46414d99ec0SAndreas Gohr $os = ''; 46514d99ec0SAndreas Gohr $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os)); 46614d99ec0SAndreas Gohr 4671878f16fSAndreas Gohr $page = addslashes($_REQUEST['p']); 4681878f16fSAndreas Gohr $ip = addslashes($_SERVER['REMOTE_ADDR']); 4691878f16fSAndreas Gohr $sx = (int) $_REQUEST['sx']; 4701878f16fSAndreas Gohr $sy = (int) $_REQUEST['sy']; 4711878f16fSAndreas Gohr $vx = (int) $_REQUEST['vx']; 4721878f16fSAndreas Gohr $vy = (int) $_REQUEST['vy']; 4731878f16fSAndreas Gohr $user = addslashes($_SERVER['REMOTE_USER']); 4741878f16fSAndreas Gohr $session = addslashes(session_id()); 4751878f16fSAndreas Gohr 47694171ff3SAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access 4771878f16fSAndreas Gohr SET page = '$page', 4781878f16fSAndreas Gohr ip = '$ip', 4791878f16fSAndreas Gohr ua = '$ua', 4801878f16fSAndreas Gohr ua_info = '$ua_info', 48114d99ec0SAndreas Gohr ua_type = '$ua_type', 48214d99ec0SAndreas Gohr ua_ver = '$ua_ver', 48314d99ec0SAndreas Gohr os = '$os', 4841878f16fSAndreas Gohr ref = '$ref', 48594171ff3SAndreas Gohr ref_md5 = '$ref_md5', 48614d99ec0SAndreas Gohr ref_type = '$ref_type', 4871878f16fSAndreas Gohr screen_x = '$sx', 4881878f16fSAndreas Gohr screen_y = '$sy', 4891878f16fSAndreas Gohr view_x = '$vx', 4901878f16fSAndreas Gohr view_y = '$vy', 4911878f16fSAndreas Gohr user = '$user', 4921878f16fSAndreas Gohr session = '$session'"; 4931878f16fSAndreas Gohr $ok = $this->runSQL($sql); 4941878f16fSAndreas Gohr if(is_null($ok)){ 4951878f16fSAndreas Gohr global $MSG; 4961878f16fSAndreas Gohr print_r($MSG); 4971878f16fSAndreas Gohr } 49814d99ec0SAndreas Gohr 49914d99ec0SAndreas Gohr // resolve the IP 50014d99ec0SAndreas Gohr $this->log_ip($_SERVER['REMOTE_ADDR']); 5011878f16fSAndreas Gohr } 5021878f16fSAndreas Gohr 5031878f16fSAndreas Gohr /** 5041878f16fSAndreas Gohr * Just send a 1x1 pixel blank gif to the browser 5051878f16fSAndreas Gohr * 5061878f16fSAndreas Gohr * @called from log.php 5071878f16fSAndreas Gohr * 5081878f16fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 5091878f16fSAndreas Gohr * @author Harry Fuecks <fuecks@gmail.com> 5101878f16fSAndreas Gohr */ 5111878f16fSAndreas Gohr function sendGIF(){ 5121878f16fSAndreas Gohr $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7'); 5131878f16fSAndreas Gohr header('Content-Type: image/gif'); 5141878f16fSAndreas Gohr header('Content-Length: '.strlen($img)); 5151878f16fSAndreas Gohr header('Connection: Close'); 5161878f16fSAndreas Gohr print $img; 5171878f16fSAndreas Gohr flush(); 5181878f16fSAndreas Gohr // Browser should drop connection after this 5191878f16fSAndreas Gohr // Thinks it's got the whole image 5201878f16fSAndreas Gohr } 5211878f16fSAndreas Gohr 5221878f16fSAndreas Gohr} 523