xref: /plugin/statistics/admin.php (revision bd4217d37e9e3e2daab36e6859def41cb66a20b7)
11878f16fSAndreas Gohr<?php
21878f16fSAndreas Gohr/**
31878f16fSAndreas Gohr * statistics plugin
41878f16fSAndreas Gohr *
51878f16fSAndreas Gohr * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
61878f16fSAndreas Gohr * @author     Andreas Gohr <gohr@cosmocode.de>
71878f16fSAndreas Gohr */
81878f16fSAndreas Gohr
91878f16fSAndreas Gohr// must be run within Dokuwiki
101878f16fSAndreas Gohrif(!defined('DOKU_INC')) die();
111878f16fSAndreas Gohr
121878f16fSAndreas Gohrif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
131878f16fSAndreas Gohrrequire_once(DOKU_PLUGIN.'admin.php');
141878f16fSAndreas Gohr
151878f16fSAndreas Gohr/**
161878f16fSAndreas Gohr * All DokuWiki plugins to extend the admin function
171878f16fSAndreas Gohr * need to inherit from this class
181878f16fSAndreas Gohr */
191878f16fSAndreas Gohrclass admin_plugin_statistics extends DokuWiki_Admin_Plugin {
201878f16fSAndreas Gohr    var $dblink = null;
21264f1744SAndreas Gohr    var $opt    = '';
22264f1744SAndreas Gohr    var $from   = '';
23264f1744SAndreas Gohr    var $to     = '';
2495eb68e6SAndreas Gohr    var $start  = '';
25264f1744SAndreas Gohr    var $tlimit = '';
261878f16fSAndreas Gohr
271878f16fSAndreas Gohr    /**
281878f16fSAndreas Gohr     * return some info
291878f16fSAndreas Gohr     */
301878f16fSAndreas Gohr    function getInfo(){
311878f16fSAndreas Gohr        return confToHash(dirname(__FILE__).'/info.txt');
321878f16fSAndreas Gohr    }
331878f16fSAndreas Gohr
341878f16fSAndreas Gohr    /**
351878f16fSAndreas Gohr     * Access for managers allowed
361878f16fSAndreas Gohr     */
371878f16fSAndreas Gohr    function forAdminOnly(){
381878f16fSAndreas Gohr        return false;
391878f16fSAndreas Gohr    }
401878f16fSAndreas Gohr
411878f16fSAndreas Gohr    /**
421878f16fSAndreas Gohr     * return sort order for position in admin menu
431878f16fSAndreas Gohr     */
441878f16fSAndreas Gohr    function getMenuSort() {
4514d99ec0SAndreas Gohr        return 150;
461878f16fSAndreas Gohr    }
471878f16fSAndreas Gohr
481878f16fSAndreas Gohr    /**
491878f16fSAndreas Gohr     * handle user request
501878f16fSAndreas Gohr     */
511878f16fSAndreas Gohr    function handle() {
52264f1744SAndreas Gohr        $this->opt = preg_replace('/[^a-z]+/','',$_REQUEST['opt']);
5395eb68e6SAndreas Gohr
5495eb68e6SAndreas Gohr        $this->start = (int) $_REQUEST['s'];
5595eb68e6SAndreas Gohr
56264f1744SAndreas Gohr        // fixme add better sanity checking here:
57264f1744SAndreas Gohr        $this->from = preg_replace('/[^\d\-]+/','',$_REQUEST['f']);
58264f1744SAndreas Gohr        $this->to = preg_replace('/[^\d\-]+/','',$_REQUEST['t']);
59264f1744SAndreas Gohr        if(!$this->from) $this->from = date('Y-m-d');
60264f1744SAndreas Gohr        if(!$this->to) $this->to     = date('Y-m-d');
61264f1744SAndreas Gohr
62264f1744SAndreas Gohr        //setup limit clause
63264f1744SAndreas Gohr        if($this->from != $this->to){
64264f1744SAndreas Gohr            $this->tlimit = "DATE(A.dt) >= DATE('".$this->from."') AND DATE(A.dt) <= DATE('".$this->to."')";
65264f1744SAndreas Gohr        }else{
66264f1744SAndreas Gohr            $this->tlimit = "DATE(A.dt) = DATE('".$this->from."')";
67264f1744SAndreas Gohr        }
681878f16fSAndreas Gohr    }
691878f16fSAndreas Gohr
701878f16fSAndreas Gohr    /**
7194171ff3SAndreas Gohr     * fixme build statistics here
721878f16fSAndreas Gohr     */
731878f16fSAndreas Gohr    function html() {
749da6395dSAndreas Gohr        $this->html_toc();
75264f1744SAndreas Gohr        echo '<h1>Access Statistics</h1>';
76264f1744SAndreas Gohr        $this->html_timeselect();
77264f1744SAndreas Gohr
78264f1744SAndreas Gohr        switch($this->opt){
799da6395dSAndreas Gohr            case 'country':
809da6395dSAndreas Gohr                $this->html_country();
819da6395dSAndreas Gohr                break;
829da6395dSAndreas Gohr            case 'page':
839da6395dSAndreas Gohr                $this->html_page();
849da6395dSAndreas Gohr                break;
8575fa767dSAndreas Gohr            case 'browser':
8675fa767dSAndreas Gohr                $this->html_browser();
8775fa767dSAndreas Gohr                break;
88*bd4217d3SAndreas Gohr            case 'os':
89*bd4217d3SAndreas Gohr                $this->html_os();
90*bd4217d3SAndreas Gohr                break;
919da6395dSAndreas Gohr            case 'referer':
929da6395dSAndreas Gohr                $this->html_referer();
939da6395dSAndreas Gohr                break;
9414d99ec0SAndreas Gohr            default:
959da6395dSAndreas Gohr                $this->html_dashboard();
9614d99ec0SAndreas Gohr        }
9714d99ec0SAndreas Gohr    }
9814d99ec0SAndreas Gohr
999da6395dSAndreas Gohr    function html_toc(){
1009da6395dSAndreas Gohr        echo '<div class="toc">';
1019da6395dSAndreas Gohr        echo '<div class="tocheader toctoggle" id="toc__header">';
1029da6395dSAndreas Gohr        echo 'Detailed Statistics';
1039da6395dSAndreas Gohr        echo '</div>';
1049da6395dSAndreas Gohr        echo '<div id="toc__inside">';
1059da6395dSAndreas Gohr        echo '<ul class="toc">';
1069da6395dSAndreas Gohr
1079da6395dSAndreas Gohr        echo '<li><div class="li">';
1089da6395dSAndreas 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>';
1099da6395dSAndreas Gohr        echo '</div></li>';
1109da6395dSAndreas Gohr
1119da6395dSAndreas Gohr        echo '<li><div class="li">';
1129da6395dSAndreas 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>';
1139da6395dSAndreas Gohr        echo '</div></li>';
1149da6395dSAndreas Gohr
1159da6395dSAndreas Gohr        echo '<li><div class="li">';
1169da6395dSAndreas 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>';
1179da6395dSAndreas Gohr        echo '</div></li>';
1189da6395dSAndreas Gohr
1199da6395dSAndreas Gohr        echo '<li><div class="li">';
12075fa767dSAndreas 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>';
12175fa767dSAndreas Gohr        echo '</div></li>';
12275fa767dSAndreas Gohr
12375fa767dSAndreas Gohr        echo '<li><div class="li">';
124*bd4217d3SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=os&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$this->start.'">Operating Systems</a>';
125*bd4217d3SAndreas Gohr        echo '</div></li>';
126*bd4217d3SAndreas Gohr
127*bd4217d3SAndreas Gohr        echo '<li><div class="li">';
1289da6395dSAndreas 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>';
1299da6395dSAndreas Gohr        echo '</div></li>';
1309da6395dSAndreas Gohr
1319da6395dSAndreas Gohr        echo '</ul>';
1329da6395dSAndreas Gohr        echo '</div>';
1339da6395dSAndreas Gohr        echo '</div>';
1349da6395dSAndreas Gohr    }
1359da6395dSAndreas Gohr
136264f1744SAndreas Gohr    /**
137264f1744SAndreas Gohr     * Print the time selection menu
138264f1744SAndreas Gohr     */
13914d99ec0SAndreas Gohr    function html_timeselect(){
140264f1744SAndreas Gohr        $now   = date('Y-m-d');
141264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
142264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
143264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
14414d99ec0SAndreas Gohr
145264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
146264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
147264f1744SAndreas Gohr        echo '<ul>';
148264f1744SAndreas Gohr
149264f1744SAndreas Gohr        echo '<li>';
15095eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'&amp;s='.$this->start.'">';
151264f1744SAndreas Gohr        echo 'today';
152264f1744SAndreas Gohr        echo '</a>';
153264f1744SAndreas Gohr        echo '</li>';
154264f1744SAndreas Gohr
155264f1744SAndreas Gohr        echo '<li>';
15695eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'&amp;s='.$this->start.'">';
157264f1744SAndreas Gohr        echo 'yesterday';
158264f1744SAndreas Gohr        echo '</a>';
159264f1744SAndreas Gohr        echo '</li>';
160264f1744SAndreas Gohr
161264f1744SAndreas Gohr        echo '<li>';
16295eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'&amp;s='.$this->start.'">';
163264f1744SAndreas Gohr        echo 'last 7 days';
164264f1744SAndreas Gohr        echo '</a>';
165264f1744SAndreas Gohr        echo '</li>';
166264f1744SAndreas Gohr
167264f1744SAndreas Gohr        echo '<li>';
16895eb68e6SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'&amp;s='.$this->start.'">';
169264f1744SAndreas Gohr        echo 'last 30 days';
170264f1744SAndreas Gohr        echo '</a>';
171264f1744SAndreas Gohr        echo '</li>';
172264f1744SAndreas Gohr
173264f1744SAndreas Gohr        echo '</ul>';
174264f1744SAndreas Gohr
175264f1744SAndreas Gohr
176264f1744SAndreas Gohr        echo '<form action="" method="get">';
177264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
178264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
179264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
18095eb68e6SAndreas Gohr        echo '<input type="hidden" name="s" value="'.$this->start.'" />';
181264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
182264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
183264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
18414d99ec0SAndreas Gohr        echo '</form>';
185264f1744SAndreas Gohr
186264f1744SAndreas Gohr        echo '</div>';
18714d99ec0SAndreas Gohr    }
18814d99ec0SAndreas Gohr
18914d99ec0SAndreas Gohr
190f5f32cbfSAndreas Gohr    /**
191f5f32cbfSAndreas Gohr     * Print an introductionary screen
192f5f32cbfSAndreas Gohr     */
19314d99ec0SAndreas Gohr    function html_dashboard(){
1942812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
1952812a751SAndreas Gohr              choose a topic from the list.</p>';
1962812a751SAndreas Gohr
1972812a751SAndreas Gohr
198264f1744SAndreas Gohr        echo '<div class="plg_stats_dashboard">';
199264f1744SAndreas Gohr
2002812a751SAndreas Gohr        // general info
2012812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
2022812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2032812a751SAndreas Gohr        echo '<ul>';
2042812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views</li>';
2052812a751SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visitors (sessions)</li>';
2062812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
2072812a751SAndreas Gohr
2082812a751SAndreas Gohr        echo '</ul>';
2092812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2102812a751SAndreas Gohr        echo '</div>';
2112812a751SAndreas Gohr
21214d99ec0SAndreas Gohr
21387d5e44bSAndreas Gohr        // top pages today
214264f1744SAndreas Gohr        echo '<div>';
215264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
21695eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
2172812a751SAndreas Gohr        $this->html_resulttable($result);
218264f1744SAndreas Gohr        echo '</div>';
21987d5e44bSAndreas Gohr
22087d5e44bSAndreas Gohr        // top referer today
221264f1744SAndreas Gohr        echo '<div>';
222264f1744SAndreas Gohr        echo '<h2>Top incoming links</h2>';
22395eb68e6SAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,15);
2242812a751SAndreas Gohr        $this->html_resulttable($result);
225264f1744SAndreas Gohr        echo '</div>';
22654f6c432SAndreas Gohr
22754f6c432SAndreas Gohr        // top countries today
228264f1744SAndreas Gohr        echo '<div>';
229264f1744SAndreas Gohr        echo '<h2>Visitor\'s top countries</h2>';
23095eb68e6SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
23195eb68e6SAndreas Gohr//        $result = $this->sql_countries($this->tlimit,$this->start,15);
23295eb68e6SAndreas Gohr//        $this->html_resulttable($result,array('','Countries','Count'));
233264f1744SAndreas Gohr        echo '</div>';
234264f1744SAndreas Gohr
235264f1744SAndreas Gohr        echo '</div>';
23614d99ec0SAndreas Gohr    }
23714d99ec0SAndreas Gohr
2389da6395dSAndreas Gohr    function html_country(){
2399da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2409da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
241*bd4217d3SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2429da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
2432812a751SAndreas Gohr        $this->html_resulttable($result);
2449da6395dSAndreas Gohr        echo '</div>';
2459da6395dSAndreas Gohr    }
2469da6395dSAndreas Gohr
2479da6395dSAndreas Gohr    function html_page(){
2489da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2499da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
2509da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
2512812a751SAndreas Gohr        $this->html_resulttable($result);
2529da6395dSAndreas Gohr        echo '</div>';
2539da6395dSAndreas Gohr    }
2549da6395dSAndreas Gohr
25575fa767dSAndreas Gohr    function html_browser(){
25675fa767dSAndreas Gohr        echo '<div class="plg_stats_full">';
25775fa767dSAndreas Gohr        echo '<h2>Browser Shootout</h2>';
25875fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
25975fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
26075fa767dSAndreas Gohr        $this->html_resulttable($result);
26175fa767dSAndreas Gohr        echo '</div>';
26275fa767dSAndreas Gohr    }
26375fa767dSAndreas Gohr
264*bd4217d3SAndreas Gohr    function html_os(){
265*bd4217d3SAndreas Gohr        echo '<div class="plg_stats_full">';
266*bd4217d3SAndreas Gohr        echo '<h2>Operating Systems</h2>';
267*bd4217d3SAndreas Gohr//        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
268*bd4217d3SAndreas Gohr        $result = $this->sql_os($this->tlimit,$this->start,150,true);
269*bd4217d3SAndreas Gohr        $this->html_resulttable($result);
270*bd4217d3SAndreas Gohr        echo '</div>';
271*bd4217d3SAndreas Gohr    }
272*bd4217d3SAndreas Gohr
2739da6395dSAndreas Gohr    function html_referer(){
2749da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2759da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
2762812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2772812a751SAndreas Gohr
2782812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
2792812a751SAndreas Gohr
2802812a751SAndreas Gohr        printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
2812812a751SAndreas Gohr                %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
2822812a751SAndreas Gohr                links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
2832812a751SAndreas Gohr                $result['search'],(100*$result['search']/$all),$result['external'],
2842812a751SAndreas Gohr                (100*$result['external']/$all));
2852812a751SAndreas Gohr
2869da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
2872812a751SAndreas Gohr        $this->html_resulttable($result);
2889da6395dSAndreas Gohr        echo '</div>';
2899da6395dSAndreas Gohr    }
2909da6395dSAndreas Gohr
2919da6395dSAndreas Gohr
2929da6395dSAndreas Gohr
29314d99ec0SAndreas Gohr    /**
29414d99ec0SAndreas Gohr     * Display a result in a HTML table
29514d99ec0SAndreas Gohr     */
2962812a751SAndreas Gohr    function html_resulttable($result,$header=''){
29714d99ec0SAndreas Gohr        echo '<table>';
2982812a751SAndreas Gohr        if(is_array($header)){
29914d99ec0SAndreas Gohr            echo '<tr>';
30014d99ec0SAndreas Gohr            foreach($header as $h){
30114d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
30214d99ec0SAndreas Gohr            }
30314d99ec0SAndreas Gohr            echo '</tr>';
3042812a751SAndreas Gohr        }
30514d99ec0SAndreas Gohr
30614d99ec0SAndreas Gohr        foreach($result as $row){
30714d99ec0SAndreas Gohr            echo '<tr>';
30814d99ec0SAndreas Gohr            foreach($row as $k => $v){
3092812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
31014d99ec0SAndreas Gohr                if($k == 'page'){
31114d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
31214d99ec0SAndreas Gohr                    echo hsc($v);
31314d99ec0SAndreas Gohr                    echo '</a>';
31414d99ec0SAndreas Gohr                }elseif($k == 'url'){
31554f6c432SAndreas Gohr                    $url = hsc($v);
3162812a751SAndreas Gohr                    if(strlen($url) > 45){
3172812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
31854f6c432SAndreas Gohr                    }
31914d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
32054f6c432SAndreas Gohr                    echo $url;
32114d99ec0SAndreas Gohr                    echo '</a>';
32275fa767dSAndreas Gohr                }elseif($k == 'browser'){
32375fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
32475fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
32575fa767dSAndreas Gohr                }elseif($k == 'bflag'){
32675fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
32775fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
328*bd4217d3SAndreas Gohr                }elseif($k == 'os'){
329*bd4217d3SAndreas Gohr                    if(empty($v)){
330*bd4217d3SAndreas Gohr                        echo 'unknown';
331*bd4217d3SAndreas Gohr                    }else{
332*bd4217d3SAndreas Gohr                        include_once(dirname(__FILE__).'/inc/operating_systems.php');
333*bd4217d3SAndreas Gohr                        echo $OSHashLib[$v];
334*bd4217d3SAndreas Gohr                    }
335*bd4217d3SAndreas Gohr                }elseif($k == 'osflag'){
336*bd4217d3SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />';
33775fa767dSAndreas Gohr                }elseif($k == 'cflag'){
33875fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
33914d99ec0SAndreas Gohr                }elseif($k == 'html'){
34014d99ec0SAndreas Gohr                    echo $v;
34114d99ec0SAndreas Gohr                }else{
34214d99ec0SAndreas Gohr                    echo hsc($v);
34314d99ec0SAndreas Gohr                }
34414d99ec0SAndreas Gohr                echo '</td>';
34514d99ec0SAndreas Gohr            }
34614d99ec0SAndreas Gohr            echo '</tr>';
34714d99ec0SAndreas Gohr        }
34814d99ec0SAndreas Gohr        echo '</table>';
3491878f16fSAndreas Gohr    }
3501878f16fSAndreas Gohr
35195eb68e6SAndreas Gohr    /**
35295eb68e6SAndreas Gohr     * Create an image
35395eb68e6SAndreas Gohr     */
35495eb68e6SAndreas Gohr    function img_build($img){
35595eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
35695eb68e6SAndreas Gohr
35795eb68e6SAndreas Gohr        switch($img){
35895eb68e6SAndreas Gohr            case 'country':
35995eb68e6SAndreas Gohr                // build top countries + other
36095eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
36195eb68e6SAndreas Gohr                $data = array();
36295eb68e6SAndreas Gohr                $top = 0;
36395eb68e6SAndreas Gohr                foreach($result as $row){
36495eb68e6SAndreas Gohr                    if($top < 7){
36595eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
36695eb68e6SAndreas Gohr                    }else{
36795eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
36895eb68e6SAndreas Gohr                    }
36995eb68e6SAndreas Gohr                    $top++;
37095eb68e6SAndreas Gohr                }
37195eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
37295eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
37395eb68e6SAndreas Gohr                $pie->setProp("showval",false);
37495eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
37595eb68e6SAndreas Gohr                $pie->setProp("type","pie");
37695eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
37795eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
37895eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
37995eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
38095eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
38195eb68e6SAndreas Gohr                @$pie->graph();
38295eb68e6SAndreas Gohr                $pie->showGraph();
38395eb68e6SAndreas Gohr                break;
38475fa767dSAndreas Gohr            case 'browser':
38575fa767dSAndreas Gohr                // build top browsers + other
38675fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
38775fa767dSAndreas Gohr
38875fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
38975fa767dSAndreas Gohr                $data = array();
39075fa767dSAndreas Gohr                $top = 0;
39175fa767dSAndreas Gohr                foreach($result as $row){
39275fa767dSAndreas Gohr                    if($top < 5){
39375fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
39475fa767dSAndreas Gohr                    }else{
39575fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
39675fa767dSAndreas Gohr                    }
39775fa767dSAndreas Gohr                    $top++;
39875fa767dSAndreas Gohr                }
39975fa767dSAndreas Gohr                $pie = new AGC(300, 200);
40075fa767dSAndreas Gohr                $pie->setProp("showkey",true);
40175fa767dSAndreas Gohr                $pie->setProp("showval",false);
40275fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
40375fa767dSAndreas Gohr                $pie->setProp("type","pie");
40475fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
40575fa767dSAndreas Gohr                $pie->setProp("keysize",8);
40675fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
40775fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
40875fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
40975fa767dSAndreas Gohr                @$pie->graph();
41075fa767dSAndreas Gohr                $pie->showGraph();
41175fa767dSAndreas Gohr                break;
4122812a751SAndreas Gohr            case 'trend':
4132812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
4142812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
4152812a751SAndreas Gohr                $data1   = array();
4162812a751SAndreas Gohr                $data2   = array();
4172812a751SAndreas Gohr
4182812a751SAndreas Gohr                $graph = new AGC(400, 150);
4192812a751SAndreas Gohr                $graph->setProp("type","bar");
4202812a751SAndreas Gohr                $graph->setProp("showgrid",false);
4212812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
42275fa767dSAndreas Gohr
4232812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
4242812a751SAndreas Gohr                $graph->setColor('color',1,'red');
4252812a751SAndreas Gohr
4262812a751SAndreas Gohr                if($hours){
4272812a751SAndreas Gohr                    //preset $hours
4282812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
4292812a751SAndreas Gohr                        $data1[$i] = 0;
4302812a751SAndreas Gohr                        $data2[$i] = 0;
4312812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
4322812a751SAndreas Gohr                    }
4332812a751SAndreas Gohr                }else{
4342812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
4352812a751SAndreas Gohr                }
4362812a751SAndreas Gohr
4372812a751SAndreas Gohr                foreach($result as $row){
4382812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
4392812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
4402812a751SAndreas Gohr                }
4412812a751SAndreas Gohr
4422812a751SAndreas Gohr                foreach($data1 as $key => $val){
4432812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
4442812a751SAndreas Gohr                }
4452812a751SAndreas Gohr                foreach($data2 as $key => $val){
4462812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
4472812a751SAndreas Gohr                }
4482812a751SAndreas Gohr
4492812a751SAndreas Gohr                @$graph->graph();
4502812a751SAndreas Gohr                $graph->showGraph();
4512812a751SAndreas Gohr
45295eb68e6SAndreas Gohr            default:
45395eb68e6SAndreas Gohr                $this->sendGIF();
45495eb68e6SAndreas Gohr        }
45595eb68e6SAndreas Gohr    }
45695eb68e6SAndreas Gohr
45795eb68e6SAndreas Gohr
4582812a751SAndreas Gohr    /**
4592812a751SAndreas Gohr     * Return some aggregated statistics
4602812a751SAndreas Gohr     */
4612812a751SAndreas Gohr    function sql_aggregate($tlimit){
4622812a751SAndreas Gohr        $data = array();
4632812a751SAndreas Gohr
4642812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
4652812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
4662812a751SAndreas Gohr                 WHERE $tlimit
4672812a751SAndreas Gohr                   AND ua_type = 'browser'
4682812a751SAndreas Gohr              GROUP BY ref_type";
4692812a751SAndreas Gohr        $result = $this->runSQL($sql);
4702812a751SAndreas Gohr
4712812a751SAndreas Gohr        foreach($result as $row){
4722812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
4732812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
4742812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
4752812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
4762812a751SAndreas Gohr        }
4772812a751SAndreas Gohr
4782812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
4792812a751SAndreas Gohr                       COUNT(session) as views,
4802812a751SAndreas Gohr                       COUNT(DISTINCT user) as users
4812812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
4822812a751SAndreas Gohr                 WHERE $tlimit
4832812a751SAndreas Gohr                   AND ua_type = 'browser'";
4842812a751SAndreas Gohr        $result = $this->runSQL($sql);
4852812a751SAndreas Gohr
48675fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
4872812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
4882812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
4892812a751SAndreas Gohr
4902812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
4912812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
4922812a751SAndreas Gohr                 WHERE $tlimit
4932812a751SAndreas Gohr                   AND ua_type = 'robot'";
4942812a751SAndreas Gohr        $result = $this->runSQL($sql);
4952812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
4962812a751SAndreas Gohr
4972812a751SAndreas Gohr        return $data;
4982812a751SAndreas Gohr    }
4992812a751SAndreas Gohr
500*bd4217d3SAndreas Gohr    /**
501*bd4217d3SAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
502*bd4217d3SAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
503*bd4217d3SAndreas Gohr     */
5042812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
5052812a751SAndreas Gohr        if($hours){
5062812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
5072812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
5082812a751SAndreas Gohr                           COUNT(session) as pageviews
5092812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
5102812a751SAndreas Gohr                     WHERE $tlimit
5112812a751SAndreas Gohr                       AND ua_type = 'browser'
5122812a751SAndreas Gohr                  GROUP BY HOUR(dt)
5132812a751SAndreas Gohr                  ORDER BY time";
5142812a751SAndreas Gohr        }else{
5152812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
5162812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
5172812a751SAndreas Gohr                           COUNT(session) as pageviews
5182812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
5192812a751SAndreas Gohr                     WHERE $tlimit
5202812a751SAndreas Gohr                       AND ua_type = 'browser'
5212812a751SAndreas Gohr                  GROUP BY DATE(dt)
5222812a751SAndreas Gohr                  ORDER BY time";
5232812a751SAndreas Gohr        }
5242812a751SAndreas Gohr        return $this->runSQL($sql);
5252812a751SAndreas Gohr    }
5262812a751SAndreas Gohr
52795eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
5282812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
52995eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
53095eb68e6SAndreas Gohr                 WHERE $tlimit
53195eb68e6SAndreas Gohr                   AND ua_type = 'browser'
53295eb68e6SAndreas Gohr              GROUP BY page
53395eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
53495eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
53595eb68e6SAndreas Gohr        return $this->runSQL($sql);
53695eb68e6SAndreas Gohr    }
53795eb68e6SAndreas Gohr
53895eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
5392812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
54095eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
54195eb68e6SAndreas Gohr                 WHERE $tlimit
54295eb68e6SAndreas Gohr                   AND ua_type = 'browser'
54395eb68e6SAndreas Gohr                   AND ref_type = 'external'
54495eb68e6SAndreas Gohr              GROUP BY ref_md5
54595eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
54695eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
54795eb68e6SAndreas Gohr        return $this->runSQL($sql);
54895eb68e6SAndreas Gohr    }
54995eb68e6SAndreas Gohr
55095eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
551*bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
55295eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
55395eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
55495eb68e6SAndreas Gohr                 WHERE $tlimit
55595eb68e6SAndreas Gohr                   AND A.ip = B.ip
55695eb68e6SAndreas Gohr              GROUP BY B.country
55795eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
55895eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
55995eb68e6SAndreas Gohr        return $this->runSQL($sql);
56095eb68e6SAndreas Gohr    }
56195eb68e6SAndreas Gohr
56275fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
56375fa767dSAndreas Gohr        if($ext){
56475fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
56575fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
56675fa767dSAndreas Gohr        }else{
56775fa767dSAndreas Gohr            $grp = 'ua_info';
56875fa767dSAndreas Gohr            $sel = 'ua_info';
56975fa767dSAndreas Gohr        }
57075fa767dSAndreas Gohr
571*bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
57275fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
57375fa767dSAndreas Gohr                 WHERE $tlimit
57475fa767dSAndreas Gohr                   AND ua_type = 'browser'
57575fa767dSAndreas Gohr              GROUP BY $grp
57675fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
57775fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
57875fa767dSAndreas Gohr        return $this->runSQL($sql);
57975fa767dSAndreas Gohr    }
58075fa767dSAndreas Gohr
581*bd4217d3SAndreas Gohr    function sql_os($tlimit,$start=0,$limit=20){
582*bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
583*bd4217d3SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
584*bd4217d3SAndreas Gohr                 WHERE $tlimit
585*bd4217d3SAndreas Gohr                   AND ua_type = 'browser'
586*bd4217d3SAndreas Gohr              GROUP BY os
587*bd4217d3SAndreas Gohr              ORDER BY cnt DESC, os".
588*bd4217d3SAndreas Gohr              $this->sql_limit($start,$limit);
589*bd4217d3SAndreas Gohr        return $this->runSQL($sql);
590*bd4217d3SAndreas Gohr    }
591*bd4217d3SAndreas Gohr
59275fa767dSAndreas Gohr
59395eb68e6SAndreas Gohr    /**
59495eb68e6SAndreas Gohr     * Builds a limit clause
59595eb68e6SAndreas Gohr     */
59695eb68e6SAndreas Gohr    function sql_limit($start,$limit){
59795eb68e6SAndreas Gohr        $start = (int) $start;
59895eb68e6SAndreas Gohr        $limit = (int) $limit;
59995eb68e6SAndreas Gohr        if($limit){
60095eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
60195eb68e6SAndreas Gohr        }elseif($start){
60295eb68e6SAndreas Gohr            return " OFFSET $start";
60395eb68e6SAndreas Gohr        }
60495eb68e6SAndreas Gohr        return '';
60595eb68e6SAndreas Gohr    }
6061878f16fSAndreas Gohr
6071878f16fSAndreas Gohr    /**
60814d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
6091878f16fSAndreas Gohr     */
61014d99ec0SAndreas Gohr    function dbLink(){
6111878f16fSAndreas Gohr        // connect to DB if needed
6121878f16fSAndreas Gohr        if(!$this->dblink){
6131878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
6141878f16fSAndreas Gohr                                          $this->getConf('db_user'),
6151878f16fSAndreas Gohr                                          $this->getConf('db_password'));
6161878f16fSAndreas Gohr            if(!$this->dblink){
6171878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
6181878f16fSAndreas Gohr                return null;
6191878f16fSAndreas Gohr            }
6201878f16fSAndreas Gohr            // set utf-8
6211878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
6221878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
6231878f16fSAndreas Gohr                return null;
6241878f16fSAndreas Gohr            }
6251878f16fSAndreas Gohr        }
62614d99ec0SAndreas Gohr        return $this->dblink;
62714d99ec0SAndreas Gohr    }
6281878f16fSAndreas Gohr
62914d99ec0SAndreas Gohr    /**
63014d99ec0SAndreas Gohr     * Simple function to run a DB query
63114d99ec0SAndreas Gohr     */
63214d99ec0SAndreas Gohr    function runSQL($sql_string) {
63314d99ec0SAndreas Gohr        $link = $this->dbLink();
63414d99ec0SAndreas Gohr
63514d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
63694171ff3SAndreas Gohr        if(!$result){
6372812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
6381878f16fSAndreas Gohr            return null;
6391878f16fSAndreas Gohr        }
6401878f16fSAndreas Gohr
6411878f16fSAndreas Gohr        $resultarray = array();
6421878f16fSAndreas Gohr
6431878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
6441878f16fSAndreas Gohr        if ($result != 1) {
6451878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
6461878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
6471878f16fSAndreas Gohr                $resultarray[]=$temparray;
6481878f16fSAndreas Gohr            }
6491878f16fSAndreas Gohr            mysql_free_result($result);
6501878f16fSAndreas Gohr        }
6511878f16fSAndreas Gohr
65214d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
65314d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
6541878f16fSAndreas Gohr        }
6551878f16fSAndreas Gohr
6561878f16fSAndreas Gohr        return $resultarray;
6571878f16fSAndreas Gohr    }
6581878f16fSAndreas Gohr
6591878f16fSAndreas Gohr    /**
66014d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
6611878f16fSAndreas Gohr     */
66214d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
66314d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
66414d99ec0SAndreas Gohr        $ua = strtolower($ua);
66514d99ec0SAndreas Gohr
66614d99ec0SAndreas Gohr        // common browsers
66714d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
66814d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
66914d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
67014d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
67114d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
67214d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
67314d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
67414d99ec0SAndreas Gohr
67514d99ec0SAndreas Gohr        $name = '';
67614d99ec0SAndreas Gohr        # IE ?
67714d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
67814d99ec0SAndreas Gohr            $type = 'browser';
67914d99ec0SAndreas Gohr            $ver  = $m[2];
68014d99ec0SAndreas Gohr            $name = 'msie';
68114d99ec0SAndreas Gohr        }
68214d99ec0SAndreas Gohr        # Firefox ?
68314d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
68414d99ec0SAndreas Gohr            $type = 'browser';
68514d99ec0SAndreas Gohr            $ver  = $m[1];
68614d99ec0SAndreas Gohr            $name = 'firefox';
68714d99ec0SAndreas Gohr        }
68814d99ec0SAndreas Gohr        # Subversion ?
68914d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
69014d99ec0SAndreas Gohr            $type = 'rcs';
69114d99ec0SAndreas Gohr            $ver  = $m[1];
69214d99ec0SAndreas Gohr            $name = 'svn';
69314d99ec0SAndreas Gohr        }
69414d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
69514d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
69614d99ec0SAndreas Gohr            $type = 'browser';
69714d99ec0SAndreas Gohr            $ver  = $m[1];
69814d99ec0SAndreas Gohr            $name = 'netscape';
69914d99ec0SAndreas Gohr        }
70014d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
70114d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
70214d99ec0SAndreas Gohr            $type = 'browser';
70314d99ec0SAndreas Gohr            $ver  = $m[2];
70414d99ec0SAndreas Gohr            $name = 'netscape';
70514d99ec0SAndreas Gohr        }else{
70614d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
70714d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
70814d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
70914d99ec0SAndreas Gohr                    // it's a browser!
71014d99ec0SAndreas Gohr                    $type = 'browser';
71114d99ec0SAndreas Gohr                    $name = strtolower($regex);
71214d99ec0SAndreas Gohr                    break;
71314d99ec0SAndreas Gohr                }
71414d99ec0SAndreas Gohr            }
71514d99ec0SAndreas Gohr        }
71614d99ec0SAndreas Gohr
71775fa767dSAndreas Gohr        // check versions for Safari and Opera
71875fa767dSAndreas Gohr        if($name == 'safari'){
71975fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
72075fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
72175fa767dSAndreas Gohr            }
72275fa767dSAndreas Gohr        }elseif($name == 'opera'){
72375fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
72475fa767dSAndreas Gohr                $ver = $match[1];
72575fa767dSAndreas Gohr            }
72675fa767dSAndreas Gohr        }
72775fa767dSAndreas Gohr
72875fa767dSAndreas Gohr
72914d99ec0SAndreas Gohr        // check OS for browsers
73014d99ec0SAndreas Gohr        if($type == 'browser'){
73114d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
73214d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
73314d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
73414d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
73514d99ec0SAndreas Gohr                    break;
73614d99ec0SAndreas Gohr                }
73714d99ec0SAndreas Gohr            }
73814d99ec0SAndreas Gohr
73914d99ec0SAndreas Gohr        }
74014d99ec0SAndreas Gohr
74114d99ec0SAndreas Gohr        // are we done now?
74214d99ec0SAndreas Gohr        if($name) return $name;
74314d99ec0SAndreas Gohr
74414d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
74514d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
74614d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
74714d99ec0SAndreas Gohr                    // it's a robot!
74814d99ec0SAndreas Gohr                    $type = 'robot';
74914d99ec0SAndreas Gohr                    return strtolower($regex);
75014d99ec0SAndreas Gohr            }
75114d99ec0SAndreas Gohr        }
75214d99ec0SAndreas Gohr
75314d99ec0SAndreas Gohr        // dunno
7541878f16fSAndreas Gohr        return '';
7551878f16fSAndreas Gohr    }
7561878f16fSAndreas Gohr
7571878f16fSAndreas Gohr    /**
75814d99ec0SAndreas Gohr     *
75914d99ec0SAndreas Gohr     * @fixme: put search engine queries in seperate table here
76014d99ec0SAndreas Gohr     */
76114d99ec0SAndreas Gohr    function log_search($referer,&$type){
76214d99ec0SAndreas Gohr        $referer = strtr($referer,' +','__');
76314d99ec0SAndreas Gohr        $referer = strtolower($referer);
76414d99ec0SAndreas Gohr
76514d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
76614d99ec0SAndreas Gohr
76714d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
76814d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$referer)){
76914d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
77014d99ec0SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$referer)){
77114d99ec0SAndreas Gohr                    // it's a search engine!
77214d99ec0SAndreas Gohr                    $type = 'search';
77314d99ec0SAndreas Gohr                    break;
77414d99ec0SAndreas Gohr                }
77514d99ec0SAndreas Gohr            }
77614d99ec0SAndreas Gohr        }
77714d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
77814d99ec0SAndreas Gohr
77914d99ec0SAndreas Gohr        #fixme now do the keyword magic!
78014d99ec0SAndreas Gohr    }
78114d99ec0SAndreas Gohr
78214d99ec0SAndreas Gohr    /**
78314d99ec0SAndreas Gohr     * Resolve IP to country/city
78414d99ec0SAndreas Gohr     */
78514d99ec0SAndreas Gohr    function log_ip($ip){
78614d99ec0SAndreas Gohr        // check if IP already known and up-to-date
78714d99ec0SAndreas Gohr        $sql = "SELECT ip
78814d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
78914d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
79014d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
79114d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
79214d99ec0SAndreas Gohr        if($result[0]['ip']) return;
79314d99ec0SAndreas Gohr
79414d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
79514d99ec0SAndreas Gohr        $http->timeout = 10;
79614d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
79714d99ec0SAndreas Gohr
79814d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
79914d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
80014d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
80114d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
80214d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
80314d99ec0SAndreas Gohr            $ip      = addslashes($ip);
80414d99ec0SAndreas Gohr
80514d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
80614d99ec0SAndreas Gohr                        SET ip = '$ip',
80714d99ec0SAndreas Gohr                            country = '$country',
80814d99ec0SAndreas Gohr                            code    = '$code',
80914d99ec0SAndreas Gohr                            city    = '$city',
81014d99ec0SAndreas Gohr                            host    = '$host'";
81114d99ec0SAndreas Gohr            $this->runSQL($sql);
81214d99ec0SAndreas Gohr        }
81314d99ec0SAndreas Gohr    }
81414d99ec0SAndreas Gohr
81514d99ec0SAndreas Gohr    /**
8161878f16fSAndreas Gohr     * log a page access
8171878f16fSAndreas Gohr     *
8181878f16fSAndreas Gohr     * called from log.php
8191878f16fSAndreas Gohr     */
8201878f16fSAndreas Gohr    function log_access(){
82194171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
82294171ff3SAndreas Gohr
82314d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
82414d99ec0SAndreas Gohr
82514d99ec0SAndreas Gohr        // handle referer
82614d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
82714d99ec0SAndreas Gohr        if($referer){
82814d99ec0SAndreas Gohr            $ref     = addslashes($referer);
82914d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
83014d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
83114d99ec0SAndreas Gohr                $ref_type = 'internal';
83214d99ec0SAndreas Gohr            }else{
83314d99ec0SAndreas Gohr                $ref_type = 'external';
83414d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
83514d99ec0SAndreas Gohr            }
83614d99ec0SAndreas Gohr        }else{
83714d99ec0SAndreas Gohr            $ref      = '';
83814d99ec0SAndreas Gohr            $ref_md5  = '';
83914d99ec0SAndreas Gohr            $ref_type = '';
84014d99ec0SAndreas Gohr        }
84114d99ec0SAndreas Gohr
84214d99ec0SAndreas Gohr        // handle user agent
84314d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
84414d99ec0SAndreas Gohr
84514d99ec0SAndreas Gohr        $ua      = addslashes($agent);
84614d99ec0SAndreas Gohr        $ua_type = '';
84714d99ec0SAndreas Gohr        $ua_ver  = '';
84814d99ec0SAndreas Gohr        $os      = '';
84914d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
85014d99ec0SAndreas Gohr
8511878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
8521878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
8531878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
8541878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
8551878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
8561878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
85775fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
8581878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
8591878f16fSAndreas Gohr        $session = addslashes(session_id());
8601878f16fSAndreas Gohr
86194171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
86275fa767dSAndreas Gohr                    SET dt       = NOW(),
86375fa767dSAndreas Gohr                        page     = '$page',
8641878f16fSAndreas Gohr                        ip       = '$ip',
8651878f16fSAndreas Gohr                        ua       = '$ua',
8661878f16fSAndreas Gohr                        ua_info  = '$ua_info',
86714d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
86814d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
86914d99ec0SAndreas Gohr                        os       = '$os',
8701878f16fSAndreas Gohr                        ref      = '$ref',
87194171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
87214d99ec0SAndreas Gohr                        ref_type = '$ref_type',
8731878f16fSAndreas Gohr                        screen_x = '$sx',
8741878f16fSAndreas Gohr                        screen_y = '$sy',
8751878f16fSAndreas Gohr                        view_x   = '$vx',
8761878f16fSAndreas Gohr                        view_y   = '$vy',
87775fa767dSAndreas Gohr                        js       = '$js',
8781878f16fSAndreas Gohr                        user     = '$user',
8791878f16fSAndreas Gohr                        session  = '$session'";
8801878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
8811878f16fSAndreas Gohr        if(is_null($ok)){
8821878f16fSAndreas Gohr            global $MSG;
8831878f16fSAndreas Gohr            print_r($MSG);
8841878f16fSAndreas Gohr        }
88514d99ec0SAndreas Gohr
88614d99ec0SAndreas Gohr        // resolve the IP
88714d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
8881878f16fSAndreas Gohr    }
8891878f16fSAndreas Gohr
8901878f16fSAndreas Gohr    /**
8911878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
8921878f16fSAndreas Gohr     *
8931878f16fSAndreas Gohr     * @called from log.php
8941878f16fSAndreas Gohr     *
8951878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
8961878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
8971878f16fSAndreas Gohr     */
8981878f16fSAndreas Gohr    function sendGIF(){
8991878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
9001878f16fSAndreas Gohr        header('Content-Type: image/gif');
9011878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
9021878f16fSAndreas Gohr        header('Connection: Close');
9031878f16fSAndreas Gohr        print $img;
9041878f16fSAndreas Gohr        flush();
9051878f16fSAndreas Gohr        // Browser should drop connection after this
9061878f16fSAndreas Gohr        // Thinks it's got the whole image
9071878f16fSAndreas Gohr    }
9081878f16fSAndreas Gohr
9091878f16fSAndreas Gohr}
910