xref: /plugin/statistics/admin.php (revision e8699bce7e2ef6ae5ccd67f98ab683c3e8419624)
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'];
54*e8699bceSAndreas Gohr        $this->setTimeframe($_REQUEST['f'],$_REQUEST['t']);
55*e8699bceSAndreas Gohr    }
5695eb68e6SAndreas Gohr
57*e8699bceSAndreas Gohr    /**
58*e8699bceSAndreas Gohr     * set limit clause
59*e8699bceSAndreas Gohr     */
60*e8699bceSAndreas Gohr    function setTimeframe($from,$to){
61264f1744SAndreas Gohr        // fixme add better sanity checking here:
62*e8699bceSAndreas Gohr        $from = preg_replace('/[^\d\-]+/','',$from);
63*e8699bceSAndreas Gohr        $to   = preg_replace('/[^\d\-]+/','',$to);
64*e8699bceSAndreas Gohr        if(!$from) $from = date('Y-m-d');
65*e8699bceSAndreas Gohr        if(!$to)   $to   = date('Y-m-d');
66264f1744SAndreas Gohr
67264f1744SAndreas Gohr        //setup limit clause
68*e8699bceSAndreas Gohr        if($from != $to){
69*e8699bceSAndreas Gohr            $tlimit = "DATE(A.dt) >= DATE('".$from."') AND DATE(A.dt) <= DATE('".$to."')";
70264f1744SAndreas Gohr        }else{
71*e8699bceSAndreas Gohr            $tlimit = "DATE(A.dt) = DATE('".$from."')";
72264f1744SAndreas Gohr        }
73*e8699bceSAndreas Gohr        $this->tlimit = $tlimit;
74*e8699bceSAndreas Gohr        $this->from   = $from;
75*e8699bceSAndreas 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
29554f6c432SAndreas Gohr        // top countries today
296264f1744SAndreas Gohr        echo '<div>';
297264f1744SAndreas Gohr        echo '<h2>Visitor\'s top countries</h2>';
29895eb68e6SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2992507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=country&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
300264f1744SAndreas Gohr        echo '</div>';
301264f1744SAndreas Gohr
302264f1744SAndreas Gohr        echo '</div>';
30314d99ec0SAndreas Gohr    }
30414d99ec0SAndreas Gohr
3059da6395dSAndreas Gohr    function html_country(){
3069da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3079da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
308bd4217d3SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
3099da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
3102507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3119da6395dSAndreas Gohr        echo '</div>';
3129da6395dSAndreas Gohr    }
3139da6395dSAndreas Gohr
3149da6395dSAndreas Gohr    function html_page(){
3159da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3169da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
3179da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
3182507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3199da6395dSAndreas Gohr        echo '</div>';
3209da6395dSAndreas Gohr    }
3219da6395dSAndreas Gohr
32275fa767dSAndreas Gohr    function html_browser(){
32375fa767dSAndreas Gohr        echo '<div class="plg_stats_full">';
32475fa767dSAndreas Gohr        echo '<h2>Browser Shootout</h2>';
32575fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
32675fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
3272507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
32875fa767dSAndreas Gohr        echo '</div>';
32975fa767dSAndreas Gohr    }
33075fa767dSAndreas Gohr
331bd4217d3SAndreas Gohr    function html_os(){
332bd4217d3SAndreas Gohr        echo '<div class="plg_stats_full">';
333bd4217d3SAndreas Gohr        echo '<h2>Operating Systems</h2>';
334bd4217d3SAndreas Gohr        $result = $this->sql_os($this->tlimit,$this->start,150,true);
3352507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
336bd4217d3SAndreas Gohr        echo '</div>';
337bd4217d3SAndreas Gohr    }
338bd4217d3SAndreas Gohr
3399da6395dSAndreas Gohr    function html_referer(){
3409da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3419da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
3422812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
3432812a751SAndreas Gohr
3442812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
3452812a751SAndreas Gohr
34694023548SAndreas Gohr        if($all){
3472812a751SAndreas Gohr            printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
3482812a751SAndreas Gohr                    %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
3492812a751SAndreas Gohr                    links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
3502812a751SAndreas Gohr                    $result['search'],(100*$result['search']/$all),$result['external'],
3512812a751SAndreas Gohr                    (100*$result['external']/$all));
35294023548SAndreas Gohr        }
3532812a751SAndreas Gohr
3549da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
3552507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3569da6395dSAndreas Gohr        echo '</div>';
3579da6395dSAndreas Gohr    }
3589da6395dSAndreas Gohr
359e7a2f1e0SAndreas Gohr    function html_newreferer(){
360e7a2f1e0SAndreas Gohr        echo '<div class="plg_stats_full">';
361e7a2f1e0SAndreas Gohr        echo '<h2>New Incoming Links</h2>';
362e7a2f1e0SAndreas Gohr        echo '<p>The following incoming links where first logged in the selected time frame,
363e7a2f1e0SAndreas Gohr              and have never been seen before.</p>';
364e7a2f1e0SAndreas Gohr
365e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,150);
3662507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
367e7a2f1e0SAndreas Gohr        echo '</div>';
368e7a2f1e0SAndreas Gohr    }
369e7a2f1e0SAndreas Gohr
370e25286daSAndreas Gohr    function html_outlinks(){
371e25286daSAndreas Gohr        echo '<div class="plg_stats_full">';
372e25286daSAndreas Gohr        echo '<h2>Outgoing Links</h2>';
373e25286daSAndreas Gohr
374e25286daSAndreas Gohr        $result = $this->sql_outlinks($this->tlimit,$this->start,150);
375e25286daSAndreas Gohr        $this->html_resulttable($result,'',150);
376e25286daSAndreas Gohr        echo '</div>';
377e25286daSAndreas Gohr    }
378e25286daSAndreas Gohr
37912dcdeccSAndreas Gohr    function html_searchphrases(){
38012dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
38112dcdeccSAndreas Gohr        echo '<h2>Search Phrases</h2>';
38212dcdeccSAndreas Gohr
38312dcdeccSAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,150);
38412dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
38512dcdeccSAndreas Gohr        echo '</div>';
38612dcdeccSAndreas Gohr    }
38712dcdeccSAndreas Gohr
38812dcdeccSAndreas Gohr    function html_searchwords(){
38912dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
39012dcdeccSAndreas Gohr        echo '<h2>Search Words</h2>';
39112dcdeccSAndreas Gohr
39212dcdeccSAndreas Gohr        $result = $this->sql_searchwords($this->tlimit,$this->start,150);
39312dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
39412dcdeccSAndreas Gohr        echo '</div>';
39512dcdeccSAndreas Gohr    }
39612dcdeccSAndreas Gohr
39712dcdeccSAndreas Gohr    function html_searchengines(){
39812dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
39912dcdeccSAndreas Gohr        echo '<h2>Search Engines</h2>';
40012dcdeccSAndreas Gohr
40112dcdeccSAndreas Gohr        $result = $this->sql_searchengines($this->tlimit,$this->start,150);
40212dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
40312dcdeccSAndreas Gohr        echo '</div>';
40412dcdeccSAndreas Gohr    }
40512dcdeccSAndreas Gohr
406e25286daSAndreas Gohr
407c73e16f1SAndreas Gohr    function html_resolution(){
408c73e16f1SAndreas Gohr        echo '<div class="plg_stats_full">';
409c73e16f1SAndreas Gohr        echo '<h2>Resolution</h2>';
410c73e16f1SAndreas Gohr        $result = $this->sql_resolution($this->tlimit,$this->start,150);
411c73e16f1SAndreas Gohr        $this->html_resulttable($result,'',150);
412c73e16f1SAndreas Gohr
413c73e16f1SAndreas Gohr        echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you
414c73e16f1SAndreas Gohr              much about about the real size of their browser windows. The graphic below shows the size distribution of
415c73e16f1SAndreas Gohr              the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged
416c73e16f1SAndreas Gohr              in all browsers. Because users may resize their browser window while browsing your site the statistics may
417c73e16f1SAndreas Gohr              be flawed. Take it with a grain of salt.</p>';
418c73e16f1SAndreas Gohr
419c73e16f1SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
420c73e16f1SAndreas Gohr        echo '</div>';
421c73e16f1SAndreas Gohr    }
4229da6395dSAndreas Gohr
4239da6395dSAndreas Gohr
42414d99ec0SAndreas Gohr    /**
42514d99ec0SAndreas Gohr     * Display a result in a HTML table
42614d99ec0SAndreas Gohr     */
4272507f8e0SAndreas Gohr    function html_resulttable($result,$header='',$pager=0){
42814d99ec0SAndreas Gohr        echo '<table>';
4292812a751SAndreas Gohr        if(is_array($header)){
43014d99ec0SAndreas Gohr            echo '<tr>';
43114d99ec0SAndreas Gohr            foreach($header as $h){
43214d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
43314d99ec0SAndreas Gohr            }
43414d99ec0SAndreas Gohr            echo '</tr>';
4352812a751SAndreas Gohr        }
43614d99ec0SAndreas Gohr
4372507f8e0SAndreas Gohr        $count = 0;
43814d99ec0SAndreas Gohr        foreach($result as $row){
43914d99ec0SAndreas Gohr            echo '<tr>';
44014d99ec0SAndreas Gohr            foreach($row as $k => $v){
4412812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
44214d99ec0SAndreas Gohr                if($k == 'page'){
44314d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
44414d99ec0SAndreas Gohr                    echo hsc($v);
44514d99ec0SAndreas Gohr                    echo '</a>';
44614d99ec0SAndreas Gohr                }elseif($k == 'url'){
44754f6c432SAndreas Gohr                    $url = hsc($v);
44883b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/','',$url);
4492812a751SAndreas Gohr                    if(strlen($url) > 45){
4502812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
45154f6c432SAndreas Gohr                    }
45214d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
45354f6c432SAndreas Gohr                    echo $url;
45414d99ec0SAndreas Gohr                    echo '</a>';
45512dcdeccSAndreas Gohr                }elseif($k == 'engine'){
45612dcdeccSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/search_engines.php');
45712dcdeccSAndreas Gohr                    echo $SearchEnginesHashLib[$v];
45875fa767dSAndreas Gohr                }elseif($k == 'browser'){
45975fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
46075fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
46175fa767dSAndreas Gohr                }elseif($k == 'bflag'){
46275fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
46375fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
464bd4217d3SAndreas Gohr                }elseif($k == 'os'){
465bd4217d3SAndreas Gohr                    if(empty($v)){
466bd4217d3SAndreas Gohr                        echo 'unknown';
467bd4217d3SAndreas Gohr                    }else{
468bd4217d3SAndreas Gohr                        include_once(dirname(__FILE__).'/inc/operating_systems.php');
469bd4217d3SAndreas Gohr                        echo $OSHashLib[$v];
470bd4217d3SAndreas Gohr                    }
471bd4217d3SAndreas Gohr                }elseif($k == 'osflag'){
472bd4217d3SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />';
47375fa767dSAndreas Gohr                }elseif($k == 'cflag'){
47475fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
47514d99ec0SAndreas Gohr                }elseif($k == 'html'){
47614d99ec0SAndreas Gohr                    echo $v;
47714d99ec0SAndreas Gohr                }else{
47814d99ec0SAndreas Gohr                    echo hsc($v);
47914d99ec0SAndreas Gohr                }
48014d99ec0SAndreas Gohr                echo '</td>';
48114d99ec0SAndreas Gohr            }
48214d99ec0SAndreas Gohr            echo '</tr>';
4832507f8e0SAndreas Gohr
4842507f8e0SAndreas Gohr            if($pager && ($count == $pager)) break;
4852507f8e0SAndreas Gohr            $count++;
48614d99ec0SAndreas Gohr        }
48714d99ec0SAndreas Gohr        echo '</table>';
4882507f8e0SAndreas Gohr
4892507f8e0SAndreas Gohr        if($pager) $this->html_pager($pager,count($result) > $pager);
4901878f16fSAndreas Gohr    }
4911878f16fSAndreas Gohr
49295eb68e6SAndreas Gohr    /**
49395eb68e6SAndreas Gohr     * Create an image
49495eb68e6SAndreas Gohr     */
49595eb68e6SAndreas Gohr    function img_build($img){
49695eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
49795eb68e6SAndreas Gohr
49895eb68e6SAndreas Gohr        switch($img){
49995eb68e6SAndreas Gohr            case 'country':
50095eb68e6SAndreas Gohr                // build top countries + other
50195eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
50295eb68e6SAndreas Gohr                $data = array();
50395eb68e6SAndreas Gohr                $top = 0;
50495eb68e6SAndreas Gohr                foreach($result as $row){
50595eb68e6SAndreas Gohr                    if($top < 7){
50695eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
50795eb68e6SAndreas Gohr                    }else{
50895eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
50995eb68e6SAndreas Gohr                    }
51095eb68e6SAndreas Gohr                    $top++;
51195eb68e6SAndreas Gohr                }
51295eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
51395eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
51495eb68e6SAndreas Gohr                $pie->setProp("showval",false);
51595eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
51695eb68e6SAndreas Gohr                $pie->setProp("type","pie");
51795eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
51895eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
51995eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
52095eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
52195eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
52295eb68e6SAndreas Gohr                @$pie->graph();
52395eb68e6SAndreas Gohr                $pie->showGraph();
52495eb68e6SAndreas Gohr                break;
52575fa767dSAndreas Gohr            case 'browser':
52675fa767dSAndreas Gohr                // build top browsers + other
52775fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
52875fa767dSAndreas Gohr
52975fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
53075fa767dSAndreas Gohr                $data = array();
53175fa767dSAndreas Gohr                $top = 0;
53275fa767dSAndreas Gohr                foreach($result as $row){
53375fa767dSAndreas Gohr                    if($top < 5){
53475fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
53575fa767dSAndreas Gohr                    }else{
53675fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
53775fa767dSAndreas Gohr                    }
53875fa767dSAndreas Gohr                    $top++;
53975fa767dSAndreas Gohr                }
54075fa767dSAndreas Gohr                $pie = new AGC(300, 200);
54175fa767dSAndreas Gohr                $pie->setProp("showkey",true);
54275fa767dSAndreas Gohr                $pie->setProp("showval",false);
54375fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
54475fa767dSAndreas Gohr                $pie->setProp("type","pie");
54575fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
54675fa767dSAndreas Gohr                $pie->setProp("keysize",8);
54775fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
54875fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
54975fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
55075fa767dSAndreas Gohr                @$pie->graph();
55175fa767dSAndreas Gohr                $pie->showGraph();
55275fa767dSAndreas Gohr                break;
553c73e16f1SAndreas Gohr            case 'view':
554c73e16f1SAndreas Gohr
555c73e16f1SAndreas Gohr                $graph = new AGC(400, 200);
556c73e16f1SAndreas Gohr                $graph->setColor('color',0,'blue');
557c73e16f1SAndreas Gohr                $graph->setColor('color',1,'red');
558c73e16f1SAndreas Gohr                $graph->setProp("showkey",true);
559c73e16f1SAndreas Gohr                $graph->setProp("key",'view port width',0);
560c73e16f1SAndreas Gohr                $graph->setProp("key",'view port height',1);
561c73e16f1SAndreas Gohr
562c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,true);
563c73e16f1SAndreas Gohr                foreach($result as $row){
564c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_x'],0);
565c73e16f1SAndreas Gohr                }
566c73e16f1SAndreas Gohr
567c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,false);
568c73e16f1SAndreas Gohr                foreach($result as $row){
569c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_y'],1);
570c73e16f1SAndreas Gohr                }
571c73e16f1SAndreas Gohr
572c73e16f1SAndreas Gohr                @$graph->graph();
573c73e16f1SAndreas Gohr                $graph->showGraph();
574c73e16f1SAndreas Gohr
575c73e16f1SAndreas Gohr                break;
5762812a751SAndreas Gohr            case 'trend':
5772812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
5782812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
5792812a751SAndreas Gohr                $data1   = array();
5802812a751SAndreas Gohr                $data2   = array();
5812812a751SAndreas Gohr
5822812a751SAndreas Gohr                $graph = new AGC(400, 150);
5832812a751SAndreas Gohr                $graph->setProp("type","bar");
5842812a751SAndreas Gohr                $graph->setProp("showgrid",false);
5852812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
58675fa767dSAndreas Gohr
5872812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
5882812a751SAndreas Gohr                $graph->setColor('color',1,'red');
5893c0acc14SAndreas Gohr                $graph->setColor('color',2,'yellow');
5902812a751SAndreas Gohr
5912812a751SAndreas Gohr                if($hours){
5922812a751SAndreas Gohr                    //preset $hours
5932812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
5942812a751SAndreas Gohr                        $data1[$i] = 0;
5952812a751SAndreas Gohr                        $data2[$i] = 0;
5963c0acc14SAndreas Gohr                        $data3[$i] = 0;
5972812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
5982812a751SAndreas Gohr                    }
5992812a751SAndreas Gohr                }else{
6002812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
6012812a751SAndreas Gohr                }
6022812a751SAndreas Gohr
6032812a751SAndreas Gohr                foreach($result as $row){
6042812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
6052812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
6063c0acc14SAndreas Gohr                    $data3[$row['time']] = $row['visitors'];
6072812a751SAndreas Gohr                }
6082812a751SAndreas Gohr
6092812a751SAndreas Gohr                foreach($data1 as $key => $val){
6102812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
6112812a751SAndreas Gohr                }
6122812a751SAndreas Gohr                foreach($data2 as $key => $val){
6132812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
6142812a751SAndreas Gohr                }
6153c0acc14SAndreas Gohr                foreach($data3 as $key => $val){
6163c0acc14SAndreas Gohr                    $graph->addPoint($val,$key,2);
6173c0acc14SAndreas Gohr                }
6182812a751SAndreas Gohr
6192812a751SAndreas Gohr                @$graph->graph();
6202812a751SAndreas Gohr                $graph->showGraph();
6212812a751SAndreas Gohr
62295eb68e6SAndreas Gohr            default:
62395eb68e6SAndreas Gohr                $this->sendGIF();
62495eb68e6SAndreas Gohr        }
62595eb68e6SAndreas Gohr    }
62695eb68e6SAndreas Gohr
62795eb68e6SAndreas Gohr
6282812a751SAndreas Gohr    /**
6292812a751SAndreas Gohr     * Return some aggregated statistics
6302812a751SAndreas Gohr     */
6312812a751SAndreas Gohr    function sql_aggregate($tlimit){
6322812a751SAndreas Gohr        $data = array();
6332812a751SAndreas Gohr
6342812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
6352812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6362812a751SAndreas Gohr                 WHERE $tlimit
6372812a751SAndreas Gohr                   AND ua_type = 'browser'
6382812a751SAndreas Gohr              GROUP BY ref_type";
6392812a751SAndreas Gohr        $result = $this->runSQL($sql);
6402812a751SAndreas Gohr
6412812a751SAndreas Gohr        foreach($result as $row){
6422812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
6432812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
6442812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
6452812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
6462812a751SAndreas Gohr        }
6472812a751SAndreas Gohr
6482812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
6492812a751SAndreas Gohr                       COUNT(session) as views,
6503c0acc14SAndreas Gohr                       COUNT(DISTINCT user) as users,
6513c0acc14SAndreas Gohr                       COUNT(DISTINCT uid) as visitors
6522812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6532812a751SAndreas Gohr                 WHERE $tlimit
6542812a751SAndreas Gohr                   AND ua_type = 'browser'";
6552812a751SAndreas Gohr        $result = $this->runSQL($sql);
6562812a751SAndreas Gohr
65775fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
6582812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
6592812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
6603c0acc14SAndreas Gohr        $data['visitors']  = $result[0]['visitors'];
6612812a751SAndreas Gohr
6622812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
6632812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6642812a751SAndreas Gohr                 WHERE $tlimit
6652812a751SAndreas Gohr                   AND ua_type = 'robot'";
6662812a751SAndreas Gohr        $result = $this->runSQL($sql);
6672812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
6682812a751SAndreas Gohr
6692812a751SAndreas Gohr        return $data;
6702812a751SAndreas Gohr    }
6712812a751SAndreas Gohr
672bd4217d3SAndreas Gohr    /**
673bd4217d3SAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
674bd4217d3SAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
675bd4217d3SAndreas Gohr     */
6762812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
6772812a751SAndreas Gohr        if($hours){
6782812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
6792812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6803c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6813c0acc14SAndreas Gohr                           COUNT(DISTINCT uid) as visitors
6822812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6832812a751SAndreas Gohr                     WHERE $tlimit
6842812a751SAndreas Gohr                       AND ua_type = 'browser'
6852812a751SAndreas Gohr                  GROUP BY HOUR(dt)
6862812a751SAndreas Gohr                  ORDER BY time";
6872812a751SAndreas Gohr        }else{
6882812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
6892812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6903c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6913c0acc14SAndreas Gohr                            COUNT(DISTINCT uid) as visitors
6922812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6932812a751SAndreas Gohr                     WHERE $tlimit
6942812a751SAndreas Gohr                       AND ua_type = 'browser'
6952812a751SAndreas Gohr                  GROUP BY DATE(dt)
6962812a751SAndreas Gohr                  ORDER BY time";
6972812a751SAndreas Gohr        }
6982812a751SAndreas Gohr        return $this->runSQL($sql);
6992812a751SAndreas Gohr    }
7002812a751SAndreas Gohr
70112dcdeccSAndreas Gohr    function sql_searchengines($tlimit,$start=0,$limit=20){
70212dcdeccSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, engine
70312dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
70412dcdeccSAndreas Gohr                 WHERE $tlimit
70512dcdeccSAndreas Gohr              GROUP BY engine
70612dcdeccSAndreas Gohr              ORDER BY cnt DESC, engine".
70712dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
70812dcdeccSAndreas Gohr        return $this->runSQL($sql);
70912dcdeccSAndreas Gohr    }
71012dcdeccSAndreas Gohr
71112dcdeccSAndreas Gohr    function sql_searchphrases($tlimit,$start=0,$limit=20){
71212dcdeccSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, query
71312dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
71412dcdeccSAndreas Gohr                 WHERE $tlimit
71512dcdeccSAndreas Gohr              GROUP BY query
71612dcdeccSAndreas Gohr              ORDER BY cnt DESC, query".
71712dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
71812dcdeccSAndreas Gohr        return $this->runSQL($sql);
71912dcdeccSAndreas Gohr    }
72012dcdeccSAndreas Gohr
72112dcdeccSAndreas Gohr    function sql_searchwords($tlimit,$start=0,$limit=20){
72212dcdeccSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, word
72312dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A,
72412dcdeccSAndreas Gohr                       ".$this->getConf('db_prefix')."searchwords as B
72512dcdeccSAndreas Gohr                 WHERE $tlimit
72612dcdeccSAndreas Gohr                   AND A.id = B.sid
72712dcdeccSAndreas Gohr              GROUP BY word
72812dcdeccSAndreas Gohr              ORDER BY cnt DESC, word".
72912dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
73012dcdeccSAndreas Gohr        return $this->runSQL($sql);
73112dcdeccSAndreas Gohr    }
73212dcdeccSAndreas Gohr
733e25286daSAndreas Gohr    function sql_outlinks($tlimit,$start=0,$limit=20){
734e25286daSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, link as url
735e25286daSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."outlinks as A
736e25286daSAndreas Gohr                 WHERE $tlimit
737e25286daSAndreas Gohr              GROUP BY link
738e25286daSAndreas Gohr              ORDER BY cnt DESC, link".
739e25286daSAndreas Gohr              $this->sql_limit($start,$limit);
740e25286daSAndreas Gohr        return $this->runSQL($sql);
741e25286daSAndreas Gohr    }
742e25286daSAndreas Gohr
74395eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
7442812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
74595eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
74695eb68e6SAndreas Gohr                 WHERE $tlimit
74795eb68e6SAndreas Gohr                   AND ua_type = 'browser'
74895eb68e6SAndreas Gohr              GROUP BY page
74995eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
75095eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
75195eb68e6SAndreas Gohr        return $this->runSQL($sql);
75295eb68e6SAndreas Gohr    }
75395eb68e6SAndreas Gohr
75495eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
7552812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
75695eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
75795eb68e6SAndreas Gohr                 WHERE $tlimit
75895eb68e6SAndreas Gohr                   AND ua_type = 'browser'
75995eb68e6SAndreas Gohr                   AND ref_type = 'external'
76095eb68e6SAndreas Gohr              GROUP BY ref_md5
76195eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
76295eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
76395eb68e6SAndreas Gohr        return $this->runSQL($sql);
76495eb68e6SAndreas Gohr    }
76595eb68e6SAndreas Gohr
766e7a2f1e0SAndreas Gohr    function sql_newreferer($tlimit,$start=0,$limit=20){
767e7a2f1e0SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
768e7a2f1e0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
769e7a2f1e0SAndreas Gohr                 WHERE ua_type = 'browser'
770e7a2f1e0SAndreas Gohr                   AND ref_type = 'external'
771e7a2f1e0SAndreas Gohr              GROUP BY ref_md5
772e7a2f1e0SAndreas Gohr                HAVING DATE(MIN(dt)) >= DATE('".$this->from."')
773e7a2f1e0SAndreas Gohr                   AND DATE(MIN(dt)) <= DATE('".$this->to."')
774e7a2f1e0SAndreas Gohr              ORDER BY cnt DESC, url".
775e7a2f1e0SAndreas Gohr              $this->sql_limit($start,$limit);
776e7a2f1e0SAndreas Gohr        return $this->runSQL($sql);
777e7a2f1e0SAndreas Gohr    }
778e7a2f1e0SAndreas Gohr
77995eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
780bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
78195eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
78295eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
78395eb68e6SAndreas Gohr                 WHERE $tlimit
78495eb68e6SAndreas Gohr                   AND A.ip = B.ip
78595eb68e6SAndreas Gohr              GROUP BY B.country
78695eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
78795eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
78895eb68e6SAndreas Gohr        return $this->runSQL($sql);
78995eb68e6SAndreas Gohr    }
79095eb68e6SAndreas Gohr
79175fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
79275fa767dSAndreas Gohr        if($ext){
79375fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
79475fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
79575fa767dSAndreas Gohr        }else{
79675fa767dSAndreas Gohr            $grp = 'ua_info';
79775fa767dSAndreas Gohr            $sel = 'ua_info';
79875fa767dSAndreas Gohr        }
79975fa767dSAndreas Gohr
800bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
80175fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
80275fa767dSAndreas Gohr                 WHERE $tlimit
80375fa767dSAndreas Gohr                   AND ua_type = 'browser'
80475fa767dSAndreas Gohr              GROUP BY $grp
80575fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
80675fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
80775fa767dSAndreas Gohr        return $this->runSQL($sql);
80875fa767dSAndreas Gohr    }
80975fa767dSAndreas Gohr
810bd4217d3SAndreas Gohr    function sql_os($tlimit,$start=0,$limit=20){
811bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
812bd4217d3SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
813bd4217d3SAndreas Gohr                 WHERE $tlimit
814bd4217d3SAndreas Gohr                   AND ua_type = 'browser'
815bd4217d3SAndreas Gohr              GROUP BY os
816bd4217d3SAndreas Gohr              ORDER BY cnt DESC, os".
817bd4217d3SAndreas Gohr              $this->sql_limit($start,$limit);
818bd4217d3SAndreas Gohr        return $this->runSQL($sql);
819bd4217d3SAndreas Gohr    }
820bd4217d3SAndreas Gohr
821c73e16f1SAndreas Gohr    function sql_resolution($tlimit,$start=0,$limit=20){
822c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res
823c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
824c73e16f1SAndreas Gohr                 WHERE $tlimit
825c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
826c73e16f1SAndreas Gohr                   AND screen_x != 0
827c73e16f1SAndreas Gohr              GROUP BY screen_x, screen_y
828c73e16f1SAndreas Gohr              ORDER BY cnt DESC, screen_x".
829c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
830c73e16f1SAndreas Gohr        return $this->runSQL($sql);
831c73e16f1SAndreas Gohr    }
832c73e16f1SAndreas Gohr
833c73e16f1SAndreas Gohr    function sql_viewport($tlimit,$start=0,$limit=20,$x=true){
834c73e16f1SAndreas Gohr        if($x){
835c73e16f1SAndreas Gohr            $col = 'view_x';
836c73e16f1SAndreas Gohr            $res = 'res_x';
837c73e16f1SAndreas Gohr        }else{
838c73e16f1SAndreas Gohr            $col = 'view_y';
839c73e16f1SAndreas Gohr            $res = 'res_y';
840c73e16f1SAndreas Gohr        }
841c73e16f1SAndreas Gohr
842c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt,
843c73e16f1SAndreas Gohr                       ROUND($col/10)*10 as $res
844c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
845c73e16f1SAndreas Gohr                 WHERE $tlimit
846c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
847c73e16f1SAndreas Gohr                   AND $col != 0
848c73e16f1SAndreas Gohr              GROUP BY $res
849c73e16f1SAndreas Gohr              ORDER BY cnt DESC, $res".
850c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
851c73e16f1SAndreas Gohr        return $this->runSQL($sql);
852c73e16f1SAndreas Gohr    }
853c73e16f1SAndreas Gohr
85475fa767dSAndreas Gohr
85595eb68e6SAndreas Gohr    /**
85695eb68e6SAndreas Gohr     * Builds a limit clause
85795eb68e6SAndreas Gohr     */
85895eb68e6SAndreas Gohr    function sql_limit($start,$limit){
85995eb68e6SAndreas Gohr        $start = (int) $start;
86095eb68e6SAndreas Gohr        $limit = (int) $limit;
86195eb68e6SAndreas Gohr        if($limit){
8622507f8e0SAndreas Gohr            $limit += 1;
86395eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
86495eb68e6SAndreas Gohr        }elseif($start){
86595eb68e6SAndreas Gohr            return " OFFSET $start";
86695eb68e6SAndreas Gohr        }
86795eb68e6SAndreas Gohr        return '';
86895eb68e6SAndreas Gohr    }
8691878f16fSAndreas Gohr
8701878f16fSAndreas Gohr    /**
87114d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
8721878f16fSAndreas Gohr     */
87314d99ec0SAndreas Gohr    function dbLink(){
8741878f16fSAndreas Gohr        // connect to DB if needed
8751878f16fSAndreas Gohr        if(!$this->dblink){
8761878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
8771878f16fSAndreas Gohr                                          $this->getConf('db_user'),
8781878f16fSAndreas Gohr                                          $this->getConf('db_password'));
8791878f16fSAndreas Gohr            if(!$this->dblink){
8801878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
8811878f16fSAndreas Gohr                return null;
8821878f16fSAndreas Gohr            }
8831878f16fSAndreas Gohr            // set utf-8
8841878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
8851878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
8861878f16fSAndreas Gohr                return null;
8871878f16fSAndreas Gohr            }
8881878f16fSAndreas Gohr        }
88914d99ec0SAndreas Gohr        return $this->dblink;
89014d99ec0SAndreas Gohr    }
8911878f16fSAndreas Gohr
89214d99ec0SAndreas Gohr    /**
89314d99ec0SAndreas Gohr     * Simple function to run a DB query
89414d99ec0SAndreas Gohr     */
89514d99ec0SAndreas Gohr    function runSQL($sql_string) {
89614d99ec0SAndreas Gohr        $link = $this->dbLink();
89714d99ec0SAndreas Gohr
89814d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
89994171ff3SAndreas Gohr        if(!$result){
9002812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
9011878f16fSAndreas Gohr            return null;
9021878f16fSAndreas Gohr        }
9031878f16fSAndreas Gohr
9041878f16fSAndreas Gohr        $resultarray = array();
9051878f16fSAndreas Gohr
9061878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
9071878f16fSAndreas Gohr        if ($result != 1) {
9081878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
9091878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
9101878f16fSAndreas Gohr                $resultarray[]=$temparray;
9111878f16fSAndreas Gohr            }
9121878f16fSAndreas Gohr            mysql_free_result($result);
9131878f16fSAndreas Gohr        }
9141878f16fSAndreas Gohr
91514d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
91614d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
9171878f16fSAndreas Gohr        }
9181878f16fSAndreas Gohr
9191878f16fSAndreas Gohr        return $resultarray;
9201878f16fSAndreas Gohr    }
9211878f16fSAndreas Gohr
9221878f16fSAndreas Gohr    /**
92314d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
9241878f16fSAndreas Gohr     */
92514d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
92614d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
92714d99ec0SAndreas Gohr        $ua = strtolower($ua);
92814d99ec0SAndreas Gohr
92914d99ec0SAndreas Gohr        // common browsers
93014d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
93114d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
93214d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
93314d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
93414d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
93514d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
93614d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
93714d99ec0SAndreas Gohr
93814d99ec0SAndreas Gohr        $name = '';
93914d99ec0SAndreas Gohr        # IE ?
94014d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
94114d99ec0SAndreas Gohr            $type = 'browser';
94214d99ec0SAndreas Gohr            $ver  = $m[2];
94314d99ec0SAndreas Gohr            $name = 'msie';
94414d99ec0SAndreas Gohr        }
94514d99ec0SAndreas Gohr        # Firefox ?
94614d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
94714d99ec0SAndreas Gohr            $type = 'browser';
94814d99ec0SAndreas Gohr            $ver  = $m[1];
94914d99ec0SAndreas Gohr            $name = 'firefox';
95014d99ec0SAndreas Gohr        }
95114d99ec0SAndreas Gohr        # Subversion ?
95214d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
95314d99ec0SAndreas Gohr            $type = 'rcs';
95414d99ec0SAndreas Gohr            $ver  = $m[1];
95514d99ec0SAndreas Gohr            $name = 'svn';
95614d99ec0SAndreas Gohr        }
95714d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
95814d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
95914d99ec0SAndreas Gohr            $type = 'browser';
96014d99ec0SAndreas Gohr            $ver  = $m[1];
96114d99ec0SAndreas Gohr            $name = 'netscape';
96214d99ec0SAndreas Gohr        }
96314d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
96414d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
96514d99ec0SAndreas Gohr            $type = 'browser';
96614d99ec0SAndreas Gohr            $ver  = $m[2];
96714d99ec0SAndreas Gohr            $name = 'netscape';
96814d99ec0SAndreas Gohr        }else{
96914d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
97014d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
97114d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
97214d99ec0SAndreas Gohr                    // it's a browser!
97314d99ec0SAndreas Gohr                    $type = 'browser';
97414d99ec0SAndreas Gohr                    $name = strtolower($regex);
97514d99ec0SAndreas Gohr                    break;
97614d99ec0SAndreas Gohr                }
97714d99ec0SAndreas Gohr            }
97814d99ec0SAndreas Gohr        }
97914d99ec0SAndreas Gohr
98075fa767dSAndreas Gohr        // check versions for Safari and Opera
98175fa767dSAndreas Gohr        if($name == 'safari'){
98275fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
98375fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
98475fa767dSAndreas Gohr            }
98575fa767dSAndreas Gohr        }elseif($name == 'opera'){
98675fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
98775fa767dSAndreas Gohr                $ver = $match[1];
98875fa767dSAndreas Gohr            }
98975fa767dSAndreas Gohr        }
99075fa767dSAndreas Gohr
99175fa767dSAndreas Gohr
99214d99ec0SAndreas Gohr        // check OS for browsers
99314d99ec0SAndreas Gohr        if($type == 'browser'){
99414d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
99514d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
99614d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
99714d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
99814d99ec0SAndreas Gohr                    break;
99914d99ec0SAndreas Gohr                }
100014d99ec0SAndreas Gohr            }
100114d99ec0SAndreas Gohr
100214d99ec0SAndreas Gohr        }
100314d99ec0SAndreas Gohr
100414d99ec0SAndreas Gohr        // are we done now?
100514d99ec0SAndreas Gohr        if($name) return $name;
100614d99ec0SAndreas Gohr
100714d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
100814d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
100914d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
101014d99ec0SAndreas Gohr                    // it's a robot!
101114d99ec0SAndreas Gohr                    $type = 'robot';
101214d99ec0SAndreas Gohr                    return strtolower($regex);
101314d99ec0SAndreas Gohr            }
101414d99ec0SAndreas Gohr        }
101514d99ec0SAndreas Gohr
101614d99ec0SAndreas Gohr        // dunno
10171878f16fSAndreas Gohr        return '';
10181878f16fSAndreas Gohr    }
10191878f16fSAndreas Gohr
10201878f16fSAndreas Gohr    /**
1021322de360SAndreas Gohr     * Log search queries
102214d99ec0SAndreas Gohr     */
102314d99ec0SAndreas Gohr    function log_search($referer,&$type){
102414d99ec0SAndreas Gohr        $referer = strtolower($referer);
1025673875b1SAndreas Gohr        $ref     = strtr($referer,' +','__');
102614d99ec0SAndreas Gohr
102714d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
102814d99ec0SAndreas Gohr
102914d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
1030673875b1SAndreas Gohr            if(preg_match('/'.$regex.'/',$ref)){
103114d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
1032673875b1SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$ref)){
103314d99ec0SAndreas Gohr                    // it's a search engine!
103414d99ec0SAndreas Gohr                    $type = 'search';
103514d99ec0SAndreas Gohr                    break;
103614d99ec0SAndreas Gohr                }
103714d99ec0SAndreas Gohr            }
103814d99ec0SAndreas Gohr        }
103914d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
104014d99ec0SAndreas Gohr
1041322de360SAndreas Gohr        // extract query
1042322de360SAndreas Gohr        $engine = $SearchEnginesHashID[$regex];
1043322de360SAndreas Gohr        $param = $SearchEnginesKnownUrl[$engine];
1044322de360SAndreas Gohr        if($param && preg_match('/'.$param.'(.*?)[&$]/',$referer,$match)){
1045322de360SAndreas Gohr            $query = array_pop($match);
1046322de360SAndreas Gohr        }elseif(preg_match('/'.$WordsToExtractSearchUrl.'(.*?)[&$]/',$referer,$match)){
1047322de360SAndreas Gohr            $query = array_pop($match);
1048322de360SAndreas Gohr        }
1049322de360SAndreas Gohr        if(!$query) return; // we failed
1050322de360SAndreas Gohr
1051322de360SAndreas Gohr        // clean the query
1052322de360SAndreas Gohr        $query = preg_replace('/^(cache|related):[^\+]+/','',$query);  // non-search queries
1053322de360SAndreas Gohr        $query = preg_replace('/%0[ad]/',' ',$query);                  // LF CR
1054322de360SAndreas Gohr        $query = preg_replace('/%2[02789abc]/',' ',$query);            // space " ' ( ) * + ,
1055322de360SAndreas Gohr        $query = preg_replace('/%3a/',' ',$query);                     // :
1056673875b1SAndreas Gohr        $query = strtr($query,'+\'()"*,:','        ');                 // badly encoded
1057322de360SAndreas Gohr        $query = preg_replace('/ +/',' ',$query);                      // ws compact
1058322de360SAndreas Gohr        $query = trim($query);
1059322de360SAndreas Gohr        $query = urldecode($query);
1060322de360SAndreas Gohr        if(!utf8_check($query)) $query = utf8_encode($query);          // assume latin1 if not utf8
1061322de360SAndreas Gohr        $query = utf8_strtolower($query);
1062322de360SAndreas Gohr
1063322de360SAndreas Gohr        // log it!
1064322de360SAndreas Gohr        $page  = addslashes($_REQUEST['p']);
1065322de360SAndreas Gohr        $query = addslashes($query);
1066673875b1SAndreas Gohr        $sql  = "INSERT INTO ".$this->getConf('db_prefix')."search
1067322de360SAndreas Gohr                    SET dt       = NOW(),
1068322de360SAndreas Gohr                        page     = '$page',
1069322de360SAndreas Gohr                        query    = '$query',
1070322de360SAndreas Gohr                        engine   = '$engine'";
1071322de360SAndreas Gohr        $id = $this->runSQL($sql);
1072322de360SAndreas Gohr        if(is_null($id)){
1073322de360SAndreas Gohr            global $MSG;
1074322de360SAndreas Gohr            print_r($MSG);
1075322de360SAndreas Gohr            return;
1076322de360SAndreas Gohr        }
1077322de360SAndreas Gohr
1078322de360SAndreas Gohr        // log single keywords
1079322de360SAndreas Gohr        $words = explode(' ',utf8_stripspecials($query,' ','\._\-:\*'));
1080322de360SAndreas Gohr        foreach($words as $word){
1081673875b1SAndreas Gohr            if(!$word) continue;
1082322de360SAndreas Gohr            $word = addslashes($word);
1083322de360SAndreas Gohr            $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."searchwords
1084322de360SAndreas Gohr                       SET sid  = $id,
1085322de360SAndreas Gohr                           word = '$word'";
1086322de360SAndreas Gohr            $ok = $this->runSQL($sql);
1087322de360SAndreas Gohr            if(is_null($ok)){
1088322de360SAndreas Gohr                global $MSG;
1089322de360SAndreas Gohr                print_r($MSG);
1090322de360SAndreas Gohr            }
1091322de360SAndreas Gohr        }
109214d99ec0SAndreas Gohr    }
109314d99ec0SAndreas Gohr
109414d99ec0SAndreas Gohr    /**
109514d99ec0SAndreas Gohr     * Resolve IP to country/city
109614d99ec0SAndreas Gohr     */
109714d99ec0SAndreas Gohr    function log_ip($ip){
109814d99ec0SAndreas Gohr        // check if IP already known and up-to-date
109914d99ec0SAndreas Gohr        $sql = "SELECT ip
110014d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
110114d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
110214d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
110314d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
110414d99ec0SAndreas Gohr        if($result[0]['ip']) return;
110514d99ec0SAndreas Gohr
110614d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
110714d99ec0SAndreas Gohr        $http->timeout = 10;
110814d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
110914d99ec0SAndreas Gohr
111014d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
111114d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
111214d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
111314d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
111414d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
111514d99ec0SAndreas Gohr            $ip      = addslashes($ip);
111614d99ec0SAndreas Gohr
111714d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
111814d99ec0SAndreas Gohr                        SET ip = '$ip',
111914d99ec0SAndreas Gohr                            country = '$country',
112014d99ec0SAndreas Gohr                            code    = '$code',
112114d99ec0SAndreas Gohr                            city    = '$city',
112214d99ec0SAndreas Gohr                            host    = '$host'";
112314d99ec0SAndreas Gohr            $this->runSQL($sql);
112414d99ec0SAndreas Gohr        }
112514d99ec0SAndreas Gohr    }
112614d99ec0SAndreas Gohr
112714d99ec0SAndreas Gohr    /**
1128e25286daSAndreas Gohr     * log a click on an external link
1129e25286daSAndreas Gohr     *
1130e25286daSAndreas Gohr     * called from log.php
1131e25286daSAndreas Gohr     */
1132e25286daSAndreas Gohr    function log_outgoing(){
1133e25286daSAndreas Gohr        if(!$_REQUEST['ol']) return;
1134e25286daSAndreas Gohr
1135e25286daSAndreas Gohr        $link_md5 = md5($link);
1136e25286daSAndreas Gohr        $link     = addslashes($_REQUEST['ol']);
1137e25286daSAndreas Gohr        $session  = addslashes(session_id());
1138d8c4d85eSAndreas Gohr        $page     = addslashes($_REQUEST['p']);
1139e25286daSAndreas Gohr
1140e25286daSAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks
1141e25286daSAndreas Gohr                    SET dt       = NOW(),
1142e25286daSAndreas Gohr                        session  = '$session',
1143d8c4d85eSAndreas Gohr                        page     = '$page',
1144e25286daSAndreas Gohr                        link_md5 = '$link_md5',
1145e25286daSAndreas Gohr                        link     = '$link'";
1146e25286daSAndreas Gohr        $ok = $this->runSQL($sql);
1147e25286daSAndreas Gohr        if(is_null($ok)){
1148e25286daSAndreas Gohr            global $MSG;
1149e25286daSAndreas Gohr            print_r($MSG);
1150e25286daSAndreas Gohr        }
1151e25286daSAndreas Gohr    }
1152e25286daSAndreas Gohr
1153e25286daSAndreas Gohr    /**
11541878f16fSAndreas Gohr     * log a page access
11551878f16fSAndreas Gohr     *
11561878f16fSAndreas Gohr     * called from log.php
11571878f16fSAndreas Gohr     */
11581878f16fSAndreas Gohr    function log_access(){
115994171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
116094171ff3SAndreas Gohr
116114d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
116214d99ec0SAndreas Gohr
116314d99ec0SAndreas Gohr        // handle referer
116414d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
116514d99ec0SAndreas Gohr        if($referer){
116614d99ec0SAndreas Gohr            $ref     = addslashes($referer);
116714d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
116814d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
116914d99ec0SAndreas Gohr                $ref_type = 'internal';
117014d99ec0SAndreas Gohr            }else{
117114d99ec0SAndreas Gohr                $ref_type = 'external';
117214d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
117314d99ec0SAndreas Gohr            }
117414d99ec0SAndreas Gohr        }else{
117514d99ec0SAndreas Gohr            $ref      = '';
117614d99ec0SAndreas Gohr            $ref_md5  = '';
117714d99ec0SAndreas Gohr            $ref_type = '';
117814d99ec0SAndreas Gohr        }
117914d99ec0SAndreas Gohr
118014d99ec0SAndreas Gohr        // handle user agent
118114d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
118214d99ec0SAndreas Gohr
118314d99ec0SAndreas Gohr        $ua      = addslashes($agent);
118414d99ec0SAndreas Gohr        $ua_type = '';
118514d99ec0SAndreas Gohr        $ua_ver  = '';
118614d99ec0SAndreas Gohr        $os      = '';
118714d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
118814d99ec0SAndreas Gohr
11891878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
11901878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
11911878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
11921878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
11931878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
11941878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
119575fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
11963c0acc14SAndreas Gohr        $uid     = addslashes($_REQUEST['uid']);
11971878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
11981878f16fSAndreas Gohr        $session = addslashes(session_id());
11993c0acc14SAndreas Gohr        if(!$uid) $uid = $session;
12001878f16fSAndreas Gohr
120194171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
120275fa767dSAndreas Gohr                    SET dt       = NOW(),
120375fa767dSAndreas Gohr                        page     = '$page',
12041878f16fSAndreas Gohr                        ip       = '$ip',
12051878f16fSAndreas Gohr                        ua       = '$ua',
12061878f16fSAndreas Gohr                        ua_info  = '$ua_info',
120714d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
120814d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
120914d99ec0SAndreas Gohr                        os       = '$os',
12101878f16fSAndreas Gohr                        ref      = '$ref',
121194171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
121214d99ec0SAndreas Gohr                        ref_type = '$ref_type',
12131878f16fSAndreas Gohr                        screen_x = '$sx',
12141878f16fSAndreas Gohr                        screen_y = '$sy',
12151878f16fSAndreas Gohr                        view_x   = '$vx',
12161878f16fSAndreas Gohr                        view_y   = '$vy',
121775fa767dSAndreas Gohr                        js       = '$js',
12181878f16fSAndreas Gohr                        user     = '$user',
12193c0acc14SAndreas Gohr                        session  = '$session',
12203c0acc14SAndreas Gohr                        uid      = '$uid'";
12211878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
12221878f16fSAndreas Gohr        if(is_null($ok)){
12231878f16fSAndreas Gohr            global $MSG;
12241878f16fSAndreas Gohr            print_r($MSG);
12251878f16fSAndreas Gohr        }
122614d99ec0SAndreas Gohr
122714d99ec0SAndreas Gohr        // resolve the IP
122814d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
12291878f16fSAndreas Gohr    }
12301878f16fSAndreas Gohr
12311878f16fSAndreas Gohr    /**
12321878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
12331878f16fSAndreas Gohr     *
12341878f16fSAndreas Gohr     * @called from log.php
12351878f16fSAndreas Gohr     *
12361878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
12371878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
12381878f16fSAndreas Gohr     */
12391878f16fSAndreas Gohr    function sendGIF(){
12401878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
12411878f16fSAndreas Gohr        header('Content-Type: image/gif');
12421878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
12431878f16fSAndreas Gohr        header('Connection: Close');
12441878f16fSAndreas Gohr        print $img;
12451878f16fSAndreas Gohr        flush();
12461878f16fSAndreas Gohr        // Browser should drop connection after this
12471878f16fSAndreas Gohr        // Thinks it's got the whole image
12481878f16fSAndreas Gohr    }
12491878f16fSAndreas Gohr
12501878f16fSAndreas Gohr}
1251