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; 94*e7a2f1e0SAndreas Gohr case 'newreferer': 95*e7a2f1e0SAndreas Gohr $this->html_newreferer(); 96*e7a2f1e0SAndreas Gohr break; 9714d99ec0SAndreas Gohr default: 989da6395dSAndreas Gohr $this->html_dashboard(); 9914d99ec0SAndreas Gohr } 10014d99ec0SAndreas Gohr } 10114d99ec0SAndreas Gohr 1029da6395dSAndreas Gohr function html_toc(){ 1039da6395dSAndreas Gohr echo '<div class="toc">'; 1049da6395dSAndreas Gohr echo '<div class="tocheader toctoggle" id="toc__header">'; 1059da6395dSAndreas Gohr echo 'Detailed Statistics'; 1069da6395dSAndreas Gohr echo '</div>'; 1079da6395dSAndreas Gohr echo '<div id="toc__inside">'; 1089da6395dSAndreas Gohr echo '<ul class="toc">'; 1099da6395dSAndreas Gohr 1109da6395dSAndreas Gohr echo '<li><div class="li">'; 1119da6395dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Dashboard</a>'; 1129da6395dSAndreas Gohr echo '</div></li>'; 1139da6395dSAndreas Gohr 1149da6395dSAndreas Gohr echo '<li><div class="li">'; 1159da6395dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=page&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Pages</a>'; 1169da6395dSAndreas Gohr echo '</div></li>'; 1179da6395dSAndreas Gohr 1189da6395dSAndreas Gohr echo '<li><div class="li">'; 1199da6395dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=referer&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Incoming Links</a>'; 1209da6395dSAndreas Gohr echo '</div></li>'; 1219da6395dSAndreas Gohr 1229da6395dSAndreas Gohr echo '<li><div class="li">'; 123*e7a2f1e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=newreferer&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">New Incoming Links</a>'; 124*e7a2f1e0SAndreas Gohr echo '</div></li>'; 125*e7a2f1e0SAndreas Gohr 126*e7a2f1e0SAndreas Gohr echo '<li><div class="li">'; 12775fa767dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=browser&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Browsers</a>'; 12875fa767dSAndreas Gohr echo '</div></li>'; 12975fa767dSAndreas Gohr 13075fa767dSAndreas Gohr echo '<li><div class="li">'; 131bd4217d3SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=os&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Operating Systems</a>'; 132bd4217d3SAndreas Gohr echo '</div></li>'; 133bd4217d3SAndreas Gohr 134bd4217d3SAndreas Gohr echo '<li><div class="li">'; 1359da6395dSAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=country&f='.$this->from.'&t='.$this->to.'&s='.$this->start.'">Countries</a>'; 1369da6395dSAndreas Gohr echo '</div></li>'; 1379da6395dSAndreas Gohr 1389da6395dSAndreas Gohr echo '</ul>'; 1399da6395dSAndreas Gohr echo '</div>'; 1409da6395dSAndreas Gohr echo '</div>'; 1419da6395dSAndreas Gohr } 1429da6395dSAndreas Gohr 143264f1744SAndreas Gohr /** 144264f1744SAndreas Gohr * Print the time selection menu 145264f1744SAndreas Gohr */ 14614d99ec0SAndreas Gohr function html_timeselect(){ 147264f1744SAndreas Gohr $now = date('Y-m-d'); 148264f1744SAndreas Gohr $yday = date('Y-m-d',time()-(60*60*24)); 149264f1744SAndreas Gohr $week = date('Y-m-d',time()-(60*60*24*7)); 150264f1744SAndreas Gohr $month = date('Y-m-d',time()-(60*60*24*30)); 15114d99ec0SAndreas Gohr 152264f1744SAndreas Gohr echo '<div class="plg_stats_timeselect">'; 153264f1744SAndreas Gohr echo '<span>Select the timeframe:</span>'; 154264f1744SAndreas Gohr echo '<ul>'; 155264f1744SAndreas Gohr 156264f1744SAndreas Gohr echo '<li>'; 15795eb68e6SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$now.'&t='.$now.'&s='.$this->start.'">'; 158264f1744SAndreas Gohr echo 'today'; 159264f1744SAndreas Gohr echo '</a>'; 160264f1744SAndreas Gohr echo '</li>'; 161264f1744SAndreas Gohr 162264f1744SAndreas Gohr echo '<li>'; 16395eb68e6SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$yday.'&t='.$yday.'&s='.$this->start.'">'; 164264f1744SAndreas Gohr echo 'yesterday'; 165264f1744SAndreas Gohr echo '</a>'; 166264f1744SAndreas Gohr echo '</li>'; 167264f1744SAndreas Gohr 168264f1744SAndreas Gohr echo '<li>'; 16995eb68e6SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$week.'&t='.$now.'&s='.$this->start.'">'; 170264f1744SAndreas Gohr echo 'last 7 days'; 171264f1744SAndreas Gohr echo '</a>'; 172264f1744SAndreas Gohr echo '</li>'; 173264f1744SAndreas Gohr 174264f1744SAndreas Gohr echo '<li>'; 17595eb68e6SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$month.'&t='.$now.'&s='.$this->start.'">'; 176264f1744SAndreas Gohr echo 'last 30 days'; 177264f1744SAndreas Gohr echo '</a>'; 178264f1744SAndreas Gohr echo '</li>'; 179264f1744SAndreas Gohr 180264f1744SAndreas Gohr echo '</ul>'; 181264f1744SAndreas Gohr 182264f1744SAndreas Gohr 183264f1744SAndreas Gohr echo '<form action="" method="get">'; 184264f1744SAndreas Gohr echo '<input type="hidden" name="do" value="admin" />'; 185264f1744SAndreas Gohr echo '<input type="hidden" name="page" value="statistics" />'; 186264f1744SAndreas Gohr echo '<input type="hidden" name="opt" value="'.$this->opt.'" />'; 18795eb68e6SAndreas Gohr echo '<input type="hidden" name="s" value="'.$this->start.'" />'; 188264f1744SAndreas Gohr echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />'; 189264f1744SAndreas Gohr echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />'; 190264f1744SAndreas Gohr echo '<input type="submit" value="go" class="button" />'; 19114d99ec0SAndreas Gohr echo '</form>'; 192264f1744SAndreas Gohr 193264f1744SAndreas Gohr echo '</div>'; 19414d99ec0SAndreas Gohr } 19514d99ec0SAndreas Gohr 19614d99ec0SAndreas Gohr 197f5f32cbfSAndreas Gohr /** 198f5f32cbfSAndreas Gohr * Print an introductionary screen 199f5f32cbfSAndreas Gohr */ 20014d99ec0SAndreas Gohr function html_dashboard(){ 2012812a751SAndreas Gohr echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists 2022812a751SAndreas Gohr choose a topic from the list.</p>'; 2032812a751SAndreas Gohr 2042812a751SAndreas Gohr 205264f1744SAndreas Gohr echo '<div class="plg_stats_dashboard">'; 206264f1744SAndreas Gohr 2072812a751SAndreas Gohr // general info 2082812a751SAndreas Gohr echo '<div class="plg_stats_top">'; 2092812a751SAndreas Gohr $result = $this->sql_aggregate($this->tlimit); 2102812a751SAndreas Gohr echo '<ul>'; 2112812a751SAndreas Gohr echo '<li><span>'.$result['pageviews'].'</span> page views</li>'; 2122812a751SAndreas Gohr echo '<li><span>'.$result['sessions'].'</span> visitors (sessions)</li>'; 2132812a751SAndreas Gohr echo '<li><span>'.$result['users'].'</span> logged in users</li>'; 2142812a751SAndreas Gohr 2152812a751SAndreas Gohr echo '</ul>'; 2162812a751SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&f='.$this->from.'&t='.$this->to.'" />'; 2172812a751SAndreas Gohr echo '</div>'; 2182812a751SAndreas Gohr 21914d99ec0SAndreas Gohr 22087d5e44bSAndreas Gohr // top pages today 221264f1744SAndreas Gohr echo '<div>'; 222264f1744SAndreas Gohr echo '<h2>Most popular pages</h2>'; 22395eb68e6SAndreas Gohr $result = $this->sql_pages($this->tlimit,$this->start,15); 2242812a751SAndreas Gohr $this->html_resulttable($result); 225264f1744SAndreas Gohr echo '</div>'; 22687d5e44bSAndreas Gohr 22787d5e44bSAndreas Gohr // top referer today 228264f1744SAndreas Gohr echo '<div>'; 229*e7a2f1e0SAndreas Gohr echo '<h2>Newest incoming links</h2>'; 230*e7a2f1e0SAndreas Gohr $result = $this->sql_newreferer($this->tlimit,$this->start,15); 2312812a751SAndreas Gohr $this->html_resulttable($result); 232264f1744SAndreas Gohr echo '</div>'; 23354f6c432SAndreas Gohr 23454f6c432SAndreas Gohr // top countries today 235264f1744SAndreas Gohr echo '<div>'; 236264f1744SAndreas Gohr echo '<h2>Visitor\'s top countries</h2>'; 23795eb68e6SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&f='.$this->from.'&t='.$this->to.'" />'; 23895eb68e6SAndreas Gohr// $result = $this->sql_countries($this->tlimit,$this->start,15); 23995eb68e6SAndreas Gohr// $this->html_resulttable($result,array('','Countries','Count')); 240264f1744SAndreas Gohr echo '</div>'; 241264f1744SAndreas Gohr 242264f1744SAndreas Gohr echo '</div>'; 24314d99ec0SAndreas Gohr } 24414d99ec0SAndreas Gohr 2459da6395dSAndreas Gohr function html_country(){ 2469da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 2479da6395dSAndreas Gohr echo '<h2>Visitor\'s Countries</h2>'; 248bd4217d3SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&f='.$this->from.'&t='.$this->to.'" />'; 2499da6395dSAndreas Gohr $result = $this->sql_countries($this->tlimit,$this->start,150); 2502812a751SAndreas Gohr $this->html_resulttable($result); 2519da6395dSAndreas Gohr echo '</div>'; 2529da6395dSAndreas Gohr } 2539da6395dSAndreas Gohr 2549da6395dSAndreas Gohr function html_page(){ 2559da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 2569da6395dSAndreas Gohr echo '<h2>Popular Pages</h2>'; 2579da6395dSAndreas Gohr $result = $this->sql_pages($this->tlimit,$this->start,150); 2582812a751SAndreas Gohr $this->html_resulttable($result); 2599da6395dSAndreas Gohr echo '</div>'; 2609da6395dSAndreas Gohr } 2619da6395dSAndreas Gohr 26275fa767dSAndreas Gohr function html_browser(){ 26375fa767dSAndreas Gohr echo '<div class="plg_stats_full">'; 26475fa767dSAndreas Gohr echo '<h2>Browser Shootout</h2>'; 26575fa767dSAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&f='.$this->from.'&t='.$this->to.'" />'; 26675fa767dSAndreas Gohr $result = $this->sql_browsers($this->tlimit,$this->start,150,true); 26775fa767dSAndreas Gohr $this->html_resulttable($result); 26875fa767dSAndreas Gohr echo '</div>'; 26975fa767dSAndreas Gohr } 27075fa767dSAndreas Gohr 271bd4217d3SAndreas Gohr function html_os(){ 272bd4217d3SAndreas Gohr echo '<div class="plg_stats_full">'; 273bd4217d3SAndreas Gohr echo '<h2>Operating Systems</h2>'; 274bd4217d3SAndreas Gohr// echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&f='.$this->from.'&t='.$this->to.'" />'; 275bd4217d3SAndreas Gohr $result = $this->sql_os($this->tlimit,$this->start,150,true); 276bd4217d3SAndreas Gohr $this->html_resulttable($result); 277bd4217d3SAndreas Gohr echo '</div>'; 278bd4217d3SAndreas Gohr } 279bd4217d3SAndreas Gohr 2809da6395dSAndreas Gohr function html_referer(){ 2819da6395dSAndreas Gohr echo '<div class="plg_stats_full">'; 2829da6395dSAndreas Gohr echo '<h2>Incoming Links</h2>'; 2832812a751SAndreas Gohr $result = $this->sql_aggregate($this->tlimit); 2842812a751SAndreas Gohr 2852812a751SAndreas Gohr $all = $result['search']+$result['external']+$result['direct']; 2862812a751SAndreas Gohr 2872812a751SAndreas Gohr printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses, 2882812a751SAndreas Gohr %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through 2892812a751SAndreas Gohr links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all), 2902812a751SAndreas Gohr $result['search'],(100*$result['search']/$all),$result['external'], 2912812a751SAndreas Gohr (100*$result['external']/$all)); 2922812a751SAndreas Gohr 2939da6395dSAndreas Gohr $result = $this->sql_referer($this->tlimit,$this->start,150); 2942812a751SAndreas Gohr $this->html_resulttable($result); 2959da6395dSAndreas Gohr echo '</div>'; 2969da6395dSAndreas Gohr } 2979da6395dSAndreas Gohr 298*e7a2f1e0SAndreas Gohr function html_newreferer(){ 299*e7a2f1e0SAndreas Gohr echo '<div class="plg_stats_full">'; 300*e7a2f1e0SAndreas Gohr echo '<h2>New Incoming Links</h2>'; 301*e7a2f1e0SAndreas Gohr echo '<p>The following incoming links where first logged in the selected time frame, 302*e7a2f1e0SAndreas Gohr and have never been seen before.</p>'; 303*e7a2f1e0SAndreas Gohr 304*e7a2f1e0SAndreas Gohr $result = $this->sql_newreferer($this->tlimit,$this->start,150); 305*e7a2f1e0SAndreas Gohr $this->html_resulttable($result); 306*e7a2f1e0SAndreas Gohr echo '</div>'; 307*e7a2f1e0SAndreas Gohr } 308*e7a2f1e0SAndreas Gohr 3099da6395dSAndreas Gohr 3109da6395dSAndreas Gohr 31114d99ec0SAndreas Gohr /** 31214d99ec0SAndreas Gohr * Display a result in a HTML table 31314d99ec0SAndreas Gohr */ 3142812a751SAndreas Gohr function html_resulttable($result,$header=''){ 31514d99ec0SAndreas Gohr echo '<table>'; 3162812a751SAndreas Gohr if(is_array($header)){ 31714d99ec0SAndreas Gohr echo '<tr>'; 31814d99ec0SAndreas Gohr foreach($header as $h){ 31914d99ec0SAndreas Gohr echo '<th>'.hsc($h).'</th>'; 32014d99ec0SAndreas Gohr } 32114d99ec0SAndreas Gohr echo '</tr>'; 3222812a751SAndreas Gohr } 32314d99ec0SAndreas Gohr 32414d99ec0SAndreas Gohr foreach($result as $row){ 32514d99ec0SAndreas Gohr echo '<tr>'; 32614d99ec0SAndreas Gohr foreach($row as $k => $v){ 3272812a751SAndreas Gohr echo '<td class="plg_stats_X'.$k.'">'; 32814d99ec0SAndreas Gohr if($k == 'page'){ 32914d99ec0SAndreas Gohr echo '<a href="'.wl($v).'" class="wikilink1">'; 33014d99ec0SAndreas Gohr echo hsc($v); 33114d99ec0SAndreas Gohr echo '</a>'; 33214d99ec0SAndreas Gohr }elseif($k == 'url'){ 33354f6c432SAndreas Gohr $url = hsc($v); 3342812a751SAndreas Gohr if(strlen($url) > 45){ 3352812a751SAndreas Gohr $url = substr($url,0,30).' … '.substr($url,-15); 33654f6c432SAndreas Gohr } 33714d99ec0SAndreas Gohr echo '<a href="'.$v.'" class="urlextern">'; 33854f6c432SAndreas Gohr echo $url; 33914d99ec0SAndreas Gohr echo '</a>'; 34075fa767dSAndreas Gohr }elseif($k == 'browser'){ 34175fa767dSAndreas Gohr include_once(dirname(__FILE__).'/inc/browsers.php'); 34275fa767dSAndreas Gohr echo $BrowsersHashIDLib[$v]; 34375fa767dSAndreas Gohr }elseif($k == 'bflag'){ 34475fa767dSAndreas Gohr include_once(dirname(__FILE__).'/inc/browsers.php'); 34575fa767dSAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />'; 346bd4217d3SAndreas Gohr }elseif($k == 'os'){ 347bd4217d3SAndreas Gohr if(empty($v)){ 348bd4217d3SAndreas Gohr echo 'unknown'; 349bd4217d3SAndreas Gohr }else{ 350bd4217d3SAndreas Gohr include_once(dirname(__FILE__).'/inc/operating_systems.php'); 351bd4217d3SAndreas Gohr echo $OSHashLib[$v]; 352bd4217d3SAndreas Gohr } 353bd4217d3SAndreas Gohr }elseif($k == 'osflag'){ 354bd4217d3SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />'; 35575fa767dSAndreas Gohr }elseif($k == 'cflag'){ 35675fa767dSAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />'; 35714d99ec0SAndreas Gohr }elseif($k == 'html'){ 35814d99ec0SAndreas Gohr echo $v; 35914d99ec0SAndreas Gohr }else{ 36014d99ec0SAndreas Gohr echo hsc($v); 36114d99ec0SAndreas Gohr } 36214d99ec0SAndreas Gohr echo '</td>'; 36314d99ec0SAndreas Gohr } 36414d99ec0SAndreas Gohr echo '</tr>'; 36514d99ec0SAndreas Gohr } 36614d99ec0SAndreas Gohr echo '</table>'; 3671878f16fSAndreas Gohr } 3681878f16fSAndreas Gohr 36995eb68e6SAndreas Gohr /** 37095eb68e6SAndreas Gohr * Create an image 37195eb68e6SAndreas Gohr */ 37295eb68e6SAndreas Gohr function img_build($img){ 37395eb68e6SAndreas Gohr include(dirname(__FILE__).'/inc/AGC.class.php'); 37495eb68e6SAndreas Gohr 37595eb68e6SAndreas Gohr switch($img){ 37695eb68e6SAndreas Gohr case 'country': 37795eb68e6SAndreas Gohr // build top countries + other 37895eb68e6SAndreas Gohr $result = $this->sql_countries($this->tlimit,$this->start,0); 37995eb68e6SAndreas Gohr $data = array(); 38095eb68e6SAndreas Gohr $top = 0; 38195eb68e6SAndreas Gohr foreach($result as $row){ 38295eb68e6SAndreas Gohr if($top < 7){ 38395eb68e6SAndreas Gohr $data[$row['country']] = $row['cnt']; 38495eb68e6SAndreas Gohr }else{ 38595eb68e6SAndreas Gohr $data['other'] += $row['cnt']; 38695eb68e6SAndreas Gohr } 38795eb68e6SAndreas Gohr $top++; 38895eb68e6SAndreas Gohr } 38995eb68e6SAndreas Gohr $pie = new AGC(300, 200); 39095eb68e6SAndreas Gohr $pie->setProp("showkey",true); 39195eb68e6SAndreas Gohr $pie->setProp("showval",false); 39295eb68e6SAndreas Gohr $pie->setProp("showgrid",false); 39395eb68e6SAndreas Gohr $pie->setProp("type","pie"); 39495eb68e6SAndreas Gohr $pie->setProp("keyinfo",1); 39595eb68e6SAndreas Gohr $pie->setProp("keysize",8); 39695eb68e6SAndreas Gohr $pie->setProp("keywidspc",-50); 39795eb68e6SAndreas Gohr $pie->setProp("key",array_keys($data)); 39895eb68e6SAndreas Gohr $pie->addBulkPoints(array_values($data)); 39995eb68e6SAndreas Gohr @$pie->graph(); 40095eb68e6SAndreas Gohr $pie->showGraph(); 40195eb68e6SAndreas Gohr break; 40275fa767dSAndreas Gohr case 'browser': 40375fa767dSAndreas Gohr // build top browsers + other 40475fa767dSAndreas Gohr include_once(dirname(__FILE__).'/inc/browsers.php'); 40575fa767dSAndreas Gohr 40675fa767dSAndreas Gohr $result = $this->sql_browsers($this->tlimit,$this->start,0,false); 40775fa767dSAndreas Gohr $data = array(); 40875fa767dSAndreas Gohr $top = 0; 40975fa767dSAndreas Gohr foreach($result as $row){ 41075fa767dSAndreas Gohr if($top < 5){ 41175fa767dSAndreas Gohr $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt']; 41275fa767dSAndreas Gohr }else{ 41375fa767dSAndreas Gohr $data['other'] += $row['cnt']; 41475fa767dSAndreas Gohr } 41575fa767dSAndreas Gohr $top++; 41675fa767dSAndreas Gohr } 41775fa767dSAndreas Gohr $pie = new AGC(300, 200); 41875fa767dSAndreas Gohr $pie->setProp("showkey",true); 41975fa767dSAndreas Gohr $pie->setProp("showval",false); 42075fa767dSAndreas Gohr $pie->setProp("showgrid",false); 42175fa767dSAndreas Gohr $pie->setProp("type","pie"); 42275fa767dSAndreas Gohr $pie->setProp("keyinfo",1); 42375fa767dSAndreas Gohr $pie->setProp("keysize",8); 42475fa767dSAndreas Gohr $pie->setProp("keywidspc",-50); 42575fa767dSAndreas Gohr $pie->setProp("key",array_keys($data)); 42675fa767dSAndreas Gohr $pie->addBulkPoints(array_values($data)); 42775fa767dSAndreas Gohr @$pie->graph(); 42875fa767dSAndreas Gohr $pie->showGraph(); 42975fa767dSAndreas Gohr break; 4302812a751SAndreas Gohr case 'trend': 4312812a751SAndreas Gohr $hours = ($this->from == $this->to); 4322812a751SAndreas Gohr $result = $this->sql_trend($this->tlimit,$hours); 4332812a751SAndreas Gohr $data1 = array(); 4342812a751SAndreas Gohr $data2 = array(); 4352812a751SAndreas Gohr 4362812a751SAndreas Gohr $graph = new AGC(400, 150); 4372812a751SAndreas Gohr $graph->setProp("type","bar"); 4382812a751SAndreas Gohr $graph->setProp("showgrid",false); 4392812a751SAndreas Gohr $graph->setProp("barwidth",.8); 44075fa767dSAndreas Gohr 4412812a751SAndreas Gohr $graph->setColor('color',0,'blue'); 4422812a751SAndreas Gohr $graph->setColor('color',1,'red'); 4432812a751SAndreas Gohr 4442812a751SAndreas Gohr if($hours){ 4452812a751SAndreas Gohr //preset $hours 4462812a751SAndreas Gohr for($i=0;$i<24;$i++){ 4472812a751SAndreas Gohr $data1[$i] = 0; 4482812a751SAndreas Gohr $data2[$i] = 0; 4492812a751SAndreas Gohr $graph->setProp("scale",array(' 0h',' 4h',' 8h',' 12h',' 16h',' 20h',' 24h')); 4502812a751SAndreas Gohr } 4512812a751SAndreas Gohr }else{ 4522812a751SAndreas Gohr $graph->setProp("scale",array(next(array_keys($data1)),$this->to)); 4532812a751SAndreas Gohr } 4542812a751SAndreas Gohr 4552812a751SAndreas Gohr foreach($result as $row){ 4562812a751SAndreas Gohr $data1[$row['time']] = $row['pageviews']; 4572812a751SAndreas Gohr $data2[$row['time']] = $row['sessions']; 4582812a751SAndreas Gohr } 4592812a751SAndreas Gohr 4602812a751SAndreas Gohr foreach($data1 as $key => $val){ 4612812a751SAndreas Gohr $graph->addPoint($val,$key,0); 4622812a751SAndreas Gohr } 4632812a751SAndreas Gohr foreach($data2 as $key => $val){ 4642812a751SAndreas Gohr $graph->addPoint($val,$key,1); 4652812a751SAndreas Gohr } 4662812a751SAndreas Gohr 4672812a751SAndreas Gohr @$graph->graph(); 4682812a751SAndreas Gohr $graph->showGraph(); 4692812a751SAndreas Gohr 47095eb68e6SAndreas Gohr default: 47195eb68e6SAndreas Gohr $this->sendGIF(); 47295eb68e6SAndreas Gohr } 47395eb68e6SAndreas Gohr } 47495eb68e6SAndreas Gohr 47595eb68e6SAndreas Gohr 4762812a751SAndreas Gohr /** 4772812a751SAndreas Gohr * Return some aggregated statistics 4782812a751SAndreas Gohr */ 4792812a751SAndreas Gohr function sql_aggregate($tlimit){ 4802812a751SAndreas Gohr $data = array(); 4812812a751SAndreas Gohr 4822812a751SAndreas Gohr $sql = "SELECT ref_type, COUNT(*) as cnt 4832812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 4842812a751SAndreas Gohr WHERE $tlimit 4852812a751SAndreas Gohr AND ua_type = 'browser' 4862812a751SAndreas Gohr GROUP BY ref_type"; 4872812a751SAndreas Gohr $result = $this->runSQL($sql); 4882812a751SAndreas Gohr 4892812a751SAndreas Gohr foreach($result as $row){ 4902812a751SAndreas Gohr if($row['ref_type'] == 'search') $data['search'] = $row['cnt']; 4912812a751SAndreas Gohr if($row['ref_type'] == 'external') $data['external'] = $row['cnt']; 4922812a751SAndreas Gohr if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt']; 4932812a751SAndreas Gohr if($row['ref_type'] == '') $data['direct'] = $row['cnt']; 4942812a751SAndreas Gohr } 4952812a751SAndreas Gohr 4962812a751SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as sessions, 4972812a751SAndreas Gohr COUNT(session) as views, 4982812a751SAndreas Gohr COUNT(DISTINCT user) as users 4992812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5002812a751SAndreas Gohr WHERE $tlimit 5012812a751SAndreas Gohr AND ua_type = 'browser'"; 5022812a751SAndreas Gohr $result = $this->runSQL($sql); 5032812a751SAndreas Gohr 50475fa767dSAndreas Gohr $data['users'] = max($result[0]['users'] - 1,0); // subtract empty user 5052812a751SAndreas Gohr $data['sessions'] = $result[0]['sessions']; 5062812a751SAndreas Gohr $data['pageviews'] = $result[0]['views']; 5072812a751SAndreas Gohr 5082812a751SAndreas Gohr $sql = "SELECT COUNT(id) as robots 5092812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5102812a751SAndreas Gohr WHERE $tlimit 5112812a751SAndreas Gohr AND ua_type = 'robot'"; 5122812a751SAndreas Gohr $result = $this->runSQL($sql); 5132812a751SAndreas Gohr $data['robots'] = $result[0]['robots']; 5142812a751SAndreas Gohr 5152812a751SAndreas Gohr return $data; 5162812a751SAndreas Gohr } 5172812a751SAndreas Gohr 518bd4217d3SAndreas Gohr /** 519bd4217d3SAndreas Gohr * standard statistics follow, only accesses made by browsers are counted 520bd4217d3SAndreas Gohr * for general stats like browser or OS only visitors not pageviews are counted 521bd4217d3SAndreas Gohr */ 5222812a751SAndreas Gohr function sql_trend($tlimit,$hours=false){ 5232812a751SAndreas Gohr if($hours){ 5242812a751SAndreas Gohr $sql = "SELECT HOUR(dt) as time, 5252812a751SAndreas Gohr COUNT(DISTINCT session) as sessions, 5262812a751SAndreas Gohr COUNT(session) as pageviews 5272812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5282812a751SAndreas Gohr WHERE $tlimit 5292812a751SAndreas Gohr AND ua_type = 'browser' 5302812a751SAndreas Gohr GROUP BY HOUR(dt) 5312812a751SAndreas Gohr ORDER BY time"; 5322812a751SAndreas Gohr }else{ 5332812a751SAndreas Gohr $sql = "SELECT DATE(dt) as time, 5342812a751SAndreas Gohr COUNT(DISTINCT session) as sessions, 5352812a751SAndreas Gohr COUNT(session) as pageviews 5362812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5372812a751SAndreas Gohr WHERE $tlimit 5382812a751SAndreas Gohr AND ua_type = 'browser' 5392812a751SAndreas Gohr GROUP BY DATE(dt) 5402812a751SAndreas Gohr ORDER BY time"; 5412812a751SAndreas Gohr } 5422812a751SAndreas Gohr return $this->runSQL($sql); 5432812a751SAndreas Gohr } 5442812a751SAndreas Gohr 54595eb68e6SAndreas Gohr function sql_pages($tlimit,$start=0,$limit=20){ 5462812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, page 54795eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 54895eb68e6SAndreas Gohr WHERE $tlimit 54995eb68e6SAndreas Gohr AND ua_type = 'browser' 55095eb68e6SAndreas Gohr GROUP BY page 55195eb68e6SAndreas Gohr ORDER BY cnt DESC, page". 55295eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 55395eb68e6SAndreas Gohr return $this->runSQL($sql); 55495eb68e6SAndreas Gohr } 55595eb68e6SAndreas Gohr 55695eb68e6SAndreas Gohr function sql_referer($tlimit,$start=0,$limit=20){ 5572812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 55895eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 55995eb68e6SAndreas Gohr WHERE $tlimit 56095eb68e6SAndreas Gohr AND ua_type = 'browser' 56195eb68e6SAndreas Gohr AND ref_type = 'external' 56295eb68e6SAndreas Gohr GROUP BY ref_md5 56395eb68e6SAndreas Gohr ORDER BY cnt DESC, url". 56495eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 56595eb68e6SAndreas Gohr return $this->runSQL($sql); 56695eb68e6SAndreas Gohr } 56795eb68e6SAndreas Gohr 568*e7a2f1e0SAndreas Gohr function sql_newreferer($tlimit,$start=0,$limit=20){ 569*e7a2f1e0SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 570*e7a2f1e0SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 571*e7a2f1e0SAndreas Gohr WHERE ua_type = 'browser' 572*e7a2f1e0SAndreas Gohr AND ref_type = 'external' 573*e7a2f1e0SAndreas Gohr GROUP BY ref_md5 574*e7a2f1e0SAndreas Gohr HAVING DATE(MIN(dt)) >= DATE('".$this->from."') 575*e7a2f1e0SAndreas Gohr AND DATE(MIN(dt)) <= DATE('".$this->to."') 576*e7a2f1e0SAndreas Gohr ORDER BY cnt DESC, url". 577*e7a2f1e0SAndreas Gohr $this->sql_limit($start,$limit); 578*e7a2f1e0SAndreas Gohr return $this->runSQL($sql); 579*e7a2f1e0SAndreas Gohr } 580*e7a2f1e0SAndreas Gohr 58195eb68e6SAndreas Gohr function sql_countries($tlimit,$start=0,$limit=20){ 582bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country 58395eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A, 58495eb68e6SAndreas Gohr ".$this->getConf('db_prefix')."iplocation as B 58595eb68e6SAndreas Gohr WHERE $tlimit 58695eb68e6SAndreas Gohr AND A.ip = B.ip 58795eb68e6SAndreas Gohr GROUP BY B.country 58895eb68e6SAndreas Gohr ORDER BY cnt DESC, B.country". 58995eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 59095eb68e6SAndreas Gohr return $this->runSQL($sql); 59195eb68e6SAndreas Gohr } 59295eb68e6SAndreas Gohr 59375fa767dSAndreas Gohr function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){ 59475fa767dSAndreas Gohr if($ext){ 59575fa767dSAndreas Gohr $sel = 'ua_info as bflag, ua_info as browser, ua_ver'; 59675fa767dSAndreas Gohr $grp = 'ua_info, ua_ver'; 59775fa767dSAndreas Gohr }else{ 59875fa767dSAndreas Gohr $grp = 'ua_info'; 59975fa767dSAndreas Gohr $sel = 'ua_info'; 60075fa767dSAndreas Gohr } 60175fa767dSAndreas Gohr 602bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel 60375fa767dSAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 60475fa767dSAndreas Gohr WHERE $tlimit 60575fa767dSAndreas Gohr AND ua_type = 'browser' 60675fa767dSAndreas Gohr GROUP BY $grp 60775fa767dSAndreas Gohr ORDER BY cnt DESC, ua_info". 60875fa767dSAndreas Gohr $this->sql_limit($start,$limit); 60975fa767dSAndreas Gohr return $this->runSQL($sql); 61075fa767dSAndreas Gohr } 61175fa767dSAndreas Gohr 612bd4217d3SAndreas Gohr function sql_os($tlimit,$start=0,$limit=20){ 613bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os 614bd4217d3SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 615bd4217d3SAndreas Gohr WHERE $tlimit 616bd4217d3SAndreas Gohr AND ua_type = 'browser' 617bd4217d3SAndreas Gohr GROUP BY os 618bd4217d3SAndreas Gohr ORDER BY cnt DESC, os". 619bd4217d3SAndreas Gohr $this->sql_limit($start,$limit); 620bd4217d3SAndreas Gohr return $this->runSQL($sql); 621bd4217d3SAndreas Gohr } 622bd4217d3SAndreas Gohr 62375fa767dSAndreas Gohr 62495eb68e6SAndreas Gohr /** 62595eb68e6SAndreas Gohr * Builds a limit clause 62695eb68e6SAndreas Gohr */ 62795eb68e6SAndreas Gohr function sql_limit($start,$limit){ 62895eb68e6SAndreas Gohr $start = (int) $start; 62995eb68e6SAndreas Gohr $limit = (int) $limit; 63095eb68e6SAndreas Gohr if($limit){ 63195eb68e6SAndreas Gohr return " LIMIT $start,$limit"; 63295eb68e6SAndreas Gohr }elseif($start){ 63395eb68e6SAndreas Gohr return " OFFSET $start"; 63495eb68e6SAndreas Gohr } 63595eb68e6SAndreas Gohr return ''; 63695eb68e6SAndreas Gohr } 6371878f16fSAndreas Gohr 6381878f16fSAndreas Gohr /** 63914d99ec0SAndreas Gohr * Return a link to the DB, opening the connection if needed 6401878f16fSAndreas Gohr */ 64114d99ec0SAndreas Gohr function dbLink(){ 6421878f16fSAndreas Gohr // connect to DB if needed 6431878f16fSAndreas Gohr if(!$this->dblink){ 6441878f16fSAndreas Gohr $this->dblink = mysql_connect($this->getConf('db_server'), 6451878f16fSAndreas Gohr $this->getConf('db_user'), 6461878f16fSAndreas Gohr $this->getConf('db_password')); 6471878f16fSAndreas Gohr if(!$this->dblink){ 6481878f16fSAndreas Gohr msg('DB Error: connection failed',-1); 6491878f16fSAndreas Gohr return null; 6501878f16fSAndreas Gohr } 6511878f16fSAndreas Gohr // set utf-8 6521878f16fSAndreas Gohr if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){ 6531878f16fSAndreas Gohr msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1); 6541878f16fSAndreas Gohr return null; 6551878f16fSAndreas Gohr } 6561878f16fSAndreas Gohr } 65714d99ec0SAndreas Gohr return $this->dblink; 65814d99ec0SAndreas Gohr } 6591878f16fSAndreas Gohr 66014d99ec0SAndreas Gohr /** 66114d99ec0SAndreas Gohr * Simple function to run a DB query 66214d99ec0SAndreas Gohr */ 66314d99ec0SAndreas Gohr function runSQL($sql_string) { 66414d99ec0SAndreas Gohr $link = $this->dbLink(); 66514d99ec0SAndreas Gohr 66614d99ec0SAndreas Gohr $result = mysql_db_query($this->conf['db_database'],$sql_string,$link); 66794171ff3SAndreas Gohr if(!$result){ 6682812a751SAndreas Gohr msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1); 6691878f16fSAndreas Gohr return null; 6701878f16fSAndreas Gohr } 6711878f16fSAndreas Gohr 6721878f16fSAndreas Gohr $resultarray = array(); 6731878f16fSAndreas Gohr 6741878f16fSAndreas Gohr //mysql_db_query returns 1 on a insert statement -> no need to ask for results 6751878f16fSAndreas Gohr if ($result != 1) { 6761878f16fSAndreas Gohr for($i=0; $i< mysql_num_rows($result); $i++) { 6771878f16fSAndreas Gohr $temparray = mysql_fetch_assoc($result); 6781878f16fSAndreas Gohr $resultarray[]=$temparray; 6791878f16fSAndreas Gohr } 6801878f16fSAndreas Gohr mysql_free_result($result); 6811878f16fSAndreas Gohr } 6821878f16fSAndreas Gohr 68314d99ec0SAndreas Gohr if (mysql_insert_id($link)) { 68414d99ec0SAndreas Gohr $resultarray = mysql_insert_id($link); //give back ID on insert 6851878f16fSAndreas Gohr } 6861878f16fSAndreas Gohr 6871878f16fSAndreas Gohr return $resultarray; 6881878f16fSAndreas Gohr } 6891878f16fSAndreas Gohr 6901878f16fSAndreas Gohr /** 69114d99ec0SAndreas Gohr * Returns a short name for a User Agent and sets type, version and os info 6921878f16fSAndreas Gohr */ 69314d99ec0SAndreas Gohr function ua_info($ua,&$type,&$ver,&$os){ 69414d99ec0SAndreas Gohr $ua = strtr($ua,' +','__'); 69514d99ec0SAndreas Gohr $ua = strtolower($ua); 69614d99ec0SAndreas Gohr 69714d99ec0SAndreas Gohr // common browsers 69814d99ec0SAndreas Gohr $regvermsie = '/msie([+_ ]|)([\d\.]*)/i'; 69914d99ec0SAndreas Gohr $regvernetscape = '/netscape.?\/([\d\.]*)/i'; 70014d99ec0SAndreas Gohr $regverfirefox = '/firefox\/([\d\.]*)/i'; 70114d99ec0SAndreas Gohr $regversvn = '/svn\/([\d\.]*)/i'; 70214d99ec0SAndreas Gohr $regvermozilla = '/mozilla(\/|)([\d\.]*)/i'; 70314d99ec0SAndreas Gohr $regnotie = '/webtv|omniweb|opera/i'; 70414d99ec0SAndreas Gohr $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i'; 70514d99ec0SAndreas Gohr 70614d99ec0SAndreas Gohr $name = ''; 70714d99ec0SAndreas Gohr # IE ? 70814d99ec0SAndreas Gohr if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){ 70914d99ec0SAndreas Gohr $type = 'browser'; 71014d99ec0SAndreas Gohr $ver = $m[2]; 71114d99ec0SAndreas Gohr $name = 'msie'; 71214d99ec0SAndreas Gohr } 71314d99ec0SAndreas Gohr # Firefox ? 71414d99ec0SAndreas Gohr elseif (preg_match($regverfirefox,$ua,$m)){ 71514d99ec0SAndreas Gohr $type = 'browser'; 71614d99ec0SAndreas Gohr $ver = $m[1]; 71714d99ec0SAndreas Gohr $name = 'firefox'; 71814d99ec0SAndreas Gohr } 71914d99ec0SAndreas Gohr # Subversion ? 72014d99ec0SAndreas Gohr elseif (preg_match($regversvn,$ua,$m)){ 72114d99ec0SAndreas Gohr $type = 'rcs'; 72214d99ec0SAndreas Gohr $ver = $m[1]; 72314d99ec0SAndreas Gohr $name = 'svn'; 72414d99ec0SAndreas Gohr } 72514d99ec0SAndreas Gohr # Netscape 6.x, 7.x ... ? 72614d99ec0SAndreas Gohr elseif (preg_match($regvernetscape,$ua,$m)){ 72714d99ec0SAndreas Gohr $type = 'browser'; 72814d99ec0SAndreas Gohr $ver = $m[1]; 72914d99ec0SAndreas Gohr $name = 'netscape'; 73014d99ec0SAndreas Gohr } 73114d99ec0SAndreas Gohr # Netscape 3.x, 4.x ... ? 73214d99ec0SAndreas Gohr elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){ 73314d99ec0SAndreas Gohr $type = 'browser'; 73414d99ec0SAndreas Gohr $ver = $m[2]; 73514d99ec0SAndreas Gohr $name = 'netscape'; 73614d99ec0SAndreas Gohr }else{ 73714d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/browsers.php'); 73814d99ec0SAndreas Gohr foreach($BrowsersSearchIDOrder as $regex){ 73914d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 74014d99ec0SAndreas Gohr // it's a browser! 74114d99ec0SAndreas Gohr $type = 'browser'; 74214d99ec0SAndreas Gohr $name = strtolower($regex); 74314d99ec0SAndreas Gohr break; 74414d99ec0SAndreas Gohr } 74514d99ec0SAndreas Gohr } 74614d99ec0SAndreas Gohr } 74714d99ec0SAndreas Gohr 74875fa767dSAndreas Gohr // check versions for Safari and Opera 74975fa767dSAndreas Gohr if($name == 'safari'){ 75075fa767dSAndreas Gohr if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){ 75175fa767dSAndreas Gohr $ver = $BrowsersSafariBuildToVersionHash[$match[1]]; 75275fa767dSAndreas Gohr } 75375fa767dSAndreas Gohr }elseif($name == 'opera'){ 75475fa767dSAndreas Gohr if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){ 75575fa767dSAndreas Gohr $ver = $match[1]; 75675fa767dSAndreas Gohr } 75775fa767dSAndreas Gohr } 75875fa767dSAndreas Gohr 75975fa767dSAndreas Gohr 76014d99ec0SAndreas Gohr // check OS for browsers 76114d99ec0SAndreas Gohr if($type == 'browser'){ 76214d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/operating_systems.php'); 76314d99ec0SAndreas Gohr foreach($OSSearchIDOrder as $regex){ 76414d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 76514d99ec0SAndreas Gohr $os = $OSHashID[$regex]; 76614d99ec0SAndreas Gohr break; 76714d99ec0SAndreas Gohr } 76814d99ec0SAndreas Gohr } 76914d99ec0SAndreas Gohr 77014d99ec0SAndreas Gohr } 77114d99ec0SAndreas Gohr 77214d99ec0SAndreas Gohr // are we done now? 77314d99ec0SAndreas Gohr if($name) return $name; 77414d99ec0SAndreas Gohr 77514d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/robots.php'); 77614d99ec0SAndreas Gohr foreach($RobotsSearchIDOrder as $regex){ 77714d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$ua)){ 77814d99ec0SAndreas Gohr // it's a robot! 77914d99ec0SAndreas Gohr $type = 'robot'; 78014d99ec0SAndreas Gohr return strtolower($regex); 78114d99ec0SAndreas Gohr } 78214d99ec0SAndreas Gohr } 78314d99ec0SAndreas Gohr 78414d99ec0SAndreas Gohr // dunno 7851878f16fSAndreas Gohr return ''; 7861878f16fSAndreas Gohr } 7871878f16fSAndreas Gohr 7881878f16fSAndreas Gohr /** 78914d99ec0SAndreas Gohr * 79014d99ec0SAndreas Gohr * @fixme: put search engine queries in seperate table here 79114d99ec0SAndreas Gohr */ 79214d99ec0SAndreas Gohr function log_search($referer,&$type){ 79314d99ec0SAndreas Gohr $referer = strtr($referer,' +','__'); 79414d99ec0SAndreas Gohr $referer = strtolower($referer); 79514d99ec0SAndreas Gohr 79614d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/search_engines.php'); 79714d99ec0SAndreas Gohr 79814d99ec0SAndreas Gohr foreach($SearchEnginesSearchIDOrder as $regex){ 79914d99ec0SAndreas Gohr if(preg_match('/'.$regex.'/',$referer)){ 80014d99ec0SAndreas Gohr if(!$NotSearchEnginesKeys[$regex] || 80114d99ec0SAndreas Gohr !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){ 80214d99ec0SAndreas Gohr // it's a search engine! 80314d99ec0SAndreas Gohr $type = 'search'; 80414d99ec0SAndreas Gohr break; 80514d99ec0SAndreas Gohr } 80614d99ec0SAndreas Gohr } 80714d99ec0SAndreas Gohr } 80814d99ec0SAndreas Gohr if($type != 'search') return; // we're done here 80914d99ec0SAndreas Gohr 81014d99ec0SAndreas Gohr #fixme now do the keyword magic! 81114d99ec0SAndreas Gohr } 81214d99ec0SAndreas Gohr 81314d99ec0SAndreas Gohr /** 81414d99ec0SAndreas Gohr * Resolve IP to country/city 81514d99ec0SAndreas Gohr */ 81614d99ec0SAndreas Gohr function log_ip($ip){ 81714d99ec0SAndreas Gohr // check if IP already known and up-to-date 81814d99ec0SAndreas Gohr $sql = "SELECT ip 81914d99ec0SAndreas Gohr FROM ".$this->getConf('db_prefix')."iplocation 82014d99ec0SAndreas Gohr WHERE ip ='".addslashes($ip)."' 82114d99ec0SAndreas Gohr AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)"; 82214d99ec0SAndreas Gohr $result = $this->runSQL($sql); 82314d99ec0SAndreas Gohr if($result[0]['ip']) return; 82414d99ec0SAndreas Gohr 82514d99ec0SAndreas Gohr $http = new DokuHTTPClient(); 82614d99ec0SAndreas Gohr $http->timeout = 10; 82714d99ec0SAndreas Gohr $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip); 82814d99ec0SAndreas Gohr 82914d99ec0SAndreas Gohr if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){ 83014d99ec0SAndreas Gohr $country = addslashes(trim($match[1])); 83114d99ec0SAndreas Gohr $code = addslashes(strtolower(trim($match[2]))); 83214d99ec0SAndreas Gohr $city = addslashes(trim($match[3])); 83314d99ec0SAndreas Gohr $host = addslashes(gethostbyaddr($ip)); 83414d99ec0SAndreas Gohr $ip = addslashes($ip); 83514d99ec0SAndreas Gohr 83614d99ec0SAndreas Gohr $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation 83714d99ec0SAndreas Gohr SET ip = '$ip', 83814d99ec0SAndreas Gohr country = '$country', 83914d99ec0SAndreas Gohr code = '$code', 84014d99ec0SAndreas Gohr city = '$city', 84114d99ec0SAndreas Gohr host = '$host'"; 84214d99ec0SAndreas Gohr $this->runSQL($sql); 84314d99ec0SAndreas Gohr } 84414d99ec0SAndreas Gohr } 84514d99ec0SAndreas Gohr 84614d99ec0SAndreas Gohr /** 8471878f16fSAndreas Gohr * log a page access 8481878f16fSAndreas Gohr * 8491878f16fSAndreas Gohr * called from log.php 8501878f16fSAndreas Gohr */ 8511878f16fSAndreas Gohr function log_access(){ 85294171ff3SAndreas Gohr if(!$_REQUEST['p']) return; 85394171ff3SAndreas Gohr 85414d99ec0SAndreas Gohr # FIXME check referer against blacklist and drop logging for bad boys 85514d99ec0SAndreas Gohr 85614d99ec0SAndreas Gohr // handle referer 85714d99ec0SAndreas Gohr $referer = trim($_REQUEST['r']); 85814d99ec0SAndreas Gohr if($referer){ 85914d99ec0SAndreas Gohr $ref = addslashes($referer); 86014d99ec0SAndreas Gohr $ref_md5 = ($ref) ? md5($referer) : ''; 86114d99ec0SAndreas Gohr if(strpos($referer,DOKU_URL) === 0){ 86214d99ec0SAndreas Gohr $ref_type = 'internal'; 86314d99ec0SAndreas Gohr }else{ 86414d99ec0SAndreas Gohr $ref_type = 'external'; 86514d99ec0SAndreas Gohr $this->log_search($referer,$ref_type); 86614d99ec0SAndreas Gohr } 86714d99ec0SAndreas Gohr }else{ 86814d99ec0SAndreas Gohr $ref = ''; 86914d99ec0SAndreas Gohr $ref_md5 = ''; 87014d99ec0SAndreas Gohr $ref_type = ''; 87114d99ec0SAndreas Gohr } 87214d99ec0SAndreas Gohr 87314d99ec0SAndreas Gohr // handle user agent 87414d99ec0SAndreas Gohr $agent = trim($_SERVER['HTTP_USER_AGENT']); 87514d99ec0SAndreas Gohr 87614d99ec0SAndreas Gohr $ua = addslashes($agent); 87714d99ec0SAndreas Gohr $ua_type = ''; 87814d99ec0SAndreas Gohr $ua_ver = ''; 87914d99ec0SAndreas Gohr $os = ''; 88014d99ec0SAndreas Gohr $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os)); 88114d99ec0SAndreas Gohr 8821878f16fSAndreas Gohr $page = addslashes($_REQUEST['p']); 8831878f16fSAndreas Gohr $ip = addslashes($_SERVER['REMOTE_ADDR']); 8841878f16fSAndreas Gohr $sx = (int) $_REQUEST['sx']; 8851878f16fSAndreas Gohr $sy = (int) $_REQUEST['sy']; 8861878f16fSAndreas Gohr $vx = (int) $_REQUEST['vx']; 8871878f16fSAndreas Gohr $vy = (int) $_REQUEST['vy']; 88875fa767dSAndreas Gohr $js = (int) $_REQUEST['js']; 8891878f16fSAndreas Gohr $user = addslashes($_SERVER['REMOTE_USER']); 8901878f16fSAndreas Gohr $session = addslashes(session_id()); 8911878f16fSAndreas Gohr 89294171ff3SAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access 89375fa767dSAndreas Gohr SET dt = NOW(), 89475fa767dSAndreas Gohr page = '$page', 8951878f16fSAndreas Gohr ip = '$ip', 8961878f16fSAndreas Gohr ua = '$ua', 8971878f16fSAndreas Gohr ua_info = '$ua_info', 89814d99ec0SAndreas Gohr ua_type = '$ua_type', 89914d99ec0SAndreas Gohr ua_ver = '$ua_ver', 90014d99ec0SAndreas Gohr os = '$os', 9011878f16fSAndreas Gohr ref = '$ref', 90294171ff3SAndreas Gohr ref_md5 = '$ref_md5', 90314d99ec0SAndreas Gohr ref_type = '$ref_type', 9041878f16fSAndreas Gohr screen_x = '$sx', 9051878f16fSAndreas Gohr screen_y = '$sy', 9061878f16fSAndreas Gohr view_x = '$vx', 9071878f16fSAndreas Gohr view_y = '$vy', 90875fa767dSAndreas Gohr js = '$js', 9091878f16fSAndreas Gohr user = '$user', 9101878f16fSAndreas Gohr session = '$session'"; 9111878f16fSAndreas Gohr $ok = $this->runSQL($sql); 9121878f16fSAndreas Gohr if(is_null($ok)){ 9131878f16fSAndreas Gohr global $MSG; 9141878f16fSAndreas Gohr print_r($MSG); 9151878f16fSAndreas Gohr } 91614d99ec0SAndreas Gohr 91714d99ec0SAndreas Gohr // resolve the IP 91814d99ec0SAndreas Gohr $this->log_ip($_SERVER['REMOTE_ADDR']); 9191878f16fSAndreas Gohr } 9201878f16fSAndreas Gohr 9211878f16fSAndreas Gohr /** 9221878f16fSAndreas Gohr * Just send a 1x1 pixel blank gif to the browser 9231878f16fSAndreas Gohr * 9241878f16fSAndreas Gohr * @called from log.php 9251878f16fSAndreas Gohr * 9261878f16fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 9271878f16fSAndreas Gohr * @author Harry Fuecks <fuecks@gmail.com> 9281878f16fSAndreas Gohr */ 9291878f16fSAndreas Gohr function sendGIF(){ 9301878f16fSAndreas Gohr $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7'); 9311878f16fSAndreas Gohr header('Content-Type: image/gif'); 9321878f16fSAndreas Gohr header('Content-Length: '.strlen($img)); 9331878f16fSAndreas Gohr header('Connection: Close'); 9341878f16fSAndreas Gohr print $img; 9351878f16fSAndreas Gohr flush(); 9361878f16fSAndreas Gohr // Browser should drop connection after this 9371878f16fSAndreas Gohr // Thinks it's got the whole image 9381878f16fSAndreas Gohr } 9391878f16fSAndreas Gohr 9401878f16fSAndreas Gohr} 941