xref: /plugin/statistics/admin.php (revision d8c4d85eb00c83b657c6864a9fea0fdb32bc8b4e)
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;
94e7a2f1e0SAndreas Gohr            case 'newreferer':
95e7a2f1e0SAndreas Gohr                $this->html_newreferer();
96e7a2f1e0SAndreas Gohr                break;
97e25286daSAndreas Gohr            case 'outlinks':
98e25286daSAndreas Gohr                $this->html_outlinks();
99e25286daSAndreas Gohr                break;
100c73e16f1SAndreas Gohr            case 'resolution':
101c73e16f1SAndreas Gohr                $this->html_resolution();
102c73e16f1SAndreas Gohr                break;
10314d99ec0SAndreas Gohr            default:
1049da6395dSAndreas Gohr                $this->html_dashboard();
10514d99ec0SAndreas Gohr        }
10614d99ec0SAndreas Gohr    }
10714d99ec0SAndreas Gohr
1089da6395dSAndreas Gohr    function html_toc(){
1099da6395dSAndreas Gohr        echo '<div class="toc">';
1109da6395dSAndreas Gohr        echo '<div class="tocheader toctoggle" id="toc__header">';
1119da6395dSAndreas Gohr        echo 'Detailed Statistics';
1129da6395dSAndreas Gohr        echo '</div>';
1139da6395dSAndreas Gohr        echo '<div id="toc__inside">';
1149da6395dSAndreas Gohr        echo '<ul class="toc">';
1159da6395dSAndreas Gohr
1169da6395dSAndreas Gohr        echo '<li><div class="li">';
1172507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=&amp;f='.$this->from.'&amp;t='.$this->to.'">Dashboard</a>';
1189da6395dSAndreas Gohr        echo '</div></li>';
1199da6395dSAndreas Gohr
1209da6395dSAndreas Gohr        echo '<li><div class="li">';
1212507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'">Pages</a>';
1229da6395dSAndreas Gohr        echo '</div></li>';
1239da6395dSAndreas Gohr
1249da6395dSAndreas Gohr        echo '<li><div class="li">';
1252507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=referer&amp;f='.$this->from.'&amp;t='.$this->to.'">Incoming Links</a>';
1269da6395dSAndreas Gohr        echo '</div></li>';
1279da6395dSAndreas Gohr
1289da6395dSAndreas Gohr        echo '<li><div class="li">';
1292507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'">New Incoming Links</a>';
130e7a2f1e0SAndreas Gohr        echo '</div></li>';
131e7a2f1e0SAndreas Gohr
132e7a2f1e0SAndreas Gohr        echo '<li><div class="li">';
133e25286daSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=outlinks&amp;f='.$this->from.'&amp;t='.$this->to.'">Outgoing Links</a>';
134e25286daSAndreas Gohr        echo '</div></li>';
135e25286daSAndreas Gohr
136e25286daSAndreas Gohr        echo '<li><div class="li">';
1372507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=browser&amp;f='.$this->from.'&amp;t='.$this->to.'">Browsers</a>';
13875fa767dSAndreas Gohr        echo '</div></li>';
13975fa767dSAndreas Gohr
14075fa767dSAndreas Gohr        echo '<li><div class="li">';
1412507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=os&amp;f='.$this->from.'&amp;t='.$this->to.'">Operating Systems</a>';
142bd4217d3SAndreas Gohr        echo '</div></li>';
143bd4217d3SAndreas Gohr
144bd4217d3SAndreas Gohr        echo '<li><div class="li">';
1452507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=country&amp;f='.$this->from.'&amp;t='.$this->to.'">Countries</a>';
1469da6395dSAndreas Gohr        echo '</div></li>';
1479da6395dSAndreas Gohr
148c73e16f1SAndreas Gohr        echo '<li><div class="li">';
149c73e16f1SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=resolution&amp;f='.$this->from.'&amp;t='.$this->to.'">Resolution</a>';
150c73e16f1SAndreas Gohr        echo '</div></li>';
151c73e16f1SAndreas Gohr
1529da6395dSAndreas Gohr        echo '</ul>';
1539da6395dSAndreas Gohr        echo '</div>';
1549da6395dSAndreas Gohr        echo '</div>';
1559da6395dSAndreas Gohr    }
1569da6395dSAndreas Gohr
1572507f8e0SAndreas Gohr    function html_pager($limit,$next){
1582507f8e0SAndreas Gohr        echo '<div class="plg_stats_pager">';
1592507f8e0SAndreas Gohr
1602507f8e0SAndreas Gohr        if($this->start > 0){
1612507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
1622507f8e0SAndreas Gohr            echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$go.'" class="prev">previous page</a>';
1632507f8e0SAndreas Gohr        }
1642507f8e0SAndreas Gohr
1652507f8e0SAndreas Gohr        if($next){
1662507f8e0SAndreas Gohr            $go = $this->start + $limit;
1672507f8e0SAndreas Gohr            echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$go.'" class="next">next page</a>';
1682507f8e0SAndreas Gohr        }
1692507f8e0SAndreas Gohr        echo '</div>';
1702507f8e0SAndreas Gohr    }
1712507f8e0SAndreas Gohr
172264f1744SAndreas Gohr    /**
173264f1744SAndreas Gohr     * Print the time selection menu
174264f1744SAndreas Gohr     */
17514d99ec0SAndreas Gohr    function html_timeselect(){
176264f1744SAndreas Gohr        $now   = date('Y-m-d');
177264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
178264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
179264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
18014d99ec0SAndreas Gohr
181264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
182264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
183264f1744SAndreas Gohr        echo '<ul>';
184264f1744SAndreas Gohr
185264f1744SAndreas Gohr        echo '<li>';
1862507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'">';
187264f1744SAndreas Gohr        echo 'today';
188264f1744SAndreas Gohr        echo '</a>';
189264f1744SAndreas Gohr        echo '</li>';
190264f1744SAndreas Gohr
191264f1744SAndreas Gohr        echo '<li>';
1922507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'">';
193264f1744SAndreas Gohr        echo 'yesterday';
194264f1744SAndreas Gohr        echo '</a>';
195264f1744SAndreas Gohr        echo '</li>';
196264f1744SAndreas Gohr
197264f1744SAndreas Gohr        echo '<li>';
1982507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'">';
199264f1744SAndreas Gohr        echo 'last 7 days';
200264f1744SAndreas Gohr        echo '</a>';
201264f1744SAndreas Gohr        echo '</li>';
202264f1744SAndreas Gohr
203264f1744SAndreas Gohr        echo '<li>';
2042507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'">';
205264f1744SAndreas Gohr        echo 'last 30 days';
206264f1744SAndreas Gohr        echo '</a>';
207264f1744SAndreas Gohr        echo '</li>';
208264f1744SAndreas Gohr
209264f1744SAndreas Gohr        echo '</ul>';
210264f1744SAndreas Gohr
211264f1744SAndreas Gohr
212264f1744SAndreas Gohr        echo '<form action="" method="get">';
213264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
214264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
215264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
216264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
217264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
218264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
21914d99ec0SAndreas Gohr        echo '</form>';
220264f1744SAndreas Gohr
221264f1744SAndreas Gohr        echo '</div>';
22214d99ec0SAndreas Gohr    }
22314d99ec0SAndreas Gohr
22414d99ec0SAndreas Gohr
225f5f32cbfSAndreas Gohr    /**
226f5f32cbfSAndreas Gohr     * Print an introductionary screen
227f5f32cbfSAndreas Gohr     */
22814d99ec0SAndreas Gohr    function html_dashboard(){
2292812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
2302812a751SAndreas Gohr              choose a topic from the list.</p>';
2312812a751SAndreas Gohr
2322812a751SAndreas Gohr
233264f1744SAndreas Gohr        echo '<div class="plg_stats_dashboard">';
234264f1744SAndreas Gohr
2352812a751SAndreas Gohr        // general info
2362812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
2372812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2382812a751SAndreas Gohr        echo '<ul>';
2392812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views </li>';
2403c0acc14SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>';
2413c0acc14SAndreas Gohr        echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>';
2422812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
2432812a751SAndreas Gohr
2442812a751SAndreas Gohr        echo '</ul>';
2452812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2462812a751SAndreas Gohr        echo '</div>';
2472812a751SAndreas Gohr
24814d99ec0SAndreas Gohr
24987d5e44bSAndreas Gohr        // top pages today
250264f1744SAndreas Gohr        echo '<div>';
251264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
25295eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
2532812a751SAndreas Gohr        $this->html_resulttable($result);
2542507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
255264f1744SAndreas Gohr        echo '</div>';
25687d5e44bSAndreas Gohr
25787d5e44bSAndreas Gohr        // top referer today
258264f1744SAndreas Gohr        echo '<div>';
259e7a2f1e0SAndreas Gohr        echo '<h2>Newest incoming links</h2>';
260e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,15);
2612812a751SAndreas Gohr        $this->html_resulttable($result);
2622507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
263264f1744SAndreas Gohr        echo '</div>';
26454f6c432SAndreas Gohr
26554f6c432SAndreas Gohr        // top countries today
266264f1744SAndreas Gohr        echo '<div>';
267264f1744SAndreas Gohr        echo '<h2>Visitor\'s top countries</h2>';
26895eb68e6SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2692507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=country&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
270264f1744SAndreas Gohr        echo '</div>';
271264f1744SAndreas Gohr
272264f1744SAndreas Gohr        echo '</div>';
27314d99ec0SAndreas Gohr    }
27414d99ec0SAndreas Gohr
2759da6395dSAndreas Gohr    function html_country(){
2769da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2779da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
278bd4217d3SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2799da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
2802507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2819da6395dSAndreas Gohr        echo '</div>';
2829da6395dSAndreas Gohr    }
2839da6395dSAndreas Gohr
2849da6395dSAndreas Gohr    function html_page(){
2859da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2869da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
2879da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
2882507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2899da6395dSAndreas Gohr        echo '</div>';
2909da6395dSAndreas Gohr    }
2919da6395dSAndreas Gohr
29275fa767dSAndreas Gohr    function html_browser(){
29375fa767dSAndreas Gohr        echo '<div class="plg_stats_full">';
29475fa767dSAndreas Gohr        echo '<h2>Browser Shootout</h2>';
29575fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
29675fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
2972507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
29875fa767dSAndreas Gohr        echo '</div>';
29975fa767dSAndreas Gohr    }
30075fa767dSAndreas Gohr
301bd4217d3SAndreas Gohr    function html_os(){
302bd4217d3SAndreas Gohr        echo '<div class="plg_stats_full">';
303bd4217d3SAndreas Gohr        echo '<h2>Operating Systems</h2>';
304bd4217d3SAndreas Gohr        $result = $this->sql_os($this->tlimit,$this->start,150,true);
3052507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
306bd4217d3SAndreas Gohr        echo '</div>';
307bd4217d3SAndreas Gohr    }
308bd4217d3SAndreas Gohr
3099da6395dSAndreas Gohr    function html_referer(){
3109da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3119da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
3122812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
3132812a751SAndreas Gohr
3142812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
3152812a751SAndreas Gohr
31694023548SAndreas Gohr        if($all){
3172812a751SAndreas Gohr            printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
3182812a751SAndreas Gohr                    %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
3192812a751SAndreas Gohr                    links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
3202812a751SAndreas Gohr                    $result['search'],(100*$result['search']/$all),$result['external'],
3212812a751SAndreas Gohr                    (100*$result['external']/$all));
32294023548SAndreas Gohr        }
3232812a751SAndreas Gohr
3249da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
3252507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3269da6395dSAndreas Gohr        echo '</div>';
3279da6395dSAndreas Gohr    }
3289da6395dSAndreas Gohr
329e7a2f1e0SAndreas Gohr    function html_newreferer(){
330e7a2f1e0SAndreas Gohr        echo '<div class="plg_stats_full">';
331e7a2f1e0SAndreas Gohr        echo '<h2>New Incoming Links</h2>';
332e7a2f1e0SAndreas Gohr        echo '<p>The following incoming links where first logged in the selected time frame,
333e7a2f1e0SAndreas Gohr              and have never been seen before.</p>';
334e7a2f1e0SAndreas Gohr
335e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,150);
3362507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
337e7a2f1e0SAndreas Gohr        echo '</div>';
338e7a2f1e0SAndreas Gohr    }
339e7a2f1e0SAndreas Gohr
340e25286daSAndreas Gohr    function html_outlinks(){
341e25286daSAndreas Gohr        echo '<div class="plg_stats_full">';
342e25286daSAndreas Gohr        echo '<h2>Outgoing Links</h2>';
343e25286daSAndreas Gohr
344e25286daSAndreas Gohr        $result = $this->sql_outlinks($this->tlimit,$this->start,150);
345e25286daSAndreas Gohr        $this->html_resulttable($result,'',150);
346e25286daSAndreas Gohr        echo '</div>';
347e25286daSAndreas Gohr    }
348e25286daSAndreas Gohr
349e25286daSAndreas Gohr
350c73e16f1SAndreas Gohr    function html_resolution(){
351c73e16f1SAndreas Gohr        echo '<div class="plg_stats_full">';
352c73e16f1SAndreas Gohr        echo '<h2>Resolution</h2>';
353c73e16f1SAndreas Gohr        $result = $this->sql_resolution($this->tlimit,$this->start,150);
354c73e16f1SAndreas Gohr        $this->html_resulttable($result,'',150);
355c73e16f1SAndreas Gohr
356c73e16f1SAndreas Gohr        echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you
357c73e16f1SAndreas Gohr              much about about the real size of their browser windows. The graphic below shows the size distribution of
358c73e16f1SAndreas Gohr              the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged
359c73e16f1SAndreas Gohr              in all browsers. Because users may resize their browser window while browsing your site the statistics may
360c73e16f1SAndreas Gohr              be flawed. Take it with a grain of salt.</p>';
361c73e16f1SAndreas Gohr
362c73e16f1SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
363c73e16f1SAndreas Gohr        echo '</div>';
364c73e16f1SAndreas Gohr    }
3659da6395dSAndreas Gohr
3669da6395dSAndreas Gohr
36714d99ec0SAndreas Gohr    /**
36814d99ec0SAndreas Gohr     * Display a result in a HTML table
36914d99ec0SAndreas Gohr     */
3702507f8e0SAndreas Gohr    function html_resulttable($result,$header='',$pager=0){
37114d99ec0SAndreas Gohr        echo '<table>';
3722812a751SAndreas Gohr        if(is_array($header)){
37314d99ec0SAndreas Gohr            echo '<tr>';
37414d99ec0SAndreas Gohr            foreach($header as $h){
37514d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
37614d99ec0SAndreas Gohr            }
37714d99ec0SAndreas Gohr            echo '</tr>';
3782812a751SAndreas Gohr        }
37914d99ec0SAndreas Gohr
3802507f8e0SAndreas Gohr        $count = 0;
38114d99ec0SAndreas Gohr        foreach($result as $row){
38214d99ec0SAndreas Gohr            echo '<tr>';
38314d99ec0SAndreas Gohr            foreach($row as $k => $v){
3842812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
38514d99ec0SAndreas Gohr                if($k == 'page'){
38614d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
38714d99ec0SAndreas Gohr                    echo hsc($v);
38814d99ec0SAndreas Gohr                    echo '</a>';
38914d99ec0SAndreas Gohr                }elseif($k == 'url'){
39054f6c432SAndreas Gohr                    $url = hsc($v);
39183b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/','',$url);
3922812a751SAndreas Gohr                    if(strlen($url) > 45){
3932812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
39454f6c432SAndreas Gohr                    }
39514d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
39654f6c432SAndreas Gohr                    echo $url;
39714d99ec0SAndreas Gohr                    echo '</a>';
39875fa767dSAndreas Gohr                }elseif($k == 'browser'){
39975fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
40075fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
40175fa767dSAndreas Gohr                }elseif($k == 'bflag'){
40275fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
40375fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
404bd4217d3SAndreas Gohr                }elseif($k == 'os'){
405bd4217d3SAndreas Gohr                    if(empty($v)){
406bd4217d3SAndreas Gohr                        echo 'unknown';
407bd4217d3SAndreas Gohr                    }else{
408bd4217d3SAndreas Gohr                        include_once(dirname(__FILE__).'/inc/operating_systems.php');
409bd4217d3SAndreas Gohr                        echo $OSHashLib[$v];
410bd4217d3SAndreas Gohr                    }
411bd4217d3SAndreas Gohr                }elseif($k == 'osflag'){
412bd4217d3SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />';
41375fa767dSAndreas Gohr                }elseif($k == 'cflag'){
41475fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
41514d99ec0SAndreas Gohr                }elseif($k == 'html'){
41614d99ec0SAndreas Gohr                    echo $v;
41714d99ec0SAndreas Gohr                }else{
41814d99ec0SAndreas Gohr                    echo hsc($v);
41914d99ec0SAndreas Gohr                }
42014d99ec0SAndreas Gohr                echo '</td>';
42114d99ec0SAndreas Gohr            }
42214d99ec0SAndreas Gohr            echo '</tr>';
4232507f8e0SAndreas Gohr
4242507f8e0SAndreas Gohr            if($pager && ($count == $pager)) break;
4252507f8e0SAndreas Gohr            $count++;
42614d99ec0SAndreas Gohr        }
42714d99ec0SAndreas Gohr        echo '</table>';
4282507f8e0SAndreas Gohr
4292507f8e0SAndreas Gohr        if($pager) $this->html_pager($pager,count($result) > $pager);
4301878f16fSAndreas Gohr    }
4311878f16fSAndreas Gohr
43295eb68e6SAndreas Gohr    /**
43395eb68e6SAndreas Gohr     * Create an image
43495eb68e6SAndreas Gohr     */
43595eb68e6SAndreas Gohr    function img_build($img){
43695eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
43795eb68e6SAndreas Gohr
43895eb68e6SAndreas Gohr        switch($img){
43995eb68e6SAndreas Gohr            case 'country':
44095eb68e6SAndreas Gohr                // build top countries + other
44195eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
44295eb68e6SAndreas Gohr                $data = array();
44395eb68e6SAndreas Gohr                $top = 0;
44495eb68e6SAndreas Gohr                foreach($result as $row){
44595eb68e6SAndreas Gohr                    if($top < 7){
44695eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
44795eb68e6SAndreas Gohr                    }else{
44895eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
44995eb68e6SAndreas Gohr                    }
45095eb68e6SAndreas Gohr                    $top++;
45195eb68e6SAndreas Gohr                }
45295eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
45395eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
45495eb68e6SAndreas Gohr                $pie->setProp("showval",false);
45595eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
45695eb68e6SAndreas Gohr                $pie->setProp("type","pie");
45795eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
45895eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
45995eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
46095eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
46195eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
46295eb68e6SAndreas Gohr                @$pie->graph();
46395eb68e6SAndreas Gohr                $pie->showGraph();
46495eb68e6SAndreas Gohr                break;
46575fa767dSAndreas Gohr            case 'browser':
46675fa767dSAndreas Gohr                // build top browsers + other
46775fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
46875fa767dSAndreas Gohr
46975fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
47075fa767dSAndreas Gohr                $data = array();
47175fa767dSAndreas Gohr                $top = 0;
47275fa767dSAndreas Gohr                foreach($result as $row){
47375fa767dSAndreas Gohr                    if($top < 5){
47475fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
47575fa767dSAndreas Gohr                    }else{
47675fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
47775fa767dSAndreas Gohr                    }
47875fa767dSAndreas Gohr                    $top++;
47975fa767dSAndreas Gohr                }
48075fa767dSAndreas Gohr                $pie = new AGC(300, 200);
48175fa767dSAndreas Gohr                $pie->setProp("showkey",true);
48275fa767dSAndreas Gohr                $pie->setProp("showval",false);
48375fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
48475fa767dSAndreas Gohr                $pie->setProp("type","pie");
48575fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
48675fa767dSAndreas Gohr                $pie->setProp("keysize",8);
48775fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
48875fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
48975fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
49075fa767dSAndreas Gohr                @$pie->graph();
49175fa767dSAndreas Gohr                $pie->showGraph();
49275fa767dSAndreas Gohr                break;
493c73e16f1SAndreas Gohr            case 'view':
494c73e16f1SAndreas Gohr
495c73e16f1SAndreas Gohr                $graph = new AGC(400, 200);
496c73e16f1SAndreas Gohr                $graph->setColor('color',0,'blue');
497c73e16f1SAndreas Gohr                $graph->setColor('color',1,'red');
498c73e16f1SAndreas Gohr                $graph->setProp("showkey",true);
499c73e16f1SAndreas Gohr                $graph->setProp("key",'view port width',0);
500c73e16f1SAndreas Gohr                $graph->setProp("key",'view port height',1);
501c73e16f1SAndreas Gohr
502c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,true);
503c73e16f1SAndreas Gohr                foreach($result as $row){
504c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_x'],0);
505c73e16f1SAndreas Gohr                }
506c73e16f1SAndreas Gohr
507c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,false);
508c73e16f1SAndreas Gohr                foreach($result as $row){
509c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_y'],1);
510c73e16f1SAndreas Gohr                }
511c73e16f1SAndreas Gohr
512c73e16f1SAndreas Gohr                @$graph->graph();
513c73e16f1SAndreas Gohr                $graph->showGraph();
514c73e16f1SAndreas Gohr
515c73e16f1SAndreas Gohr                break;
5162812a751SAndreas Gohr            case 'trend':
5172812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
5182812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
5192812a751SAndreas Gohr                $data1   = array();
5202812a751SAndreas Gohr                $data2   = array();
5212812a751SAndreas Gohr
5222812a751SAndreas Gohr                $graph = new AGC(400, 150);
5232812a751SAndreas Gohr                $graph->setProp("type","bar");
5242812a751SAndreas Gohr                $graph->setProp("showgrid",false);
5252812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
52675fa767dSAndreas Gohr
5272812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
5282812a751SAndreas Gohr                $graph->setColor('color',1,'red');
5293c0acc14SAndreas Gohr                $graph->setColor('color',2,'yellow');
5302812a751SAndreas Gohr
5312812a751SAndreas Gohr                if($hours){
5322812a751SAndreas Gohr                    //preset $hours
5332812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
5342812a751SAndreas Gohr                        $data1[$i] = 0;
5352812a751SAndreas Gohr                        $data2[$i] = 0;
5363c0acc14SAndreas Gohr                        $data3[$i] = 0;
5372812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
5382812a751SAndreas Gohr                    }
5392812a751SAndreas Gohr                }else{
5402812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
5412812a751SAndreas Gohr                }
5422812a751SAndreas Gohr
5432812a751SAndreas Gohr                foreach($result as $row){
5442812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
5452812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
5463c0acc14SAndreas Gohr                    $data3[$row['time']] = $row['visitors'];
5472812a751SAndreas Gohr                }
5482812a751SAndreas Gohr
5492812a751SAndreas Gohr                foreach($data1 as $key => $val){
5502812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
5512812a751SAndreas Gohr                }
5522812a751SAndreas Gohr                foreach($data2 as $key => $val){
5532812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
5542812a751SAndreas Gohr                }
5553c0acc14SAndreas Gohr                foreach($data3 as $key => $val){
5563c0acc14SAndreas Gohr                    $graph->addPoint($val,$key,2);
5573c0acc14SAndreas Gohr                }
5582812a751SAndreas Gohr
5592812a751SAndreas Gohr                @$graph->graph();
5602812a751SAndreas Gohr                $graph->showGraph();
5612812a751SAndreas Gohr
56295eb68e6SAndreas Gohr            default:
56395eb68e6SAndreas Gohr                $this->sendGIF();
56495eb68e6SAndreas Gohr        }
56595eb68e6SAndreas Gohr    }
56695eb68e6SAndreas Gohr
56795eb68e6SAndreas Gohr
5682812a751SAndreas Gohr    /**
5692812a751SAndreas Gohr     * Return some aggregated statistics
5702812a751SAndreas Gohr     */
5712812a751SAndreas Gohr    function sql_aggregate($tlimit){
5722812a751SAndreas Gohr        $data = array();
5732812a751SAndreas Gohr
5742812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
5752812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5762812a751SAndreas Gohr                 WHERE $tlimit
5772812a751SAndreas Gohr                   AND ua_type = 'browser'
5782812a751SAndreas Gohr              GROUP BY ref_type";
5792812a751SAndreas Gohr        $result = $this->runSQL($sql);
5802812a751SAndreas Gohr
5812812a751SAndreas Gohr        foreach($result as $row){
5822812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
5832812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
5842812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
5852812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
5862812a751SAndreas Gohr        }
5872812a751SAndreas Gohr
5882812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
5892812a751SAndreas Gohr                       COUNT(session) as views,
5903c0acc14SAndreas Gohr                       COUNT(DISTINCT user) as users,
5913c0acc14SAndreas Gohr                       COUNT(DISTINCT uid) as visitors
5922812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5932812a751SAndreas Gohr                 WHERE $tlimit
5942812a751SAndreas Gohr                   AND ua_type = 'browser'";
5952812a751SAndreas Gohr        $result = $this->runSQL($sql);
5962812a751SAndreas Gohr
59775fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
5982812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
5992812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
6003c0acc14SAndreas Gohr        $data['visitors']  = $result[0]['visitors'];
6012812a751SAndreas Gohr
6022812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
6032812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6042812a751SAndreas Gohr                 WHERE $tlimit
6052812a751SAndreas Gohr                   AND ua_type = 'robot'";
6062812a751SAndreas Gohr        $result = $this->runSQL($sql);
6072812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
6082812a751SAndreas Gohr
6092812a751SAndreas Gohr        return $data;
6102812a751SAndreas Gohr    }
6112812a751SAndreas Gohr
612bd4217d3SAndreas Gohr    /**
613bd4217d3SAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
614bd4217d3SAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
615bd4217d3SAndreas Gohr     */
6162812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
6172812a751SAndreas Gohr        if($hours){
6182812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
6192812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6203c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6213c0acc14SAndreas Gohr                           COUNT(DISTINCT uid) as visitors
6222812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6232812a751SAndreas Gohr                     WHERE $tlimit
6242812a751SAndreas Gohr                       AND ua_type = 'browser'
6252812a751SAndreas Gohr                  GROUP BY HOUR(dt)
6262812a751SAndreas Gohr                  ORDER BY time";
6272812a751SAndreas Gohr        }else{
6282812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
6292812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6303c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6313c0acc14SAndreas Gohr                            COUNT(DISTINCT uid) as visitors
6322812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6332812a751SAndreas Gohr                     WHERE $tlimit
6342812a751SAndreas Gohr                       AND ua_type = 'browser'
6352812a751SAndreas Gohr                  GROUP BY DATE(dt)
6362812a751SAndreas Gohr                  ORDER BY time";
6372812a751SAndreas Gohr        }
6382812a751SAndreas Gohr        return $this->runSQL($sql);
6392812a751SAndreas Gohr    }
6402812a751SAndreas Gohr
641e25286daSAndreas Gohr    function sql_outlinks($tlimit,$start=0,$limit=20){
642e25286daSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, link as url
643e25286daSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."outlinks as A
644e25286daSAndreas Gohr                 WHERE $tlimit
645e25286daSAndreas Gohr              GROUP BY link
646e25286daSAndreas Gohr              ORDER BY cnt DESC, link".
647e25286daSAndreas Gohr              $this->sql_limit($start,$limit);
648e25286daSAndreas Gohr        return $this->runSQL($sql);
649e25286daSAndreas Gohr    }
650e25286daSAndreas Gohr
65195eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
6522812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
65395eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
65495eb68e6SAndreas Gohr                 WHERE $tlimit
65595eb68e6SAndreas Gohr                   AND ua_type = 'browser'
65695eb68e6SAndreas Gohr              GROUP BY page
65795eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
65895eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
65995eb68e6SAndreas Gohr        return $this->runSQL($sql);
66095eb68e6SAndreas Gohr    }
66195eb68e6SAndreas Gohr
66295eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
6632812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
66495eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
66595eb68e6SAndreas Gohr                 WHERE $tlimit
66695eb68e6SAndreas Gohr                   AND ua_type = 'browser'
66795eb68e6SAndreas Gohr                   AND ref_type = 'external'
66895eb68e6SAndreas Gohr              GROUP BY ref_md5
66995eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
67095eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
67195eb68e6SAndreas Gohr        return $this->runSQL($sql);
67295eb68e6SAndreas Gohr    }
67395eb68e6SAndreas Gohr
674e7a2f1e0SAndreas Gohr    function sql_newreferer($tlimit,$start=0,$limit=20){
675e7a2f1e0SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
676e7a2f1e0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
677e7a2f1e0SAndreas Gohr                 WHERE ua_type = 'browser'
678e7a2f1e0SAndreas Gohr                   AND ref_type = 'external'
679e7a2f1e0SAndreas Gohr              GROUP BY ref_md5
680e7a2f1e0SAndreas Gohr                HAVING DATE(MIN(dt)) >= DATE('".$this->from."')
681e7a2f1e0SAndreas Gohr                   AND DATE(MIN(dt)) <= DATE('".$this->to."')
682e7a2f1e0SAndreas Gohr              ORDER BY cnt DESC, url".
683e7a2f1e0SAndreas Gohr              $this->sql_limit($start,$limit);
684e7a2f1e0SAndreas Gohr        return $this->runSQL($sql);
685e7a2f1e0SAndreas Gohr    }
686e7a2f1e0SAndreas Gohr
68795eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
688bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
68995eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
69095eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
69195eb68e6SAndreas Gohr                 WHERE $tlimit
69295eb68e6SAndreas Gohr                   AND A.ip = B.ip
69395eb68e6SAndreas Gohr              GROUP BY B.country
69495eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
69595eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
69695eb68e6SAndreas Gohr        return $this->runSQL($sql);
69795eb68e6SAndreas Gohr    }
69895eb68e6SAndreas Gohr
69975fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
70075fa767dSAndreas Gohr        if($ext){
70175fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
70275fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
70375fa767dSAndreas Gohr        }else{
70475fa767dSAndreas Gohr            $grp = 'ua_info';
70575fa767dSAndreas Gohr            $sel = 'ua_info';
70675fa767dSAndreas Gohr        }
70775fa767dSAndreas Gohr
708bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
70975fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
71075fa767dSAndreas Gohr                 WHERE $tlimit
71175fa767dSAndreas Gohr                   AND ua_type = 'browser'
71275fa767dSAndreas Gohr              GROUP BY $grp
71375fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
71475fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
71575fa767dSAndreas Gohr        return $this->runSQL($sql);
71675fa767dSAndreas Gohr    }
71775fa767dSAndreas Gohr
718bd4217d3SAndreas Gohr    function sql_os($tlimit,$start=0,$limit=20){
719bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
720bd4217d3SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
721bd4217d3SAndreas Gohr                 WHERE $tlimit
722bd4217d3SAndreas Gohr                   AND ua_type = 'browser'
723bd4217d3SAndreas Gohr              GROUP BY os
724bd4217d3SAndreas Gohr              ORDER BY cnt DESC, os".
725bd4217d3SAndreas Gohr              $this->sql_limit($start,$limit);
726bd4217d3SAndreas Gohr        return $this->runSQL($sql);
727bd4217d3SAndreas Gohr    }
728bd4217d3SAndreas Gohr
729c73e16f1SAndreas Gohr    function sql_resolution($tlimit,$start=0,$limit=20){
730c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res
731c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
732c73e16f1SAndreas Gohr                 WHERE $tlimit
733c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
734c73e16f1SAndreas Gohr                   AND screen_x != 0
735c73e16f1SAndreas Gohr              GROUP BY screen_x, screen_y
736c73e16f1SAndreas Gohr              ORDER BY cnt DESC, screen_x".
737c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
738c73e16f1SAndreas Gohr        return $this->runSQL($sql);
739c73e16f1SAndreas Gohr    }
740c73e16f1SAndreas Gohr
741c73e16f1SAndreas Gohr    function sql_viewport($tlimit,$start=0,$limit=20,$x=true){
742c73e16f1SAndreas Gohr        if($x){
743c73e16f1SAndreas Gohr            $col = 'view_x';
744c73e16f1SAndreas Gohr            $res = 'res_x';
745c73e16f1SAndreas Gohr        }else{
746c73e16f1SAndreas Gohr            $col = 'view_y';
747c73e16f1SAndreas Gohr            $res = 'res_y';
748c73e16f1SAndreas Gohr        }
749c73e16f1SAndreas Gohr
750c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt,
751c73e16f1SAndreas Gohr                       ROUND($col/10)*10 as $res
752c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
753c73e16f1SAndreas Gohr                 WHERE $tlimit
754c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
755c73e16f1SAndreas Gohr                   AND $col != 0
756c73e16f1SAndreas Gohr              GROUP BY $res
757c73e16f1SAndreas Gohr              ORDER BY cnt DESC, $res".
758c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
759c73e16f1SAndreas Gohr        return $this->runSQL($sql);
760c73e16f1SAndreas Gohr    }
761c73e16f1SAndreas Gohr
76275fa767dSAndreas Gohr
76395eb68e6SAndreas Gohr    /**
76495eb68e6SAndreas Gohr     * Builds a limit clause
76595eb68e6SAndreas Gohr     */
76695eb68e6SAndreas Gohr    function sql_limit($start,$limit){
76795eb68e6SAndreas Gohr        $start = (int) $start;
76895eb68e6SAndreas Gohr        $limit = (int) $limit;
76995eb68e6SAndreas Gohr        if($limit){
7702507f8e0SAndreas Gohr            $limit += 1;
77195eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
77295eb68e6SAndreas Gohr        }elseif($start){
77395eb68e6SAndreas Gohr            return " OFFSET $start";
77495eb68e6SAndreas Gohr        }
77595eb68e6SAndreas Gohr        return '';
77695eb68e6SAndreas Gohr    }
7771878f16fSAndreas Gohr
7781878f16fSAndreas Gohr    /**
77914d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
7801878f16fSAndreas Gohr     */
78114d99ec0SAndreas Gohr    function dbLink(){
7821878f16fSAndreas Gohr        // connect to DB if needed
7831878f16fSAndreas Gohr        if(!$this->dblink){
7841878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
7851878f16fSAndreas Gohr                                          $this->getConf('db_user'),
7861878f16fSAndreas Gohr                                          $this->getConf('db_password'));
7871878f16fSAndreas Gohr            if(!$this->dblink){
7881878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
7891878f16fSAndreas Gohr                return null;
7901878f16fSAndreas Gohr            }
7911878f16fSAndreas Gohr            // set utf-8
7921878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
7931878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
7941878f16fSAndreas Gohr                return null;
7951878f16fSAndreas Gohr            }
7961878f16fSAndreas Gohr        }
79714d99ec0SAndreas Gohr        return $this->dblink;
79814d99ec0SAndreas Gohr    }
7991878f16fSAndreas Gohr
80014d99ec0SAndreas Gohr    /**
80114d99ec0SAndreas Gohr     * Simple function to run a DB query
80214d99ec0SAndreas Gohr     */
80314d99ec0SAndreas Gohr    function runSQL($sql_string) {
80414d99ec0SAndreas Gohr        $link = $this->dbLink();
80514d99ec0SAndreas Gohr
80614d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
80794171ff3SAndreas Gohr        if(!$result){
8082812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
8091878f16fSAndreas Gohr            return null;
8101878f16fSAndreas Gohr        }
8111878f16fSAndreas Gohr
8121878f16fSAndreas Gohr        $resultarray = array();
8131878f16fSAndreas Gohr
8141878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
8151878f16fSAndreas Gohr        if ($result != 1) {
8161878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
8171878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
8181878f16fSAndreas Gohr                $resultarray[]=$temparray;
8191878f16fSAndreas Gohr            }
8201878f16fSAndreas Gohr            mysql_free_result($result);
8211878f16fSAndreas Gohr        }
8221878f16fSAndreas Gohr
82314d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
82414d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
8251878f16fSAndreas Gohr        }
8261878f16fSAndreas Gohr
8271878f16fSAndreas Gohr        return $resultarray;
8281878f16fSAndreas Gohr    }
8291878f16fSAndreas Gohr
8301878f16fSAndreas Gohr    /**
83114d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
8321878f16fSAndreas Gohr     */
83314d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
83414d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
83514d99ec0SAndreas Gohr        $ua = strtolower($ua);
83614d99ec0SAndreas Gohr
83714d99ec0SAndreas Gohr        // common browsers
83814d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
83914d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
84014d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
84114d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
84214d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
84314d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
84414d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
84514d99ec0SAndreas Gohr
84614d99ec0SAndreas Gohr        $name = '';
84714d99ec0SAndreas Gohr        # IE ?
84814d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
84914d99ec0SAndreas Gohr            $type = 'browser';
85014d99ec0SAndreas Gohr            $ver  = $m[2];
85114d99ec0SAndreas Gohr            $name = 'msie';
85214d99ec0SAndreas Gohr        }
85314d99ec0SAndreas Gohr        # Firefox ?
85414d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
85514d99ec0SAndreas Gohr            $type = 'browser';
85614d99ec0SAndreas Gohr            $ver  = $m[1];
85714d99ec0SAndreas Gohr            $name = 'firefox';
85814d99ec0SAndreas Gohr        }
85914d99ec0SAndreas Gohr        # Subversion ?
86014d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
86114d99ec0SAndreas Gohr            $type = 'rcs';
86214d99ec0SAndreas Gohr            $ver  = $m[1];
86314d99ec0SAndreas Gohr            $name = 'svn';
86414d99ec0SAndreas Gohr        }
86514d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
86614d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
86714d99ec0SAndreas Gohr            $type = 'browser';
86814d99ec0SAndreas Gohr            $ver  = $m[1];
86914d99ec0SAndreas Gohr            $name = 'netscape';
87014d99ec0SAndreas Gohr        }
87114d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
87214d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
87314d99ec0SAndreas Gohr            $type = 'browser';
87414d99ec0SAndreas Gohr            $ver  = $m[2];
87514d99ec0SAndreas Gohr            $name = 'netscape';
87614d99ec0SAndreas Gohr        }else{
87714d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
87814d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
87914d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
88014d99ec0SAndreas Gohr                    // it's a browser!
88114d99ec0SAndreas Gohr                    $type = 'browser';
88214d99ec0SAndreas Gohr                    $name = strtolower($regex);
88314d99ec0SAndreas Gohr                    break;
88414d99ec0SAndreas Gohr                }
88514d99ec0SAndreas Gohr            }
88614d99ec0SAndreas Gohr        }
88714d99ec0SAndreas Gohr
88875fa767dSAndreas Gohr        // check versions for Safari and Opera
88975fa767dSAndreas Gohr        if($name == 'safari'){
89075fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
89175fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
89275fa767dSAndreas Gohr            }
89375fa767dSAndreas Gohr        }elseif($name == 'opera'){
89475fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
89575fa767dSAndreas Gohr                $ver = $match[1];
89675fa767dSAndreas Gohr            }
89775fa767dSAndreas Gohr        }
89875fa767dSAndreas Gohr
89975fa767dSAndreas Gohr
90014d99ec0SAndreas Gohr        // check OS for browsers
90114d99ec0SAndreas Gohr        if($type == 'browser'){
90214d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
90314d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
90414d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
90514d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
90614d99ec0SAndreas Gohr                    break;
90714d99ec0SAndreas Gohr                }
90814d99ec0SAndreas Gohr            }
90914d99ec0SAndreas Gohr
91014d99ec0SAndreas Gohr        }
91114d99ec0SAndreas Gohr
91214d99ec0SAndreas Gohr        // are we done now?
91314d99ec0SAndreas Gohr        if($name) return $name;
91414d99ec0SAndreas Gohr
91514d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
91614d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
91714d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
91814d99ec0SAndreas Gohr                    // it's a robot!
91914d99ec0SAndreas Gohr                    $type = 'robot';
92014d99ec0SAndreas Gohr                    return strtolower($regex);
92114d99ec0SAndreas Gohr            }
92214d99ec0SAndreas Gohr        }
92314d99ec0SAndreas Gohr
92414d99ec0SAndreas Gohr        // dunno
9251878f16fSAndreas Gohr        return '';
9261878f16fSAndreas Gohr    }
9271878f16fSAndreas Gohr
9281878f16fSAndreas Gohr    /**
92914d99ec0SAndreas Gohr     *
93014d99ec0SAndreas Gohr     * @fixme: put search engine queries in seperate table here
93114d99ec0SAndreas Gohr     */
93214d99ec0SAndreas Gohr    function log_search($referer,&$type){
93314d99ec0SAndreas Gohr        $referer = strtr($referer,' +','__');
93414d99ec0SAndreas Gohr        $referer = strtolower($referer);
93514d99ec0SAndreas Gohr
93614d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
93714d99ec0SAndreas Gohr
93814d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
93914d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$referer)){
94014d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
94114d99ec0SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){
94214d99ec0SAndreas Gohr                    // it's a search engine!
94314d99ec0SAndreas Gohr                    $type = 'search';
94414d99ec0SAndreas Gohr                    break;
94514d99ec0SAndreas Gohr                }
94614d99ec0SAndreas Gohr            }
94714d99ec0SAndreas Gohr        }
94814d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
94914d99ec0SAndreas Gohr
95014d99ec0SAndreas Gohr        #fixme now do the keyword magic!
95114d99ec0SAndreas Gohr    }
95214d99ec0SAndreas Gohr
95314d99ec0SAndreas Gohr    /**
95414d99ec0SAndreas Gohr     * Resolve IP to country/city
95514d99ec0SAndreas Gohr     */
95614d99ec0SAndreas Gohr    function log_ip($ip){
95714d99ec0SAndreas Gohr        // check if IP already known and up-to-date
95814d99ec0SAndreas Gohr        $sql = "SELECT ip
95914d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
96014d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
96114d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
96214d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
96314d99ec0SAndreas Gohr        if($result[0]['ip']) return;
96414d99ec0SAndreas Gohr
96514d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
96614d99ec0SAndreas Gohr        $http->timeout = 10;
96714d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
96814d99ec0SAndreas Gohr
96914d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
97014d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
97114d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
97214d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
97314d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
97414d99ec0SAndreas Gohr            $ip      = addslashes($ip);
97514d99ec0SAndreas Gohr
97614d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
97714d99ec0SAndreas Gohr                        SET ip = '$ip',
97814d99ec0SAndreas Gohr                            country = '$country',
97914d99ec0SAndreas Gohr                            code    = '$code',
98014d99ec0SAndreas Gohr                            city    = '$city',
98114d99ec0SAndreas Gohr                            host    = '$host'";
98214d99ec0SAndreas Gohr            $this->runSQL($sql);
98314d99ec0SAndreas Gohr        }
98414d99ec0SAndreas Gohr    }
98514d99ec0SAndreas Gohr
98614d99ec0SAndreas Gohr    /**
987e25286daSAndreas Gohr     * log a click on an external link
988e25286daSAndreas Gohr     *
989e25286daSAndreas Gohr     * called from log.php
990e25286daSAndreas Gohr     */
991e25286daSAndreas Gohr    function log_outgoing(){
992e25286daSAndreas Gohr        if(!$_REQUEST['ol']) return;
993e25286daSAndreas Gohr
994e25286daSAndreas Gohr        $link_md5 = md5($link);
995e25286daSAndreas Gohr        $link     = addslashes($_REQUEST['ol']);
996e25286daSAndreas Gohr        $session  = addslashes(session_id());
997*d8c4d85eSAndreas Gohr        $page     = addslashes($_REQUEST['p']);
998e25286daSAndreas Gohr
999e25286daSAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks
1000e25286daSAndreas Gohr                    SET dt       = NOW(),
1001e25286daSAndreas Gohr                        session  = '$session',
1002*d8c4d85eSAndreas Gohr                        page     = '$page',
1003e25286daSAndreas Gohr                        link_md5 = '$link_md5',
1004e25286daSAndreas Gohr                        link     = '$link'";
1005e25286daSAndreas Gohr        $ok = $this->runSQL($sql);
1006e25286daSAndreas Gohr        if(is_null($ok)){
1007e25286daSAndreas Gohr            global $MSG;
1008e25286daSAndreas Gohr            print_r($MSG);
1009e25286daSAndreas Gohr        }
1010e25286daSAndreas Gohr    }
1011e25286daSAndreas Gohr
1012e25286daSAndreas Gohr    /**
10131878f16fSAndreas Gohr     * log a page access
10141878f16fSAndreas Gohr     *
10151878f16fSAndreas Gohr     * called from log.php
10161878f16fSAndreas Gohr     */
10171878f16fSAndreas Gohr    function log_access(){
101894171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
101994171ff3SAndreas Gohr
102014d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
102114d99ec0SAndreas Gohr
102214d99ec0SAndreas Gohr        // handle referer
102314d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
102414d99ec0SAndreas Gohr        if($referer){
102514d99ec0SAndreas Gohr            $ref     = addslashes($referer);
102614d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
102714d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
102814d99ec0SAndreas Gohr                $ref_type = 'internal';
102914d99ec0SAndreas Gohr            }else{
103014d99ec0SAndreas Gohr                $ref_type = 'external';
103114d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
103214d99ec0SAndreas Gohr            }
103314d99ec0SAndreas Gohr        }else{
103414d99ec0SAndreas Gohr            $ref      = '';
103514d99ec0SAndreas Gohr            $ref_md5  = '';
103614d99ec0SAndreas Gohr            $ref_type = '';
103714d99ec0SAndreas Gohr        }
103814d99ec0SAndreas Gohr
103914d99ec0SAndreas Gohr        // handle user agent
104014d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
104114d99ec0SAndreas Gohr
104214d99ec0SAndreas Gohr        $ua      = addslashes($agent);
104314d99ec0SAndreas Gohr        $ua_type = '';
104414d99ec0SAndreas Gohr        $ua_ver  = '';
104514d99ec0SAndreas Gohr        $os      = '';
104614d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
104714d99ec0SAndreas Gohr
10481878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
10491878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
10501878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
10511878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
10521878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
10531878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
105475fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
10553c0acc14SAndreas Gohr        $uid     = addslashes($_REQUEST['uid']);
10561878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
10571878f16fSAndreas Gohr        $session = addslashes(session_id());
10583c0acc14SAndreas Gohr        if(!$uid) $uid = $session;
10591878f16fSAndreas Gohr
106094171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
106175fa767dSAndreas Gohr                    SET dt       = NOW(),
106275fa767dSAndreas Gohr                        page     = '$page',
10631878f16fSAndreas Gohr                        ip       = '$ip',
10641878f16fSAndreas Gohr                        ua       = '$ua',
10651878f16fSAndreas Gohr                        ua_info  = '$ua_info',
106614d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
106714d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
106814d99ec0SAndreas Gohr                        os       = '$os',
10691878f16fSAndreas Gohr                        ref      = '$ref',
107094171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
107114d99ec0SAndreas Gohr                        ref_type = '$ref_type',
10721878f16fSAndreas Gohr                        screen_x = '$sx',
10731878f16fSAndreas Gohr                        screen_y = '$sy',
10741878f16fSAndreas Gohr                        view_x   = '$vx',
10751878f16fSAndreas Gohr                        view_y   = '$vy',
107675fa767dSAndreas Gohr                        js       = '$js',
10771878f16fSAndreas Gohr                        user     = '$user',
10783c0acc14SAndreas Gohr                        session  = '$session',
10793c0acc14SAndreas Gohr                        uid      = '$uid'";
10801878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
10811878f16fSAndreas Gohr        if(is_null($ok)){
10821878f16fSAndreas Gohr            global $MSG;
10831878f16fSAndreas Gohr            print_r($MSG);
10841878f16fSAndreas Gohr        }
108514d99ec0SAndreas Gohr
108614d99ec0SAndreas Gohr        // resolve the IP
108714d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
10881878f16fSAndreas Gohr    }
10891878f16fSAndreas Gohr
10901878f16fSAndreas Gohr    /**
10911878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
10921878f16fSAndreas Gohr     *
10931878f16fSAndreas Gohr     * @called from log.php
10941878f16fSAndreas Gohr     *
10951878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
10961878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
10971878f16fSAndreas Gohr     */
10981878f16fSAndreas Gohr    function sendGIF(){
10991878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
11001878f16fSAndreas Gohr        header('Content-Type: image/gif');
11011878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
11021878f16fSAndreas Gohr        header('Connection: Close');
11031878f16fSAndreas Gohr        print $img;
11041878f16fSAndreas Gohr        flush();
11051878f16fSAndreas Gohr        // Browser should drop connection after this
11061878f16fSAndreas Gohr        // Thinks it's got the whole image
11071878f16fSAndreas Gohr    }
11081878f16fSAndreas Gohr
11091878f16fSAndreas Gohr}
1110