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 15*2998b1f6SAndreas Gohrrequire_once(DOKU_PLUGIN.'statistics/inc/DokuBrowscap.php'); 16*2998b1f6SAndreas Gohr 171878f16fSAndreas Gohr/** 181878f16fSAndreas Gohr * All DokuWiki plugins to extend the admin function 191878f16fSAndreas Gohr * need to inherit from this class 201878f16fSAndreas Gohr */ 211878f16fSAndreas Gohrclass admin_plugin_statistics extends DokuWiki_Admin_Plugin { 22a901d721SAndreas Gohr public $dblink = null; 23a901d721SAndreas Gohr protected $opt = ''; 24a901d721SAndreas Gohr protected $from = ''; 25a901d721SAndreas Gohr protected $to = ''; 26a901d721SAndreas Gohr protected $start = ''; 27a901d721SAndreas Gohr protected $tlimit = ''; 28a901d721SAndreas Gohr 29a901d721SAndreas Gohr /** 30a901d721SAndreas Gohr * Available statistic pages 31a901d721SAndreas Gohr */ 32a901d721SAndreas Gohr protected $pages = array('dashboard','page','referer','newreferer', 33a901d721SAndreas Gohr 'outlinks','searchphrases','searchwords', 34a901d721SAndreas Gohr 'searchengines','browser','os','country', 35a901d721SAndreas Gohr 'resolution'); 361878f16fSAndreas Gohr 371878f16fSAndreas Gohr /** 381878f16fSAndreas Gohr * Access for managers allowed 391878f16fSAndreas Gohr */ 401878f16fSAndreas Gohr function forAdminOnly(){ 411878f16fSAndreas Gohr return false; 421878f16fSAndreas Gohr } 431878f16fSAndreas Gohr 441878f16fSAndreas Gohr /** 451878f16fSAndreas Gohr * return sort order for position in admin menu 461878f16fSAndreas Gohr */ 471878f16fSAndreas Gohr function getMenuSort() { 4814d99ec0SAndreas Gohr return 150; 491878f16fSAndreas Gohr } 501878f16fSAndreas Gohr 511878f16fSAndreas Gohr /** 521878f16fSAndreas Gohr * handle user request 531878f16fSAndreas Gohr */ 541878f16fSAndreas Gohr function handle() { 55264f1744SAndreas Gohr $this->opt = preg_replace('/[^a-z]+/','',$_REQUEST['opt']); 56a901d721SAndreas Gohr if(!in_array($this->opt,$this->pages)) $this->opt = 'dashboard'; 57a901d721SAndreas Gohr 5895eb68e6SAndreas Gohr $this->start = (int) $_REQUEST['s']; 59e8699bceSAndreas Gohr $this->setTimeframe($_REQUEST['f'],$_REQUEST['t']); 60e8699bceSAndreas Gohr } 6195eb68e6SAndreas Gohr 62e8699bceSAndreas Gohr /** 63e8699bceSAndreas Gohr * set limit clause 64e8699bceSAndreas Gohr */ 65e8699bceSAndreas Gohr function setTimeframe($from,$to){ 66264f1744SAndreas Gohr // fixme add better sanity checking here: 67e8699bceSAndreas Gohr $from = preg_replace('/[^\d\-]+/','',$from); 68e8699bceSAndreas Gohr $to = preg_replace('/[^\d\-]+/','',$to); 69e8699bceSAndreas Gohr if(!$from) $from = date('Y-m-d'); 70e8699bceSAndreas Gohr if(!$to) $to = date('Y-m-d'); 71264f1744SAndreas Gohr 72264f1744SAndreas Gohr //setup limit clause 732ee939eeSAndreas Gohr $tlimit = "A.dt >= '$from 00:00:00' AND A.dt <= '$to 23:59:59'"; 74e8699bceSAndreas Gohr $this->tlimit = $tlimit; 75e8699bceSAndreas Gohr $this->from = $from; 76e8699bceSAndreas Gohr $this->to = $to; 771878f16fSAndreas Gohr } 781878f16fSAndreas Gohr 791878f16fSAndreas Gohr /** 8079b4a855SAndreas Gohr * Output the Statistics 811878f16fSAndreas Gohr */ 821878f16fSAndreas Gohr function html() { 83264f1744SAndreas Gohr echo '<h1>Access Statistics</h1>'; 84264f1744SAndreas Gohr $this->html_timeselect(); 85264f1744SAndreas Gohr 8679b4a855SAndreas Gohr $method = 'html_'.$this->opt; 8779b4a855SAndreas Gohr if(method_exists($this,$method)){ 88a901d721SAndreas Gohr echo '<div class="plg_stats_'.$this->opt.'">'; 89a901d721SAndreas Gohr echo '<h2>'.$this->getLang($this->opt).'</h2>'; 9079b4a855SAndreas Gohr $this->$method(); 91a901d721SAndreas Gohr echo '</div>'; 9214d99ec0SAndreas Gohr } 9314d99ec0SAndreas Gohr } 9414d99ec0SAndreas Gohr 9547ffcf7dSAndreas Gohr function getTOC(){ 9647ffcf7dSAndreas Gohr $toc = array(); 97a901d721SAndreas Gohr foreach($this->pages as $page){ 9847ffcf7dSAndreas Gohr $toc[] = array( 9947ffcf7dSAndreas Gohr 'link' => '?do=admin&page=statistics&opt='.$page.'&f='.$this->from.'&t='.$this->to, 10047ffcf7dSAndreas Gohr 'title' => $this->getLang($page), 10147ffcf7dSAndreas Gohr 'level' => 1, 10247ffcf7dSAndreas Gohr 'type' => 'ul' 10347ffcf7dSAndreas Gohr ); 10447ffcf7dSAndreas Gohr } 10547ffcf7dSAndreas Gohr return $toc; 1069da6395dSAndreas Gohr } 1079da6395dSAndreas Gohr 1082507f8e0SAndreas Gohr function html_pager($limit,$next){ 1092507f8e0SAndreas Gohr echo '<div class="plg_stats_pager">'; 1102507f8e0SAndreas Gohr 1112507f8e0SAndreas Gohr if($this->start > 0){ 1122507f8e0SAndreas Gohr $go = max($this->start - $limit, 0); 1132507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$this->from.'&t='.$this->to.'&s='.$go.'" class="prev">previous page</a>'; 1142507f8e0SAndreas Gohr } 1152507f8e0SAndreas Gohr 1162507f8e0SAndreas Gohr if($next){ 1172507f8e0SAndreas Gohr $go = $this->start + $limit; 1182507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$this->from.'&t='.$this->to.'&s='.$go.'" class="next">next page</a>'; 1192507f8e0SAndreas Gohr } 1202507f8e0SAndreas Gohr echo '</div>'; 1212507f8e0SAndreas Gohr } 1222507f8e0SAndreas Gohr 123264f1744SAndreas Gohr /** 124264f1744SAndreas Gohr * Print the time selection menu 125264f1744SAndreas Gohr */ 12614d99ec0SAndreas Gohr function html_timeselect(){ 127264f1744SAndreas Gohr $now = date('Y-m-d'); 128264f1744SAndreas Gohr $yday = date('Y-m-d',time()-(60*60*24)); 129264f1744SAndreas Gohr $week = date('Y-m-d',time()-(60*60*24*7)); 130264f1744SAndreas Gohr $month = date('Y-m-d',time()-(60*60*24*30)); 13114d99ec0SAndreas Gohr 132264f1744SAndreas Gohr echo '<div class="plg_stats_timeselect">'; 133264f1744SAndreas Gohr echo '<span>Select the timeframe:</span>'; 134264f1744SAndreas Gohr echo '<ul>'; 135264f1744SAndreas Gohr 136264f1744SAndreas Gohr echo '<li>'; 1372507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$now.'&t='.$now.'">'; 138264f1744SAndreas Gohr echo 'today'; 139264f1744SAndreas Gohr echo '</a>'; 140264f1744SAndreas Gohr echo '</li>'; 141264f1744SAndreas Gohr 142264f1744SAndreas Gohr echo '<li>'; 1432507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$yday.'&t='.$yday.'">'; 144264f1744SAndreas Gohr echo 'yesterday'; 145264f1744SAndreas Gohr echo '</a>'; 146264f1744SAndreas Gohr echo '</li>'; 147264f1744SAndreas Gohr 148264f1744SAndreas Gohr echo '<li>'; 1492507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$week.'&t='.$now.'">'; 150264f1744SAndreas Gohr echo 'last 7 days'; 151264f1744SAndreas Gohr echo '</a>'; 152264f1744SAndreas Gohr echo '</li>'; 153264f1744SAndreas Gohr 154264f1744SAndreas Gohr echo '<li>'; 1552507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt='.$this->opt.'&f='.$month.'&t='.$now.'">'; 156264f1744SAndreas Gohr echo 'last 30 days'; 157264f1744SAndreas Gohr echo '</a>'; 158264f1744SAndreas Gohr echo '</li>'; 159264f1744SAndreas Gohr 160264f1744SAndreas Gohr echo '</ul>'; 161264f1744SAndreas Gohr 162264f1744SAndreas Gohr 163264f1744SAndreas Gohr echo '<form action="" method="get">'; 164264f1744SAndreas Gohr echo '<input type="hidden" name="do" value="admin" />'; 165264f1744SAndreas Gohr echo '<input type="hidden" name="page" value="statistics" />'; 166264f1744SAndreas Gohr echo '<input type="hidden" name="opt" value="'.$this->opt.'" />'; 167264f1744SAndreas Gohr echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />'; 168264f1744SAndreas Gohr echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />'; 169264f1744SAndreas Gohr echo '<input type="submit" value="go" class="button" />'; 17014d99ec0SAndreas Gohr echo '</form>'; 171264f1744SAndreas Gohr 172264f1744SAndreas Gohr echo '</div>'; 17314d99ec0SAndreas Gohr } 17414d99ec0SAndreas Gohr 17514d99ec0SAndreas Gohr 176f5f32cbfSAndreas Gohr /** 177f5f32cbfSAndreas Gohr * Print an introductionary screen 178f5f32cbfSAndreas Gohr */ 17914d99ec0SAndreas Gohr function html_dashboard(){ 1802812a751SAndreas Gohr echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists 1812812a751SAndreas Gohr choose a topic from the list.</p>'; 1822812a751SAndreas Gohr 1832812a751SAndreas Gohr // general info 1842812a751SAndreas Gohr echo '<div class="plg_stats_top">'; 1852812a751SAndreas Gohr $result = $this->sql_aggregate($this->tlimit); 1862812a751SAndreas Gohr echo '<ul>'; 1872812a751SAndreas Gohr echo '<li><span>'.$result['pageviews'].'</span> page views </li>'; 1883c0acc14SAndreas Gohr echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>'; 1893c0acc14SAndreas Gohr echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>'; 1902812a751SAndreas Gohr echo '<li><span>'.$result['users'].'</span> logged in users</li>'; 1912812a751SAndreas Gohr 1922812a751SAndreas Gohr echo '</ul>'; 1932812a751SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&f='.$this->from.'&t='.$this->to.'" />'; 1942812a751SAndreas Gohr echo '</div>'; 1952812a751SAndreas Gohr 19614d99ec0SAndreas Gohr 19787d5e44bSAndreas Gohr // top pages today 198264f1744SAndreas Gohr echo '<div>'; 199264f1744SAndreas Gohr echo '<h2>Most popular pages</h2>'; 20095eb68e6SAndreas Gohr $result = $this->sql_pages($this->tlimit,$this->start,15); 2012812a751SAndreas Gohr $this->html_resulttable($result); 2022507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=page&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 203264f1744SAndreas Gohr echo '</div>'; 20487d5e44bSAndreas Gohr 20587d5e44bSAndreas Gohr // top referer today 206264f1744SAndreas Gohr echo '<div>'; 207e7a2f1e0SAndreas Gohr echo '<h2>Newest incoming links</h2>'; 208e7a2f1e0SAndreas Gohr $result = $this->sql_newreferer($this->tlimit,$this->start,15); 2092812a751SAndreas Gohr $this->html_resulttable($result); 2102507f8e0SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=newreferer&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 211264f1744SAndreas Gohr echo '</div>'; 21254f6c432SAndreas Gohr 21329dea504SAndreas Gohr // top searches today 214264f1744SAndreas Gohr echo '<div>'; 21529dea504SAndreas Gohr echo '<h2>Top search phrases</h2>'; 21629dea504SAndreas Gohr $result = $this->sql_searchphrases($this->tlimit,$this->start,15); 21729dea504SAndreas Gohr $this->html_resulttable($result); 21829dea504SAndreas Gohr echo '<a href="?do=admin&page=statistics&opt=searchphrases&f='.$this->from.'&t='.$this->to.'" class="more">more</a>'; 219264f1744SAndreas Gohr echo '</div>'; 22014d99ec0SAndreas Gohr } 22114d99ec0SAndreas Gohr 2229da6395dSAndreas Gohr function html_country(){ 223bd4217d3SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&f='.$this->from.'&t='.$this->to.'" />'; 2249da6395dSAndreas Gohr $result = $this->sql_countries($this->tlimit,$this->start,150); 2252507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 2269da6395dSAndreas Gohr } 2279da6395dSAndreas Gohr 2289da6395dSAndreas Gohr function html_page(){ 2299da6395dSAndreas Gohr $result = $this->sql_pages($this->tlimit,$this->start,150); 2302507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 2319da6395dSAndreas Gohr } 2329da6395dSAndreas Gohr 23375fa767dSAndreas Gohr function html_browser(){ 23475fa767dSAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&f='.$this->from.'&t='.$this->to.'" />'; 23575fa767dSAndreas Gohr $result = $this->sql_browsers($this->tlimit,$this->start,150,true); 2362507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 23775fa767dSAndreas Gohr } 23875fa767dSAndreas Gohr 239bd4217d3SAndreas Gohr function html_os(){ 240bd4217d3SAndreas Gohr $result = $this->sql_os($this->tlimit,$this->start,150,true); 2412507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 242bd4217d3SAndreas Gohr } 243bd4217d3SAndreas Gohr 2449da6395dSAndreas Gohr function html_referer(){ 2452812a751SAndreas Gohr $result = $this->sql_aggregate($this->tlimit); 2462812a751SAndreas Gohr 2472812a751SAndreas Gohr $all = $result['search']+$result['external']+$result['direct']; 2482812a751SAndreas Gohr 24994023548SAndreas Gohr if($all){ 2502812a751SAndreas Gohr printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses, 2512812a751SAndreas Gohr %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through 2522812a751SAndreas Gohr links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all), 2532812a751SAndreas Gohr $result['search'],(100*$result['search']/$all),$result['external'], 2542812a751SAndreas Gohr (100*$result['external']/$all)); 25594023548SAndreas Gohr } 2562812a751SAndreas Gohr 2579da6395dSAndreas Gohr $result = $this->sql_referer($this->tlimit,$this->start,150); 2582507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 2599da6395dSAndreas Gohr } 2609da6395dSAndreas Gohr 261e7a2f1e0SAndreas Gohr function html_newreferer(){ 262e7a2f1e0SAndreas Gohr echo '<p>The following incoming links where first logged in the selected time frame, 263e7a2f1e0SAndreas Gohr and have never been seen before.</p>'; 264e7a2f1e0SAndreas Gohr 265e7a2f1e0SAndreas Gohr $result = $this->sql_newreferer($this->tlimit,$this->start,150); 2662507f8e0SAndreas Gohr $this->html_resulttable($result,'',150); 267e7a2f1e0SAndreas Gohr } 268e7a2f1e0SAndreas Gohr 269e25286daSAndreas Gohr function html_outlinks(){ 270e25286daSAndreas Gohr $result = $this->sql_outlinks($this->tlimit,$this->start,150); 271e25286daSAndreas Gohr $this->html_resulttable($result,'',150); 272e25286daSAndreas Gohr } 273e25286daSAndreas Gohr 27412dcdeccSAndreas Gohr function html_searchphrases(){ 27512dcdeccSAndreas Gohr $result = $this->sql_searchphrases($this->tlimit,$this->start,150); 27612dcdeccSAndreas Gohr $this->html_resulttable($result,'',150); 27712dcdeccSAndreas Gohr } 27812dcdeccSAndreas Gohr 27912dcdeccSAndreas Gohr function html_searchwords(){ 28012dcdeccSAndreas Gohr $result = $this->sql_searchwords($this->tlimit,$this->start,150); 28112dcdeccSAndreas Gohr $this->html_resulttable($result,'',150); 28212dcdeccSAndreas Gohr } 28312dcdeccSAndreas Gohr 28412dcdeccSAndreas Gohr function html_searchengines(){ 28512dcdeccSAndreas Gohr $result = $this->sql_searchengines($this->tlimit,$this->start,150); 28612dcdeccSAndreas Gohr $this->html_resulttable($result,'',150); 28712dcdeccSAndreas Gohr } 28812dcdeccSAndreas Gohr 289e25286daSAndreas Gohr 290c73e16f1SAndreas Gohr function html_resolution(){ 291c73e16f1SAndreas Gohr $result = $this->sql_resolution($this->tlimit,$this->start,150); 292c73e16f1SAndreas Gohr $this->html_resulttable($result,'',150); 293c73e16f1SAndreas Gohr 294c73e16f1SAndreas Gohr echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you 295c73e16f1SAndreas Gohr much about about the real size of their browser windows. The graphic below shows the size distribution of 296c73e16f1SAndreas Gohr the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged 297c73e16f1SAndreas Gohr in all browsers. Because users may resize their browser window while browsing your site the statistics may 298c73e16f1SAndreas Gohr be flawed. Take it with a grain of salt.</p>'; 299c73e16f1SAndreas Gohr 300c73e16f1SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&f='.$this->from.'&t='.$this->to.'" />'; 301c73e16f1SAndreas Gohr } 3029da6395dSAndreas Gohr 3039da6395dSAndreas Gohr 30414d99ec0SAndreas Gohr /** 30514d99ec0SAndreas Gohr * Display a result in a HTML table 30614d99ec0SAndreas Gohr */ 3072507f8e0SAndreas Gohr function html_resulttable($result,$header='',$pager=0){ 30814d99ec0SAndreas Gohr echo '<table>'; 3092812a751SAndreas Gohr if(is_array($header)){ 31014d99ec0SAndreas Gohr echo '<tr>'; 31114d99ec0SAndreas Gohr foreach($header as $h){ 31214d99ec0SAndreas Gohr echo '<th>'.hsc($h).'</th>'; 31314d99ec0SAndreas Gohr } 31414d99ec0SAndreas Gohr echo '</tr>'; 3152812a751SAndreas Gohr } 31614d99ec0SAndreas Gohr 3172507f8e0SAndreas Gohr $count = 0; 3182ee939eeSAndreas Gohr if(is_array($result)) foreach($result as $row){ 31914d99ec0SAndreas Gohr echo '<tr>'; 32014d99ec0SAndreas Gohr foreach($row as $k => $v){ 3212812a751SAndreas Gohr echo '<td class="plg_stats_X'.$k.'">'; 32214d99ec0SAndreas Gohr if($k == 'page'){ 32314d99ec0SAndreas Gohr echo '<a href="'.wl($v).'" class="wikilink1">'; 32414d99ec0SAndreas Gohr echo hsc($v); 32514d99ec0SAndreas Gohr echo '</a>'; 32614d99ec0SAndreas Gohr }elseif($k == 'url'){ 32754f6c432SAndreas Gohr $url = hsc($v); 32883b63546SAndreas Gohr $url = preg_replace('/^https?:\/\/(www\.)?/','',$url); 3292812a751SAndreas Gohr if(strlen($url) > 45){ 3302812a751SAndreas Gohr $url = substr($url,0,30).' … '.substr($url,-15); 33154f6c432SAndreas Gohr } 33214d99ec0SAndreas Gohr echo '<a href="'.$v.'" class="urlextern">'; 33354f6c432SAndreas Gohr echo $url; 33414d99ec0SAndreas Gohr echo '</a>'; 33529dea504SAndreas Gohr }elseif($k == 'lookup'){ 33629dea504SAndreas Gohr echo '<a href="http://www.google.com/search?q='.rawurlencode($v).'">'; 33729dea504SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/google.png" alt="lookup in Google" border="0" />'; 33829dea504SAndreas Gohr echo '</a> '; 33929dea504SAndreas Gohr 34029dea504SAndreas Gohr echo '<a href="http://search.yahoo.com/search?p='.rawurlencode($v).'">'; 34129dea504SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/yahoo.png" alt="lookup in Yahoo" border="0" />'; 34229dea504SAndreas Gohr echo '</a> '; 34329dea504SAndreas Gohr 34429dea504SAndreas Gohr echo '<a href="http://search.msn.com/results.aspx?q='.rawurlencode($v).'">'; 34529dea504SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/msn.png" alt="lookup in MSN Live" border="0" />'; 34629dea504SAndreas Gohr echo '</a> '; 34729dea504SAndreas Gohr 34812dcdeccSAndreas Gohr }elseif($k == 'engine'){ 34912dcdeccSAndreas Gohr include_once(dirname(__FILE__).'/inc/search_engines.php'); 35012dcdeccSAndreas Gohr echo $SearchEnginesHashLib[$v]; 35175fa767dSAndreas Gohr }elseif($k == 'bflag'){ 352*2998b1f6SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.strtolower(preg_replace('/[^\w]+/','',$v)).'.png" alt="'.hsc($v).'" />'; 353bd4217d3SAndreas Gohr }elseif($k == 'osflag'){ 354*2998b1f6SAndreas Gohr echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.strtolower(preg_replace('/[^\w]+/','',$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>'; 3652507f8e0SAndreas Gohr 3662507f8e0SAndreas Gohr if($pager && ($count == $pager)) break; 3672507f8e0SAndreas Gohr $count++; 36814d99ec0SAndreas Gohr } 36914d99ec0SAndreas Gohr echo '</table>'; 3702507f8e0SAndreas Gohr 3712507f8e0SAndreas Gohr if($pager) $this->html_pager($pager,count($result) > $pager); 3721878f16fSAndreas Gohr } 3731878f16fSAndreas Gohr 37495eb68e6SAndreas Gohr /** 37595eb68e6SAndreas Gohr * Create an image 37695eb68e6SAndreas Gohr */ 37795eb68e6SAndreas Gohr function img_build($img){ 37895eb68e6SAndreas Gohr include(dirname(__FILE__).'/inc/AGC.class.php'); 37995eb68e6SAndreas Gohr 38095eb68e6SAndreas Gohr switch($img){ 38195eb68e6SAndreas Gohr case 'country': 38295eb68e6SAndreas Gohr // build top countries + other 38395eb68e6SAndreas Gohr $result = $this->sql_countries($this->tlimit,$this->start,0); 38495eb68e6SAndreas Gohr $data = array(); 38595eb68e6SAndreas Gohr $top = 0; 38695eb68e6SAndreas Gohr foreach($result as $row){ 38795eb68e6SAndreas Gohr if($top < 7){ 38895eb68e6SAndreas Gohr $data[$row['country']] = $row['cnt']; 38995eb68e6SAndreas Gohr }else{ 39095eb68e6SAndreas Gohr $data['other'] += $row['cnt']; 39195eb68e6SAndreas Gohr } 39295eb68e6SAndreas Gohr $top++; 39395eb68e6SAndreas Gohr } 39495eb68e6SAndreas Gohr $pie = new AGC(300, 200); 39595eb68e6SAndreas Gohr $pie->setProp("showkey",true); 39695eb68e6SAndreas Gohr $pie->setProp("showval",false); 39795eb68e6SAndreas Gohr $pie->setProp("showgrid",false); 39895eb68e6SAndreas Gohr $pie->setProp("type","pie"); 39995eb68e6SAndreas Gohr $pie->setProp("keyinfo",1); 40095eb68e6SAndreas Gohr $pie->setProp("keysize",8); 40195eb68e6SAndreas Gohr $pie->setProp("keywidspc",-50); 40295eb68e6SAndreas Gohr $pie->setProp("key",array_keys($data)); 40395eb68e6SAndreas Gohr $pie->addBulkPoints(array_values($data)); 40495eb68e6SAndreas Gohr @$pie->graph(); 40595eb68e6SAndreas Gohr $pie->showGraph(); 40695eb68e6SAndreas Gohr break; 40775fa767dSAndreas Gohr case 'browser': 40875fa767dSAndreas Gohr // build top browsers + other 40975fa767dSAndreas Gohr include_once(dirname(__FILE__).'/inc/browsers.php'); 41075fa767dSAndreas Gohr 41175fa767dSAndreas Gohr $result = $this->sql_browsers($this->tlimit,$this->start,0,false); 41275fa767dSAndreas Gohr $data = array(); 41375fa767dSAndreas Gohr $top = 0; 41475fa767dSAndreas Gohr foreach($result as $row){ 41575fa767dSAndreas Gohr if($top < 5){ 41675fa767dSAndreas Gohr $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt']; 41775fa767dSAndreas Gohr }else{ 41875fa767dSAndreas Gohr $data['other'] += $row['cnt']; 41975fa767dSAndreas Gohr } 42075fa767dSAndreas Gohr $top++; 42175fa767dSAndreas Gohr } 42275fa767dSAndreas Gohr $pie = new AGC(300, 200); 42375fa767dSAndreas Gohr $pie->setProp("showkey",true); 42475fa767dSAndreas Gohr $pie->setProp("showval",false); 42575fa767dSAndreas Gohr $pie->setProp("showgrid",false); 42675fa767dSAndreas Gohr $pie->setProp("type","pie"); 42775fa767dSAndreas Gohr $pie->setProp("keyinfo",1); 42875fa767dSAndreas Gohr $pie->setProp("keysize",8); 42975fa767dSAndreas Gohr $pie->setProp("keywidspc",-50); 43075fa767dSAndreas Gohr $pie->setProp("key",array_keys($data)); 43175fa767dSAndreas Gohr $pie->addBulkPoints(array_values($data)); 43275fa767dSAndreas Gohr @$pie->graph(); 43375fa767dSAndreas Gohr $pie->showGraph(); 43475fa767dSAndreas Gohr break; 435c73e16f1SAndreas Gohr case 'view': 436c73e16f1SAndreas Gohr 437c73e16f1SAndreas Gohr $graph = new AGC(400, 200); 438c73e16f1SAndreas Gohr $graph->setColor('color',0,'blue'); 439c73e16f1SAndreas Gohr $graph->setColor('color',1,'red'); 440c73e16f1SAndreas Gohr $graph->setProp("showkey",true); 441c73e16f1SAndreas Gohr $graph->setProp("key",'view port width',0); 442c73e16f1SAndreas Gohr $graph->setProp("key",'view port height',1); 443c73e16f1SAndreas Gohr 444c73e16f1SAndreas Gohr $result = $this->sql_viewport($this->tlimit,0,0,true); 445c73e16f1SAndreas Gohr foreach($result as $row){ 446c73e16f1SAndreas Gohr $graph->addPoint($row['cnt'],$row['res_x'],0); 447c73e16f1SAndreas Gohr } 448c73e16f1SAndreas Gohr 449c73e16f1SAndreas Gohr $result = $this->sql_viewport($this->tlimit,0,0,false); 450c73e16f1SAndreas Gohr foreach($result as $row){ 451c73e16f1SAndreas Gohr $graph->addPoint($row['cnt'],$row['res_y'],1); 452c73e16f1SAndreas Gohr } 453c73e16f1SAndreas Gohr 454c73e16f1SAndreas Gohr @$graph->graph(); 455c73e16f1SAndreas Gohr $graph->showGraph(); 456c73e16f1SAndreas Gohr 457c73e16f1SAndreas Gohr break; 4582812a751SAndreas Gohr case 'trend': 4592812a751SAndreas Gohr $hours = ($this->from == $this->to); 4602812a751SAndreas Gohr $result = $this->sql_trend($this->tlimit,$hours); 4612812a751SAndreas Gohr $data1 = array(); 4622812a751SAndreas Gohr $data2 = array(); 4632812a751SAndreas Gohr 4642812a751SAndreas Gohr $graph = new AGC(400, 150); 4652812a751SAndreas Gohr $graph->setProp("type","bar"); 4662812a751SAndreas Gohr $graph->setProp("showgrid",false); 4672812a751SAndreas Gohr $graph->setProp("barwidth",.8); 46875fa767dSAndreas Gohr 4692812a751SAndreas Gohr $graph->setColor('color',0,'blue'); 4702812a751SAndreas Gohr $graph->setColor('color',1,'red'); 4713c0acc14SAndreas Gohr $graph->setColor('color',2,'yellow'); 4722812a751SAndreas Gohr 4732812a751SAndreas Gohr if($hours){ 4742812a751SAndreas Gohr //preset $hours 4752812a751SAndreas Gohr for($i=0;$i<24;$i++){ 4762812a751SAndreas Gohr $data1[$i] = 0; 4772812a751SAndreas Gohr $data2[$i] = 0; 4783c0acc14SAndreas Gohr $data3[$i] = 0; 4792812a751SAndreas Gohr $graph->setProp("scale",array(' 0h',' 4h',' 8h',' 12h',' 16h',' 20h',' 24h')); 4802812a751SAndreas Gohr } 4812812a751SAndreas Gohr }else{ 4822812a751SAndreas Gohr $graph->setProp("scale",array(next(array_keys($data1)),$this->to)); 4832812a751SAndreas Gohr } 4842812a751SAndreas Gohr 4852812a751SAndreas Gohr foreach($result as $row){ 4862812a751SAndreas Gohr $data1[$row['time']] = $row['pageviews']; 4872812a751SAndreas Gohr $data2[$row['time']] = $row['sessions']; 4883c0acc14SAndreas Gohr $data3[$row['time']] = $row['visitors']; 4892812a751SAndreas Gohr } 4902812a751SAndreas Gohr 4912812a751SAndreas Gohr foreach($data1 as $key => $val){ 4922812a751SAndreas Gohr $graph->addPoint($val,$key,0); 4932812a751SAndreas Gohr } 4942812a751SAndreas Gohr foreach($data2 as $key => $val){ 4952812a751SAndreas Gohr $graph->addPoint($val,$key,1); 4962812a751SAndreas Gohr } 4973c0acc14SAndreas Gohr foreach($data3 as $key => $val){ 4983c0acc14SAndreas Gohr $graph->addPoint($val,$key,2); 4993c0acc14SAndreas Gohr } 5002812a751SAndreas Gohr 5012812a751SAndreas Gohr @$graph->graph(); 5022812a751SAndreas Gohr $graph->showGraph(); 5032812a751SAndreas Gohr 50495eb68e6SAndreas Gohr default: 50595eb68e6SAndreas Gohr $this->sendGIF(); 50695eb68e6SAndreas Gohr } 50795eb68e6SAndreas Gohr } 50895eb68e6SAndreas Gohr 50995eb68e6SAndreas Gohr 5102812a751SAndreas Gohr /** 5112812a751SAndreas Gohr * Return some aggregated statistics 5122812a751SAndreas Gohr */ 5132812a751SAndreas Gohr function sql_aggregate($tlimit){ 5142812a751SAndreas Gohr $data = array(); 5152812a751SAndreas Gohr 5162812a751SAndreas Gohr $sql = "SELECT ref_type, COUNT(*) as cnt 5172812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5182812a751SAndreas Gohr WHERE $tlimit 5192812a751SAndreas Gohr AND ua_type = 'browser' 5202812a751SAndreas Gohr GROUP BY ref_type"; 5212812a751SAndreas Gohr $result = $this->runSQL($sql); 5222812a751SAndreas Gohr 5232ee939eeSAndreas Gohr if(is_array($result)) foreach($result as $row){ 5242812a751SAndreas Gohr if($row['ref_type'] == 'search') $data['search'] = $row['cnt']; 5252812a751SAndreas Gohr if($row['ref_type'] == 'external') $data['external'] = $row['cnt']; 5262812a751SAndreas Gohr if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt']; 5272812a751SAndreas Gohr if($row['ref_type'] == '') $data['direct'] = $row['cnt']; 5282812a751SAndreas Gohr } 5292812a751SAndreas Gohr 5302812a751SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as sessions, 5312812a751SAndreas Gohr COUNT(session) as views, 5323c0acc14SAndreas Gohr COUNT(DISTINCT user) as users, 5333c0acc14SAndreas Gohr COUNT(DISTINCT uid) as visitors 5342812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5352812a751SAndreas Gohr WHERE $tlimit 5362812a751SAndreas Gohr AND ua_type = 'browser'"; 5372812a751SAndreas Gohr $result = $this->runSQL($sql); 5382812a751SAndreas Gohr 53975fa767dSAndreas Gohr $data['users'] = max($result[0]['users'] - 1,0); // subtract empty user 5402812a751SAndreas Gohr $data['sessions'] = $result[0]['sessions']; 5412812a751SAndreas Gohr $data['pageviews'] = $result[0]['views']; 5423c0acc14SAndreas Gohr $data['visitors'] = $result[0]['visitors']; 5432812a751SAndreas Gohr 5442812a751SAndreas Gohr $sql = "SELECT COUNT(id) as robots 5452812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5462812a751SAndreas Gohr WHERE $tlimit 5472812a751SAndreas Gohr AND ua_type = 'robot'"; 5482812a751SAndreas Gohr $result = $this->runSQL($sql); 5492812a751SAndreas Gohr $data['robots'] = $result[0]['robots']; 5502812a751SAndreas Gohr 5512812a751SAndreas Gohr return $data; 5522812a751SAndreas Gohr } 5532812a751SAndreas Gohr 554bd4217d3SAndreas Gohr /** 555bd4217d3SAndreas Gohr * standard statistics follow, only accesses made by browsers are counted 556bd4217d3SAndreas Gohr * for general stats like browser or OS only visitors not pageviews are counted 557bd4217d3SAndreas Gohr */ 5582812a751SAndreas Gohr function sql_trend($tlimit,$hours=false){ 5592812a751SAndreas Gohr if($hours){ 5602812a751SAndreas Gohr $sql = "SELECT HOUR(dt) as time, 5612812a751SAndreas Gohr COUNT(DISTINCT session) as sessions, 5623c0acc14SAndreas Gohr COUNT(session) as pageviews, 5633c0acc14SAndreas Gohr COUNT(DISTINCT uid) as visitors 5642812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5652812a751SAndreas Gohr WHERE $tlimit 5662812a751SAndreas Gohr AND ua_type = 'browser' 5672812a751SAndreas Gohr GROUP BY HOUR(dt) 5682812a751SAndreas Gohr ORDER BY time"; 5692812a751SAndreas Gohr }else{ 5702812a751SAndreas Gohr $sql = "SELECT DATE(dt) as time, 5712812a751SAndreas Gohr COUNT(DISTINCT session) as sessions, 5723c0acc14SAndreas Gohr COUNT(session) as pageviews, 5733c0acc14SAndreas Gohr COUNT(DISTINCT uid) as visitors 5742812a751SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 5752812a751SAndreas Gohr WHERE $tlimit 5762812a751SAndreas Gohr AND ua_type = 'browser' 5772812a751SAndreas Gohr GROUP BY DATE(dt) 5782812a751SAndreas Gohr ORDER BY time"; 5792812a751SAndreas Gohr } 5802812a751SAndreas Gohr return $this->runSQL($sql); 5812812a751SAndreas Gohr } 5822812a751SAndreas Gohr 58312dcdeccSAndreas Gohr function sql_searchengines($tlimit,$start=0,$limit=20){ 58412dcdeccSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, engine 58512dcdeccSAndreas Gohr FROM ".$this->getConf('db_prefix')."search as A 58612dcdeccSAndreas Gohr WHERE $tlimit 58712dcdeccSAndreas Gohr GROUP BY engine 58812dcdeccSAndreas Gohr ORDER BY cnt DESC, engine". 58912dcdeccSAndreas Gohr $this->sql_limit($start,$limit); 59012dcdeccSAndreas Gohr return $this->runSQL($sql); 59112dcdeccSAndreas Gohr } 59212dcdeccSAndreas Gohr 59312dcdeccSAndreas Gohr function sql_searchphrases($tlimit,$start=0,$limit=20){ 59429dea504SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, query, query as lookup 59512dcdeccSAndreas Gohr FROM ".$this->getConf('db_prefix')."search as A 59612dcdeccSAndreas Gohr WHERE $tlimit 59712dcdeccSAndreas Gohr GROUP BY query 59812dcdeccSAndreas Gohr ORDER BY cnt DESC, query". 59912dcdeccSAndreas Gohr $this->sql_limit($start,$limit); 60012dcdeccSAndreas Gohr return $this->runSQL($sql); 60112dcdeccSAndreas Gohr } 60212dcdeccSAndreas Gohr 60312dcdeccSAndreas Gohr function sql_searchwords($tlimit,$start=0,$limit=20){ 60429dea504SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, word, word as lookup 60512dcdeccSAndreas Gohr FROM ".$this->getConf('db_prefix')."search as A, 60612dcdeccSAndreas Gohr ".$this->getConf('db_prefix')."searchwords as B 60712dcdeccSAndreas Gohr WHERE $tlimit 60812dcdeccSAndreas Gohr AND A.id = B.sid 60912dcdeccSAndreas Gohr GROUP BY word 61012dcdeccSAndreas Gohr ORDER BY cnt DESC, word". 61112dcdeccSAndreas Gohr $this->sql_limit($start,$limit); 61212dcdeccSAndreas Gohr return $this->runSQL($sql); 61312dcdeccSAndreas Gohr } 61412dcdeccSAndreas Gohr 615e25286daSAndreas Gohr function sql_outlinks($tlimit,$start=0,$limit=20){ 616e25286daSAndreas Gohr $sql = "SELECT COUNT(*) as cnt, link as url 617e25286daSAndreas Gohr FROM ".$this->getConf('db_prefix')."outlinks as A 618e25286daSAndreas Gohr WHERE $tlimit 619e25286daSAndreas Gohr GROUP BY link 620e25286daSAndreas Gohr ORDER BY cnt DESC, link". 621e25286daSAndreas Gohr $this->sql_limit($start,$limit); 622e25286daSAndreas Gohr return $this->runSQL($sql); 623e25286daSAndreas Gohr } 624e25286daSAndreas Gohr 62595eb68e6SAndreas Gohr function sql_pages($tlimit,$start=0,$limit=20){ 6262812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, page 62795eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 62895eb68e6SAndreas Gohr WHERE $tlimit 62995eb68e6SAndreas Gohr AND ua_type = 'browser' 63095eb68e6SAndreas Gohr GROUP BY page 63195eb68e6SAndreas Gohr ORDER BY cnt DESC, page". 63295eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 63395eb68e6SAndreas Gohr return $this->runSQL($sql); 63495eb68e6SAndreas Gohr } 63595eb68e6SAndreas Gohr 63695eb68e6SAndreas Gohr function sql_referer($tlimit,$start=0,$limit=20){ 6372812a751SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 63895eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 63995eb68e6SAndreas Gohr WHERE $tlimit 64095eb68e6SAndreas Gohr AND ua_type = 'browser' 64195eb68e6SAndreas Gohr AND ref_type = 'external' 64295eb68e6SAndreas Gohr GROUP BY ref_md5 64395eb68e6SAndreas Gohr ORDER BY cnt DESC, url". 64495eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 64595eb68e6SAndreas Gohr return $this->runSQL($sql); 64695eb68e6SAndreas Gohr } 64795eb68e6SAndreas Gohr 648e7a2f1e0SAndreas Gohr function sql_newreferer($tlimit,$start=0,$limit=20){ 649e7a2f1e0SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, ref as url 6502ee939eeSAndreas Gohr FROM ".$this->getConf('db_prefix')."access as B, 6512ee939eeSAndreas Gohr ".$this->getConf('db_prefix')."refseen as A 6522ee939eeSAndreas Gohr WHERE $tlimit 6532ee939eeSAndreas Gohr AND ua_type = 'browser' 654e7a2f1e0SAndreas Gohr AND ref_type = 'external' 6552ee939eeSAndreas Gohr AND A.ref_md5 = B.ref_md5 6562ee939eeSAndreas Gohr GROUP BY A.ref_md5 657e7a2f1e0SAndreas Gohr ORDER BY cnt DESC, url". 658e7a2f1e0SAndreas Gohr $this->sql_limit($start,$limit); 659e7a2f1e0SAndreas Gohr return $this->runSQL($sql); 660e7a2f1e0SAndreas Gohr } 661e7a2f1e0SAndreas Gohr 66295eb68e6SAndreas Gohr function sql_countries($tlimit,$start=0,$limit=20){ 663bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country 66495eb68e6SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A, 66595eb68e6SAndreas Gohr ".$this->getConf('db_prefix')."iplocation as B 66695eb68e6SAndreas Gohr WHERE $tlimit 66795eb68e6SAndreas Gohr AND A.ip = B.ip 66895eb68e6SAndreas Gohr GROUP BY B.country 66995eb68e6SAndreas Gohr ORDER BY cnt DESC, B.country". 67095eb68e6SAndreas Gohr $this->sql_limit($start,$limit); 67195eb68e6SAndreas Gohr return $this->runSQL($sql); 67295eb68e6SAndreas Gohr } 67395eb68e6SAndreas Gohr 67475fa767dSAndreas Gohr function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){ 67575fa767dSAndreas Gohr if($ext){ 67675fa767dSAndreas Gohr $sel = 'ua_info as bflag, ua_info as browser, ua_ver'; 67775fa767dSAndreas Gohr $grp = 'ua_info, ua_ver'; 67875fa767dSAndreas Gohr }else{ 67975fa767dSAndreas Gohr $grp = 'ua_info'; 68075fa767dSAndreas Gohr $sel = 'ua_info'; 68175fa767dSAndreas Gohr } 68275fa767dSAndreas Gohr 683bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel 68475fa767dSAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 68575fa767dSAndreas Gohr WHERE $tlimit 68675fa767dSAndreas Gohr AND ua_type = 'browser' 68775fa767dSAndreas Gohr GROUP BY $grp 68875fa767dSAndreas Gohr ORDER BY cnt DESC, ua_info". 68975fa767dSAndreas Gohr $this->sql_limit($start,$limit); 69075fa767dSAndreas Gohr return $this->runSQL($sql); 69175fa767dSAndreas Gohr } 69275fa767dSAndreas Gohr 693bd4217d3SAndreas Gohr function sql_os($tlimit,$start=0,$limit=20){ 694bd4217d3SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os 695bd4217d3SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 696bd4217d3SAndreas Gohr WHERE $tlimit 697bd4217d3SAndreas Gohr AND ua_type = 'browser' 698bd4217d3SAndreas Gohr GROUP BY os 699bd4217d3SAndreas Gohr ORDER BY cnt DESC, os". 700bd4217d3SAndreas Gohr $this->sql_limit($start,$limit); 701bd4217d3SAndreas Gohr return $this->runSQL($sql); 702bd4217d3SAndreas Gohr } 703bd4217d3SAndreas Gohr 704c73e16f1SAndreas Gohr function sql_resolution($tlimit,$start=0,$limit=20){ 705c73e16f1SAndreas Gohr $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res 706c73e16f1SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 707c73e16f1SAndreas Gohr WHERE $tlimit 708c73e16f1SAndreas Gohr AND ua_type = 'browser' 709c73e16f1SAndreas Gohr AND screen_x != 0 710c73e16f1SAndreas Gohr GROUP BY screen_x, screen_y 711c73e16f1SAndreas Gohr ORDER BY cnt DESC, screen_x". 712c73e16f1SAndreas Gohr $this->sql_limit($start,$limit); 713c73e16f1SAndreas Gohr return $this->runSQL($sql); 714c73e16f1SAndreas Gohr } 715c73e16f1SAndreas Gohr 716c73e16f1SAndreas Gohr function sql_viewport($tlimit,$start=0,$limit=20,$x=true){ 717c73e16f1SAndreas Gohr if($x){ 718c73e16f1SAndreas Gohr $col = 'view_x'; 719c73e16f1SAndreas Gohr $res = 'res_x'; 720c73e16f1SAndreas Gohr }else{ 721c73e16f1SAndreas Gohr $col = 'view_y'; 722c73e16f1SAndreas Gohr $res = 'res_y'; 723c73e16f1SAndreas Gohr } 724c73e16f1SAndreas Gohr 725c73e16f1SAndreas Gohr $sql = "SELECT COUNT(*) as cnt, 726c73e16f1SAndreas Gohr ROUND($col/10)*10 as $res 727c73e16f1SAndreas Gohr FROM ".$this->getConf('db_prefix')."access as A 728c73e16f1SAndreas Gohr WHERE $tlimit 729c73e16f1SAndreas Gohr AND ua_type = 'browser' 730c73e16f1SAndreas Gohr AND $col != 0 731c73e16f1SAndreas Gohr GROUP BY $res 732c73e16f1SAndreas Gohr ORDER BY cnt DESC, $res". 733c73e16f1SAndreas Gohr $this->sql_limit($start,$limit); 734c73e16f1SAndreas Gohr return $this->runSQL($sql); 735c73e16f1SAndreas Gohr } 736c73e16f1SAndreas Gohr 73775fa767dSAndreas Gohr 73895eb68e6SAndreas Gohr /** 73995eb68e6SAndreas Gohr * Builds a limit clause 74095eb68e6SAndreas Gohr */ 74195eb68e6SAndreas Gohr function sql_limit($start,$limit){ 74295eb68e6SAndreas Gohr $start = (int) $start; 74395eb68e6SAndreas Gohr $limit = (int) $limit; 74495eb68e6SAndreas Gohr if($limit){ 7452507f8e0SAndreas Gohr $limit += 1; 74695eb68e6SAndreas Gohr return " LIMIT $start,$limit"; 74795eb68e6SAndreas Gohr }elseif($start){ 74895eb68e6SAndreas Gohr return " OFFSET $start"; 74995eb68e6SAndreas Gohr } 75095eb68e6SAndreas Gohr return ''; 75195eb68e6SAndreas Gohr } 7521878f16fSAndreas Gohr 7531878f16fSAndreas Gohr /** 75414d99ec0SAndreas Gohr * Return a link to the DB, opening the connection if needed 7551878f16fSAndreas Gohr */ 75614d99ec0SAndreas Gohr function dbLink(){ 7571878f16fSAndreas Gohr // connect to DB if needed 7581878f16fSAndreas Gohr if(!$this->dblink){ 7591878f16fSAndreas Gohr $this->dblink = mysql_connect($this->getConf('db_server'), 7601878f16fSAndreas Gohr $this->getConf('db_user'), 7611878f16fSAndreas Gohr $this->getConf('db_password')); 7621878f16fSAndreas Gohr if(!$this->dblink){ 7631878f16fSAndreas Gohr msg('DB Error: connection failed',-1); 7641878f16fSAndreas Gohr return null; 7651878f16fSAndreas Gohr } 7661878f16fSAndreas Gohr // set utf-8 7671878f16fSAndreas Gohr if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){ 7681878f16fSAndreas Gohr msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1); 7691878f16fSAndreas Gohr return null; 7701878f16fSAndreas Gohr } 7711878f16fSAndreas Gohr } 77214d99ec0SAndreas Gohr return $this->dblink; 77314d99ec0SAndreas Gohr } 7741878f16fSAndreas Gohr 77514d99ec0SAndreas Gohr /** 77614d99ec0SAndreas Gohr * Simple function to run a DB query 77714d99ec0SAndreas Gohr */ 77814d99ec0SAndreas Gohr function runSQL($sql_string) { 77914d99ec0SAndreas Gohr $link = $this->dbLink(); 78014d99ec0SAndreas Gohr 78114d99ec0SAndreas Gohr $result = mysql_db_query($this->conf['db_database'],$sql_string,$link); 78294171ff3SAndreas Gohr if(!$result){ 7832812a751SAndreas Gohr msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1); 7841878f16fSAndreas Gohr return null; 7851878f16fSAndreas Gohr } 7861878f16fSAndreas Gohr 7871878f16fSAndreas Gohr $resultarray = array(); 7881878f16fSAndreas Gohr 7891878f16fSAndreas Gohr //mysql_db_query returns 1 on a insert statement -> no need to ask for results 7901878f16fSAndreas Gohr if ($result != 1) { 7911878f16fSAndreas Gohr for($i=0; $i< mysql_num_rows($result); $i++) { 7921878f16fSAndreas Gohr $temparray = mysql_fetch_assoc($result); 7931878f16fSAndreas Gohr $resultarray[]=$temparray; 7941878f16fSAndreas Gohr } 7951878f16fSAndreas Gohr mysql_free_result($result); 7961878f16fSAndreas Gohr } 7971878f16fSAndreas Gohr 79814d99ec0SAndreas Gohr if (mysql_insert_id($link)) { 79914d99ec0SAndreas Gohr $resultarray = mysql_insert_id($link); //give back ID on insert 8001878f16fSAndreas Gohr } 8011878f16fSAndreas Gohr 8021878f16fSAndreas Gohr return $resultarray; 8031878f16fSAndreas Gohr } 8041878f16fSAndreas Gohr 8051878f16fSAndreas Gohr /** 80614d99ec0SAndreas Gohr * Returns a short name for a User Agent and sets type, version and os info 8071878f16fSAndreas Gohr */ 808*2998b1f6SAndreas Gohr function ua_info($agent,&$type,&$version,&$os){ 809*2998b1f6SAndreas Gohr global $conf; 810*2998b1f6SAndreas Gohr $bc = new DokuBrowscap($conf['cachedir']); 811*2998b1f6SAndreas Gohr $ua = $bc->getBrowser($agent); 81214d99ec0SAndreas Gohr 81314d99ec0SAndreas Gohr $type = 'browser'; 814*2998b1f6SAndreas Gohr if($ua->Crawler) $type = 'robot'; 815*2998b1f6SAndreas Gohr if($ua->isSyndicationReader) $type = 'feedreader'; 81614d99ec0SAndreas Gohr 817*2998b1f6SAndreas Gohr $version = $ua->Version; 818*2998b1f6SAndreas Gohr $os = $ua->Platform; 819*2998b1f6SAndreas Gohr return $ua->Browser; 8201878f16fSAndreas Gohr } 8211878f16fSAndreas Gohr 8221878f16fSAndreas Gohr /** 823322de360SAndreas Gohr * Log search queries 82414d99ec0SAndreas Gohr */ 82514d99ec0SAndreas Gohr function log_search($referer,&$type){ 82614d99ec0SAndreas Gohr $referer = strtolower($referer); 827673875b1SAndreas Gohr $ref = strtr($referer,' +','__'); 82814d99ec0SAndreas Gohr 82914d99ec0SAndreas Gohr include(dirname(__FILE__).'/inc/search_engines.php'); 83014d99ec0SAndreas Gohr 83114d99ec0SAndreas Gohr foreach($SearchEnginesSearchIDOrder as $regex){ 832673875b1SAndreas Gohr if(preg_match('/'.$regex.'/',$ref)){ 83314d99ec0SAndreas Gohr if(!$NotSearchEnginesKeys[$regex] || 834673875b1SAndreas Gohr !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$ref)){ 83514d99ec0SAndreas Gohr // it's a search engine! 83614d99ec0SAndreas Gohr $type = 'search'; 83714d99ec0SAndreas Gohr break; 83814d99ec0SAndreas Gohr } 83914d99ec0SAndreas Gohr } 84014d99ec0SAndreas Gohr } 84114d99ec0SAndreas Gohr if($type != 'search') return; // we're done here 84214d99ec0SAndreas Gohr 843322de360SAndreas Gohr // extract query 844322de360SAndreas Gohr $engine = $SearchEnginesHashID[$regex]; 845322de360SAndreas Gohr $param = $SearchEnginesKnownUrl[$engine]; 846322de360SAndreas Gohr if($param && preg_match('/'.$param.'(.*?)[&$]/',$referer,$match)){ 847322de360SAndreas Gohr $query = array_pop($match); 848322de360SAndreas Gohr }elseif(preg_match('/'.$WordsToExtractSearchUrl.'(.*?)[&$]/',$referer,$match)){ 849322de360SAndreas Gohr $query = array_pop($match); 850322de360SAndreas Gohr } 851322de360SAndreas Gohr if(!$query) return; // we failed 852322de360SAndreas Gohr 853322de360SAndreas Gohr // clean the query 854322de360SAndreas Gohr $query = preg_replace('/^(cache|related):[^\+]+/','',$query); // non-search queries 855322de360SAndreas Gohr $query = preg_replace('/%0[ad]/',' ',$query); // LF CR 856322de360SAndreas Gohr $query = preg_replace('/%2[02789abc]/',' ',$query); // space " ' ( ) * + , 857322de360SAndreas Gohr $query = preg_replace('/%3a/',' ',$query); // : 858673875b1SAndreas Gohr $query = strtr($query,'+\'()"*,:',' '); // badly encoded 859322de360SAndreas Gohr $query = preg_replace('/ +/',' ',$query); // ws compact 860322de360SAndreas Gohr $query = trim($query); 861322de360SAndreas Gohr $query = urldecode($query); 862322de360SAndreas Gohr if(!utf8_check($query)) $query = utf8_encode($query); // assume latin1 if not utf8 863322de360SAndreas Gohr $query = utf8_strtolower($query); 864322de360SAndreas Gohr 865322de360SAndreas Gohr // log it! 866322de360SAndreas Gohr $page = addslashes($_REQUEST['p']); 867322de360SAndreas Gohr $query = addslashes($query); 868673875b1SAndreas Gohr $sql = "INSERT INTO ".$this->getConf('db_prefix')."search 869322de360SAndreas Gohr SET dt = NOW(), 870322de360SAndreas Gohr page = '$page', 871322de360SAndreas Gohr query = '$query', 872322de360SAndreas Gohr engine = '$engine'"; 873322de360SAndreas Gohr $id = $this->runSQL($sql); 874322de360SAndreas Gohr if(is_null($id)){ 875322de360SAndreas Gohr global $MSG; 876322de360SAndreas Gohr print_r($MSG); 877322de360SAndreas Gohr return; 878322de360SAndreas Gohr } 879322de360SAndreas Gohr 880322de360SAndreas Gohr // log single keywords 881322de360SAndreas Gohr $words = explode(' ',utf8_stripspecials($query,' ','\._\-:\*')); 882322de360SAndreas Gohr foreach($words as $word){ 883673875b1SAndreas Gohr if(!$word) continue; 884322de360SAndreas Gohr $word = addslashes($word); 885322de360SAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."searchwords 886322de360SAndreas Gohr SET sid = $id, 887322de360SAndreas Gohr word = '$word'"; 888322de360SAndreas Gohr $ok = $this->runSQL($sql); 889322de360SAndreas Gohr if(is_null($ok)){ 890322de360SAndreas Gohr global $MSG; 891322de360SAndreas Gohr print_r($MSG); 892322de360SAndreas Gohr } 893322de360SAndreas Gohr } 89414d99ec0SAndreas Gohr } 89514d99ec0SAndreas Gohr 89614d99ec0SAndreas Gohr /** 89714d99ec0SAndreas Gohr * Resolve IP to country/city 89814d99ec0SAndreas Gohr */ 89914d99ec0SAndreas Gohr function log_ip($ip){ 90014d99ec0SAndreas Gohr // check if IP already known and up-to-date 90114d99ec0SAndreas Gohr $sql = "SELECT ip 90214d99ec0SAndreas Gohr FROM ".$this->getConf('db_prefix')."iplocation 90314d99ec0SAndreas Gohr WHERE ip ='".addslashes($ip)."' 90414d99ec0SAndreas Gohr AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)"; 90514d99ec0SAndreas Gohr $result = $this->runSQL($sql); 90614d99ec0SAndreas Gohr if($result[0]['ip']) return; 90714d99ec0SAndreas Gohr 90814d99ec0SAndreas Gohr $http = new DokuHTTPClient(); 90914d99ec0SAndreas Gohr $http->timeout = 10; 91014d99ec0SAndreas Gohr $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip); 91114d99ec0SAndreas Gohr 91214d99ec0SAndreas Gohr if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){ 91314d99ec0SAndreas Gohr $country = addslashes(trim($match[1])); 91414d99ec0SAndreas Gohr $code = addslashes(strtolower(trim($match[2]))); 91514d99ec0SAndreas Gohr $city = addslashes(trim($match[3])); 91614d99ec0SAndreas Gohr $host = addslashes(gethostbyaddr($ip)); 91714d99ec0SAndreas Gohr $ip = addslashes($ip); 91814d99ec0SAndreas Gohr 91914d99ec0SAndreas Gohr $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation 92014d99ec0SAndreas Gohr SET ip = '$ip', 92114d99ec0SAndreas Gohr country = '$country', 92214d99ec0SAndreas Gohr code = '$code', 92314d99ec0SAndreas Gohr city = '$city', 92414d99ec0SAndreas Gohr host = '$host'"; 92514d99ec0SAndreas Gohr $this->runSQL($sql); 92614d99ec0SAndreas Gohr } 92714d99ec0SAndreas Gohr } 92814d99ec0SAndreas Gohr 92914d99ec0SAndreas Gohr /** 930e25286daSAndreas Gohr * log a click on an external link 931e25286daSAndreas Gohr * 932e25286daSAndreas Gohr * called from log.php 933e25286daSAndreas Gohr */ 934e25286daSAndreas Gohr function log_outgoing(){ 935e25286daSAndreas Gohr if(!$_REQUEST['ol']) return; 936e25286daSAndreas Gohr 937e25286daSAndreas Gohr $link_md5 = md5($link); 938e25286daSAndreas Gohr $link = addslashes($_REQUEST['ol']); 939e25286daSAndreas Gohr $session = addslashes(session_id()); 940d8c4d85eSAndreas Gohr $page = addslashes($_REQUEST['p']); 941e25286daSAndreas Gohr 942e25286daSAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks 943e25286daSAndreas Gohr SET dt = NOW(), 944e25286daSAndreas Gohr session = '$session', 945d8c4d85eSAndreas Gohr page = '$page', 946e25286daSAndreas Gohr link_md5 = '$link_md5', 947e25286daSAndreas Gohr link = '$link'"; 948e25286daSAndreas Gohr $ok = $this->runSQL($sql); 949e25286daSAndreas Gohr if(is_null($ok)){ 950e25286daSAndreas Gohr global $MSG; 951e25286daSAndreas Gohr print_r($MSG); 952e25286daSAndreas Gohr } 953e25286daSAndreas Gohr } 954e25286daSAndreas Gohr 955e25286daSAndreas Gohr /** 9561878f16fSAndreas Gohr * log a page access 9571878f16fSAndreas Gohr * 9581878f16fSAndreas Gohr * called from log.php 9591878f16fSAndreas Gohr */ 9601878f16fSAndreas Gohr function log_access(){ 96194171ff3SAndreas Gohr if(!$_REQUEST['p']) return; 96294171ff3SAndreas Gohr 96314d99ec0SAndreas Gohr # FIXME check referer against blacklist and drop logging for bad boys 96414d99ec0SAndreas Gohr 96514d99ec0SAndreas Gohr // handle referer 96614d99ec0SAndreas Gohr $referer = trim($_REQUEST['r']); 96714d99ec0SAndreas Gohr if($referer){ 96814d99ec0SAndreas Gohr $ref = addslashes($referer); 96914d99ec0SAndreas Gohr $ref_md5 = ($ref) ? md5($referer) : ''; 97014d99ec0SAndreas Gohr if(strpos($referer,DOKU_URL) === 0){ 97114d99ec0SAndreas Gohr $ref_type = 'internal'; 97214d99ec0SAndreas Gohr }else{ 97314d99ec0SAndreas Gohr $ref_type = 'external'; 97414d99ec0SAndreas Gohr $this->log_search($referer,$ref_type); 97514d99ec0SAndreas Gohr } 97614d99ec0SAndreas Gohr }else{ 97714d99ec0SAndreas Gohr $ref = ''; 97814d99ec0SAndreas Gohr $ref_md5 = ''; 97914d99ec0SAndreas Gohr $ref_type = ''; 98014d99ec0SAndreas Gohr } 98114d99ec0SAndreas Gohr 98214d99ec0SAndreas Gohr // handle user agent 98314d99ec0SAndreas Gohr $agent = trim($_SERVER['HTTP_USER_AGENT']); 98414d99ec0SAndreas Gohr 98514d99ec0SAndreas Gohr $ua = addslashes($agent); 98614d99ec0SAndreas Gohr $ua_type = ''; 98714d99ec0SAndreas Gohr $ua_ver = ''; 98814d99ec0SAndreas Gohr $os = ''; 98914d99ec0SAndreas Gohr $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os)); 99014d99ec0SAndreas Gohr 9911878f16fSAndreas Gohr $page = addslashes($_REQUEST['p']); 9921878f16fSAndreas Gohr $ip = addslashes($_SERVER['REMOTE_ADDR']); 9931878f16fSAndreas Gohr $sx = (int) $_REQUEST['sx']; 9941878f16fSAndreas Gohr $sy = (int) $_REQUEST['sy']; 9951878f16fSAndreas Gohr $vx = (int) $_REQUEST['vx']; 9961878f16fSAndreas Gohr $vy = (int) $_REQUEST['vy']; 99775fa767dSAndreas Gohr $js = (int) $_REQUEST['js']; 9983c0acc14SAndreas Gohr $uid = addslashes($_REQUEST['uid']); 9991878f16fSAndreas Gohr $user = addslashes($_SERVER['REMOTE_USER']); 10001878f16fSAndreas Gohr $session = addslashes(session_id()); 10013c0acc14SAndreas Gohr if(!$uid) $uid = $session; 10021878f16fSAndreas Gohr 100394171ff3SAndreas Gohr $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access 100475fa767dSAndreas Gohr SET dt = NOW(), 100575fa767dSAndreas Gohr page = '$page', 10061878f16fSAndreas Gohr ip = '$ip', 10071878f16fSAndreas Gohr ua = '$ua', 10081878f16fSAndreas Gohr ua_info = '$ua_info', 100914d99ec0SAndreas Gohr ua_type = '$ua_type', 101014d99ec0SAndreas Gohr ua_ver = '$ua_ver', 101114d99ec0SAndreas Gohr os = '$os', 10121878f16fSAndreas Gohr ref = '$ref', 101394171ff3SAndreas Gohr ref_md5 = '$ref_md5', 101414d99ec0SAndreas Gohr ref_type = '$ref_type', 10151878f16fSAndreas Gohr screen_x = '$sx', 10161878f16fSAndreas Gohr screen_y = '$sy', 10171878f16fSAndreas Gohr view_x = '$vx', 10181878f16fSAndreas Gohr view_y = '$vy', 101975fa767dSAndreas Gohr js = '$js', 10201878f16fSAndreas Gohr user = '$user', 10213c0acc14SAndreas Gohr session = '$session', 10223c0acc14SAndreas Gohr uid = '$uid'"; 10231878f16fSAndreas Gohr $ok = $this->runSQL($sql); 10241878f16fSAndreas Gohr if(is_null($ok)){ 10251878f16fSAndreas Gohr global $MSG; 10261878f16fSAndreas Gohr print_r($MSG); 10271878f16fSAndreas Gohr } 102814d99ec0SAndreas Gohr 10292ee939eeSAndreas Gohr $sql = "INSERT DELAYED IGNORE INTO ".$this->getConf('db_prefix')."refseen 10302ee939eeSAndreas Gohr SET ref_md5 = '$ref_md5', 10312ee939eeSAndreas Gohr dt = NOW()"; 10322ee939eeSAndreas Gohr $ok = $this->runSQL($sql); 10332ee939eeSAndreas Gohr if(is_null($ok)){ 10342ee939eeSAndreas Gohr global $MSG; 10352ee939eeSAndreas Gohr print_r($MSG); 10362ee939eeSAndreas Gohr } 10372ee939eeSAndreas Gohr 103814d99ec0SAndreas Gohr // resolve the IP 103914d99ec0SAndreas Gohr $this->log_ip($_SERVER['REMOTE_ADDR']); 10401878f16fSAndreas Gohr } 10411878f16fSAndreas Gohr 10421878f16fSAndreas Gohr /** 10431878f16fSAndreas Gohr * Just send a 1x1 pixel blank gif to the browser 10441878f16fSAndreas Gohr * 10451878f16fSAndreas Gohr * @called from log.php 10461878f16fSAndreas Gohr * 10471878f16fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 10481878f16fSAndreas Gohr * @author Harry Fuecks <fuecks@gmail.com> 10491878f16fSAndreas Gohr */ 10501878f16fSAndreas Gohr function sendGIF(){ 10511878f16fSAndreas Gohr $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7'); 10521878f16fSAndreas Gohr header('Content-Type: image/gif'); 10531878f16fSAndreas Gohr header('Content-Length: '.strlen($img)); 10541878f16fSAndreas Gohr header('Connection: Close'); 10551878f16fSAndreas Gohr print $img; 10561878f16fSAndreas Gohr flush(); 10571878f16fSAndreas Gohr // Browser should drop connection after this 10581878f16fSAndreas Gohr // Thinks it's got the whole image 10591878f16fSAndreas Gohr } 10601878f16fSAndreas Gohr 10611878f16fSAndreas Gohr} 1062