xref: /plugin/statistics/admin.php (revision 75fa767de5b14be2623c6c33982b34f2eab2100e)
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;
85*75fa767dSAndreas Gohr            case 'browser':
86*75fa767dSAndreas Gohr                $this->html_browser();
87*75fa767dSAndreas Gohr                break;
889da6395dSAndreas Gohr            case 'referer':
899da6395dSAndreas Gohr                $this->html_referer();
909da6395dSAndreas Gohr                break;
9114d99ec0SAndreas Gohr            default:
929da6395dSAndreas Gohr                $this->html_dashboard();
9314d99ec0SAndreas Gohr        }
9414d99ec0SAndreas Gohr    }
9514d99ec0SAndreas Gohr
969da6395dSAndreas Gohr    function html_toc(){
979da6395dSAndreas Gohr        echo '<div class="toc">';
989da6395dSAndreas Gohr        echo '<div class="tocheader toctoggle" id="toc__header">';
999da6395dSAndreas Gohr        echo 'Detailed Statistics';
1009da6395dSAndreas Gohr        echo '</div>';
1019da6395dSAndreas Gohr        echo '<div id="toc__inside">';
1029da6395dSAndreas Gohr        echo '<ul class="toc">';
1039da6395dSAndreas Gohr
1049da6395dSAndreas Gohr        echo '<li><div class="li">';
1059da6395dSAndreas 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>';
1069da6395dSAndreas Gohr        echo '</div></li>';
1079da6395dSAndreas Gohr
1089da6395dSAndreas Gohr        echo '<li><div class="li">';
1099da6395dSAndreas 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>';
1109da6395dSAndreas Gohr        echo '</div></li>';
1119da6395dSAndreas Gohr
1129da6395dSAndreas Gohr        echo '<li><div class="li">';
1139da6395dSAndreas 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>';
1149da6395dSAndreas Gohr        echo '</div></li>';
1159da6395dSAndreas Gohr
1169da6395dSAndreas Gohr        echo '<li><div class="li">';
117*75fa767dSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=browser&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$this->start.'">Browsers</a>';
118*75fa767dSAndreas Gohr        echo '</div></li>';
119*75fa767dSAndreas Gohr
120*75fa767dSAndreas Gohr        echo '<li><div class="li">';
1219da6395dSAndreas 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>';
1229da6395dSAndreas Gohr        echo '</div></li>';
1239da6395dSAndreas Gohr
1249da6395dSAndreas Gohr        echo '</ul>';
1259da6395dSAndreas Gohr        echo '</div>';
1269da6395dSAndreas Gohr        echo '</div>';
1279da6395dSAndreas Gohr    }
1289da6395dSAndreas Gohr
129264f1744SAndreas Gohr    /**
130264f1744SAndreas Gohr     * Print the time selection menu
131264f1744SAndreas Gohr     */
13214d99ec0SAndreas Gohr    function html_timeselect(){
133264f1744SAndreas Gohr        $now   = date('Y-m-d');
134264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
135264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
136264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
13714d99ec0SAndreas Gohr
138264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
139264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
140264f1744SAndreas Gohr        echo '<ul>';
141264f1744SAndreas Gohr
142264f1744SAndreas Gohr        echo '<li>';
14395eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'&amp;s='.$this->start.'">';
144264f1744SAndreas Gohr        echo 'today';
145264f1744SAndreas Gohr        echo '</a>';
146264f1744SAndreas Gohr        echo '</li>';
147264f1744SAndreas Gohr
148264f1744SAndreas Gohr        echo '<li>';
14995eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'&amp;s='.$this->start.'">';
150264f1744SAndreas Gohr        echo 'yesterday';
151264f1744SAndreas Gohr        echo '</a>';
152264f1744SAndreas Gohr        echo '</li>';
153264f1744SAndreas Gohr
154264f1744SAndreas Gohr        echo '<li>';
15595eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'&amp;s='.$this->start.'">';
156264f1744SAndreas Gohr        echo 'last 7 days';
157264f1744SAndreas Gohr        echo '</a>';
158264f1744SAndreas Gohr        echo '</li>';
159264f1744SAndreas Gohr
160264f1744SAndreas Gohr        echo '<li>';
16195eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'&amp;s='.$this->start.'">';
162264f1744SAndreas Gohr        echo 'last 30 days';
163264f1744SAndreas Gohr        echo '</a>';
164264f1744SAndreas Gohr        echo '</li>';
165264f1744SAndreas Gohr
166264f1744SAndreas Gohr        echo '</ul>';
167264f1744SAndreas Gohr
168264f1744SAndreas Gohr
169264f1744SAndreas Gohr        echo '<form action="" method="get">';
170264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
171264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
172264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
17395eb68e6SAndreas Gohr        echo '<input type="hidden" name="s" value="'.$this->start.'" />';
174264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
175264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
176264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
17714d99ec0SAndreas Gohr        echo '</form>';
178264f1744SAndreas Gohr
179264f1744SAndreas Gohr        echo '</div>';
18014d99ec0SAndreas Gohr    }
18114d99ec0SAndreas Gohr
18214d99ec0SAndreas Gohr
183f5f32cbfSAndreas Gohr    /**
184f5f32cbfSAndreas Gohr     * Print an introductionary screen
185f5f32cbfSAndreas Gohr     */
18614d99ec0SAndreas Gohr    function html_dashboard(){
1872812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
1882812a751SAndreas Gohr              choose a topic from the list.</p>';
1892812a751SAndreas Gohr
1902812a751SAndreas Gohr
191264f1744SAndreas Gohr        echo '<div class="plg_stats_dashboard">';
192264f1744SAndreas Gohr
1932812a751SAndreas Gohr        // general info
1942812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
1952812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
1962812a751SAndreas Gohr        echo '<ul>';
1972812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views</li>';
1982812a751SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visitors (sessions)</li>';
1992812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
2002812a751SAndreas Gohr
2012812a751SAndreas Gohr        echo '</ul>';
2022812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2032812a751SAndreas Gohr        echo '</div>';
2042812a751SAndreas Gohr
20514d99ec0SAndreas Gohr
20687d5e44bSAndreas Gohr        // top pages today
207264f1744SAndreas Gohr        echo '<div>';
208264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
20995eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
2102812a751SAndreas Gohr        $this->html_resulttable($result);
211264f1744SAndreas Gohr        echo '</div>';
21287d5e44bSAndreas Gohr
21387d5e44bSAndreas Gohr        // top referer today
214264f1744SAndreas Gohr        echo '<div>';
215264f1744SAndreas Gohr        echo '<h2>Top incoming links</h2>';
21695eb68e6SAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,15);
2172812a751SAndreas Gohr        $this->html_resulttable($result);
218264f1744SAndreas Gohr        echo '</div>';
21954f6c432SAndreas Gohr
22054f6c432SAndreas Gohr        // top countries today
221264f1744SAndreas Gohr        echo '<div>';
222264f1744SAndreas Gohr        echo '<h2>Visitor\'s top countries</h2>';
22395eb68e6SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
22495eb68e6SAndreas Gohr//        $result = $this->sql_countries($this->tlimit,$this->start,15);
22595eb68e6SAndreas Gohr//        $this->html_resulttable($result,array('','Countries','Count'));
226264f1744SAndreas Gohr        echo '</div>';
227264f1744SAndreas Gohr
228264f1744SAndreas Gohr        echo '</div>';
22914d99ec0SAndreas Gohr    }
23014d99ec0SAndreas Gohr
2319da6395dSAndreas Gohr    function html_country(){
2329da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2339da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
2349da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
2352812a751SAndreas Gohr        $this->html_resulttable($result);
2369da6395dSAndreas Gohr        echo '</div>';
2379da6395dSAndreas Gohr    }
2389da6395dSAndreas Gohr
2399da6395dSAndreas Gohr    function html_page(){
2409da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2419da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
2429da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
2432812a751SAndreas Gohr        $this->html_resulttable($result);
2449da6395dSAndreas Gohr        echo '</div>';
2459da6395dSAndreas Gohr    }
2469da6395dSAndreas Gohr
247*75fa767dSAndreas Gohr    function html_browser(){
248*75fa767dSAndreas Gohr        echo '<div class="plg_stats_full">';
249*75fa767dSAndreas Gohr        echo '<h2>Browser Shootout</h2>';
250*75fa767dSAndreas Gohr
251*75fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
252*75fa767dSAndreas Gohr
253*75fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
254*75fa767dSAndreas Gohr        $this->html_resulttable($result);
255*75fa767dSAndreas Gohr        echo '</div>';
256*75fa767dSAndreas Gohr    }
257*75fa767dSAndreas Gohr
2589da6395dSAndreas Gohr    function html_referer(){
2599da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2609da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
2612812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2622812a751SAndreas Gohr
2632812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
2642812a751SAndreas Gohr
2652812a751SAndreas Gohr        printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
2662812a751SAndreas Gohr                %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
2672812a751SAndreas Gohr                links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
2682812a751SAndreas Gohr                $result['search'],(100*$result['search']/$all),$result['external'],
2692812a751SAndreas Gohr                (100*$result['external']/$all));
2702812a751SAndreas Gohr
2719da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
2722812a751SAndreas Gohr        $this->html_resulttable($result);
2739da6395dSAndreas Gohr        echo '</div>';
2749da6395dSAndreas Gohr    }
2759da6395dSAndreas Gohr
2769da6395dSAndreas Gohr
2779da6395dSAndreas Gohr
27814d99ec0SAndreas Gohr    /**
27914d99ec0SAndreas Gohr     * Display a result in a HTML table
28014d99ec0SAndreas Gohr     */
2812812a751SAndreas Gohr    function html_resulttable($result,$header=''){
28214d99ec0SAndreas Gohr        echo '<table>';
2832812a751SAndreas Gohr        if(is_array($header)){
28414d99ec0SAndreas Gohr            echo '<tr>';
28514d99ec0SAndreas Gohr            foreach($header as $h){
28614d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
28714d99ec0SAndreas Gohr            }
28814d99ec0SAndreas Gohr            echo '</tr>';
2892812a751SAndreas Gohr        }
29014d99ec0SAndreas Gohr
29114d99ec0SAndreas Gohr        foreach($result as $row){
29214d99ec0SAndreas Gohr            echo '<tr>';
29314d99ec0SAndreas Gohr            foreach($row as $k => $v){
2942812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
29514d99ec0SAndreas Gohr                if($k == 'page'){
29614d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
29714d99ec0SAndreas Gohr                    echo hsc($v);
29814d99ec0SAndreas Gohr                    echo '</a>';
29914d99ec0SAndreas Gohr                }elseif($k == 'url'){
30054f6c432SAndreas Gohr                    $url = hsc($v);
3012812a751SAndreas Gohr                    if(strlen($url) > 45){
3022812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
30354f6c432SAndreas Gohr                    }
30414d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
30554f6c432SAndreas Gohr                    echo $url;
30614d99ec0SAndreas Gohr                    echo '</a>';
307*75fa767dSAndreas Gohr                }elseif($k == 'browser'){
308*75fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
309*75fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
310*75fa767dSAndreas Gohr                }elseif($k == 'bflag'){
311*75fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
312*75fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
313*75fa767dSAndreas Gohr                }elseif($k == 'cflag'){
314*75fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
31514d99ec0SAndreas Gohr                }elseif($k == 'html'){
31614d99ec0SAndreas Gohr                    echo $v;
31714d99ec0SAndreas Gohr                }else{
31814d99ec0SAndreas Gohr                    echo hsc($v);
31914d99ec0SAndreas Gohr                }
32014d99ec0SAndreas Gohr                echo '</td>';
32114d99ec0SAndreas Gohr            }
32214d99ec0SAndreas Gohr            echo '</tr>';
32314d99ec0SAndreas Gohr        }
32414d99ec0SAndreas Gohr        echo '</table>';
3251878f16fSAndreas Gohr    }
3261878f16fSAndreas Gohr
32795eb68e6SAndreas Gohr    /**
32895eb68e6SAndreas Gohr     * Create an image
32995eb68e6SAndreas Gohr     */
33095eb68e6SAndreas Gohr    function img_build($img){
33195eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
33295eb68e6SAndreas Gohr
33395eb68e6SAndreas Gohr        switch($img){
33495eb68e6SAndreas Gohr            case 'country':
33595eb68e6SAndreas Gohr                // build top countries + other
33695eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
33795eb68e6SAndreas Gohr                $data = array();
33895eb68e6SAndreas Gohr                $top = 0;
33995eb68e6SAndreas Gohr                foreach($result as $row){
34095eb68e6SAndreas Gohr                    if($top < 7){
34195eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
34295eb68e6SAndreas Gohr                    }else{
34395eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
34495eb68e6SAndreas Gohr                    }
34595eb68e6SAndreas Gohr                    $top++;
34695eb68e6SAndreas Gohr                }
34795eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
34895eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
34995eb68e6SAndreas Gohr                $pie->setProp("showval",false);
35095eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
35195eb68e6SAndreas Gohr                $pie->setProp("type","pie");
35295eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
35395eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
35495eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
35595eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
35695eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
35795eb68e6SAndreas Gohr                @$pie->graph();
35895eb68e6SAndreas Gohr                $pie->showGraph();
35995eb68e6SAndreas Gohr                break;
360*75fa767dSAndreas Gohr            case 'browser':
361*75fa767dSAndreas Gohr                // build top browsers + other
362*75fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
363*75fa767dSAndreas Gohr
364*75fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
365*75fa767dSAndreas Gohr                $data = array();
366*75fa767dSAndreas Gohr                $top = 0;
367*75fa767dSAndreas Gohr                foreach($result as $row){
368*75fa767dSAndreas Gohr                    if($top < 5){
369*75fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
370*75fa767dSAndreas Gohr                    }else{
371*75fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
372*75fa767dSAndreas Gohr                    }
373*75fa767dSAndreas Gohr                    $top++;
374*75fa767dSAndreas Gohr                }
375*75fa767dSAndreas Gohr                $pie = new AGC(300, 200);
376*75fa767dSAndreas Gohr                $pie->setProp("showkey",true);
377*75fa767dSAndreas Gohr                $pie->setProp("showval",false);
378*75fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
379*75fa767dSAndreas Gohr                $pie->setProp("type","pie");
380*75fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
381*75fa767dSAndreas Gohr                $pie->setProp("keysize",8);
382*75fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
383*75fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
384*75fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
385*75fa767dSAndreas Gohr                @$pie->graph();
386*75fa767dSAndreas Gohr                $pie->showGraph();
387*75fa767dSAndreas Gohr                break;
3882812a751SAndreas Gohr            case 'trend':
3892812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
3902812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
3912812a751SAndreas Gohr                $data1   = array();
3922812a751SAndreas Gohr                $data2   = array();
3932812a751SAndreas Gohr
3942812a751SAndreas Gohr                $graph = new AGC(400, 150);
3952812a751SAndreas Gohr                $graph->setProp("type","bar");
3962812a751SAndreas Gohr                $graph->setProp("showgrid",false);
3972812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
398*75fa767dSAndreas Gohr
3992812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
4002812a751SAndreas Gohr                $graph->setColor('color',1,'red');
4012812a751SAndreas Gohr
4022812a751SAndreas Gohr                if($hours){
4032812a751SAndreas Gohr                    //preset $hours
4042812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
4052812a751SAndreas Gohr                        $data1[$i] = 0;
4062812a751SAndreas Gohr                        $data2[$i] = 0;
4072812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
4082812a751SAndreas Gohr                    }
4092812a751SAndreas Gohr                }else{
4102812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
4112812a751SAndreas Gohr                }
4122812a751SAndreas Gohr
4132812a751SAndreas Gohr                foreach($result as $row){
4142812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
4152812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
4162812a751SAndreas Gohr                }
4172812a751SAndreas Gohr
4182812a751SAndreas Gohr                foreach($data1 as $key => $val){
4192812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
4202812a751SAndreas Gohr                }
4212812a751SAndreas Gohr                foreach($data2 as $key => $val){
4222812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
4232812a751SAndreas Gohr                }
4242812a751SAndreas Gohr
4252812a751SAndreas Gohr                @$graph->graph();
4262812a751SAndreas Gohr                $graph->showGraph();
4272812a751SAndreas Gohr
42895eb68e6SAndreas Gohr            default:
42995eb68e6SAndreas Gohr                $this->sendGIF();
43095eb68e6SAndreas Gohr        }
43195eb68e6SAndreas Gohr    }
43295eb68e6SAndreas Gohr
43395eb68e6SAndreas Gohr
4342812a751SAndreas Gohr    /**
4352812a751SAndreas Gohr     * Return some aggregated statistics
4362812a751SAndreas Gohr     */
4372812a751SAndreas Gohr    function sql_aggregate($tlimit){
4382812a751SAndreas Gohr        $data = array();
4392812a751SAndreas Gohr
4402812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
4412812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
4422812a751SAndreas Gohr                 WHERE $tlimit
4432812a751SAndreas Gohr                   AND ua_type = 'browser'
4442812a751SAndreas Gohr              GROUP BY ref_type";
4452812a751SAndreas Gohr        $result = $this->runSQL($sql);
4462812a751SAndreas Gohr
4472812a751SAndreas Gohr        foreach($result as $row){
4482812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
4492812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
4502812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
4512812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
4522812a751SAndreas Gohr        }
4532812a751SAndreas Gohr
4542812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
4552812a751SAndreas Gohr                       COUNT(session) as views,
4562812a751SAndreas Gohr                       COUNT(DISTINCT user) as users
4572812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
4582812a751SAndreas Gohr                 WHERE $tlimit
4592812a751SAndreas Gohr                   AND ua_type = 'browser'";
4602812a751SAndreas Gohr        $result = $this->runSQL($sql);
4612812a751SAndreas Gohr
462*75fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
4632812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
4642812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
4652812a751SAndreas Gohr
4662812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
4672812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
4682812a751SAndreas Gohr                 WHERE $tlimit
4692812a751SAndreas Gohr                   AND ua_type = 'robot'";
4702812a751SAndreas Gohr        $result = $this->runSQL($sql);
4712812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
4722812a751SAndreas Gohr
4732812a751SAndreas Gohr        return $data;
4742812a751SAndreas Gohr    }
4752812a751SAndreas Gohr
4762812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
4772812a751SAndreas Gohr        if($hours){
4782812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
4792812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
4802812a751SAndreas Gohr                           COUNT(session) as pageviews
4812812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
4822812a751SAndreas Gohr                     WHERE $tlimit
4832812a751SAndreas Gohr                       AND ua_type = 'browser'
4842812a751SAndreas Gohr                  GROUP BY HOUR(dt)
4852812a751SAndreas Gohr                  ORDER BY time";
4862812a751SAndreas Gohr        }else{
4872812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
4882812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
4892812a751SAndreas Gohr                           COUNT(session) as pageviews
4902812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
4912812a751SAndreas Gohr                     WHERE $tlimit
4922812a751SAndreas Gohr                       AND ua_type = 'browser'
4932812a751SAndreas Gohr                  GROUP BY DATE(dt)
4942812a751SAndreas Gohr                  ORDER BY time";
4952812a751SAndreas Gohr        }
4962812a751SAndreas Gohr        return $this->runSQL($sql);
4972812a751SAndreas Gohr    }
4982812a751SAndreas Gohr
49995eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
5002812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
50195eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
50295eb68e6SAndreas Gohr                 WHERE $tlimit
50395eb68e6SAndreas Gohr                   AND ua_type = 'browser'
50495eb68e6SAndreas Gohr              GROUP BY page
50595eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
50695eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
50795eb68e6SAndreas Gohr        return $this->runSQL($sql);
50895eb68e6SAndreas Gohr    }
50995eb68e6SAndreas Gohr
51095eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
5112812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
51295eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
51395eb68e6SAndreas Gohr                 WHERE $tlimit
51495eb68e6SAndreas Gohr                   AND ua_type = 'browser'
51595eb68e6SAndreas Gohr                   AND ref_type = 'external'
51695eb68e6SAndreas Gohr              GROUP BY ref_md5
51795eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
51895eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
51995eb68e6SAndreas Gohr        return $this->runSQL($sql);
52095eb68e6SAndreas Gohr    }
52195eb68e6SAndreas Gohr
52295eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
5232812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, B.code AS cflag, B.country
52495eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
52595eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
52695eb68e6SAndreas Gohr                 WHERE $tlimit
52795eb68e6SAndreas Gohr                   AND A.ip = B.ip
52895eb68e6SAndreas Gohr              GROUP BY B.country
52995eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
53095eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
53195eb68e6SAndreas Gohr        return $this->runSQL($sql);
53295eb68e6SAndreas Gohr    }
53395eb68e6SAndreas Gohr
534*75fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
535*75fa767dSAndreas Gohr        if($ext){
536*75fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
537*75fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
538*75fa767dSAndreas Gohr        }else{
539*75fa767dSAndreas Gohr            $grp = 'ua_info';
540*75fa767dSAndreas Gohr            $sel = 'ua_info';
541*75fa767dSAndreas Gohr        }
542*75fa767dSAndreas Gohr
543*75fa767dSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, $sel
544*75fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
545*75fa767dSAndreas Gohr                 WHERE $tlimit
546*75fa767dSAndreas Gohr                   AND ua_type = 'browser'
547*75fa767dSAndreas Gohr              GROUP BY $grp
548*75fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
549*75fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
550*75fa767dSAndreas Gohr        return $this->runSQL($sql);
551*75fa767dSAndreas Gohr    }
552*75fa767dSAndreas Gohr
553*75fa767dSAndreas Gohr
55495eb68e6SAndreas Gohr    /**
55595eb68e6SAndreas Gohr     * Builds a limit clause
55695eb68e6SAndreas Gohr     */
55795eb68e6SAndreas Gohr    function sql_limit($start,$limit){
55895eb68e6SAndreas Gohr        $start = (int) $start;
55995eb68e6SAndreas Gohr        $limit = (int) $limit;
56095eb68e6SAndreas Gohr        if($limit){
56195eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
56295eb68e6SAndreas Gohr        }elseif($start){
56395eb68e6SAndreas Gohr            return " OFFSET $start";
56495eb68e6SAndreas Gohr        }
56595eb68e6SAndreas Gohr        return '';
56695eb68e6SAndreas Gohr    }
5671878f16fSAndreas Gohr
5681878f16fSAndreas Gohr    /**
56914d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
5701878f16fSAndreas Gohr     */
57114d99ec0SAndreas Gohr    function dbLink(){
5721878f16fSAndreas Gohr        // connect to DB if needed
5731878f16fSAndreas Gohr        if(!$this->dblink){
5741878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
5751878f16fSAndreas Gohr                                          $this->getConf('db_user'),
5761878f16fSAndreas Gohr                                          $this->getConf('db_password'));
5771878f16fSAndreas Gohr            if(!$this->dblink){
5781878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
5791878f16fSAndreas Gohr                return null;
5801878f16fSAndreas Gohr            }
5811878f16fSAndreas Gohr            // set utf-8
5821878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
5831878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
5841878f16fSAndreas Gohr                return null;
5851878f16fSAndreas Gohr            }
5861878f16fSAndreas Gohr        }
58714d99ec0SAndreas Gohr        return $this->dblink;
58814d99ec0SAndreas Gohr    }
5891878f16fSAndreas Gohr
59014d99ec0SAndreas Gohr    /**
59114d99ec0SAndreas Gohr     * Simple function to run a DB query
59214d99ec0SAndreas Gohr     */
59314d99ec0SAndreas Gohr    function runSQL($sql_string) {
59414d99ec0SAndreas Gohr        $link = $this->dbLink();
59514d99ec0SAndreas Gohr
59614d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
59794171ff3SAndreas Gohr        if(!$result){
5982812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
5991878f16fSAndreas Gohr            return null;
6001878f16fSAndreas Gohr        }
6011878f16fSAndreas Gohr
6021878f16fSAndreas Gohr        $resultarray = array();
6031878f16fSAndreas Gohr
6041878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
6051878f16fSAndreas Gohr        if ($result != 1) {
6061878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
6071878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
6081878f16fSAndreas Gohr                $resultarray[]=$temparray;
6091878f16fSAndreas Gohr            }
6101878f16fSAndreas Gohr            mysql_free_result($result);
6111878f16fSAndreas Gohr        }
6121878f16fSAndreas Gohr
61314d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
61414d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
6151878f16fSAndreas Gohr        }
6161878f16fSAndreas Gohr
6171878f16fSAndreas Gohr        return $resultarray;
6181878f16fSAndreas Gohr    }
6191878f16fSAndreas Gohr
6201878f16fSAndreas Gohr    /**
62114d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
6221878f16fSAndreas Gohr     */
62314d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
62414d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
62514d99ec0SAndreas Gohr        $ua = strtolower($ua);
62614d99ec0SAndreas Gohr
62714d99ec0SAndreas Gohr        // common browsers
62814d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
62914d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
63014d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
63114d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
63214d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
63314d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
63414d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
63514d99ec0SAndreas Gohr
63614d99ec0SAndreas Gohr        $name = '';
63714d99ec0SAndreas Gohr        # IE ?
63814d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
63914d99ec0SAndreas Gohr            $type = 'browser';
64014d99ec0SAndreas Gohr            $ver  = $m[2];
64114d99ec0SAndreas Gohr            $name = 'msie';
64214d99ec0SAndreas Gohr        }
64314d99ec0SAndreas Gohr        # Firefox ?
64414d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
64514d99ec0SAndreas Gohr            $type = 'browser';
64614d99ec0SAndreas Gohr            $ver  = $m[1];
64714d99ec0SAndreas Gohr            $name = 'firefox';
64814d99ec0SAndreas Gohr        }
64914d99ec0SAndreas Gohr        # Subversion ?
65014d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
65114d99ec0SAndreas Gohr            $type = 'rcs';
65214d99ec0SAndreas Gohr            $ver  = $m[1];
65314d99ec0SAndreas Gohr            $name = 'svn';
65414d99ec0SAndreas Gohr        }
65514d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
65614d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
65714d99ec0SAndreas Gohr            $type = 'browser';
65814d99ec0SAndreas Gohr            $ver  = $m[1];
65914d99ec0SAndreas Gohr            $name = 'netscape';
66014d99ec0SAndreas Gohr        }
66114d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
66214d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
66314d99ec0SAndreas Gohr            $type = 'browser';
66414d99ec0SAndreas Gohr            $ver  = $m[2];
66514d99ec0SAndreas Gohr            $name = 'netscape';
66614d99ec0SAndreas Gohr        }else{
66714d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
66814d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
66914d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
67014d99ec0SAndreas Gohr                    // it's a browser!
67114d99ec0SAndreas Gohr                    $type = 'browser';
67214d99ec0SAndreas Gohr                    $name = strtolower($regex);
67314d99ec0SAndreas Gohr                    break;
67414d99ec0SAndreas Gohr                }
67514d99ec0SAndreas Gohr            }
67614d99ec0SAndreas Gohr        }
67714d99ec0SAndreas Gohr
678*75fa767dSAndreas Gohr        // check versions for Safari and Opera
679*75fa767dSAndreas Gohr        if($name == 'safari'){
680*75fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
681*75fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
682*75fa767dSAndreas Gohr            }
683*75fa767dSAndreas Gohr        }elseif($name == 'opera'){
684*75fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
685*75fa767dSAndreas Gohr                $ver = $match[1];
686*75fa767dSAndreas Gohr            }
687*75fa767dSAndreas Gohr        }
688*75fa767dSAndreas Gohr
689*75fa767dSAndreas Gohr
69014d99ec0SAndreas Gohr        // check OS for browsers
69114d99ec0SAndreas Gohr        if($type == 'browser'){
69214d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
69314d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
69414d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
69514d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
69614d99ec0SAndreas Gohr                    break;
69714d99ec0SAndreas Gohr                }
69814d99ec0SAndreas Gohr            }
69914d99ec0SAndreas Gohr
70014d99ec0SAndreas Gohr        }
70114d99ec0SAndreas Gohr
70214d99ec0SAndreas Gohr        // are we done now?
70314d99ec0SAndreas Gohr        if($name) return $name;
70414d99ec0SAndreas Gohr
70514d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
70614d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
70714d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
70814d99ec0SAndreas Gohr                    // it's a robot!
70914d99ec0SAndreas Gohr                    $type = 'robot';
71014d99ec0SAndreas Gohr                    return strtolower($regex);
71114d99ec0SAndreas Gohr            }
71214d99ec0SAndreas Gohr        }
71314d99ec0SAndreas Gohr
71414d99ec0SAndreas Gohr        // dunno
7151878f16fSAndreas Gohr        return '';
7161878f16fSAndreas Gohr    }
7171878f16fSAndreas Gohr
7181878f16fSAndreas Gohr    /**
71914d99ec0SAndreas Gohr     *
72014d99ec0SAndreas Gohr     * @fixme: put search engine queries in seperate table here
72114d99ec0SAndreas Gohr     */
72214d99ec0SAndreas Gohr    function log_search($referer,&$type){
72314d99ec0SAndreas Gohr        $referer = strtr($referer,' +','__');
72414d99ec0SAndreas Gohr        $referer = strtolower($referer);
72514d99ec0SAndreas Gohr
72614d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
72714d99ec0SAndreas Gohr
72814d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
72914d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$referer)){
73014d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
73114d99ec0SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){
73214d99ec0SAndreas Gohr                    // it's a search engine!
73314d99ec0SAndreas Gohr                    $type = 'search';
73414d99ec0SAndreas Gohr                    break;
73514d99ec0SAndreas Gohr                }
73614d99ec0SAndreas Gohr            }
73714d99ec0SAndreas Gohr        }
73814d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
73914d99ec0SAndreas Gohr
74014d99ec0SAndreas Gohr        #fixme now do the keyword magic!
74114d99ec0SAndreas Gohr    }
74214d99ec0SAndreas Gohr
74314d99ec0SAndreas Gohr    /**
74414d99ec0SAndreas Gohr     * Resolve IP to country/city
74514d99ec0SAndreas Gohr     */
74614d99ec0SAndreas Gohr    function log_ip($ip){
74714d99ec0SAndreas Gohr        // check if IP already known and up-to-date
74814d99ec0SAndreas Gohr        $sql = "SELECT ip
74914d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
75014d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
75114d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
75214d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
75314d99ec0SAndreas Gohr        if($result[0]['ip']) return;
75414d99ec0SAndreas Gohr
75514d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
75614d99ec0SAndreas Gohr        $http->timeout = 10;
75714d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
75814d99ec0SAndreas Gohr
75914d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
76014d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
76114d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
76214d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
76314d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
76414d99ec0SAndreas Gohr            $ip      = addslashes($ip);
76514d99ec0SAndreas Gohr
76614d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
76714d99ec0SAndreas Gohr                        SET ip = '$ip',
76814d99ec0SAndreas Gohr                            country = '$country',
76914d99ec0SAndreas Gohr                            code    = '$code',
77014d99ec0SAndreas Gohr                            city    = '$city',
77114d99ec0SAndreas Gohr                            host    = '$host'";
77214d99ec0SAndreas Gohr            $this->runSQL($sql);
77314d99ec0SAndreas Gohr        }
77414d99ec0SAndreas Gohr    }
77514d99ec0SAndreas Gohr
77614d99ec0SAndreas Gohr    /**
7771878f16fSAndreas Gohr     * log a page access
7781878f16fSAndreas Gohr     *
7791878f16fSAndreas Gohr     * called from log.php
7801878f16fSAndreas Gohr     */
7811878f16fSAndreas Gohr    function log_access(){
78294171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
78394171ff3SAndreas Gohr
78414d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
78514d99ec0SAndreas Gohr
78614d99ec0SAndreas Gohr        // handle referer
78714d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
78814d99ec0SAndreas Gohr        if($referer){
78914d99ec0SAndreas Gohr            $ref     = addslashes($referer);
79014d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
79114d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
79214d99ec0SAndreas Gohr                $ref_type = 'internal';
79314d99ec0SAndreas Gohr            }else{
79414d99ec0SAndreas Gohr                $ref_type = 'external';
79514d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
79614d99ec0SAndreas Gohr            }
79714d99ec0SAndreas Gohr        }else{
79814d99ec0SAndreas Gohr            $ref      = '';
79914d99ec0SAndreas Gohr            $ref_md5  = '';
80014d99ec0SAndreas Gohr            $ref_type = '';
80114d99ec0SAndreas Gohr        }
80214d99ec0SAndreas Gohr
80314d99ec0SAndreas Gohr        // handle user agent
80414d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
80514d99ec0SAndreas Gohr
80614d99ec0SAndreas Gohr        $ua      = addslashes($agent);
80714d99ec0SAndreas Gohr        $ua_type = '';
80814d99ec0SAndreas Gohr        $ua_ver  = '';
80914d99ec0SAndreas Gohr        $os      = '';
81014d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
81114d99ec0SAndreas Gohr
8121878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
8131878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
8141878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
8151878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
8161878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
8171878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
818*75fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
8191878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
8201878f16fSAndreas Gohr        $session = addslashes(session_id());
8211878f16fSAndreas Gohr
82294171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
823*75fa767dSAndreas Gohr                    SET dt       = NOW(),
824*75fa767dSAndreas Gohr                        page     = '$page',
8251878f16fSAndreas Gohr                        ip       = '$ip',
8261878f16fSAndreas Gohr                        ua       = '$ua',
8271878f16fSAndreas Gohr                        ua_info  = '$ua_info',
82814d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
82914d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
83014d99ec0SAndreas Gohr                        os       = '$os',
8311878f16fSAndreas Gohr                        ref      = '$ref',
83294171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
83314d99ec0SAndreas Gohr                        ref_type = '$ref_type',
8341878f16fSAndreas Gohr                        screen_x = '$sx',
8351878f16fSAndreas Gohr                        screen_y = '$sy',
8361878f16fSAndreas Gohr                        view_x   = '$vx',
8371878f16fSAndreas Gohr                        view_y   = '$vy',
838*75fa767dSAndreas Gohr                        js       = '$js',
8391878f16fSAndreas Gohr                        user     = '$user',
8401878f16fSAndreas Gohr                        session  = '$session'";
8411878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
8421878f16fSAndreas Gohr        if(is_null($ok)){
8431878f16fSAndreas Gohr            global $MSG;
8441878f16fSAndreas Gohr            print_r($MSG);
8451878f16fSAndreas Gohr        }
84614d99ec0SAndreas Gohr
84714d99ec0SAndreas Gohr        // resolve the IP
84814d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
8491878f16fSAndreas Gohr    }
8501878f16fSAndreas Gohr
8511878f16fSAndreas Gohr    /**
8521878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
8531878f16fSAndreas Gohr     *
8541878f16fSAndreas Gohr     * @called from log.php
8551878f16fSAndreas Gohr     *
8561878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
8571878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
8581878f16fSAndreas Gohr     */
8591878f16fSAndreas Gohr    function sendGIF(){
8601878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
8611878f16fSAndreas Gohr        header('Content-Type: image/gif');
8621878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
8631878f16fSAndreas Gohr        header('Connection: Close');
8641878f16fSAndreas Gohr        print $img;
8651878f16fSAndreas Gohr        flush();
8661878f16fSAndreas Gohr        // Browser should drop connection after this
8671878f16fSAndreas Gohr        // Thinks it's got the whole image
8681878f16fSAndreas Gohr    }
8691878f16fSAndreas Gohr
8701878f16fSAndreas Gohr}
871