xref: /plugin/statistics/admin.php (revision 29dea504e04d11ce820fdf914c87636f52d1776a)
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        $this->start = (int) $_REQUEST['s'];
54e8699bceSAndreas Gohr        $this->setTimeframe($_REQUEST['f'],$_REQUEST['t']);
55e8699bceSAndreas Gohr    }
5695eb68e6SAndreas Gohr
57e8699bceSAndreas Gohr    /**
58e8699bceSAndreas Gohr     * set limit clause
59e8699bceSAndreas Gohr     */
60e8699bceSAndreas Gohr    function setTimeframe($from,$to){
61264f1744SAndreas Gohr        // fixme add better sanity checking here:
62e8699bceSAndreas Gohr        $from = preg_replace('/[^\d\-]+/','',$from);
63e8699bceSAndreas Gohr        $to   = preg_replace('/[^\d\-]+/','',$to);
64e8699bceSAndreas Gohr        if(!$from) $from = date('Y-m-d');
65e8699bceSAndreas Gohr        if(!$to)   $to   = date('Y-m-d');
66264f1744SAndreas Gohr
67264f1744SAndreas Gohr        //setup limit clause
68e8699bceSAndreas Gohr        if($from != $to){
69e8699bceSAndreas Gohr            $tlimit = "DATE(A.dt) >= DATE('".$from."') AND DATE(A.dt) <= DATE('".$to."')";
70264f1744SAndreas Gohr        }else{
71e8699bceSAndreas Gohr            $tlimit = "DATE(A.dt) = DATE('".$from."')";
72264f1744SAndreas Gohr        }
73e8699bceSAndreas Gohr        $this->tlimit = $tlimit;
74e8699bceSAndreas Gohr        $this->from   = $from;
75e8699bceSAndreas Gohr        $this->to     = $to;
761878f16fSAndreas Gohr    }
771878f16fSAndreas Gohr
781878f16fSAndreas Gohr    /**
7994171ff3SAndreas Gohr     * fixme build statistics here
801878f16fSAndreas Gohr     */
811878f16fSAndreas Gohr    function html() {
829da6395dSAndreas Gohr        $this->html_toc();
83264f1744SAndreas Gohr        echo '<h1>Access Statistics</h1>';
84264f1744SAndreas Gohr        $this->html_timeselect();
85264f1744SAndreas Gohr
86264f1744SAndreas Gohr        switch($this->opt){
879da6395dSAndreas Gohr            case 'country':
889da6395dSAndreas Gohr                $this->html_country();
899da6395dSAndreas Gohr                break;
909da6395dSAndreas Gohr            case 'page':
919da6395dSAndreas Gohr                $this->html_page();
929da6395dSAndreas Gohr                break;
9375fa767dSAndreas Gohr            case 'browser':
9475fa767dSAndreas Gohr                $this->html_browser();
9575fa767dSAndreas Gohr                break;
96bd4217d3SAndreas Gohr            case 'os':
97bd4217d3SAndreas Gohr                $this->html_os();
98bd4217d3SAndreas Gohr                break;
999da6395dSAndreas Gohr            case 'referer':
1009da6395dSAndreas Gohr                $this->html_referer();
1019da6395dSAndreas Gohr                break;
102e7a2f1e0SAndreas Gohr            case 'newreferer':
103e7a2f1e0SAndreas Gohr                $this->html_newreferer();
104e7a2f1e0SAndreas Gohr                break;
105e25286daSAndreas Gohr            case 'outlinks':
106e25286daSAndreas Gohr                $this->html_outlinks();
107e25286daSAndreas Gohr                break;
108c73e16f1SAndreas Gohr            case 'resolution':
109c73e16f1SAndreas Gohr                $this->html_resolution();
110c73e16f1SAndreas Gohr                break;
11112dcdeccSAndreas Gohr            case 'searchphrases':
11212dcdeccSAndreas Gohr                $this->html_searchphrases();
11312dcdeccSAndreas Gohr                break;
11412dcdeccSAndreas Gohr            case 'searchwords':
11512dcdeccSAndreas Gohr                $this->html_searchwords();
11612dcdeccSAndreas Gohr                break;
11712dcdeccSAndreas Gohr            case 'searchengines':
11812dcdeccSAndreas Gohr                $this->html_searchengines();
11912dcdeccSAndreas Gohr                break;
12014d99ec0SAndreas Gohr            default:
1219da6395dSAndreas Gohr                $this->html_dashboard();
12214d99ec0SAndreas Gohr        }
12314d99ec0SAndreas Gohr    }
12414d99ec0SAndreas Gohr
1259da6395dSAndreas Gohr    function html_toc(){
1269da6395dSAndreas Gohr        echo '<div class="toc">';
1279da6395dSAndreas Gohr        echo '<div class="tocheader toctoggle" id="toc__header">';
1289da6395dSAndreas Gohr        echo 'Detailed Statistics';
1299da6395dSAndreas Gohr        echo '</div>';
1309da6395dSAndreas Gohr        echo '<div id="toc__inside">';
1319da6395dSAndreas Gohr        echo '<ul class="toc">';
1329da6395dSAndreas Gohr
1339da6395dSAndreas Gohr        echo '<li><div class="li">';
1342507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=&amp;f='.$this->from.'&amp;t='.$this->to.'">Dashboard</a>';
1359da6395dSAndreas Gohr        echo '</div></li>';
1369da6395dSAndreas Gohr
1379da6395dSAndreas Gohr        echo '<li><div class="li">';
1382507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'">Pages</a>';
1399da6395dSAndreas Gohr        echo '</div></li>';
1409da6395dSAndreas Gohr
1419da6395dSAndreas Gohr        echo '<li><div class="li">';
1422507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=referer&amp;f='.$this->from.'&amp;t='.$this->to.'">Incoming Links</a>';
1439da6395dSAndreas Gohr        echo '</div></li>';
1449da6395dSAndreas Gohr
1459da6395dSAndreas Gohr        echo '<li><div class="li">';
1462507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'">New Incoming Links</a>';
147e7a2f1e0SAndreas Gohr        echo '</div></li>';
148e7a2f1e0SAndreas Gohr
149e7a2f1e0SAndreas Gohr        echo '<li><div class="li">';
150e25286daSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=outlinks&amp;f='.$this->from.'&amp;t='.$this->to.'">Outgoing Links</a>';
151e25286daSAndreas Gohr        echo '</div></li>';
152e25286daSAndreas Gohr
153e25286daSAndreas Gohr        echo '<li><div class="li">';
15412dcdeccSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchphrases&amp;f='.$this->from.'&amp;t='.$this->to.'">Search Phrases</a>';
15512dcdeccSAndreas Gohr        echo '</div></li>';
15612dcdeccSAndreas Gohr
15712dcdeccSAndreas Gohr        echo '<li><div class="li">';
15812dcdeccSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchwords&amp;f='.$this->from.'&amp;t='.$this->to.'">Search Words</a>';
15912dcdeccSAndreas Gohr        echo '</div></li>';
16012dcdeccSAndreas Gohr
16112dcdeccSAndreas Gohr        echo '<li><div class="li">';
16212dcdeccSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchengines&amp;f='.$this->from.'&amp;t='.$this->to.'">Search Engines</a>';
16312dcdeccSAndreas Gohr        echo '</div></li>';
16412dcdeccSAndreas Gohr
16512dcdeccSAndreas Gohr
16612dcdeccSAndreas Gohr        echo '<li><div class="li">';
1672507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=browser&amp;f='.$this->from.'&amp;t='.$this->to.'">Browsers</a>';
16875fa767dSAndreas Gohr        echo '</div></li>';
16975fa767dSAndreas Gohr
17075fa767dSAndreas Gohr        echo '<li><div class="li">';
1712507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=os&amp;f='.$this->from.'&amp;t='.$this->to.'">Operating Systems</a>';
172bd4217d3SAndreas Gohr        echo '</div></li>';
173bd4217d3SAndreas Gohr
174bd4217d3SAndreas Gohr        echo '<li><div class="li">';
1752507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=country&amp;f='.$this->from.'&amp;t='.$this->to.'">Countries</a>';
1769da6395dSAndreas Gohr        echo '</div></li>';
1779da6395dSAndreas Gohr
178c73e16f1SAndreas Gohr        echo '<li><div class="li">';
179c73e16f1SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=resolution&amp;f='.$this->from.'&amp;t='.$this->to.'">Resolution</a>';
180c73e16f1SAndreas Gohr        echo '</div></li>';
181c73e16f1SAndreas Gohr
1829da6395dSAndreas Gohr        echo '</ul>';
1839da6395dSAndreas Gohr        echo '</div>';
1849da6395dSAndreas Gohr        echo '</div>';
1859da6395dSAndreas Gohr    }
1869da6395dSAndreas Gohr
1872507f8e0SAndreas Gohr    function html_pager($limit,$next){
1882507f8e0SAndreas Gohr        echo '<div class="plg_stats_pager">';
1892507f8e0SAndreas Gohr
1902507f8e0SAndreas Gohr        if($this->start > 0){
1912507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
1922507f8e0SAndreas Gohr            echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$go.'" class="prev">previous page</a>';
1932507f8e0SAndreas Gohr        }
1942507f8e0SAndreas Gohr
1952507f8e0SAndreas Gohr        if($next){
1962507f8e0SAndreas Gohr            $go = $this->start + $limit;
1972507f8e0SAndreas Gohr            echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$this->from.'&amp;t='.$this->to.'&amp;s='.$go.'" class="next">next page</a>';
1982507f8e0SAndreas Gohr        }
1992507f8e0SAndreas Gohr        echo '</div>';
2002507f8e0SAndreas Gohr    }
2012507f8e0SAndreas Gohr
202264f1744SAndreas Gohr    /**
203264f1744SAndreas Gohr     * Print the time selection menu
204264f1744SAndreas Gohr     */
20514d99ec0SAndreas Gohr    function html_timeselect(){
206264f1744SAndreas Gohr        $now   = date('Y-m-d');
207264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
208264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
209264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
21014d99ec0SAndreas Gohr
211264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
212264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
213264f1744SAndreas Gohr        echo '<ul>';
214264f1744SAndreas Gohr
215264f1744SAndreas Gohr        echo '<li>';
2162507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'">';
217264f1744SAndreas Gohr        echo 'today';
218264f1744SAndreas Gohr        echo '</a>';
219264f1744SAndreas Gohr        echo '</li>';
220264f1744SAndreas Gohr
221264f1744SAndreas Gohr        echo '<li>';
2222507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'">';
223264f1744SAndreas Gohr        echo 'yesterday';
224264f1744SAndreas Gohr        echo '</a>';
225264f1744SAndreas Gohr        echo '</li>';
226264f1744SAndreas Gohr
227264f1744SAndreas Gohr        echo '<li>';
2282507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'">';
229264f1744SAndreas Gohr        echo 'last 7 days';
230264f1744SAndreas Gohr        echo '</a>';
231264f1744SAndreas Gohr        echo '</li>';
232264f1744SAndreas Gohr
233264f1744SAndreas Gohr        echo '<li>';
2342507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'">';
235264f1744SAndreas Gohr        echo 'last 30 days';
236264f1744SAndreas Gohr        echo '</a>';
237264f1744SAndreas Gohr        echo '</li>';
238264f1744SAndreas Gohr
239264f1744SAndreas Gohr        echo '</ul>';
240264f1744SAndreas Gohr
241264f1744SAndreas Gohr
242264f1744SAndreas Gohr        echo '<form action="" method="get">';
243264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
244264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
245264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
246264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
247264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
248264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
24914d99ec0SAndreas Gohr        echo '</form>';
250264f1744SAndreas Gohr
251264f1744SAndreas Gohr        echo '</div>';
25214d99ec0SAndreas Gohr    }
25314d99ec0SAndreas Gohr
25414d99ec0SAndreas Gohr
255f5f32cbfSAndreas Gohr    /**
256f5f32cbfSAndreas Gohr     * Print an introductionary screen
257f5f32cbfSAndreas Gohr     */
25814d99ec0SAndreas Gohr    function html_dashboard(){
2592812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
2602812a751SAndreas Gohr              choose a topic from the list.</p>';
2612812a751SAndreas Gohr
2622812a751SAndreas Gohr
263264f1744SAndreas Gohr        echo '<div class="plg_stats_dashboard">';
264264f1744SAndreas Gohr
2652812a751SAndreas Gohr        // general info
2662812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
2672812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2682812a751SAndreas Gohr        echo '<ul>';
2692812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views </li>';
2703c0acc14SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>';
2713c0acc14SAndreas Gohr        echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>';
2722812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
2732812a751SAndreas Gohr
2742812a751SAndreas Gohr        echo '</ul>';
2752812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2762812a751SAndreas Gohr        echo '</div>';
2772812a751SAndreas Gohr
27814d99ec0SAndreas Gohr
27987d5e44bSAndreas Gohr        // top pages today
280264f1744SAndreas Gohr        echo '<div>';
281264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
28295eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
2832812a751SAndreas Gohr        $this->html_resulttable($result);
2842507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
285264f1744SAndreas Gohr        echo '</div>';
28687d5e44bSAndreas Gohr
28787d5e44bSAndreas Gohr        // top referer today
288264f1744SAndreas Gohr        echo '<div>';
289e7a2f1e0SAndreas Gohr        echo '<h2>Newest incoming links</h2>';
290e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,15);
2912812a751SAndreas Gohr        $this->html_resulttable($result);
2922507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
293264f1744SAndreas Gohr        echo '</div>';
29454f6c432SAndreas Gohr
295*29dea504SAndreas Gohr        // top searches today
296264f1744SAndreas Gohr        echo '<div>';
297*29dea504SAndreas Gohr        echo '<h2>Top search phrases</h2>';
298*29dea504SAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,15);
299*29dea504SAndreas Gohr        $this->html_resulttable($result);
300*29dea504SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchphrases&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
301264f1744SAndreas Gohr        echo '</div>';
302264f1744SAndreas Gohr
303264f1744SAndreas Gohr        echo '</div>';
30414d99ec0SAndreas Gohr    }
30514d99ec0SAndreas Gohr
3069da6395dSAndreas Gohr    function html_country(){
3079da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3089da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
309bd4217d3SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
3109da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
3112507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3129da6395dSAndreas Gohr        echo '</div>';
3139da6395dSAndreas Gohr    }
3149da6395dSAndreas Gohr
3159da6395dSAndreas Gohr    function html_page(){
3169da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3179da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
3189da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
3192507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3209da6395dSAndreas Gohr        echo '</div>';
3219da6395dSAndreas Gohr    }
3229da6395dSAndreas Gohr
32375fa767dSAndreas Gohr    function html_browser(){
32475fa767dSAndreas Gohr        echo '<div class="plg_stats_full">';
32575fa767dSAndreas Gohr        echo '<h2>Browser Shootout</h2>';
32675fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
32775fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
3282507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
32975fa767dSAndreas Gohr        echo '</div>';
33075fa767dSAndreas Gohr    }
33175fa767dSAndreas Gohr
332bd4217d3SAndreas Gohr    function html_os(){
333bd4217d3SAndreas Gohr        echo '<div class="plg_stats_full">';
334bd4217d3SAndreas Gohr        echo '<h2>Operating Systems</h2>';
335bd4217d3SAndreas Gohr        $result = $this->sql_os($this->tlimit,$this->start,150,true);
3362507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
337bd4217d3SAndreas Gohr        echo '</div>';
338bd4217d3SAndreas Gohr    }
339bd4217d3SAndreas Gohr
3409da6395dSAndreas Gohr    function html_referer(){
3419da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3429da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
3432812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
3442812a751SAndreas Gohr
3452812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
3462812a751SAndreas Gohr
34794023548SAndreas Gohr        if($all){
3482812a751SAndreas Gohr            printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
3492812a751SAndreas Gohr                    %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
3502812a751SAndreas Gohr                    links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
3512812a751SAndreas Gohr                    $result['search'],(100*$result['search']/$all),$result['external'],
3522812a751SAndreas Gohr                    (100*$result['external']/$all));
35394023548SAndreas Gohr        }
3542812a751SAndreas Gohr
3559da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
3562507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3579da6395dSAndreas Gohr        echo '</div>';
3589da6395dSAndreas Gohr    }
3599da6395dSAndreas Gohr
360e7a2f1e0SAndreas Gohr    function html_newreferer(){
361e7a2f1e0SAndreas Gohr        echo '<div class="plg_stats_full">';
362e7a2f1e0SAndreas Gohr        echo '<h2>New Incoming Links</h2>';
363e7a2f1e0SAndreas Gohr        echo '<p>The following incoming links where first logged in the selected time frame,
364e7a2f1e0SAndreas Gohr              and have never been seen before.</p>';
365e7a2f1e0SAndreas Gohr
366e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,150);
3672507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
368e7a2f1e0SAndreas Gohr        echo '</div>';
369e7a2f1e0SAndreas Gohr    }
370e7a2f1e0SAndreas Gohr
371e25286daSAndreas Gohr    function html_outlinks(){
372e25286daSAndreas Gohr        echo '<div class="plg_stats_full">';
373e25286daSAndreas Gohr        echo '<h2>Outgoing Links</h2>';
374e25286daSAndreas Gohr
375e25286daSAndreas Gohr        $result = $this->sql_outlinks($this->tlimit,$this->start,150);
376e25286daSAndreas Gohr        $this->html_resulttable($result,'',150);
377e25286daSAndreas Gohr        echo '</div>';
378e25286daSAndreas Gohr    }
379e25286daSAndreas Gohr
38012dcdeccSAndreas Gohr    function html_searchphrases(){
38112dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
38212dcdeccSAndreas Gohr        echo '<h2>Search Phrases</h2>';
38312dcdeccSAndreas Gohr
38412dcdeccSAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,150);
38512dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
38612dcdeccSAndreas Gohr        echo '</div>';
38712dcdeccSAndreas Gohr    }
38812dcdeccSAndreas Gohr
38912dcdeccSAndreas Gohr    function html_searchwords(){
39012dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
39112dcdeccSAndreas Gohr        echo '<h2>Search Words</h2>';
39212dcdeccSAndreas Gohr
39312dcdeccSAndreas Gohr        $result = $this->sql_searchwords($this->tlimit,$this->start,150);
39412dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
39512dcdeccSAndreas Gohr        echo '</div>';
39612dcdeccSAndreas Gohr    }
39712dcdeccSAndreas Gohr
39812dcdeccSAndreas Gohr    function html_searchengines(){
39912dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
40012dcdeccSAndreas Gohr        echo '<h2>Search Engines</h2>';
40112dcdeccSAndreas Gohr
40212dcdeccSAndreas Gohr        $result = $this->sql_searchengines($this->tlimit,$this->start,150);
40312dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
40412dcdeccSAndreas Gohr        echo '</div>';
40512dcdeccSAndreas Gohr    }
40612dcdeccSAndreas Gohr
407e25286daSAndreas Gohr
408c73e16f1SAndreas Gohr    function html_resolution(){
409c73e16f1SAndreas Gohr        echo '<div class="plg_stats_full">';
410c73e16f1SAndreas Gohr        echo '<h2>Resolution</h2>';
411c73e16f1SAndreas Gohr        $result = $this->sql_resolution($this->tlimit,$this->start,150);
412c73e16f1SAndreas Gohr        $this->html_resulttable($result,'',150);
413c73e16f1SAndreas Gohr
414c73e16f1SAndreas Gohr        echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you
415c73e16f1SAndreas Gohr              much about about the real size of their browser windows. The graphic below shows the size distribution of
416c73e16f1SAndreas Gohr              the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged
417c73e16f1SAndreas Gohr              in all browsers. Because users may resize their browser window while browsing your site the statistics may
418c73e16f1SAndreas Gohr              be flawed. Take it with a grain of salt.</p>';
419c73e16f1SAndreas Gohr
420c73e16f1SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
421c73e16f1SAndreas Gohr        echo '</div>';
422c73e16f1SAndreas Gohr    }
4239da6395dSAndreas Gohr
4249da6395dSAndreas Gohr
42514d99ec0SAndreas Gohr    /**
42614d99ec0SAndreas Gohr     * Display a result in a HTML table
42714d99ec0SAndreas Gohr     */
4282507f8e0SAndreas Gohr    function html_resulttable($result,$header='',$pager=0){
42914d99ec0SAndreas Gohr        echo '<table>';
4302812a751SAndreas Gohr        if(is_array($header)){
43114d99ec0SAndreas Gohr            echo '<tr>';
43214d99ec0SAndreas Gohr            foreach($header as $h){
43314d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
43414d99ec0SAndreas Gohr            }
43514d99ec0SAndreas Gohr            echo '</tr>';
4362812a751SAndreas Gohr        }
43714d99ec0SAndreas Gohr
4382507f8e0SAndreas Gohr        $count = 0;
43914d99ec0SAndreas Gohr        foreach($result as $row){
44014d99ec0SAndreas Gohr            echo '<tr>';
44114d99ec0SAndreas Gohr            foreach($row as $k => $v){
4422812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
44314d99ec0SAndreas Gohr                if($k == 'page'){
44414d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
44514d99ec0SAndreas Gohr                    echo hsc($v);
44614d99ec0SAndreas Gohr                    echo '</a>';
44714d99ec0SAndreas Gohr                }elseif($k == 'url'){
44854f6c432SAndreas Gohr                    $url = hsc($v);
44983b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/','',$url);
4502812a751SAndreas Gohr                    if(strlen($url) > 45){
4512812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
45254f6c432SAndreas Gohr                    }
45314d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
45454f6c432SAndreas Gohr                    echo $url;
45514d99ec0SAndreas Gohr                    echo '</a>';
456*29dea504SAndreas Gohr                }elseif($k == 'lookup'){
457*29dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q='.rawurlencode($v).'">';
458*29dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/google.png" alt="lookup in Google" border="0" />';
459*29dea504SAndreas Gohr                    echo '</a> ';
460*29dea504SAndreas Gohr
461*29dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p='.rawurlencode($v).'">';
462*29dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/yahoo.png" alt="lookup in Yahoo" border="0" />';
463*29dea504SAndreas Gohr                    echo '</a> ';
464*29dea504SAndreas Gohr
465*29dea504SAndreas Gohr                    echo '<a href="http://search.msn.com/results.aspx?q='.rawurlencode($v).'">';
466*29dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/msn.png" alt="lookup in MSN Live" border="0" />';
467*29dea504SAndreas Gohr                    echo '</a> ';
468*29dea504SAndreas Gohr
46912dcdeccSAndreas Gohr                }elseif($k == 'engine'){
47012dcdeccSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/search_engines.php');
47112dcdeccSAndreas Gohr                    echo $SearchEnginesHashLib[$v];
47275fa767dSAndreas Gohr                }elseif($k == 'browser'){
47375fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
47475fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
47575fa767dSAndreas Gohr                }elseif($k == 'bflag'){
47675fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
47775fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
478bd4217d3SAndreas Gohr                }elseif($k == 'os'){
479bd4217d3SAndreas Gohr                    if(empty($v)){
480bd4217d3SAndreas Gohr                        echo 'unknown';
481bd4217d3SAndreas Gohr                    }else{
482bd4217d3SAndreas Gohr                        include_once(dirname(__FILE__).'/inc/operating_systems.php');
483bd4217d3SAndreas Gohr                        echo $OSHashLib[$v];
484bd4217d3SAndreas Gohr                    }
485bd4217d3SAndreas Gohr                }elseif($k == 'osflag'){
486bd4217d3SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />';
48775fa767dSAndreas Gohr                }elseif($k == 'cflag'){
48875fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
48914d99ec0SAndreas Gohr                }elseif($k == 'html'){
49014d99ec0SAndreas Gohr                    echo $v;
49114d99ec0SAndreas Gohr                }else{
49214d99ec0SAndreas Gohr                    echo hsc($v);
49314d99ec0SAndreas Gohr                }
49414d99ec0SAndreas Gohr                echo '</td>';
49514d99ec0SAndreas Gohr            }
49614d99ec0SAndreas Gohr            echo '</tr>';
4972507f8e0SAndreas Gohr
4982507f8e0SAndreas Gohr            if($pager && ($count == $pager)) break;
4992507f8e0SAndreas Gohr            $count++;
50014d99ec0SAndreas Gohr        }
50114d99ec0SAndreas Gohr        echo '</table>';
5022507f8e0SAndreas Gohr
5032507f8e0SAndreas Gohr        if($pager) $this->html_pager($pager,count($result) > $pager);
5041878f16fSAndreas Gohr    }
5051878f16fSAndreas Gohr
50695eb68e6SAndreas Gohr    /**
50795eb68e6SAndreas Gohr     * Create an image
50895eb68e6SAndreas Gohr     */
50995eb68e6SAndreas Gohr    function img_build($img){
51095eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
51195eb68e6SAndreas Gohr
51295eb68e6SAndreas Gohr        switch($img){
51395eb68e6SAndreas Gohr            case 'country':
51495eb68e6SAndreas Gohr                // build top countries + other
51595eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
51695eb68e6SAndreas Gohr                $data = array();
51795eb68e6SAndreas Gohr                $top = 0;
51895eb68e6SAndreas Gohr                foreach($result as $row){
51995eb68e6SAndreas Gohr                    if($top < 7){
52095eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
52195eb68e6SAndreas Gohr                    }else{
52295eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
52395eb68e6SAndreas Gohr                    }
52495eb68e6SAndreas Gohr                    $top++;
52595eb68e6SAndreas Gohr                }
52695eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
52795eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
52895eb68e6SAndreas Gohr                $pie->setProp("showval",false);
52995eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
53095eb68e6SAndreas Gohr                $pie->setProp("type","pie");
53195eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
53295eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
53395eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
53495eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
53595eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
53695eb68e6SAndreas Gohr                @$pie->graph();
53795eb68e6SAndreas Gohr                $pie->showGraph();
53895eb68e6SAndreas Gohr                break;
53975fa767dSAndreas Gohr            case 'browser':
54075fa767dSAndreas Gohr                // build top browsers + other
54175fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
54275fa767dSAndreas Gohr
54375fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
54475fa767dSAndreas Gohr                $data = array();
54575fa767dSAndreas Gohr                $top = 0;
54675fa767dSAndreas Gohr                foreach($result as $row){
54775fa767dSAndreas Gohr                    if($top < 5){
54875fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
54975fa767dSAndreas Gohr                    }else{
55075fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
55175fa767dSAndreas Gohr                    }
55275fa767dSAndreas Gohr                    $top++;
55375fa767dSAndreas Gohr                }
55475fa767dSAndreas Gohr                $pie = new AGC(300, 200);
55575fa767dSAndreas Gohr                $pie->setProp("showkey",true);
55675fa767dSAndreas Gohr                $pie->setProp("showval",false);
55775fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
55875fa767dSAndreas Gohr                $pie->setProp("type","pie");
55975fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
56075fa767dSAndreas Gohr                $pie->setProp("keysize",8);
56175fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
56275fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
56375fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
56475fa767dSAndreas Gohr                @$pie->graph();
56575fa767dSAndreas Gohr                $pie->showGraph();
56675fa767dSAndreas Gohr                break;
567c73e16f1SAndreas Gohr            case 'view':
568c73e16f1SAndreas Gohr
569c73e16f1SAndreas Gohr                $graph = new AGC(400, 200);
570c73e16f1SAndreas Gohr                $graph->setColor('color',0,'blue');
571c73e16f1SAndreas Gohr                $graph->setColor('color',1,'red');
572c73e16f1SAndreas Gohr                $graph->setProp("showkey",true);
573c73e16f1SAndreas Gohr                $graph->setProp("key",'view port width',0);
574c73e16f1SAndreas Gohr                $graph->setProp("key",'view port height',1);
575c73e16f1SAndreas Gohr
576c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,true);
577c73e16f1SAndreas Gohr                foreach($result as $row){
578c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_x'],0);
579c73e16f1SAndreas Gohr                }
580c73e16f1SAndreas Gohr
581c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,false);
582c73e16f1SAndreas Gohr                foreach($result as $row){
583c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_y'],1);
584c73e16f1SAndreas Gohr                }
585c73e16f1SAndreas Gohr
586c73e16f1SAndreas Gohr                @$graph->graph();
587c73e16f1SAndreas Gohr                $graph->showGraph();
588c73e16f1SAndreas Gohr
589c73e16f1SAndreas Gohr                break;
5902812a751SAndreas Gohr            case 'trend':
5912812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
5922812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
5932812a751SAndreas Gohr                $data1   = array();
5942812a751SAndreas Gohr                $data2   = array();
5952812a751SAndreas Gohr
5962812a751SAndreas Gohr                $graph = new AGC(400, 150);
5972812a751SAndreas Gohr                $graph->setProp("type","bar");
5982812a751SAndreas Gohr                $graph->setProp("showgrid",false);
5992812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
60075fa767dSAndreas Gohr
6012812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
6022812a751SAndreas Gohr                $graph->setColor('color',1,'red');
6033c0acc14SAndreas Gohr                $graph->setColor('color',2,'yellow');
6042812a751SAndreas Gohr
6052812a751SAndreas Gohr                if($hours){
6062812a751SAndreas Gohr                    //preset $hours
6072812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
6082812a751SAndreas Gohr                        $data1[$i] = 0;
6092812a751SAndreas Gohr                        $data2[$i] = 0;
6103c0acc14SAndreas Gohr                        $data3[$i] = 0;
6112812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
6122812a751SAndreas Gohr                    }
6132812a751SAndreas Gohr                }else{
6142812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
6152812a751SAndreas Gohr                }
6162812a751SAndreas Gohr
6172812a751SAndreas Gohr                foreach($result as $row){
6182812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
6192812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
6203c0acc14SAndreas Gohr                    $data3[$row['time']] = $row['visitors'];
6212812a751SAndreas Gohr                }
6222812a751SAndreas Gohr
6232812a751SAndreas Gohr                foreach($data1 as $key => $val){
6242812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
6252812a751SAndreas Gohr                }
6262812a751SAndreas Gohr                foreach($data2 as $key => $val){
6272812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
6282812a751SAndreas Gohr                }
6293c0acc14SAndreas Gohr                foreach($data3 as $key => $val){
6303c0acc14SAndreas Gohr                    $graph->addPoint($val,$key,2);
6313c0acc14SAndreas Gohr                }
6322812a751SAndreas Gohr
6332812a751SAndreas Gohr                @$graph->graph();
6342812a751SAndreas Gohr                $graph->showGraph();
6352812a751SAndreas Gohr
63695eb68e6SAndreas Gohr            default:
63795eb68e6SAndreas Gohr                $this->sendGIF();
63895eb68e6SAndreas Gohr        }
63995eb68e6SAndreas Gohr    }
64095eb68e6SAndreas Gohr
64195eb68e6SAndreas Gohr
6422812a751SAndreas Gohr    /**
6432812a751SAndreas Gohr     * Return some aggregated statistics
6442812a751SAndreas Gohr     */
6452812a751SAndreas Gohr    function sql_aggregate($tlimit){
6462812a751SAndreas Gohr        $data = array();
6472812a751SAndreas Gohr
6482812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
6492812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6502812a751SAndreas Gohr                 WHERE $tlimit
6512812a751SAndreas Gohr                   AND ua_type = 'browser'
6522812a751SAndreas Gohr              GROUP BY ref_type";
6532812a751SAndreas Gohr        $result = $this->runSQL($sql);
6542812a751SAndreas Gohr
6552812a751SAndreas Gohr        foreach($result as $row){
6562812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
6572812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
6582812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
6592812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
6602812a751SAndreas Gohr        }
6612812a751SAndreas Gohr
6622812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
6632812a751SAndreas Gohr                       COUNT(session) as views,
6643c0acc14SAndreas Gohr                       COUNT(DISTINCT user) as users,
6653c0acc14SAndreas Gohr                       COUNT(DISTINCT uid) as visitors
6662812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6672812a751SAndreas Gohr                 WHERE $tlimit
6682812a751SAndreas Gohr                   AND ua_type = 'browser'";
6692812a751SAndreas Gohr        $result = $this->runSQL($sql);
6702812a751SAndreas Gohr
67175fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
6722812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
6732812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
6743c0acc14SAndreas Gohr        $data['visitors']  = $result[0]['visitors'];
6752812a751SAndreas Gohr
6762812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
6772812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6782812a751SAndreas Gohr                 WHERE $tlimit
6792812a751SAndreas Gohr                   AND ua_type = 'robot'";
6802812a751SAndreas Gohr        $result = $this->runSQL($sql);
6812812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
6822812a751SAndreas Gohr
6832812a751SAndreas Gohr        return $data;
6842812a751SAndreas Gohr    }
6852812a751SAndreas Gohr
686bd4217d3SAndreas Gohr    /**
687bd4217d3SAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
688bd4217d3SAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
689bd4217d3SAndreas Gohr     */
6902812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
6912812a751SAndreas Gohr        if($hours){
6922812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
6932812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6943c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6953c0acc14SAndreas Gohr                           COUNT(DISTINCT uid) as visitors
6962812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6972812a751SAndreas Gohr                     WHERE $tlimit
6982812a751SAndreas Gohr                       AND ua_type = 'browser'
6992812a751SAndreas Gohr                  GROUP BY HOUR(dt)
7002812a751SAndreas Gohr                  ORDER BY time";
7012812a751SAndreas Gohr        }else{
7022812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
7032812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
7043c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
7053c0acc14SAndreas Gohr                            COUNT(DISTINCT uid) as visitors
7062812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
7072812a751SAndreas Gohr                     WHERE $tlimit
7082812a751SAndreas Gohr                       AND ua_type = 'browser'
7092812a751SAndreas Gohr                  GROUP BY DATE(dt)
7102812a751SAndreas Gohr                  ORDER BY time";
7112812a751SAndreas Gohr        }
7122812a751SAndreas Gohr        return $this->runSQL($sql);
7132812a751SAndreas Gohr    }
7142812a751SAndreas Gohr
71512dcdeccSAndreas Gohr    function sql_searchengines($tlimit,$start=0,$limit=20){
71612dcdeccSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, engine
71712dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
71812dcdeccSAndreas Gohr                 WHERE $tlimit
71912dcdeccSAndreas Gohr              GROUP BY engine
72012dcdeccSAndreas Gohr              ORDER BY cnt DESC, engine".
72112dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
72212dcdeccSAndreas Gohr        return $this->runSQL($sql);
72312dcdeccSAndreas Gohr    }
72412dcdeccSAndreas Gohr
72512dcdeccSAndreas Gohr    function sql_searchphrases($tlimit,$start=0,$limit=20){
726*29dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, query, query as lookup
72712dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
72812dcdeccSAndreas Gohr                 WHERE $tlimit
72912dcdeccSAndreas Gohr              GROUP BY query
73012dcdeccSAndreas Gohr              ORDER BY cnt DESC, query".
73112dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
73212dcdeccSAndreas Gohr        return $this->runSQL($sql);
73312dcdeccSAndreas Gohr    }
73412dcdeccSAndreas Gohr
73512dcdeccSAndreas Gohr    function sql_searchwords($tlimit,$start=0,$limit=20){
736*29dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, word, word as lookup
73712dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A,
73812dcdeccSAndreas Gohr                       ".$this->getConf('db_prefix')."searchwords as B
73912dcdeccSAndreas Gohr                 WHERE $tlimit
74012dcdeccSAndreas Gohr                   AND A.id = B.sid
74112dcdeccSAndreas Gohr              GROUP BY word
74212dcdeccSAndreas Gohr              ORDER BY cnt DESC, word".
74312dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
74412dcdeccSAndreas Gohr        return $this->runSQL($sql);
74512dcdeccSAndreas Gohr    }
74612dcdeccSAndreas Gohr
747e25286daSAndreas Gohr    function sql_outlinks($tlimit,$start=0,$limit=20){
748e25286daSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, link as url
749e25286daSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."outlinks as A
750e25286daSAndreas Gohr                 WHERE $tlimit
751e25286daSAndreas Gohr              GROUP BY link
752e25286daSAndreas Gohr              ORDER BY cnt DESC, link".
753e25286daSAndreas Gohr              $this->sql_limit($start,$limit);
754e25286daSAndreas Gohr        return $this->runSQL($sql);
755e25286daSAndreas Gohr    }
756e25286daSAndreas Gohr
75795eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
7582812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
75995eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
76095eb68e6SAndreas Gohr                 WHERE $tlimit
76195eb68e6SAndreas Gohr                   AND ua_type = 'browser'
76295eb68e6SAndreas Gohr              GROUP BY page
76395eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
76495eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
76595eb68e6SAndreas Gohr        return $this->runSQL($sql);
76695eb68e6SAndreas Gohr    }
76795eb68e6SAndreas Gohr
76895eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
7692812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
77095eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
77195eb68e6SAndreas Gohr                 WHERE $tlimit
77295eb68e6SAndreas Gohr                   AND ua_type = 'browser'
77395eb68e6SAndreas Gohr                   AND ref_type = 'external'
77495eb68e6SAndreas Gohr              GROUP BY ref_md5
77595eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
77695eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
77795eb68e6SAndreas Gohr        return $this->runSQL($sql);
77895eb68e6SAndreas Gohr    }
77995eb68e6SAndreas Gohr
780e7a2f1e0SAndreas Gohr    function sql_newreferer($tlimit,$start=0,$limit=20){
781e7a2f1e0SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
782e7a2f1e0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
783e7a2f1e0SAndreas Gohr                 WHERE ua_type = 'browser'
784e7a2f1e0SAndreas Gohr                   AND ref_type = 'external'
785e7a2f1e0SAndreas Gohr              GROUP BY ref_md5
786e7a2f1e0SAndreas Gohr                HAVING DATE(MIN(dt)) >= DATE('".$this->from."')
787e7a2f1e0SAndreas Gohr                   AND DATE(MIN(dt)) <= DATE('".$this->to."')
788e7a2f1e0SAndreas Gohr              ORDER BY cnt DESC, url".
789e7a2f1e0SAndreas Gohr              $this->sql_limit($start,$limit);
790e7a2f1e0SAndreas Gohr        return $this->runSQL($sql);
791e7a2f1e0SAndreas Gohr    }
792e7a2f1e0SAndreas Gohr
79395eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
794bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
79595eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
79695eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
79795eb68e6SAndreas Gohr                 WHERE $tlimit
79895eb68e6SAndreas Gohr                   AND A.ip = B.ip
79995eb68e6SAndreas Gohr              GROUP BY B.country
80095eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
80195eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
80295eb68e6SAndreas Gohr        return $this->runSQL($sql);
80395eb68e6SAndreas Gohr    }
80495eb68e6SAndreas Gohr
80575fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
80675fa767dSAndreas Gohr        if($ext){
80775fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
80875fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
80975fa767dSAndreas Gohr        }else{
81075fa767dSAndreas Gohr            $grp = 'ua_info';
81175fa767dSAndreas Gohr            $sel = 'ua_info';
81275fa767dSAndreas Gohr        }
81375fa767dSAndreas Gohr
814bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
81575fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
81675fa767dSAndreas Gohr                 WHERE $tlimit
81775fa767dSAndreas Gohr                   AND ua_type = 'browser'
81875fa767dSAndreas Gohr              GROUP BY $grp
81975fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
82075fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
82175fa767dSAndreas Gohr        return $this->runSQL($sql);
82275fa767dSAndreas Gohr    }
82375fa767dSAndreas Gohr
824bd4217d3SAndreas Gohr    function sql_os($tlimit,$start=0,$limit=20){
825bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
826bd4217d3SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
827bd4217d3SAndreas Gohr                 WHERE $tlimit
828bd4217d3SAndreas Gohr                   AND ua_type = 'browser'
829bd4217d3SAndreas Gohr              GROUP BY os
830bd4217d3SAndreas Gohr              ORDER BY cnt DESC, os".
831bd4217d3SAndreas Gohr              $this->sql_limit($start,$limit);
832bd4217d3SAndreas Gohr        return $this->runSQL($sql);
833bd4217d3SAndreas Gohr    }
834bd4217d3SAndreas Gohr
835c73e16f1SAndreas Gohr    function sql_resolution($tlimit,$start=0,$limit=20){
836c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res
837c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
838c73e16f1SAndreas Gohr                 WHERE $tlimit
839c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
840c73e16f1SAndreas Gohr                   AND screen_x != 0
841c73e16f1SAndreas Gohr              GROUP BY screen_x, screen_y
842c73e16f1SAndreas Gohr              ORDER BY cnt DESC, screen_x".
843c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
844c73e16f1SAndreas Gohr        return $this->runSQL($sql);
845c73e16f1SAndreas Gohr    }
846c73e16f1SAndreas Gohr
847c73e16f1SAndreas Gohr    function sql_viewport($tlimit,$start=0,$limit=20,$x=true){
848c73e16f1SAndreas Gohr        if($x){
849c73e16f1SAndreas Gohr            $col = 'view_x';
850c73e16f1SAndreas Gohr            $res = 'res_x';
851c73e16f1SAndreas Gohr        }else{
852c73e16f1SAndreas Gohr            $col = 'view_y';
853c73e16f1SAndreas Gohr            $res = 'res_y';
854c73e16f1SAndreas Gohr        }
855c73e16f1SAndreas Gohr
856c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt,
857c73e16f1SAndreas Gohr                       ROUND($col/10)*10 as $res
858c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
859c73e16f1SAndreas Gohr                 WHERE $tlimit
860c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
861c73e16f1SAndreas Gohr                   AND $col != 0
862c73e16f1SAndreas Gohr              GROUP BY $res
863c73e16f1SAndreas Gohr              ORDER BY cnt DESC, $res".
864c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
865c73e16f1SAndreas Gohr        return $this->runSQL($sql);
866c73e16f1SAndreas Gohr    }
867c73e16f1SAndreas Gohr
86875fa767dSAndreas Gohr
86995eb68e6SAndreas Gohr    /**
87095eb68e6SAndreas Gohr     * Builds a limit clause
87195eb68e6SAndreas Gohr     */
87295eb68e6SAndreas Gohr    function sql_limit($start,$limit){
87395eb68e6SAndreas Gohr        $start = (int) $start;
87495eb68e6SAndreas Gohr        $limit = (int) $limit;
87595eb68e6SAndreas Gohr        if($limit){
8762507f8e0SAndreas Gohr            $limit += 1;
87795eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
87895eb68e6SAndreas Gohr        }elseif($start){
87995eb68e6SAndreas Gohr            return " OFFSET $start";
88095eb68e6SAndreas Gohr        }
88195eb68e6SAndreas Gohr        return '';
88295eb68e6SAndreas Gohr    }
8831878f16fSAndreas Gohr
8841878f16fSAndreas Gohr    /**
88514d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
8861878f16fSAndreas Gohr     */
88714d99ec0SAndreas Gohr    function dbLink(){
8881878f16fSAndreas Gohr        // connect to DB if needed
8891878f16fSAndreas Gohr        if(!$this->dblink){
8901878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
8911878f16fSAndreas Gohr                                          $this->getConf('db_user'),
8921878f16fSAndreas Gohr                                          $this->getConf('db_password'));
8931878f16fSAndreas Gohr            if(!$this->dblink){
8941878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
8951878f16fSAndreas Gohr                return null;
8961878f16fSAndreas Gohr            }
8971878f16fSAndreas Gohr            // set utf-8
8981878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
8991878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
9001878f16fSAndreas Gohr                return null;
9011878f16fSAndreas Gohr            }
9021878f16fSAndreas Gohr        }
90314d99ec0SAndreas Gohr        return $this->dblink;
90414d99ec0SAndreas Gohr    }
9051878f16fSAndreas Gohr
90614d99ec0SAndreas Gohr    /**
90714d99ec0SAndreas Gohr     * Simple function to run a DB query
90814d99ec0SAndreas Gohr     */
90914d99ec0SAndreas Gohr    function runSQL($sql_string) {
91014d99ec0SAndreas Gohr        $link = $this->dbLink();
91114d99ec0SAndreas Gohr
91214d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
91394171ff3SAndreas Gohr        if(!$result){
9142812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
9151878f16fSAndreas Gohr            return null;
9161878f16fSAndreas Gohr        }
9171878f16fSAndreas Gohr
9181878f16fSAndreas Gohr        $resultarray = array();
9191878f16fSAndreas Gohr
9201878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
9211878f16fSAndreas Gohr        if ($result != 1) {
9221878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
9231878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
9241878f16fSAndreas Gohr                $resultarray[]=$temparray;
9251878f16fSAndreas Gohr            }
9261878f16fSAndreas Gohr            mysql_free_result($result);
9271878f16fSAndreas Gohr        }
9281878f16fSAndreas Gohr
92914d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
93014d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
9311878f16fSAndreas Gohr        }
9321878f16fSAndreas Gohr
9331878f16fSAndreas Gohr        return $resultarray;
9341878f16fSAndreas Gohr    }
9351878f16fSAndreas Gohr
9361878f16fSAndreas Gohr    /**
93714d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
9381878f16fSAndreas Gohr     */
93914d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
94014d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
94114d99ec0SAndreas Gohr        $ua = strtolower($ua);
94214d99ec0SAndreas Gohr
94314d99ec0SAndreas Gohr        // common browsers
94414d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
94514d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
94614d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
94714d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
94814d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
94914d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
95014d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
95114d99ec0SAndreas Gohr
95214d99ec0SAndreas Gohr        $name = '';
95314d99ec0SAndreas Gohr        # IE ?
95414d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
95514d99ec0SAndreas Gohr            $type = 'browser';
95614d99ec0SAndreas Gohr            $ver  = $m[2];
95714d99ec0SAndreas Gohr            $name = 'msie';
95814d99ec0SAndreas Gohr        }
95914d99ec0SAndreas Gohr        # Firefox ?
96014d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
96114d99ec0SAndreas Gohr            $type = 'browser';
96214d99ec0SAndreas Gohr            $ver  = $m[1];
96314d99ec0SAndreas Gohr            $name = 'firefox';
96414d99ec0SAndreas Gohr        }
96514d99ec0SAndreas Gohr        # Subversion ?
96614d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
96714d99ec0SAndreas Gohr            $type = 'rcs';
96814d99ec0SAndreas Gohr            $ver  = $m[1];
96914d99ec0SAndreas Gohr            $name = 'svn';
97014d99ec0SAndreas Gohr        }
97114d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
97214d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
97314d99ec0SAndreas Gohr            $type = 'browser';
97414d99ec0SAndreas Gohr            $ver  = $m[1];
97514d99ec0SAndreas Gohr            $name = 'netscape';
97614d99ec0SAndreas Gohr        }
97714d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
97814d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
97914d99ec0SAndreas Gohr            $type = 'browser';
98014d99ec0SAndreas Gohr            $ver  = $m[2];
98114d99ec0SAndreas Gohr            $name = 'netscape';
98214d99ec0SAndreas Gohr        }else{
98314d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
98414d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
98514d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
98614d99ec0SAndreas Gohr                    // it's a browser!
98714d99ec0SAndreas Gohr                    $type = 'browser';
98814d99ec0SAndreas Gohr                    $name = strtolower($regex);
98914d99ec0SAndreas Gohr                    break;
99014d99ec0SAndreas Gohr                }
99114d99ec0SAndreas Gohr            }
99214d99ec0SAndreas Gohr        }
99314d99ec0SAndreas Gohr
99475fa767dSAndreas Gohr        // check versions for Safari and Opera
99575fa767dSAndreas Gohr        if($name == 'safari'){
99675fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
99775fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
99875fa767dSAndreas Gohr            }
99975fa767dSAndreas Gohr        }elseif($name == 'opera'){
100075fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
100175fa767dSAndreas Gohr                $ver = $match[1];
100275fa767dSAndreas Gohr            }
100375fa767dSAndreas Gohr        }
100475fa767dSAndreas Gohr
100575fa767dSAndreas Gohr
100614d99ec0SAndreas Gohr        // check OS for browsers
100714d99ec0SAndreas Gohr        if($type == 'browser'){
100814d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
100914d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
101014d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
101114d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
101214d99ec0SAndreas Gohr                    break;
101314d99ec0SAndreas Gohr                }
101414d99ec0SAndreas Gohr            }
101514d99ec0SAndreas Gohr
101614d99ec0SAndreas Gohr        }
101714d99ec0SAndreas Gohr
101814d99ec0SAndreas Gohr        // are we done now?
101914d99ec0SAndreas Gohr        if($name) return $name;
102014d99ec0SAndreas Gohr
102114d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
102214d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
102314d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
102414d99ec0SAndreas Gohr                    // it's a robot!
102514d99ec0SAndreas Gohr                    $type = 'robot';
102614d99ec0SAndreas Gohr                    return strtolower($regex);
102714d99ec0SAndreas Gohr            }
102814d99ec0SAndreas Gohr        }
102914d99ec0SAndreas Gohr
103014d99ec0SAndreas Gohr        // dunno
10311878f16fSAndreas Gohr        return '';
10321878f16fSAndreas Gohr    }
10331878f16fSAndreas Gohr
10341878f16fSAndreas Gohr    /**
1035322de360SAndreas Gohr     * Log search queries
103614d99ec0SAndreas Gohr     */
103714d99ec0SAndreas Gohr    function log_search($referer,&$type){
103814d99ec0SAndreas Gohr        $referer = strtolower($referer);
1039673875b1SAndreas Gohr        $ref     = strtr($referer,' +','__');
104014d99ec0SAndreas Gohr
104114d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
104214d99ec0SAndreas Gohr
104314d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
1044673875b1SAndreas Gohr            if(preg_match('/'.$regex.'/',$ref)){
104514d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
1046673875b1SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$ref)){
104714d99ec0SAndreas Gohr                    // it's a search engine!
104814d99ec0SAndreas Gohr                    $type = 'search';
104914d99ec0SAndreas Gohr                    break;
105014d99ec0SAndreas Gohr                }
105114d99ec0SAndreas Gohr            }
105214d99ec0SAndreas Gohr        }
105314d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
105414d99ec0SAndreas Gohr
1055322de360SAndreas Gohr        // extract query
1056322de360SAndreas Gohr        $engine = $SearchEnginesHashID[$regex];
1057322de360SAndreas Gohr        $param = $SearchEnginesKnownUrl[$engine];
1058322de360SAndreas Gohr        if($param && preg_match('/'.$param.'(.*?)[&$]/',$referer,$match)){
1059322de360SAndreas Gohr            $query = array_pop($match);
1060322de360SAndreas Gohr        }elseif(preg_match('/'.$WordsToExtractSearchUrl.'(.*?)[&$]/',$referer,$match)){
1061322de360SAndreas Gohr            $query = array_pop($match);
1062322de360SAndreas Gohr        }
1063322de360SAndreas Gohr        if(!$query) return; // we failed
1064322de360SAndreas Gohr
1065322de360SAndreas Gohr        // clean the query
1066322de360SAndreas Gohr        $query = preg_replace('/^(cache|related):[^\+]+/','',$query);  // non-search queries
1067322de360SAndreas Gohr        $query = preg_replace('/%0[ad]/',' ',$query);                  // LF CR
1068322de360SAndreas Gohr        $query = preg_replace('/%2[02789abc]/',' ',$query);            // space " ' ( ) * + ,
1069322de360SAndreas Gohr        $query = preg_replace('/%3a/',' ',$query);                     // :
1070673875b1SAndreas Gohr        $query = strtr($query,'+\'()"*,:','        ');                 // badly encoded
1071322de360SAndreas Gohr        $query = preg_replace('/ +/',' ',$query);                      // ws compact
1072322de360SAndreas Gohr        $query = trim($query);
1073322de360SAndreas Gohr        $query = urldecode($query);
1074322de360SAndreas Gohr        if(!utf8_check($query)) $query = utf8_encode($query);          // assume latin1 if not utf8
1075322de360SAndreas Gohr        $query = utf8_strtolower($query);
1076322de360SAndreas Gohr
1077322de360SAndreas Gohr        // log it!
1078322de360SAndreas Gohr        $page  = addslashes($_REQUEST['p']);
1079322de360SAndreas Gohr        $query = addslashes($query);
1080673875b1SAndreas Gohr        $sql  = "INSERT INTO ".$this->getConf('db_prefix')."search
1081322de360SAndreas Gohr                    SET dt       = NOW(),
1082322de360SAndreas Gohr                        page     = '$page',
1083322de360SAndreas Gohr                        query    = '$query',
1084322de360SAndreas Gohr                        engine   = '$engine'";
1085322de360SAndreas Gohr        $id = $this->runSQL($sql);
1086322de360SAndreas Gohr        if(is_null($id)){
1087322de360SAndreas Gohr            global $MSG;
1088322de360SAndreas Gohr            print_r($MSG);
1089322de360SAndreas Gohr            return;
1090322de360SAndreas Gohr        }
1091322de360SAndreas Gohr
1092322de360SAndreas Gohr        // log single keywords
1093322de360SAndreas Gohr        $words = explode(' ',utf8_stripspecials($query,' ','\._\-:\*'));
1094322de360SAndreas Gohr        foreach($words as $word){
1095673875b1SAndreas Gohr            if(!$word) continue;
1096322de360SAndreas Gohr            $word = addslashes($word);
1097322de360SAndreas Gohr            $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."searchwords
1098322de360SAndreas Gohr                       SET sid  = $id,
1099322de360SAndreas Gohr                           word = '$word'";
1100322de360SAndreas Gohr            $ok = $this->runSQL($sql);
1101322de360SAndreas Gohr            if(is_null($ok)){
1102322de360SAndreas Gohr                global $MSG;
1103322de360SAndreas Gohr                print_r($MSG);
1104322de360SAndreas Gohr            }
1105322de360SAndreas Gohr        }
110614d99ec0SAndreas Gohr    }
110714d99ec0SAndreas Gohr
110814d99ec0SAndreas Gohr    /**
110914d99ec0SAndreas Gohr     * Resolve IP to country/city
111014d99ec0SAndreas Gohr     */
111114d99ec0SAndreas Gohr    function log_ip($ip){
111214d99ec0SAndreas Gohr        // check if IP already known and up-to-date
111314d99ec0SAndreas Gohr        $sql = "SELECT ip
111414d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
111514d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
111614d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
111714d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
111814d99ec0SAndreas Gohr        if($result[0]['ip']) return;
111914d99ec0SAndreas Gohr
112014d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
112114d99ec0SAndreas Gohr        $http->timeout = 10;
112214d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
112314d99ec0SAndreas Gohr
112414d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
112514d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
112614d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
112714d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
112814d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
112914d99ec0SAndreas Gohr            $ip      = addslashes($ip);
113014d99ec0SAndreas Gohr
113114d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
113214d99ec0SAndreas Gohr                        SET ip = '$ip',
113314d99ec0SAndreas Gohr                            country = '$country',
113414d99ec0SAndreas Gohr                            code    = '$code',
113514d99ec0SAndreas Gohr                            city    = '$city',
113614d99ec0SAndreas Gohr                            host    = '$host'";
113714d99ec0SAndreas Gohr            $this->runSQL($sql);
113814d99ec0SAndreas Gohr        }
113914d99ec0SAndreas Gohr    }
114014d99ec0SAndreas Gohr
114114d99ec0SAndreas Gohr    /**
1142e25286daSAndreas Gohr     * log a click on an external link
1143e25286daSAndreas Gohr     *
1144e25286daSAndreas Gohr     * called from log.php
1145e25286daSAndreas Gohr     */
1146e25286daSAndreas Gohr    function log_outgoing(){
1147e25286daSAndreas Gohr        if(!$_REQUEST['ol']) return;
1148e25286daSAndreas Gohr
1149e25286daSAndreas Gohr        $link_md5 = md5($link);
1150e25286daSAndreas Gohr        $link     = addslashes($_REQUEST['ol']);
1151e25286daSAndreas Gohr        $session  = addslashes(session_id());
1152d8c4d85eSAndreas Gohr        $page     = addslashes($_REQUEST['p']);
1153e25286daSAndreas Gohr
1154e25286daSAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks
1155e25286daSAndreas Gohr                    SET dt       = NOW(),
1156e25286daSAndreas Gohr                        session  = '$session',
1157d8c4d85eSAndreas Gohr                        page     = '$page',
1158e25286daSAndreas Gohr                        link_md5 = '$link_md5',
1159e25286daSAndreas Gohr                        link     = '$link'";
1160e25286daSAndreas Gohr        $ok = $this->runSQL($sql);
1161e25286daSAndreas Gohr        if(is_null($ok)){
1162e25286daSAndreas Gohr            global $MSG;
1163e25286daSAndreas Gohr            print_r($MSG);
1164e25286daSAndreas Gohr        }
1165e25286daSAndreas Gohr    }
1166e25286daSAndreas Gohr
1167e25286daSAndreas Gohr    /**
11681878f16fSAndreas Gohr     * log a page access
11691878f16fSAndreas Gohr     *
11701878f16fSAndreas Gohr     * called from log.php
11711878f16fSAndreas Gohr     */
11721878f16fSAndreas Gohr    function log_access(){
117394171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
117494171ff3SAndreas Gohr
117514d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
117614d99ec0SAndreas Gohr
117714d99ec0SAndreas Gohr        // handle referer
117814d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
117914d99ec0SAndreas Gohr        if($referer){
118014d99ec0SAndreas Gohr            $ref     = addslashes($referer);
118114d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
118214d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
118314d99ec0SAndreas Gohr                $ref_type = 'internal';
118414d99ec0SAndreas Gohr            }else{
118514d99ec0SAndreas Gohr                $ref_type = 'external';
118614d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
118714d99ec0SAndreas Gohr            }
118814d99ec0SAndreas Gohr        }else{
118914d99ec0SAndreas Gohr            $ref      = '';
119014d99ec0SAndreas Gohr            $ref_md5  = '';
119114d99ec0SAndreas Gohr            $ref_type = '';
119214d99ec0SAndreas Gohr        }
119314d99ec0SAndreas Gohr
119414d99ec0SAndreas Gohr        // handle user agent
119514d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
119614d99ec0SAndreas Gohr
119714d99ec0SAndreas Gohr        $ua      = addslashes($agent);
119814d99ec0SAndreas Gohr        $ua_type = '';
119914d99ec0SAndreas Gohr        $ua_ver  = '';
120014d99ec0SAndreas Gohr        $os      = '';
120114d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
120214d99ec0SAndreas Gohr
12031878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
12041878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
12051878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
12061878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
12071878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
12081878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
120975fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
12103c0acc14SAndreas Gohr        $uid     = addslashes($_REQUEST['uid']);
12111878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
12121878f16fSAndreas Gohr        $session = addslashes(session_id());
12133c0acc14SAndreas Gohr        if(!$uid) $uid = $session;
12141878f16fSAndreas Gohr
121594171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
121675fa767dSAndreas Gohr                    SET dt       = NOW(),
121775fa767dSAndreas Gohr                        page     = '$page',
12181878f16fSAndreas Gohr                        ip       = '$ip',
12191878f16fSAndreas Gohr                        ua       = '$ua',
12201878f16fSAndreas Gohr                        ua_info  = '$ua_info',
122114d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
122214d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
122314d99ec0SAndreas Gohr                        os       = '$os',
12241878f16fSAndreas Gohr                        ref      = '$ref',
122594171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
122614d99ec0SAndreas Gohr                        ref_type = '$ref_type',
12271878f16fSAndreas Gohr                        screen_x = '$sx',
12281878f16fSAndreas Gohr                        screen_y = '$sy',
12291878f16fSAndreas Gohr                        view_x   = '$vx',
12301878f16fSAndreas Gohr                        view_y   = '$vy',
123175fa767dSAndreas Gohr                        js       = '$js',
12321878f16fSAndreas Gohr                        user     = '$user',
12333c0acc14SAndreas Gohr                        session  = '$session',
12343c0acc14SAndreas Gohr                        uid      = '$uid'";
12351878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
12361878f16fSAndreas Gohr        if(is_null($ok)){
12371878f16fSAndreas Gohr            global $MSG;
12381878f16fSAndreas Gohr            print_r($MSG);
12391878f16fSAndreas Gohr        }
124014d99ec0SAndreas Gohr
124114d99ec0SAndreas Gohr        // resolve the IP
124214d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
12431878f16fSAndreas Gohr    }
12441878f16fSAndreas Gohr
12451878f16fSAndreas Gohr    /**
12461878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
12471878f16fSAndreas Gohr     *
12481878f16fSAndreas Gohr     * @called from log.php
12491878f16fSAndreas Gohr     *
12501878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
12511878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
12521878f16fSAndreas Gohr     */
12531878f16fSAndreas Gohr    function sendGIF(){
12541878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
12551878f16fSAndreas Gohr        header('Content-Type: image/gif');
12561878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
12571878f16fSAndreas Gohr        header('Connection: Close');
12581878f16fSAndreas Gohr        print $img;
12591878f16fSAndreas Gohr        flush();
12601878f16fSAndreas Gohr        // Browser should drop connection after this
12611878f16fSAndreas Gohr        // Thinks it's got the whole image
12621878f16fSAndreas Gohr    }
12631878f16fSAndreas Gohr
12641878f16fSAndreas Gohr}
1265