xref: /plugin/statistics/admin.php (revision 2812a7519d6c63c493fa4b6e912a9321cbe63a38)
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;
859da6395dSAndreas Gohr            case 'referer':
869da6395dSAndreas Gohr                $this->html_referer();
879da6395dSAndreas Gohr                break;
8814d99ec0SAndreas Gohr            default:
899da6395dSAndreas Gohr                $this->html_dashboard();
9014d99ec0SAndreas Gohr        }
9114d99ec0SAndreas Gohr    }
9214d99ec0SAndreas Gohr
939da6395dSAndreas Gohr    function html_toc(){
949da6395dSAndreas Gohr        echo '<div class="toc">';
959da6395dSAndreas Gohr        echo '<div class="tocheader toctoggle" id="toc__header">';
969da6395dSAndreas Gohr        echo 'Detailed Statistics';
979da6395dSAndreas Gohr        echo '</div>';
989da6395dSAndreas Gohr        echo '<div id="toc__inside">';
999da6395dSAndreas Gohr        echo '<ul class="toc">';
1009da6395dSAndreas Gohr
1019da6395dSAndreas Gohr        echo '<li><div class="li">';
1029da6395dSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$this->start.'">Dashboard</a>';
1039da6395dSAndreas Gohr        echo '</div></li>';
1049da6395dSAndreas Gohr
1059da6395dSAndreas Gohr        echo '<li><div class="li">';
1069da6395dSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$this->start.'">Pages</a>';
1079da6395dSAndreas Gohr        echo '</div></li>';
1089da6395dSAndreas Gohr
1099da6395dSAndreas Gohr        echo '<li><div class="li">';
1109da6395dSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=referer&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$this->start.'">Incoming Links</a>';
1119da6395dSAndreas Gohr        echo '</div></li>';
1129da6395dSAndreas Gohr
1139da6395dSAndreas Gohr        echo '<li><div class="li">';
1149da6395dSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=country&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$this->start.'">Countries</a>';
1159da6395dSAndreas Gohr        echo '</div></li>';
1169da6395dSAndreas Gohr
1179da6395dSAndreas Gohr        echo '</ul>';
1189da6395dSAndreas Gohr        echo '</div>';
1199da6395dSAndreas Gohr        echo '</div>';
1209da6395dSAndreas Gohr    }
1219da6395dSAndreas Gohr
122264f1744SAndreas Gohr    /**
123264f1744SAndreas Gohr     * Print the time selection menu
124264f1744SAndreas Gohr     */
12514d99ec0SAndreas Gohr    function html_timeselect(){
126264f1744SAndreas Gohr        $now   = date('Y-m-d');
127264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
128264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
129264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
13014d99ec0SAndreas Gohr
131264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
132264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
133264f1744SAndreas Gohr        echo '<ul>';
134264f1744SAndreas Gohr
135264f1744SAndreas Gohr        echo '<li>';
13695eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'&amp;s='.$this->start.'">';
137264f1744SAndreas Gohr        echo 'today';
138264f1744SAndreas Gohr        echo '</a>';
139264f1744SAndreas Gohr        echo '</li>';
140264f1744SAndreas Gohr
141264f1744SAndreas Gohr        echo '<li>';
14295eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'&amp;s='.$this->start.'">';
143264f1744SAndreas Gohr        echo 'yesterday';
144264f1744SAndreas Gohr        echo '</a>';
145264f1744SAndreas Gohr        echo '</li>';
146264f1744SAndreas Gohr
147264f1744SAndreas Gohr        echo '<li>';
14895eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'&amp;s='.$this->start.'">';
149264f1744SAndreas Gohr        echo 'last 7 days';
150264f1744SAndreas Gohr        echo '</a>';
151264f1744SAndreas Gohr        echo '</li>';
152264f1744SAndreas Gohr
153264f1744SAndreas Gohr        echo '<li>';
15495eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'&amp;s='.$this->start.'">';
155264f1744SAndreas Gohr        echo 'last 30 days';
156264f1744SAndreas Gohr        echo '</a>';
157264f1744SAndreas Gohr        echo '</li>';
158264f1744SAndreas Gohr
159264f1744SAndreas Gohr        echo '</ul>';
160264f1744SAndreas Gohr
161264f1744SAndreas Gohr
162264f1744SAndreas Gohr        echo '<form action="" method="get">';
163264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
164264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
165264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
16695eb68e6SAndreas Gohr        echo '<input type="hidden" name="s" value="'.$this->start.'" />';
167264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
168264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
169264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
17014d99ec0SAndreas Gohr        echo '</form>';
171264f1744SAndreas Gohr
172264f1744SAndreas Gohr        echo '</div>';
17314d99ec0SAndreas Gohr    }
17414d99ec0SAndreas Gohr
17514d99ec0SAndreas Gohr
176f5f32cbfSAndreas Gohr    /**
177f5f32cbfSAndreas Gohr     * Print an introductionary screen
178f5f32cbfSAndreas Gohr     */
17914d99ec0SAndreas Gohr    function html_dashboard(){
180*2812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
181*2812a751SAndreas Gohr              choose a topic from the list.</p>';
182*2812a751SAndreas Gohr
183*2812a751SAndreas Gohr
184264f1744SAndreas Gohr        echo '<div class="plg_stats_dashboard">';
185264f1744SAndreas Gohr
186*2812a751SAndreas Gohr        // general info
187*2812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
188*2812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
189*2812a751SAndreas Gohr        echo '<ul>';
190*2812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views</li>';
191*2812a751SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visitors (sessions)</li>';
192*2812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
193*2812a751SAndreas Gohr
194*2812a751SAndreas Gohr        echo '</ul>';
195*2812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
196*2812a751SAndreas Gohr        echo '</div>';
197*2812a751SAndreas Gohr
19814d99ec0SAndreas Gohr
19987d5e44bSAndreas Gohr        // top pages today
200264f1744SAndreas Gohr        echo '<div>';
201264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
20295eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
203*2812a751SAndreas Gohr        $this->html_resulttable($result);
204264f1744SAndreas Gohr        echo '</div>';
20587d5e44bSAndreas Gohr
20687d5e44bSAndreas Gohr        // top referer today
207264f1744SAndreas Gohr        echo '<div>';
208264f1744SAndreas Gohr        echo '<h2>Top incoming links</h2>';
20995eb68e6SAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,15);
210*2812a751SAndreas Gohr        $this->html_resulttable($result);
211264f1744SAndreas Gohr        echo '</div>';
21254f6c432SAndreas Gohr
21354f6c432SAndreas Gohr        // top countries today
214264f1744SAndreas Gohr        echo '<div>';
215264f1744SAndreas Gohr        echo '<h2>Visitor\'s top countries</h2>';
21695eb68e6SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
21795eb68e6SAndreas Gohr//        $result = $this->sql_countries($this->tlimit,$this->start,15);
21895eb68e6SAndreas Gohr//        $this->html_resulttable($result,array('','Countries','Count'));
219264f1744SAndreas Gohr        echo '</div>';
220264f1744SAndreas Gohr
221264f1744SAndreas Gohr        echo '</div>';
22214d99ec0SAndreas Gohr    }
22314d99ec0SAndreas Gohr
2249da6395dSAndreas Gohr    function html_country(){
2259da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2269da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
2279da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
228*2812a751SAndreas Gohr        $this->html_resulttable($result);
2299da6395dSAndreas Gohr        echo '</div>';
2309da6395dSAndreas Gohr    }
2319da6395dSAndreas Gohr
2329da6395dSAndreas Gohr    function html_page(){
2339da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2349da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
2359da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
236*2812a751SAndreas Gohr        $this->html_resulttable($result);
2379da6395dSAndreas Gohr        echo '</div>';
2389da6395dSAndreas Gohr    }
2399da6395dSAndreas Gohr
2409da6395dSAndreas Gohr    function html_referer(){
2419da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2429da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
243*2812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
244*2812a751SAndreas Gohr
245*2812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
246*2812a751SAndreas Gohr
247*2812a751SAndreas Gohr        printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
248*2812a751SAndreas Gohr                %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
249*2812a751SAndreas Gohr                links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
250*2812a751SAndreas Gohr                $result['search'],(100*$result['search']/$all),$result['external'],
251*2812a751SAndreas Gohr                (100*$result['external']/$all));
252*2812a751SAndreas Gohr
2539da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
254*2812a751SAndreas Gohr        $this->html_resulttable($result);
2559da6395dSAndreas Gohr        echo '</div>';
2569da6395dSAndreas Gohr    }
2579da6395dSAndreas Gohr
2589da6395dSAndreas Gohr
2599da6395dSAndreas Gohr
26014d99ec0SAndreas Gohr    /**
26114d99ec0SAndreas Gohr     * Display a result in a HTML table
26214d99ec0SAndreas Gohr     */
263*2812a751SAndreas Gohr    function html_resulttable($result,$header=''){
26414d99ec0SAndreas Gohr        echo '<table>';
265*2812a751SAndreas Gohr        if(is_array($header)){
26614d99ec0SAndreas Gohr            echo '<tr>';
26714d99ec0SAndreas Gohr            foreach($header as $h){
26814d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
26914d99ec0SAndreas Gohr            }
27014d99ec0SAndreas Gohr            echo '</tr>';
271*2812a751SAndreas Gohr        }
27214d99ec0SAndreas Gohr
27314d99ec0SAndreas Gohr        foreach($result as $row){
27414d99ec0SAndreas Gohr            echo '<tr>';
27514d99ec0SAndreas Gohr            foreach($row as $k => $v){
276*2812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
27714d99ec0SAndreas Gohr                if($k == 'page'){
27814d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
27914d99ec0SAndreas Gohr                    echo hsc($v);
28014d99ec0SAndreas Gohr                    echo '</a>';
28114d99ec0SAndreas Gohr                }elseif($k == 'url'){
28254f6c432SAndreas Gohr                    $url = hsc($v);
283*2812a751SAndreas Gohr                    if(strlen($url) > 45){
284*2812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
28554f6c432SAndreas Gohr                    }
28614d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
28754f6c432SAndreas Gohr                    echo $url;
28814d99ec0SAndreas Gohr                    echo '</a>';
28914d99ec0SAndreas Gohr                }elseif($k == 'html'){
29014d99ec0SAndreas Gohr                    echo $v;
291f5f32cbfSAndreas Gohr                }elseif($k == 'cflag'){
29295eb68e6SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12"/>';
29314d99ec0SAndreas Gohr                }else{
29414d99ec0SAndreas Gohr                    echo hsc($v);
29514d99ec0SAndreas Gohr                }
29614d99ec0SAndreas Gohr                echo '</td>';
29714d99ec0SAndreas Gohr            }
29814d99ec0SAndreas Gohr            echo '</tr>';
29914d99ec0SAndreas Gohr        }
30014d99ec0SAndreas Gohr        echo '</table>';
3011878f16fSAndreas Gohr    }
3021878f16fSAndreas Gohr
30395eb68e6SAndreas Gohr    /**
30495eb68e6SAndreas Gohr     * Create an image
30595eb68e6SAndreas Gohr     */
30695eb68e6SAndreas Gohr    function img_build($img){
30795eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
30895eb68e6SAndreas Gohr
30995eb68e6SAndreas Gohr        switch($img){
31095eb68e6SAndreas Gohr            case 'country':
31195eb68e6SAndreas Gohr                // build top countries + other
31295eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
31395eb68e6SAndreas Gohr                $data = array();
31495eb68e6SAndreas Gohr                $top = 0;
31595eb68e6SAndreas Gohr                foreach($result as $row){
31695eb68e6SAndreas Gohr                    if($top < 7){
31795eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
31895eb68e6SAndreas Gohr                    }else{
31995eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
32095eb68e6SAndreas Gohr                    }
32195eb68e6SAndreas Gohr                    $top++;
32295eb68e6SAndreas Gohr                }
32395eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
32495eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
32595eb68e6SAndreas Gohr                $pie->setProp("showval",false);
32695eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
32795eb68e6SAndreas Gohr                $pie->setProp("type","pie");
32895eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
32995eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
33095eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
33195eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
33295eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
33395eb68e6SAndreas Gohr                @$pie->graph();
33495eb68e6SAndreas Gohr                $pie->showGraph();
33595eb68e6SAndreas Gohr                break;
336*2812a751SAndreas Gohr            case 'trend':
337*2812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
338*2812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
339*2812a751SAndreas Gohr                $data1   = array();
340*2812a751SAndreas Gohr                $data2   = array();
341*2812a751SAndreas Gohr
342*2812a751SAndreas Gohr                $graph = new AGC(400, 150);
343*2812a751SAndreas Gohr                $graph->setProp("type","bar");
344*2812a751SAndreas Gohr                $graph->setProp("showgrid",false);
345*2812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
346*2812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
347*2812a751SAndreas Gohr                $graph->setColor('color',1,'red');
348*2812a751SAndreas Gohr
349*2812a751SAndreas Gohr                if($hours){
350*2812a751SAndreas Gohr                    //preset $hours
351*2812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
352*2812a751SAndreas Gohr                        $data1[$i] = 0;
353*2812a751SAndreas Gohr                        $data2[$i] = 0;
354*2812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
355*2812a751SAndreas Gohr                    }
356*2812a751SAndreas Gohr                }else{
357*2812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
358*2812a751SAndreas Gohr                }
359*2812a751SAndreas Gohr
360*2812a751SAndreas Gohr                foreach($result as $row){
361*2812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
362*2812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
363*2812a751SAndreas Gohr                }
364*2812a751SAndreas Gohr
365*2812a751SAndreas Gohr                foreach($data1 as $key => $val){
366*2812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
367*2812a751SAndreas Gohr                }
368*2812a751SAndreas Gohr                foreach($data2 as $key => $val){
369*2812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
370*2812a751SAndreas Gohr                }
371*2812a751SAndreas Gohr
372*2812a751SAndreas Gohr                @$graph->graph();
373*2812a751SAndreas Gohr                $graph->showGraph();
374*2812a751SAndreas Gohr
37595eb68e6SAndreas Gohr            default:
37695eb68e6SAndreas Gohr                $this->sendGIF();
37795eb68e6SAndreas Gohr        }
37895eb68e6SAndreas Gohr    }
37995eb68e6SAndreas Gohr
38095eb68e6SAndreas Gohr
381*2812a751SAndreas Gohr    /**
382*2812a751SAndreas Gohr     * Return some aggregated statistics
383*2812a751SAndreas Gohr     */
384*2812a751SAndreas Gohr    function sql_aggregate($tlimit){
385*2812a751SAndreas Gohr        $data = array();
386*2812a751SAndreas Gohr
387*2812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
388*2812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
389*2812a751SAndreas Gohr                 WHERE $tlimit
390*2812a751SAndreas Gohr                   AND ua_type = 'browser'
391*2812a751SAndreas Gohr              GROUP BY ref_type";
392*2812a751SAndreas Gohr        $result = $this->runSQL($sql);
393*2812a751SAndreas Gohr
394*2812a751SAndreas Gohr        foreach($result as $row){
395*2812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
396*2812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
397*2812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
398*2812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
399*2812a751SAndreas Gohr        }
400*2812a751SAndreas Gohr
401*2812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
402*2812a751SAndreas Gohr                       COUNT(session) as views,
403*2812a751SAndreas Gohr                       COUNT(DISTINCT user) as users
404*2812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
405*2812a751SAndreas Gohr                 WHERE $tlimit
406*2812a751SAndreas Gohr                   AND ua_type = 'browser'";
407*2812a751SAndreas Gohr        $result = $this->runSQL($sql);
408*2812a751SAndreas Gohr
409*2812a751SAndreas Gohr        $data['users']     = $result[0]['users'] - 1; // subtract empty user
410*2812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
411*2812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
412*2812a751SAndreas Gohr
413*2812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
414*2812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
415*2812a751SAndreas Gohr                 WHERE $tlimit
416*2812a751SAndreas Gohr                   AND ua_type = 'robot'";
417*2812a751SAndreas Gohr        $result = $this->runSQL($sql);
418*2812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
419*2812a751SAndreas Gohr
420*2812a751SAndreas Gohr        return $data;
421*2812a751SAndreas Gohr    }
422*2812a751SAndreas Gohr
423*2812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
424*2812a751SAndreas Gohr        if($hours){
425*2812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
426*2812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
427*2812a751SAndreas Gohr                           COUNT(session) as pageviews
428*2812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
429*2812a751SAndreas Gohr                     WHERE $tlimit
430*2812a751SAndreas Gohr                       AND ua_type = 'browser'
431*2812a751SAndreas Gohr                  GROUP BY HOUR(dt)
432*2812a751SAndreas Gohr                  ORDER BY time";
433*2812a751SAndreas Gohr        }else{
434*2812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
435*2812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
436*2812a751SAndreas Gohr                           COUNT(session) as pageviews
437*2812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
438*2812a751SAndreas Gohr                     WHERE $tlimit
439*2812a751SAndreas Gohr                       AND ua_type = 'browser'
440*2812a751SAndreas Gohr                  GROUP BY DATE(dt)
441*2812a751SAndreas Gohr                  ORDER BY time";
442*2812a751SAndreas Gohr        }
443*2812a751SAndreas Gohr        return $this->runSQL($sql);
444*2812a751SAndreas Gohr    }
445*2812a751SAndreas Gohr
44695eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
447*2812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
44895eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
44995eb68e6SAndreas Gohr                 WHERE $tlimit
45095eb68e6SAndreas Gohr                   AND ua_type = 'browser'
45195eb68e6SAndreas Gohr              GROUP BY page
45295eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
45395eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
45495eb68e6SAndreas Gohr        return $this->runSQL($sql);
45595eb68e6SAndreas Gohr    }
45695eb68e6SAndreas Gohr
45795eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
458*2812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
45995eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
46095eb68e6SAndreas Gohr                 WHERE $tlimit
46195eb68e6SAndreas Gohr                   AND ua_type = 'browser'
46295eb68e6SAndreas Gohr                   AND ref_type = 'external'
46395eb68e6SAndreas Gohr              GROUP BY ref_md5
46495eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
46595eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
46695eb68e6SAndreas Gohr        return $this->runSQL($sql);
46795eb68e6SAndreas Gohr    }
46895eb68e6SAndreas Gohr
46995eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
470*2812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, B.code AS cflag, B.country
47195eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
47295eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
47395eb68e6SAndreas Gohr                 WHERE $tlimit
47495eb68e6SAndreas Gohr                   AND A.ip = B.ip
47595eb68e6SAndreas Gohr              GROUP BY B.country
47695eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
47795eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
47895eb68e6SAndreas Gohr        return $this->runSQL($sql);
47995eb68e6SAndreas Gohr    }
48095eb68e6SAndreas Gohr
48195eb68e6SAndreas Gohr    /**
48295eb68e6SAndreas Gohr     * Builds a limit clause
48395eb68e6SAndreas Gohr     */
48495eb68e6SAndreas Gohr    function sql_limit($start,$limit){
48595eb68e6SAndreas Gohr        $start = (int) $start;
48695eb68e6SAndreas Gohr        $limit = (int) $limit;
48795eb68e6SAndreas Gohr        if($limit){
48895eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
48995eb68e6SAndreas Gohr        }elseif($start){
49095eb68e6SAndreas Gohr            return " OFFSET $start";
49195eb68e6SAndreas Gohr        }
49295eb68e6SAndreas Gohr        return '';
49395eb68e6SAndreas Gohr    }
4941878f16fSAndreas Gohr
4951878f16fSAndreas Gohr    /**
49614d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
4971878f16fSAndreas Gohr     */
49814d99ec0SAndreas Gohr    function dbLink(){
4991878f16fSAndreas Gohr        // connect to DB if needed
5001878f16fSAndreas Gohr        if(!$this->dblink){
5011878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
5021878f16fSAndreas Gohr                                          $this->getConf('db_user'),
5031878f16fSAndreas Gohr                                          $this->getConf('db_password'));
5041878f16fSAndreas Gohr            if(!$this->dblink){
5051878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
5061878f16fSAndreas Gohr                return null;
5071878f16fSAndreas Gohr            }
5081878f16fSAndreas Gohr            // set utf-8
5091878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
5101878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
5111878f16fSAndreas Gohr                return null;
5121878f16fSAndreas Gohr            }
5131878f16fSAndreas Gohr        }
51414d99ec0SAndreas Gohr        return $this->dblink;
51514d99ec0SAndreas Gohr    }
5161878f16fSAndreas Gohr
51714d99ec0SAndreas Gohr    /**
51814d99ec0SAndreas Gohr     * Simple function to run a DB query
51914d99ec0SAndreas Gohr     */
52014d99ec0SAndreas Gohr    function runSQL($sql_string) {
52114d99ec0SAndreas Gohr        $link = $this->dbLink();
52214d99ec0SAndreas Gohr
52314d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
52494171ff3SAndreas Gohr        if(!$result){
525*2812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
5261878f16fSAndreas Gohr            return null;
5271878f16fSAndreas Gohr        }
5281878f16fSAndreas Gohr
5291878f16fSAndreas Gohr        $resultarray = array();
5301878f16fSAndreas Gohr
5311878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
5321878f16fSAndreas Gohr        if ($result != 1) {
5331878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
5341878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
5351878f16fSAndreas Gohr                $resultarray[]=$temparray;
5361878f16fSAndreas Gohr            }
5371878f16fSAndreas Gohr            mysql_free_result($result);
5381878f16fSAndreas Gohr        }
5391878f16fSAndreas Gohr
54014d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
54114d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
5421878f16fSAndreas Gohr        }
5431878f16fSAndreas Gohr
5441878f16fSAndreas Gohr        return $resultarray;
5451878f16fSAndreas Gohr    }
5461878f16fSAndreas Gohr
5471878f16fSAndreas Gohr    /**
54814d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
5491878f16fSAndreas Gohr     */
55014d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
55114d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
55214d99ec0SAndreas Gohr        $ua = strtolower($ua);
55314d99ec0SAndreas Gohr
55414d99ec0SAndreas Gohr        // common browsers
55514d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
55614d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
55714d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
55814d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
55914d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
56014d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
56114d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
56214d99ec0SAndreas Gohr
56314d99ec0SAndreas Gohr        $name = '';
56414d99ec0SAndreas Gohr        # IE ?
56514d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
56614d99ec0SAndreas Gohr            $type = 'browser';
56714d99ec0SAndreas Gohr            $ver  = $m[2];
56814d99ec0SAndreas Gohr            $name = 'msie';
56914d99ec0SAndreas Gohr        }
57014d99ec0SAndreas Gohr        # Firefox ?
57114d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
57214d99ec0SAndreas Gohr            $type = 'browser';
57314d99ec0SAndreas Gohr            $ver  = $m[1];
57414d99ec0SAndreas Gohr            $name = 'firefox';
57514d99ec0SAndreas Gohr        }
57614d99ec0SAndreas Gohr        # Subversion ?
57714d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
57814d99ec0SAndreas Gohr            $type = 'rcs';
57914d99ec0SAndreas Gohr            $ver  = $m[1];
58014d99ec0SAndreas Gohr            $name = 'svn';
58114d99ec0SAndreas Gohr        }
58214d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
58314d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
58414d99ec0SAndreas Gohr            $type = 'browser';
58514d99ec0SAndreas Gohr            $ver  = $m[1];
58614d99ec0SAndreas Gohr            $name = 'netscape';
58714d99ec0SAndreas Gohr        }
58814d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
58914d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
59014d99ec0SAndreas Gohr            $type = 'browser';
59114d99ec0SAndreas Gohr            $ver  = $m[2];
59214d99ec0SAndreas Gohr            $name = 'netscape';
59314d99ec0SAndreas Gohr        }else{
59414d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
59514d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
59614d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
59714d99ec0SAndreas Gohr                    // it's a browser!
59814d99ec0SAndreas Gohr                    $type = 'browser';
59914d99ec0SAndreas Gohr                    $name = strtolower($regex);
60014d99ec0SAndreas Gohr                    break;
60114d99ec0SAndreas Gohr                }
60214d99ec0SAndreas Gohr            }
60314d99ec0SAndreas Gohr        }
60414d99ec0SAndreas Gohr
60514d99ec0SAndreas Gohr        // check OS for browsers
60614d99ec0SAndreas Gohr        if($type == 'browser'){
60714d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
60814d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
60914d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
61014d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
61114d99ec0SAndreas Gohr                    break;
61214d99ec0SAndreas Gohr                }
61314d99ec0SAndreas Gohr            }
61414d99ec0SAndreas Gohr
61514d99ec0SAndreas Gohr        }
61614d99ec0SAndreas Gohr
61714d99ec0SAndreas Gohr        // are we done now?
61814d99ec0SAndreas Gohr        if($name) return $name;
61914d99ec0SAndreas Gohr
62014d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
62114d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
62214d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
62314d99ec0SAndreas Gohr                    // it's a robot!
62414d99ec0SAndreas Gohr                    $type = 'robot';
62514d99ec0SAndreas Gohr                    return strtolower($regex);
62614d99ec0SAndreas Gohr            }
62714d99ec0SAndreas Gohr        }
62814d99ec0SAndreas Gohr
62914d99ec0SAndreas Gohr        // dunno
6301878f16fSAndreas Gohr        return '';
6311878f16fSAndreas Gohr    }
6321878f16fSAndreas Gohr
6331878f16fSAndreas Gohr    /**
63414d99ec0SAndreas Gohr     *
63514d99ec0SAndreas Gohr     * @fixme: put search engine queries in seperate table here
63614d99ec0SAndreas Gohr     */
63714d99ec0SAndreas Gohr    function log_search($referer,&$type){
63814d99ec0SAndreas Gohr        $referer = strtr($referer,' +','__');
63914d99ec0SAndreas Gohr        $referer = strtolower($referer);
64014d99ec0SAndreas Gohr
64114d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
64214d99ec0SAndreas Gohr
64314d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
64414d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$referer)){
64514d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
64614d99ec0SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){
64714d99ec0SAndreas Gohr                    // it's a search engine!
64814d99ec0SAndreas Gohr                    $type = 'search';
64914d99ec0SAndreas Gohr                    break;
65014d99ec0SAndreas Gohr                }
65114d99ec0SAndreas Gohr            }
65214d99ec0SAndreas Gohr        }
65314d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
65414d99ec0SAndreas Gohr
65514d99ec0SAndreas Gohr        #fixme now do the keyword magic!
65614d99ec0SAndreas Gohr    }
65714d99ec0SAndreas Gohr
65814d99ec0SAndreas Gohr    /**
65914d99ec0SAndreas Gohr     * Resolve IP to country/city
66014d99ec0SAndreas Gohr     */
66114d99ec0SAndreas Gohr    function log_ip($ip){
66214d99ec0SAndreas Gohr        // check if IP already known and up-to-date
66314d99ec0SAndreas Gohr        $sql = "SELECT ip
66414d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
66514d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
66614d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
66714d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
66814d99ec0SAndreas Gohr        if($result[0]['ip']) return;
66914d99ec0SAndreas Gohr
67014d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
67114d99ec0SAndreas Gohr        $http->timeout = 10;
67214d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
67314d99ec0SAndreas Gohr
67414d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
67514d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
67614d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
67714d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
67814d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
67914d99ec0SAndreas Gohr            $ip      = addslashes($ip);
68014d99ec0SAndreas Gohr
68114d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
68214d99ec0SAndreas Gohr                        SET ip = '$ip',
68314d99ec0SAndreas Gohr                            country = '$country',
68414d99ec0SAndreas Gohr                            code    = '$code',
68514d99ec0SAndreas Gohr                            city    = '$city',
68614d99ec0SAndreas Gohr                            host    = '$host'";
68714d99ec0SAndreas Gohr            $this->runSQL($sql);
68814d99ec0SAndreas Gohr        }
68914d99ec0SAndreas Gohr    }
69014d99ec0SAndreas Gohr
69114d99ec0SAndreas Gohr    /**
6921878f16fSAndreas Gohr     * log a page access
6931878f16fSAndreas Gohr     *
6941878f16fSAndreas Gohr     * called from log.php
6951878f16fSAndreas Gohr     */
6961878f16fSAndreas Gohr    function log_access(){
69794171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
69894171ff3SAndreas Gohr
69914d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
70014d99ec0SAndreas Gohr
70114d99ec0SAndreas Gohr        // handle referer
70214d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
70314d99ec0SAndreas Gohr        if($referer){
70414d99ec0SAndreas Gohr            $ref     = addslashes($referer);
70514d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
70614d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
70714d99ec0SAndreas Gohr                $ref_type = 'internal';
70814d99ec0SAndreas Gohr            }else{
70914d99ec0SAndreas Gohr                $ref_type = 'external';
71014d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
71114d99ec0SAndreas Gohr            }
71214d99ec0SAndreas Gohr        }else{
71314d99ec0SAndreas Gohr            $ref      = '';
71414d99ec0SAndreas Gohr            $ref_md5  = '';
71514d99ec0SAndreas Gohr            $ref_type = '';
71614d99ec0SAndreas Gohr        }
71714d99ec0SAndreas Gohr
71814d99ec0SAndreas Gohr        // handle user agent
71914d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
72014d99ec0SAndreas Gohr
72114d99ec0SAndreas Gohr        $ua      = addslashes($agent);
72214d99ec0SAndreas Gohr        $ua_type = '';
72314d99ec0SAndreas Gohr        $ua_ver  = '';
72414d99ec0SAndreas Gohr        $os      = '';
72514d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
72614d99ec0SAndreas Gohr
7271878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
7281878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
7291878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
7301878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
7311878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
7321878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
7331878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
7341878f16fSAndreas Gohr        $session = addslashes(session_id());
7351878f16fSAndreas Gohr
73694171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
7371878f16fSAndreas Gohr                    SET page     = '$page',
7381878f16fSAndreas Gohr                        ip       = '$ip',
7391878f16fSAndreas Gohr                        ua       = '$ua',
7401878f16fSAndreas Gohr                        ua_info  = '$ua_info',
74114d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
74214d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
74314d99ec0SAndreas Gohr                        os       = '$os',
7441878f16fSAndreas Gohr                        ref      = '$ref',
74594171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
74614d99ec0SAndreas Gohr                        ref_type = '$ref_type',
7471878f16fSAndreas Gohr                        screen_x = '$sx',
7481878f16fSAndreas Gohr                        screen_y = '$sy',
7491878f16fSAndreas Gohr                        view_x   = '$vx',
7501878f16fSAndreas Gohr                        view_y   = '$vy',
7511878f16fSAndreas Gohr                        user     = '$user',
7521878f16fSAndreas Gohr                        session  = '$session'";
7531878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
7541878f16fSAndreas Gohr        if(is_null($ok)){
7551878f16fSAndreas Gohr            global $MSG;
7561878f16fSAndreas Gohr            print_r($MSG);
7571878f16fSAndreas Gohr        }
75814d99ec0SAndreas Gohr
75914d99ec0SAndreas Gohr        // resolve the IP
76014d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
7611878f16fSAndreas Gohr    }
7621878f16fSAndreas Gohr
7631878f16fSAndreas Gohr    /**
7641878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
7651878f16fSAndreas Gohr     *
7661878f16fSAndreas Gohr     * @called from log.php
7671878f16fSAndreas Gohr     *
7681878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
7691878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
7701878f16fSAndreas Gohr     */
7711878f16fSAndreas Gohr    function sendGIF(){
7721878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
7731878f16fSAndreas Gohr        header('Content-Type: image/gif');
7741878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
7751878f16fSAndreas Gohr        header('Connection: Close');
7761878f16fSAndreas Gohr        print $img;
7771878f16fSAndreas Gohr        flush();
7781878f16fSAndreas Gohr        // Browser should drop connection after this
7791878f16fSAndreas Gohr        // Thinks it's got the whole image
7801878f16fSAndreas Gohr    }
7811878f16fSAndreas Gohr
7821878f16fSAndreas Gohr}
783