xref: /plugin/statistics/admin.php (revision 673875b1e52973b3327880de291169de63218fd4)
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    /**
929322de360SAndreas Gohr     * Log search queries
93014d99ec0SAndreas Gohr     */
93114d99ec0SAndreas Gohr    function log_search($referer,&$type){
93214d99ec0SAndreas Gohr        $referer = strtolower($referer);
933*673875b1SAndreas Gohr        $ref     = strtr($referer,' +','__');
93414d99ec0SAndreas Gohr
93514d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
93614d99ec0SAndreas Gohr
93714d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
938*673875b1SAndreas Gohr            if(preg_match('/'.$regex.'/',$ref)){
93914d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
940*673875b1SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$ref)){
94114d99ec0SAndreas Gohr                    // it's a search engine!
94214d99ec0SAndreas Gohr                    $type = 'search';
94314d99ec0SAndreas Gohr                    break;
94414d99ec0SAndreas Gohr                }
94514d99ec0SAndreas Gohr            }
94614d99ec0SAndreas Gohr        }
94714d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
94814d99ec0SAndreas Gohr
949322de360SAndreas Gohr        // extract query
950322de360SAndreas Gohr        $engine = $SearchEnginesHashID[$regex];
951322de360SAndreas Gohr        $param = $SearchEnginesKnownUrl[$engine];
952322de360SAndreas Gohr        if($param && preg_match('/'.$param.'(.*?)[&$]/',$referer,$match)){
953322de360SAndreas Gohr            $query = array_pop($match);
954322de360SAndreas Gohr        }elseif(preg_match('/'.$WordsToExtractSearchUrl.'(.*?)[&$]/',$referer,$match)){
955322de360SAndreas Gohr            $query = array_pop($match);
956322de360SAndreas Gohr        }
957322de360SAndreas Gohr        if(!$query) return; // we failed
958322de360SAndreas Gohr
959322de360SAndreas Gohr        // clean the query
960322de360SAndreas Gohr        $query = preg_replace('/^(cache|related):[^\+]+/','',$query);  // non-search queries
961322de360SAndreas Gohr        $query = preg_replace('/%0[ad]/',' ',$query);                  // LF CR
962322de360SAndreas Gohr        $query = preg_replace('/%2[02789abc]/',' ',$query);            // space " ' ( ) * + ,
963322de360SAndreas Gohr        $query = preg_replace('/%3a/',' ',$query);                     // :
964*673875b1SAndreas Gohr        $query = strtr($query,'+\'()"*,:','        ');                 // badly encoded
965322de360SAndreas Gohr        $query = preg_replace('/ +/',' ',$query);                      // ws compact
966322de360SAndreas Gohr        $query = trim($query);
967322de360SAndreas Gohr        $query = urldecode($query);
968322de360SAndreas Gohr        if(!utf8_check($query)) $query = utf8_encode($query);          // assume latin1 if not utf8
969322de360SAndreas Gohr        $query = utf8_strtolower($query);
970322de360SAndreas Gohr
971322de360SAndreas Gohr        // log it!
972322de360SAndreas Gohr        $page  = addslashes($_REQUEST['p']);
973322de360SAndreas Gohr        $query = addslashes($query);
974*673875b1SAndreas Gohr        $sql  = "INSERT INTO ".$this->getConf('db_prefix')."search
975322de360SAndreas Gohr                    SET dt       = NOW(),
976322de360SAndreas Gohr                        page     = '$page',
977322de360SAndreas Gohr                        query    = '$query',
978322de360SAndreas Gohr                        engine   = '$engine'";
979322de360SAndreas Gohr        $id = $this->runSQL($sql);
980322de360SAndreas Gohr        if(is_null($id)){
981322de360SAndreas Gohr            global $MSG;
982322de360SAndreas Gohr            print_r($MSG);
983322de360SAndreas Gohr            return;
984322de360SAndreas Gohr        }
985322de360SAndreas Gohr
986322de360SAndreas Gohr        // log single keywords
987322de360SAndreas Gohr        $words = explode(' ',utf8_stripspecials($query,' ','\._\-:\*'));
988322de360SAndreas Gohr        foreach($words as $word){
989*673875b1SAndreas Gohr            if(!$word) continue;
990322de360SAndreas Gohr            $word = addslashes($word);
991322de360SAndreas Gohr            $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."searchwords
992322de360SAndreas Gohr                       SET sid  = $id,
993322de360SAndreas Gohr                           word = '$word'";
994322de360SAndreas Gohr            $ok = $this->runSQL($sql);
995322de360SAndreas Gohr            if(is_null($ok)){
996322de360SAndreas Gohr                global $MSG;
997322de360SAndreas Gohr                print_r($MSG);
998322de360SAndreas Gohr            }
999322de360SAndreas Gohr        }
100014d99ec0SAndreas Gohr    }
100114d99ec0SAndreas Gohr
100214d99ec0SAndreas Gohr    /**
100314d99ec0SAndreas Gohr     * Resolve IP to country/city
100414d99ec0SAndreas Gohr     */
100514d99ec0SAndreas Gohr    function log_ip($ip){
100614d99ec0SAndreas Gohr        // check if IP already known and up-to-date
100714d99ec0SAndreas Gohr        $sql = "SELECT ip
100814d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
100914d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
101014d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
101114d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
101214d99ec0SAndreas Gohr        if($result[0]['ip']) return;
101314d99ec0SAndreas Gohr
101414d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
101514d99ec0SAndreas Gohr        $http->timeout = 10;
101614d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
101714d99ec0SAndreas Gohr
101814d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
101914d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
102014d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
102114d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
102214d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
102314d99ec0SAndreas Gohr            $ip      = addslashes($ip);
102414d99ec0SAndreas Gohr
102514d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
102614d99ec0SAndreas Gohr                        SET ip = '$ip',
102714d99ec0SAndreas Gohr                            country = '$country',
102814d99ec0SAndreas Gohr                            code    = '$code',
102914d99ec0SAndreas Gohr                            city    = '$city',
103014d99ec0SAndreas Gohr                            host    = '$host'";
103114d99ec0SAndreas Gohr            $this->runSQL($sql);
103214d99ec0SAndreas Gohr        }
103314d99ec0SAndreas Gohr    }
103414d99ec0SAndreas Gohr
103514d99ec0SAndreas Gohr    /**
1036e25286daSAndreas Gohr     * log a click on an external link
1037e25286daSAndreas Gohr     *
1038e25286daSAndreas Gohr     * called from log.php
1039e25286daSAndreas Gohr     */
1040e25286daSAndreas Gohr    function log_outgoing(){
1041e25286daSAndreas Gohr        if(!$_REQUEST['ol']) return;
1042e25286daSAndreas Gohr
1043e25286daSAndreas Gohr        $link_md5 = md5($link);
1044e25286daSAndreas Gohr        $link     = addslashes($_REQUEST['ol']);
1045e25286daSAndreas Gohr        $session  = addslashes(session_id());
1046d8c4d85eSAndreas Gohr        $page     = addslashes($_REQUEST['p']);
1047e25286daSAndreas Gohr
1048e25286daSAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks
1049e25286daSAndreas Gohr                    SET dt       = NOW(),
1050e25286daSAndreas Gohr                        session  = '$session',
1051d8c4d85eSAndreas Gohr                        page     = '$page',
1052e25286daSAndreas Gohr                        link_md5 = '$link_md5',
1053e25286daSAndreas Gohr                        link     = '$link'";
1054e25286daSAndreas Gohr        $ok = $this->runSQL($sql);
1055e25286daSAndreas Gohr        if(is_null($ok)){
1056e25286daSAndreas Gohr            global $MSG;
1057e25286daSAndreas Gohr            print_r($MSG);
1058e25286daSAndreas Gohr        }
1059e25286daSAndreas Gohr    }
1060e25286daSAndreas Gohr
1061e25286daSAndreas Gohr    /**
10621878f16fSAndreas Gohr     * log a page access
10631878f16fSAndreas Gohr     *
10641878f16fSAndreas Gohr     * called from log.php
10651878f16fSAndreas Gohr     */
10661878f16fSAndreas Gohr    function log_access(){
106794171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
106894171ff3SAndreas Gohr
106914d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
107014d99ec0SAndreas Gohr
107114d99ec0SAndreas Gohr        // handle referer
107214d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
107314d99ec0SAndreas Gohr        if($referer){
107414d99ec0SAndreas Gohr            $ref     = addslashes($referer);
107514d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
107614d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
107714d99ec0SAndreas Gohr                $ref_type = 'internal';
107814d99ec0SAndreas Gohr            }else{
107914d99ec0SAndreas Gohr                $ref_type = 'external';
108014d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
108114d99ec0SAndreas Gohr            }
108214d99ec0SAndreas Gohr        }else{
108314d99ec0SAndreas Gohr            $ref      = '';
108414d99ec0SAndreas Gohr            $ref_md5  = '';
108514d99ec0SAndreas Gohr            $ref_type = '';
108614d99ec0SAndreas Gohr        }
108714d99ec0SAndreas Gohr
108814d99ec0SAndreas Gohr        // handle user agent
108914d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
109014d99ec0SAndreas Gohr
109114d99ec0SAndreas Gohr        $ua      = addslashes($agent);
109214d99ec0SAndreas Gohr        $ua_type = '';
109314d99ec0SAndreas Gohr        $ua_ver  = '';
109414d99ec0SAndreas Gohr        $os      = '';
109514d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
109614d99ec0SAndreas Gohr
10971878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
10981878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
10991878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
11001878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
11011878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
11021878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
110375fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
11043c0acc14SAndreas Gohr        $uid     = addslashes($_REQUEST['uid']);
11051878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
11061878f16fSAndreas Gohr        $session = addslashes(session_id());
11073c0acc14SAndreas Gohr        if(!$uid) $uid = $session;
11081878f16fSAndreas Gohr
110994171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
111075fa767dSAndreas Gohr                    SET dt       = NOW(),
111175fa767dSAndreas Gohr                        page     = '$page',
11121878f16fSAndreas Gohr                        ip       = '$ip',
11131878f16fSAndreas Gohr                        ua       = '$ua',
11141878f16fSAndreas Gohr                        ua_info  = '$ua_info',
111514d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
111614d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
111714d99ec0SAndreas Gohr                        os       = '$os',
11181878f16fSAndreas Gohr                        ref      = '$ref',
111994171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
112014d99ec0SAndreas Gohr                        ref_type = '$ref_type',
11211878f16fSAndreas Gohr                        screen_x = '$sx',
11221878f16fSAndreas Gohr                        screen_y = '$sy',
11231878f16fSAndreas Gohr                        view_x   = '$vx',
11241878f16fSAndreas Gohr                        view_y   = '$vy',
112575fa767dSAndreas Gohr                        js       = '$js',
11261878f16fSAndreas Gohr                        user     = '$user',
11273c0acc14SAndreas Gohr                        session  = '$session',
11283c0acc14SAndreas Gohr                        uid      = '$uid'";
11291878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
11301878f16fSAndreas Gohr        if(is_null($ok)){
11311878f16fSAndreas Gohr            global $MSG;
11321878f16fSAndreas Gohr            print_r($MSG);
11331878f16fSAndreas Gohr        }
113414d99ec0SAndreas Gohr
113514d99ec0SAndreas Gohr        // resolve the IP
113614d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
11371878f16fSAndreas Gohr    }
11381878f16fSAndreas Gohr
11391878f16fSAndreas Gohr    /**
11401878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
11411878f16fSAndreas Gohr     *
11421878f16fSAndreas Gohr     * @called from log.php
11431878f16fSAndreas Gohr     *
11441878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
11451878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
11461878f16fSAndreas Gohr     */
11471878f16fSAndreas Gohr    function sendGIF(){
11481878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
11491878f16fSAndreas Gohr        header('Content-Type: image/gif');
11501878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
11511878f16fSAndreas Gohr        header('Connection: Close');
11521878f16fSAndreas Gohr        print $img;
11531878f16fSAndreas Gohr        flush();
11541878f16fSAndreas Gohr        // Browser should drop connection after this
11551878f16fSAndreas Gohr        // Thinks it's got the whole image
11561878f16fSAndreas Gohr    }
11571878f16fSAndreas Gohr
11581878f16fSAndreas Gohr}
1159