xref: /plugin/statistics/admin.php (revision 2ee939eedbbb7aaf24774bef97e5194b1f3ea054)
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
68*2ee939eeSAndreas Gohr        $tlimit = "A.dt >= '$from 00:00:00' AND A.dt <= '$to 23:59:59'";
69e8699bceSAndreas Gohr        $this->tlimit = $tlimit;
70e8699bceSAndreas Gohr        $this->from   = $from;
71e8699bceSAndreas Gohr        $this->to     = $to;
721878f16fSAndreas Gohr    }
731878f16fSAndreas Gohr
741878f16fSAndreas Gohr    /**
7594171ff3SAndreas Gohr     * fixme build statistics here
761878f16fSAndreas Gohr     */
771878f16fSAndreas Gohr    function html() {
789da6395dSAndreas Gohr        $this->html_toc();
79264f1744SAndreas Gohr        echo '<h1>Access Statistics</h1>';
80264f1744SAndreas Gohr        $this->html_timeselect();
81264f1744SAndreas Gohr
82264f1744SAndreas Gohr        switch($this->opt){
839da6395dSAndreas Gohr            case 'country':
849da6395dSAndreas Gohr                $this->html_country();
859da6395dSAndreas Gohr                break;
869da6395dSAndreas Gohr            case 'page':
879da6395dSAndreas Gohr                $this->html_page();
889da6395dSAndreas Gohr                break;
8975fa767dSAndreas Gohr            case 'browser':
9075fa767dSAndreas Gohr                $this->html_browser();
9175fa767dSAndreas Gohr                break;
92bd4217d3SAndreas Gohr            case 'os':
93bd4217d3SAndreas Gohr                $this->html_os();
94bd4217d3SAndreas Gohr                break;
959da6395dSAndreas Gohr            case 'referer':
969da6395dSAndreas Gohr                $this->html_referer();
979da6395dSAndreas Gohr                break;
98e7a2f1e0SAndreas Gohr            case 'newreferer':
99e7a2f1e0SAndreas Gohr                $this->html_newreferer();
100e7a2f1e0SAndreas Gohr                break;
101e25286daSAndreas Gohr            case 'outlinks':
102e25286daSAndreas Gohr                $this->html_outlinks();
103e25286daSAndreas Gohr                break;
104c73e16f1SAndreas Gohr            case 'resolution':
105c73e16f1SAndreas Gohr                $this->html_resolution();
106c73e16f1SAndreas Gohr                break;
10712dcdeccSAndreas Gohr            case 'searchphrases':
10812dcdeccSAndreas Gohr                $this->html_searchphrases();
10912dcdeccSAndreas Gohr                break;
11012dcdeccSAndreas Gohr            case 'searchwords':
11112dcdeccSAndreas Gohr                $this->html_searchwords();
11212dcdeccSAndreas Gohr                break;
11312dcdeccSAndreas Gohr            case 'searchengines':
11412dcdeccSAndreas Gohr                $this->html_searchengines();
11512dcdeccSAndreas Gohr                break;
11614d99ec0SAndreas Gohr            default:
1179da6395dSAndreas Gohr                $this->html_dashboard();
11814d99ec0SAndreas Gohr        }
11914d99ec0SAndreas Gohr    }
12014d99ec0SAndreas Gohr
1219da6395dSAndreas Gohr    function html_toc(){
1229da6395dSAndreas Gohr        echo '<div class="toc">';
1239da6395dSAndreas Gohr        echo '<div class="tocheader toctoggle" id="toc__header">';
1249da6395dSAndreas Gohr        echo 'Detailed Statistics';
1259da6395dSAndreas Gohr        echo '</div>';
1269da6395dSAndreas Gohr        echo '<div id="toc__inside">';
1279da6395dSAndreas Gohr        echo '<ul class="toc">';
1289da6395dSAndreas Gohr
1299da6395dSAndreas Gohr        echo '<li><div class="li">';
1302507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=&amp;f='.$this->from.'&amp;t='.$this->to.'">Dashboard</a>';
1319da6395dSAndreas Gohr        echo '</div></li>';
1329da6395dSAndreas Gohr
1339da6395dSAndreas Gohr        echo '<li><div class="li">';
1342507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'">Pages</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=referer&amp;f='.$this->from.'&amp;t='.$this->to.'">Incoming Links</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=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'">New Incoming Links</a>';
143e7a2f1e0SAndreas Gohr        echo '</div></li>';
144e7a2f1e0SAndreas Gohr
145e7a2f1e0SAndreas Gohr        echo '<li><div class="li">';
146e25286daSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=outlinks&amp;f='.$this->from.'&amp;t='.$this->to.'">Outgoing Links</a>';
147e25286daSAndreas Gohr        echo '</div></li>';
148e25286daSAndreas Gohr
149e25286daSAndreas Gohr        echo '<li><div class="li">';
15012dcdeccSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchphrases&amp;f='.$this->from.'&amp;t='.$this->to.'">Search Phrases</a>';
15112dcdeccSAndreas Gohr        echo '</div></li>';
15212dcdeccSAndreas Gohr
15312dcdeccSAndreas Gohr        echo '<li><div class="li">';
15412dcdeccSAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchwords&amp;f='.$this->from.'&amp;t='.$this->to.'">Search Words</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=searchengines&amp;f='.$this->from.'&amp;t='.$this->to.'">Search Engines</a>';
15912dcdeccSAndreas Gohr        echo '</div></li>';
16012dcdeccSAndreas Gohr
16112dcdeccSAndreas Gohr
16212dcdeccSAndreas Gohr        echo '<li><div class="li">';
1632507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=browser&amp;f='.$this->from.'&amp;t='.$this->to.'">Browsers</a>';
16475fa767dSAndreas Gohr        echo '</div></li>';
16575fa767dSAndreas Gohr
16675fa767dSAndreas Gohr        echo '<li><div class="li">';
1672507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=os&amp;f='.$this->from.'&amp;t='.$this->to.'">Operating Systems</a>';
168bd4217d3SAndreas Gohr        echo '</div></li>';
169bd4217d3SAndreas Gohr
170bd4217d3SAndreas Gohr        echo '<li><div class="li">';
1712507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=country&amp;f='.$this->from.'&amp;t='.$this->to.'">Countries</a>';
1729da6395dSAndreas Gohr        echo '</div></li>';
1739da6395dSAndreas Gohr
174c73e16f1SAndreas Gohr        echo '<li><div class="li">';
175c73e16f1SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=resolution&amp;f='.$this->from.'&amp;t='.$this->to.'">Resolution</a>';
176c73e16f1SAndreas Gohr        echo '</div></li>';
177c73e16f1SAndreas Gohr
1789da6395dSAndreas Gohr        echo '</ul>';
1799da6395dSAndreas Gohr        echo '</div>';
1809da6395dSAndreas Gohr        echo '</div>';
1819da6395dSAndreas Gohr    }
1829da6395dSAndreas Gohr
1832507f8e0SAndreas Gohr    function html_pager($limit,$next){
1842507f8e0SAndreas Gohr        echo '<div class="plg_stats_pager">';
1852507f8e0SAndreas Gohr
1862507f8e0SAndreas Gohr        if($this->start > 0){
1872507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
1882507f8e0SAndreas 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>';
1892507f8e0SAndreas Gohr        }
1902507f8e0SAndreas Gohr
1912507f8e0SAndreas Gohr        if($next){
1922507f8e0SAndreas Gohr            $go = $this->start + $limit;
1932507f8e0SAndreas 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>';
1942507f8e0SAndreas Gohr        }
1952507f8e0SAndreas Gohr        echo '</div>';
1962507f8e0SAndreas Gohr    }
1972507f8e0SAndreas Gohr
198264f1744SAndreas Gohr    /**
199264f1744SAndreas Gohr     * Print the time selection menu
200264f1744SAndreas Gohr     */
20114d99ec0SAndreas Gohr    function html_timeselect(){
202264f1744SAndreas Gohr        $now   = date('Y-m-d');
203264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
204264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
205264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
20614d99ec0SAndreas Gohr
207264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
208264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
209264f1744SAndreas Gohr        echo '<ul>';
210264f1744SAndreas Gohr
211264f1744SAndreas Gohr        echo '<li>';
2122507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'">';
213264f1744SAndreas Gohr        echo 'today';
214264f1744SAndreas Gohr        echo '</a>';
215264f1744SAndreas Gohr        echo '</li>';
216264f1744SAndreas Gohr
217264f1744SAndreas Gohr        echo '<li>';
2182507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'">';
219264f1744SAndreas Gohr        echo 'yesterday';
220264f1744SAndreas Gohr        echo '</a>';
221264f1744SAndreas Gohr        echo '</li>';
222264f1744SAndreas Gohr
223264f1744SAndreas Gohr        echo '<li>';
2242507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'">';
225264f1744SAndreas Gohr        echo 'last 7 days';
226264f1744SAndreas Gohr        echo '</a>';
227264f1744SAndreas Gohr        echo '</li>';
228264f1744SAndreas Gohr
229264f1744SAndreas Gohr        echo '<li>';
2302507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'">';
231264f1744SAndreas Gohr        echo 'last 30 days';
232264f1744SAndreas Gohr        echo '</a>';
233264f1744SAndreas Gohr        echo '</li>';
234264f1744SAndreas Gohr
235264f1744SAndreas Gohr        echo '</ul>';
236264f1744SAndreas Gohr
237264f1744SAndreas Gohr
238264f1744SAndreas Gohr        echo '<form action="" method="get">';
239264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
240264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
241264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
242264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
243264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
244264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
24514d99ec0SAndreas Gohr        echo '</form>';
246264f1744SAndreas Gohr
247264f1744SAndreas Gohr        echo '</div>';
24814d99ec0SAndreas Gohr    }
24914d99ec0SAndreas Gohr
25014d99ec0SAndreas Gohr
251f5f32cbfSAndreas Gohr    /**
252f5f32cbfSAndreas Gohr     * Print an introductionary screen
253f5f32cbfSAndreas Gohr     */
25414d99ec0SAndreas Gohr    function html_dashboard(){
2552812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
2562812a751SAndreas Gohr              choose a topic from the list.</p>';
2572812a751SAndreas Gohr
2582812a751SAndreas Gohr
259264f1744SAndreas Gohr        echo '<div class="plg_stats_dashboard">';
260264f1744SAndreas Gohr
2612812a751SAndreas Gohr        // general info
2622812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
2632812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2642812a751SAndreas Gohr        echo '<ul>';
2652812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views </li>';
2663c0acc14SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>';
2673c0acc14SAndreas Gohr        echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>';
2682812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
2692812a751SAndreas Gohr
2702812a751SAndreas Gohr        echo '</ul>';
2712812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2722812a751SAndreas Gohr        echo '</div>';
2732812a751SAndreas Gohr
27414d99ec0SAndreas Gohr
27587d5e44bSAndreas Gohr        // top pages today
276264f1744SAndreas Gohr        echo '<div>';
277264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
27895eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
2792812a751SAndreas Gohr        $this->html_resulttable($result);
2802507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
281264f1744SAndreas Gohr        echo '</div>';
28287d5e44bSAndreas Gohr
28387d5e44bSAndreas Gohr        // top referer today
284264f1744SAndreas Gohr        echo '<div>';
285e7a2f1e0SAndreas Gohr        echo '<h2>Newest incoming links</h2>';
286e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,15);
2872812a751SAndreas Gohr        $this->html_resulttable($result);
2882507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
289264f1744SAndreas Gohr        echo '</div>';
29054f6c432SAndreas Gohr
29129dea504SAndreas Gohr        // top searches today
292264f1744SAndreas Gohr        echo '<div>';
29329dea504SAndreas Gohr        echo '<h2>Top search phrases</h2>';
29429dea504SAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,15);
29529dea504SAndreas Gohr        $this->html_resulttable($result);
29629dea504SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchphrases&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
297264f1744SAndreas Gohr        echo '</div>';
298264f1744SAndreas Gohr
299264f1744SAndreas Gohr        echo '</div>';
30014d99ec0SAndreas Gohr    }
30114d99ec0SAndreas Gohr
3029da6395dSAndreas Gohr    function html_country(){
3039da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3049da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
305bd4217d3SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
3069da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
3072507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3089da6395dSAndreas Gohr        echo '</div>';
3099da6395dSAndreas Gohr    }
3109da6395dSAndreas Gohr
3119da6395dSAndreas Gohr    function html_page(){
3129da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3139da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
3149da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
3152507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3169da6395dSAndreas Gohr        echo '</div>';
3179da6395dSAndreas Gohr    }
3189da6395dSAndreas Gohr
31975fa767dSAndreas Gohr    function html_browser(){
32075fa767dSAndreas Gohr        echo '<div class="plg_stats_full">';
32175fa767dSAndreas Gohr        echo '<h2>Browser Shootout</h2>';
32275fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
32375fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
3242507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
32575fa767dSAndreas Gohr        echo '</div>';
32675fa767dSAndreas Gohr    }
32775fa767dSAndreas Gohr
328bd4217d3SAndreas Gohr    function html_os(){
329bd4217d3SAndreas Gohr        echo '<div class="plg_stats_full">';
330bd4217d3SAndreas Gohr        echo '<h2>Operating Systems</h2>';
331bd4217d3SAndreas Gohr        $result = $this->sql_os($this->tlimit,$this->start,150,true);
3322507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
333bd4217d3SAndreas Gohr        echo '</div>';
334bd4217d3SAndreas Gohr    }
335bd4217d3SAndreas Gohr
3369da6395dSAndreas Gohr    function html_referer(){
3379da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
3389da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
3392812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
3402812a751SAndreas Gohr
3412812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
3422812a751SAndreas Gohr
34394023548SAndreas Gohr        if($all){
3442812a751SAndreas Gohr            printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
3452812a751SAndreas Gohr                    %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
3462812a751SAndreas Gohr                    links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
3472812a751SAndreas Gohr                    $result['search'],(100*$result['search']/$all),$result['external'],
3482812a751SAndreas Gohr                    (100*$result['external']/$all));
34994023548SAndreas Gohr        }
3502812a751SAndreas Gohr
3519da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
3522507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3539da6395dSAndreas Gohr        echo '</div>';
3549da6395dSAndreas Gohr    }
3559da6395dSAndreas Gohr
356e7a2f1e0SAndreas Gohr    function html_newreferer(){
357e7a2f1e0SAndreas Gohr        echo '<div class="plg_stats_full">';
358e7a2f1e0SAndreas Gohr        echo '<h2>New Incoming Links</h2>';
359e7a2f1e0SAndreas Gohr        echo '<p>The following incoming links where first logged in the selected time frame,
360e7a2f1e0SAndreas Gohr              and have never been seen before.</p>';
361e7a2f1e0SAndreas Gohr
362e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,150);
3632507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
364e7a2f1e0SAndreas Gohr        echo '</div>';
365e7a2f1e0SAndreas Gohr    }
366e7a2f1e0SAndreas Gohr
367e25286daSAndreas Gohr    function html_outlinks(){
368e25286daSAndreas Gohr        echo '<div class="plg_stats_full">';
369e25286daSAndreas Gohr        echo '<h2>Outgoing Links</h2>';
370e25286daSAndreas Gohr
371e25286daSAndreas Gohr        $result = $this->sql_outlinks($this->tlimit,$this->start,150);
372e25286daSAndreas Gohr        $this->html_resulttable($result,'',150);
373e25286daSAndreas Gohr        echo '</div>';
374e25286daSAndreas Gohr    }
375e25286daSAndreas Gohr
37612dcdeccSAndreas Gohr    function html_searchphrases(){
37712dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
37812dcdeccSAndreas Gohr        echo '<h2>Search Phrases</h2>';
37912dcdeccSAndreas Gohr
38012dcdeccSAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,150);
38112dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
38212dcdeccSAndreas Gohr        echo '</div>';
38312dcdeccSAndreas Gohr    }
38412dcdeccSAndreas Gohr
38512dcdeccSAndreas Gohr    function html_searchwords(){
38612dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
38712dcdeccSAndreas Gohr        echo '<h2>Search Words</h2>';
38812dcdeccSAndreas Gohr
38912dcdeccSAndreas Gohr        $result = $this->sql_searchwords($this->tlimit,$this->start,150);
39012dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
39112dcdeccSAndreas Gohr        echo '</div>';
39212dcdeccSAndreas Gohr    }
39312dcdeccSAndreas Gohr
39412dcdeccSAndreas Gohr    function html_searchengines(){
39512dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
39612dcdeccSAndreas Gohr        echo '<h2>Search Engines</h2>';
39712dcdeccSAndreas Gohr
39812dcdeccSAndreas Gohr        $result = $this->sql_searchengines($this->tlimit,$this->start,150);
39912dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
40012dcdeccSAndreas Gohr        echo '</div>';
40112dcdeccSAndreas Gohr    }
40212dcdeccSAndreas Gohr
403e25286daSAndreas Gohr
404c73e16f1SAndreas Gohr    function html_resolution(){
405c73e16f1SAndreas Gohr        echo '<div class="plg_stats_full">';
406c73e16f1SAndreas Gohr        echo '<h2>Resolution</h2>';
407c73e16f1SAndreas Gohr        $result = $this->sql_resolution($this->tlimit,$this->start,150);
408c73e16f1SAndreas Gohr        $this->html_resulttable($result,'',150);
409c73e16f1SAndreas Gohr
410c73e16f1SAndreas Gohr        echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you
411c73e16f1SAndreas Gohr              much about about the real size of their browser windows. The graphic below shows the size distribution of
412c73e16f1SAndreas Gohr              the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged
413c73e16f1SAndreas Gohr              in all browsers. Because users may resize their browser window while browsing your site the statistics may
414c73e16f1SAndreas Gohr              be flawed. Take it with a grain of salt.</p>';
415c73e16f1SAndreas Gohr
416c73e16f1SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
417c73e16f1SAndreas Gohr        echo '</div>';
418c73e16f1SAndreas Gohr    }
4199da6395dSAndreas Gohr
4209da6395dSAndreas Gohr
42114d99ec0SAndreas Gohr    /**
42214d99ec0SAndreas Gohr     * Display a result in a HTML table
42314d99ec0SAndreas Gohr     */
4242507f8e0SAndreas Gohr    function html_resulttable($result,$header='',$pager=0){
42514d99ec0SAndreas Gohr        echo '<table>';
4262812a751SAndreas Gohr        if(is_array($header)){
42714d99ec0SAndreas Gohr            echo '<tr>';
42814d99ec0SAndreas Gohr            foreach($header as $h){
42914d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
43014d99ec0SAndreas Gohr            }
43114d99ec0SAndreas Gohr            echo '</tr>';
4322812a751SAndreas Gohr        }
43314d99ec0SAndreas Gohr
4342507f8e0SAndreas Gohr        $count = 0;
435*2ee939eeSAndreas Gohr        if(is_array($result)) foreach($result as $row){
43614d99ec0SAndreas Gohr            echo '<tr>';
43714d99ec0SAndreas Gohr            foreach($row as $k => $v){
4382812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
43914d99ec0SAndreas Gohr                if($k == 'page'){
44014d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
44114d99ec0SAndreas Gohr                    echo hsc($v);
44214d99ec0SAndreas Gohr                    echo '</a>';
44314d99ec0SAndreas Gohr                }elseif($k == 'url'){
44454f6c432SAndreas Gohr                    $url = hsc($v);
44583b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/','',$url);
4462812a751SAndreas Gohr                    if(strlen($url) > 45){
4472812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
44854f6c432SAndreas Gohr                    }
44914d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
45054f6c432SAndreas Gohr                    echo $url;
45114d99ec0SAndreas Gohr                    echo '</a>';
45229dea504SAndreas Gohr                }elseif($k == 'lookup'){
45329dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q='.rawurlencode($v).'">';
45429dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/google.png" alt="lookup in Google" border="0" />';
45529dea504SAndreas Gohr                    echo '</a> ';
45629dea504SAndreas Gohr
45729dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p='.rawurlencode($v).'">';
45829dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/yahoo.png" alt="lookup in Yahoo" border="0" />';
45929dea504SAndreas Gohr                    echo '</a> ';
46029dea504SAndreas Gohr
46129dea504SAndreas Gohr                    echo '<a href="http://search.msn.com/results.aspx?q='.rawurlencode($v).'">';
46229dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/msn.png" alt="lookup in MSN Live" border="0" />';
46329dea504SAndreas Gohr                    echo '</a> ';
46429dea504SAndreas Gohr
46512dcdeccSAndreas Gohr                }elseif($k == 'engine'){
46612dcdeccSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/search_engines.php');
46712dcdeccSAndreas Gohr                    echo $SearchEnginesHashLib[$v];
46875fa767dSAndreas Gohr                }elseif($k == 'browser'){
46975fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
47075fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
47175fa767dSAndreas Gohr                }elseif($k == 'bflag'){
47275fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
47375fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
474bd4217d3SAndreas Gohr                }elseif($k == 'os'){
475bd4217d3SAndreas Gohr                    if(empty($v)){
476bd4217d3SAndreas Gohr                        echo 'unknown';
477bd4217d3SAndreas Gohr                    }else{
478bd4217d3SAndreas Gohr                        include_once(dirname(__FILE__).'/inc/operating_systems.php');
479bd4217d3SAndreas Gohr                        echo $OSHashLib[$v];
480bd4217d3SAndreas Gohr                    }
481bd4217d3SAndreas Gohr                }elseif($k == 'osflag'){
482bd4217d3SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />';
48375fa767dSAndreas Gohr                }elseif($k == 'cflag'){
48475fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
48514d99ec0SAndreas Gohr                }elseif($k == 'html'){
48614d99ec0SAndreas Gohr                    echo $v;
48714d99ec0SAndreas Gohr                }else{
48814d99ec0SAndreas Gohr                    echo hsc($v);
48914d99ec0SAndreas Gohr                }
49014d99ec0SAndreas Gohr                echo '</td>';
49114d99ec0SAndreas Gohr            }
49214d99ec0SAndreas Gohr            echo '</tr>';
4932507f8e0SAndreas Gohr
4942507f8e0SAndreas Gohr            if($pager && ($count == $pager)) break;
4952507f8e0SAndreas Gohr            $count++;
49614d99ec0SAndreas Gohr        }
49714d99ec0SAndreas Gohr        echo '</table>';
4982507f8e0SAndreas Gohr
4992507f8e0SAndreas Gohr        if($pager) $this->html_pager($pager,count($result) > $pager);
5001878f16fSAndreas Gohr    }
5011878f16fSAndreas Gohr
50295eb68e6SAndreas Gohr    /**
50395eb68e6SAndreas Gohr     * Create an image
50495eb68e6SAndreas Gohr     */
50595eb68e6SAndreas Gohr    function img_build($img){
50695eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
50795eb68e6SAndreas Gohr
50895eb68e6SAndreas Gohr        switch($img){
50995eb68e6SAndreas Gohr            case 'country':
51095eb68e6SAndreas Gohr                // build top countries + other
51195eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
51295eb68e6SAndreas Gohr                $data = array();
51395eb68e6SAndreas Gohr                $top = 0;
51495eb68e6SAndreas Gohr                foreach($result as $row){
51595eb68e6SAndreas Gohr                    if($top < 7){
51695eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
51795eb68e6SAndreas Gohr                    }else{
51895eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
51995eb68e6SAndreas Gohr                    }
52095eb68e6SAndreas Gohr                    $top++;
52195eb68e6SAndreas Gohr                }
52295eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
52395eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
52495eb68e6SAndreas Gohr                $pie->setProp("showval",false);
52595eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
52695eb68e6SAndreas Gohr                $pie->setProp("type","pie");
52795eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
52895eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
52995eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
53095eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
53195eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
53295eb68e6SAndreas Gohr                @$pie->graph();
53395eb68e6SAndreas Gohr                $pie->showGraph();
53495eb68e6SAndreas Gohr                break;
53575fa767dSAndreas Gohr            case 'browser':
53675fa767dSAndreas Gohr                // build top browsers + other
53775fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
53875fa767dSAndreas Gohr
53975fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
54075fa767dSAndreas Gohr                $data = array();
54175fa767dSAndreas Gohr                $top = 0;
54275fa767dSAndreas Gohr                foreach($result as $row){
54375fa767dSAndreas Gohr                    if($top < 5){
54475fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
54575fa767dSAndreas Gohr                    }else{
54675fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
54775fa767dSAndreas Gohr                    }
54875fa767dSAndreas Gohr                    $top++;
54975fa767dSAndreas Gohr                }
55075fa767dSAndreas Gohr                $pie = new AGC(300, 200);
55175fa767dSAndreas Gohr                $pie->setProp("showkey",true);
55275fa767dSAndreas Gohr                $pie->setProp("showval",false);
55375fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
55475fa767dSAndreas Gohr                $pie->setProp("type","pie");
55575fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
55675fa767dSAndreas Gohr                $pie->setProp("keysize",8);
55775fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
55875fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
55975fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
56075fa767dSAndreas Gohr                @$pie->graph();
56175fa767dSAndreas Gohr                $pie->showGraph();
56275fa767dSAndreas Gohr                break;
563c73e16f1SAndreas Gohr            case 'view':
564c73e16f1SAndreas Gohr
565c73e16f1SAndreas Gohr                $graph = new AGC(400, 200);
566c73e16f1SAndreas Gohr                $graph->setColor('color',0,'blue');
567c73e16f1SAndreas Gohr                $graph->setColor('color',1,'red');
568c73e16f1SAndreas Gohr                $graph->setProp("showkey",true);
569c73e16f1SAndreas Gohr                $graph->setProp("key",'view port width',0);
570c73e16f1SAndreas Gohr                $graph->setProp("key",'view port height',1);
571c73e16f1SAndreas Gohr
572c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,true);
573c73e16f1SAndreas Gohr                foreach($result as $row){
574c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_x'],0);
575c73e16f1SAndreas Gohr                }
576c73e16f1SAndreas Gohr
577c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,false);
578c73e16f1SAndreas Gohr                foreach($result as $row){
579c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_y'],1);
580c73e16f1SAndreas Gohr                }
581c73e16f1SAndreas Gohr
582c73e16f1SAndreas Gohr                @$graph->graph();
583c73e16f1SAndreas Gohr                $graph->showGraph();
584c73e16f1SAndreas Gohr
585c73e16f1SAndreas Gohr                break;
5862812a751SAndreas Gohr            case 'trend':
5872812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
5882812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
5892812a751SAndreas Gohr                $data1   = array();
5902812a751SAndreas Gohr                $data2   = array();
5912812a751SAndreas Gohr
5922812a751SAndreas Gohr                $graph = new AGC(400, 150);
5932812a751SAndreas Gohr                $graph->setProp("type","bar");
5942812a751SAndreas Gohr                $graph->setProp("showgrid",false);
5952812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
59675fa767dSAndreas Gohr
5972812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
5982812a751SAndreas Gohr                $graph->setColor('color',1,'red');
5993c0acc14SAndreas Gohr                $graph->setColor('color',2,'yellow');
6002812a751SAndreas Gohr
6012812a751SAndreas Gohr                if($hours){
6022812a751SAndreas Gohr                    //preset $hours
6032812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
6042812a751SAndreas Gohr                        $data1[$i] = 0;
6052812a751SAndreas Gohr                        $data2[$i] = 0;
6063c0acc14SAndreas Gohr                        $data3[$i] = 0;
6072812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
6082812a751SAndreas Gohr                    }
6092812a751SAndreas Gohr                }else{
6102812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
6112812a751SAndreas Gohr                }
6122812a751SAndreas Gohr
6132812a751SAndreas Gohr                foreach($result as $row){
6142812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
6152812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
6163c0acc14SAndreas Gohr                    $data3[$row['time']] = $row['visitors'];
6172812a751SAndreas Gohr                }
6182812a751SAndreas Gohr
6192812a751SAndreas Gohr                foreach($data1 as $key => $val){
6202812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
6212812a751SAndreas Gohr                }
6222812a751SAndreas Gohr                foreach($data2 as $key => $val){
6232812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
6242812a751SAndreas Gohr                }
6253c0acc14SAndreas Gohr                foreach($data3 as $key => $val){
6263c0acc14SAndreas Gohr                    $graph->addPoint($val,$key,2);
6273c0acc14SAndreas Gohr                }
6282812a751SAndreas Gohr
6292812a751SAndreas Gohr                @$graph->graph();
6302812a751SAndreas Gohr                $graph->showGraph();
6312812a751SAndreas Gohr
63295eb68e6SAndreas Gohr            default:
63395eb68e6SAndreas Gohr                $this->sendGIF();
63495eb68e6SAndreas Gohr        }
63595eb68e6SAndreas Gohr    }
63695eb68e6SAndreas Gohr
63795eb68e6SAndreas Gohr
6382812a751SAndreas Gohr    /**
6392812a751SAndreas Gohr     * Return some aggregated statistics
6402812a751SAndreas Gohr     */
6412812a751SAndreas Gohr    function sql_aggregate($tlimit){
6422812a751SAndreas Gohr        $data = array();
6432812a751SAndreas Gohr
6442812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
6452812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6462812a751SAndreas Gohr                 WHERE $tlimit
6472812a751SAndreas Gohr                   AND ua_type = 'browser'
6482812a751SAndreas Gohr              GROUP BY ref_type";
6492812a751SAndreas Gohr        $result = $this->runSQL($sql);
6502812a751SAndreas Gohr
651*2ee939eeSAndreas Gohr        if(is_array($result)) foreach($result as $row){
6522812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
6532812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
6542812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
6552812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
6562812a751SAndreas Gohr        }
6572812a751SAndreas Gohr
6582812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
6592812a751SAndreas Gohr                       COUNT(session) as views,
6603c0acc14SAndreas Gohr                       COUNT(DISTINCT user) as users,
6613c0acc14SAndreas Gohr                       COUNT(DISTINCT uid) as visitors
6622812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6632812a751SAndreas Gohr                 WHERE $tlimit
6642812a751SAndreas Gohr                   AND ua_type = 'browser'";
6652812a751SAndreas Gohr        $result = $this->runSQL($sql);
6662812a751SAndreas Gohr
66775fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
6682812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
6692812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
6703c0acc14SAndreas Gohr        $data['visitors']  = $result[0]['visitors'];
6712812a751SAndreas Gohr
6722812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
6732812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6742812a751SAndreas Gohr                 WHERE $tlimit
6752812a751SAndreas Gohr                   AND ua_type = 'robot'";
6762812a751SAndreas Gohr        $result = $this->runSQL($sql);
6772812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
6782812a751SAndreas Gohr
6792812a751SAndreas Gohr        return $data;
6802812a751SAndreas Gohr    }
6812812a751SAndreas Gohr
682bd4217d3SAndreas Gohr    /**
683bd4217d3SAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
684bd4217d3SAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
685bd4217d3SAndreas Gohr     */
6862812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
6872812a751SAndreas Gohr        if($hours){
6882812a751SAndreas Gohr            $sql = "SELECT HOUR(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 HOUR(dt)
6962812a751SAndreas Gohr                  ORDER BY time";
6972812a751SAndreas Gohr        }else{
6982812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
6992812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
7003c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
7013c0acc14SAndreas Gohr                            COUNT(DISTINCT uid) as visitors
7022812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
7032812a751SAndreas Gohr                     WHERE $tlimit
7042812a751SAndreas Gohr                       AND ua_type = 'browser'
7052812a751SAndreas Gohr                  GROUP BY DATE(dt)
7062812a751SAndreas Gohr                  ORDER BY time";
7072812a751SAndreas Gohr        }
7082812a751SAndreas Gohr        return $this->runSQL($sql);
7092812a751SAndreas Gohr    }
7102812a751SAndreas Gohr
71112dcdeccSAndreas Gohr    function sql_searchengines($tlimit,$start=0,$limit=20){
71212dcdeccSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, engine
71312dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
71412dcdeccSAndreas Gohr                 WHERE $tlimit
71512dcdeccSAndreas Gohr              GROUP BY engine
71612dcdeccSAndreas Gohr              ORDER BY cnt DESC, engine".
71712dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
71812dcdeccSAndreas Gohr        return $this->runSQL($sql);
71912dcdeccSAndreas Gohr    }
72012dcdeccSAndreas Gohr
72112dcdeccSAndreas Gohr    function sql_searchphrases($tlimit,$start=0,$limit=20){
72229dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, query, query as lookup
72312dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
72412dcdeccSAndreas Gohr                 WHERE $tlimit
72512dcdeccSAndreas Gohr              GROUP BY query
72612dcdeccSAndreas Gohr              ORDER BY cnt DESC, query".
72712dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
72812dcdeccSAndreas Gohr        return $this->runSQL($sql);
72912dcdeccSAndreas Gohr    }
73012dcdeccSAndreas Gohr
73112dcdeccSAndreas Gohr    function sql_searchwords($tlimit,$start=0,$limit=20){
73229dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, word, word as lookup
73312dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A,
73412dcdeccSAndreas Gohr                       ".$this->getConf('db_prefix')."searchwords as B
73512dcdeccSAndreas Gohr                 WHERE $tlimit
73612dcdeccSAndreas Gohr                   AND A.id = B.sid
73712dcdeccSAndreas Gohr              GROUP BY word
73812dcdeccSAndreas Gohr              ORDER BY cnt DESC, word".
73912dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
74012dcdeccSAndreas Gohr        return $this->runSQL($sql);
74112dcdeccSAndreas Gohr    }
74212dcdeccSAndreas Gohr
743e25286daSAndreas Gohr    function sql_outlinks($tlimit,$start=0,$limit=20){
744e25286daSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, link as url
745e25286daSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."outlinks as A
746e25286daSAndreas Gohr                 WHERE $tlimit
747e25286daSAndreas Gohr              GROUP BY link
748e25286daSAndreas Gohr              ORDER BY cnt DESC, link".
749e25286daSAndreas Gohr              $this->sql_limit($start,$limit);
750e25286daSAndreas Gohr        return $this->runSQL($sql);
751e25286daSAndreas Gohr    }
752e25286daSAndreas Gohr
75395eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
7542812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
75595eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
75695eb68e6SAndreas Gohr                 WHERE $tlimit
75795eb68e6SAndreas Gohr                   AND ua_type = 'browser'
75895eb68e6SAndreas Gohr              GROUP BY page
75995eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
76095eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
76195eb68e6SAndreas Gohr        return $this->runSQL($sql);
76295eb68e6SAndreas Gohr    }
76395eb68e6SAndreas Gohr
76495eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
7652812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
76695eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
76795eb68e6SAndreas Gohr                 WHERE $tlimit
76895eb68e6SAndreas Gohr                   AND ua_type = 'browser'
76995eb68e6SAndreas Gohr                   AND ref_type = 'external'
77095eb68e6SAndreas Gohr              GROUP BY ref_md5
77195eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
77295eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
77395eb68e6SAndreas Gohr        return $this->runSQL($sql);
77495eb68e6SAndreas Gohr    }
77595eb68e6SAndreas Gohr
776e7a2f1e0SAndreas Gohr    function sql_newreferer($tlimit,$start=0,$limit=20){
777e7a2f1e0SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
778*2ee939eeSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as B,
779*2ee939eeSAndreas Gohr                       ".$this->getConf('db_prefix')."refseen as A
780*2ee939eeSAndreas Gohr                 WHERE $tlimit
781*2ee939eeSAndreas Gohr                   AND ua_type = 'browser'
782e7a2f1e0SAndreas Gohr                   AND ref_type = 'external'
783*2ee939eeSAndreas Gohr                   AND A.ref_md5 = B.ref_md5
784*2ee939eeSAndreas Gohr              GROUP BY A.ref_md5
785e7a2f1e0SAndreas Gohr              ORDER BY cnt DESC, url".
786e7a2f1e0SAndreas Gohr              $this->sql_limit($start,$limit);
787e7a2f1e0SAndreas Gohr        return $this->runSQL($sql);
788e7a2f1e0SAndreas Gohr    }
789e7a2f1e0SAndreas Gohr
79095eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
791bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
79295eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
79395eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
79495eb68e6SAndreas Gohr                 WHERE $tlimit
79595eb68e6SAndreas Gohr                   AND A.ip = B.ip
79695eb68e6SAndreas Gohr              GROUP BY B.country
79795eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
79895eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
79995eb68e6SAndreas Gohr        return $this->runSQL($sql);
80095eb68e6SAndreas Gohr    }
80195eb68e6SAndreas Gohr
80275fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
80375fa767dSAndreas Gohr        if($ext){
80475fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
80575fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
80675fa767dSAndreas Gohr        }else{
80775fa767dSAndreas Gohr            $grp = 'ua_info';
80875fa767dSAndreas Gohr            $sel = 'ua_info';
80975fa767dSAndreas Gohr        }
81075fa767dSAndreas Gohr
811bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
81275fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
81375fa767dSAndreas Gohr                 WHERE $tlimit
81475fa767dSAndreas Gohr                   AND ua_type = 'browser'
81575fa767dSAndreas Gohr              GROUP BY $grp
81675fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
81775fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
81875fa767dSAndreas Gohr        return $this->runSQL($sql);
81975fa767dSAndreas Gohr    }
82075fa767dSAndreas Gohr
821bd4217d3SAndreas Gohr    function sql_os($tlimit,$start=0,$limit=20){
822bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
823bd4217d3SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
824bd4217d3SAndreas Gohr                 WHERE $tlimit
825bd4217d3SAndreas Gohr                   AND ua_type = 'browser'
826bd4217d3SAndreas Gohr              GROUP BY os
827bd4217d3SAndreas Gohr              ORDER BY cnt DESC, os".
828bd4217d3SAndreas Gohr              $this->sql_limit($start,$limit);
829bd4217d3SAndreas Gohr        return $this->runSQL($sql);
830bd4217d3SAndreas Gohr    }
831bd4217d3SAndreas Gohr
832c73e16f1SAndreas Gohr    function sql_resolution($tlimit,$start=0,$limit=20){
833c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res
834c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
835c73e16f1SAndreas Gohr                 WHERE $tlimit
836c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
837c73e16f1SAndreas Gohr                   AND screen_x != 0
838c73e16f1SAndreas Gohr              GROUP BY screen_x, screen_y
839c73e16f1SAndreas Gohr              ORDER BY cnt DESC, screen_x".
840c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
841c73e16f1SAndreas Gohr        return $this->runSQL($sql);
842c73e16f1SAndreas Gohr    }
843c73e16f1SAndreas Gohr
844c73e16f1SAndreas Gohr    function sql_viewport($tlimit,$start=0,$limit=20,$x=true){
845c73e16f1SAndreas Gohr        if($x){
846c73e16f1SAndreas Gohr            $col = 'view_x';
847c73e16f1SAndreas Gohr            $res = 'res_x';
848c73e16f1SAndreas Gohr        }else{
849c73e16f1SAndreas Gohr            $col = 'view_y';
850c73e16f1SAndreas Gohr            $res = 'res_y';
851c73e16f1SAndreas Gohr        }
852c73e16f1SAndreas Gohr
853c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt,
854c73e16f1SAndreas Gohr                       ROUND($col/10)*10 as $res
855c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
856c73e16f1SAndreas Gohr                 WHERE $tlimit
857c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
858c73e16f1SAndreas Gohr                   AND $col != 0
859c73e16f1SAndreas Gohr              GROUP BY $res
860c73e16f1SAndreas Gohr              ORDER BY cnt DESC, $res".
861c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
862c73e16f1SAndreas Gohr        return $this->runSQL($sql);
863c73e16f1SAndreas Gohr    }
864c73e16f1SAndreas Gohr
86575fa767dSAndreas Gohr
86695eb68e6SAndreas Gohr    /**
86795eb68e6SAndreas Gohr     * Builds a limit clause
86895eb68e6SAndreas Gohr     */
86995eb68e6SAndreas Gohr    function sql_limit($start,$limit){
87095eb68e6SAndreas Gohr        $start = (int) $start;
87195eb68e6SAndreas Gohr        $limit = (int) $limit;
87295eb68e6SAndreas Gohr        if($limit){
8732507f8e0SAndreas Gohr            $limit += 1;
87495eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
87595eb68e6SAndreas Gohr        }elseif($start){
87695eb68e6SAndreas Gohr            return " OFFSET $start";
87795eb68e6SAndreas Gohr        }
87895eb68e6SAndreas Gohr        return '';
87995eb68e6SAndreas Gohr    }
8801878f16fSAndreas Gohr
8811878f16fSAndreas Gohr    /**
88214d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
8831878f16fSAndreas Gohr     */
88414d99ec0SAndreas Gohr    function dbLink(){
8851878f16fSAndreas Gohr        // connect to DB if needed
8861878f16fSAndreas Gohr        if(!$this->dblink){
8871878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
8881878f16fSAndreas Gohr                                          $this->getConf('db_user'),
8891878f16fSAndreas Gohr                                          $this->getConf('db_password'));
8901878f16fSAndreas Gohr            if(!$this->dblink){
8911878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
8921878f16fSAndreas Gohr                return null;
8931878f16fSAndreas Gohr            }
8941878f16fSAndreas Gohr            // set utf-8
8951878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
8961878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
8971878f16fSAndreas Gohr                return null;
8981878f16fSAndreas Gohr            }
8991878f16fSAndreas Gohr        }
90014d99ec0SAndreas Gohr        return $this->dblink;
90114d99ec0SAndreas Gohr    }
9021878f16fSAndreas Gohr
90314d99ec0SAndreas Gohr    /**
90414d99ec0SAndreas Gohr     * Simple function to run a DB query
90514d99ec0SAndreas Gohr     */
90614d99ec0SAndreas Gohr    function runSQL($sql_string) {
90714d99ec0SAndreas Gohr        $link = $this->dbLink();
90814d99ec0SAndreas Gohr
90914d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
91094171ff3SAndreas Gohr        if(!$result){
9112812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
9121878f16fSAndreas Gohr            return null;
9131878f16fSAndreas Gohr        }
9141878f16fSAndreas Gohr
9151878f16fSAndreas Gohr        $resultarray = array();
9161878f16fSAndreas Gohr
9171878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
9181878f16fSAndreas Gohr        if ($result != 1) {
9191878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
9201878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
9211878f16fSAndreas Gohr                $resultarray[]=$temparray;
9221878f16fSAndreas Gohr            }
9231878f16fSAndreas Gohr            mysql_free_result($result);
9241878f16fSAndreas Gohr        }
9251878f16fSAndreas Gohr
92614d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
92714d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
9281878f16fSAndreas Gohr        }
9291878f16fSAndreas Gohr
9301878f16fSAndreas Gohr        return $resultarray;
9311878f16fSAndreas Gohr    }
9321878f16fSAndreas Gohr
9331878f16fSAndreas Gohr    /**
93414d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
9351878f16fSAndreas Gohr     */
93614d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
93714d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
93814d99ec0SAndreas Gohr        $ua = strtolower($ua);
93914d99ec0SAndreas Gohr
94014d99ec0SAndreas Gohr        // common browsers
94114d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
94214d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
94314d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
94414d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
94514d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
94614d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
94714d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
94814d99ec0SAndreas Gohr
94914d99ec0SAndreas Gohr        $name = '';
95014d99ec0SAndreas Gohr        # IE ?
95114d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
95214d99ec0SAndreas Gohr            $type = 'browser';
95314d99ec0SAndreas Gohr            $ver  = $m[2];
95414d99ec0SAndreas Gohr            $name = 'msie';
95514d99ec0SAndreas Gohr        }
95614d99ec0SAndreas Gohr        # Firefox ?
95714d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
95814d99ec0SAndreas Gohr            $type = 'browser';
95914d99ec0SAndreas Gohr            $ver  = $m[1];
96014d99ec0SAndreas Gohr            $name = 'firefox';
96114d99ec0SAndreas Gohr        }
96214d99ec0SAndreas Gohr        # Subversion ?
96314d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
96414d99ec0SAndreas Gohr            $type = 'rcs';
96514d99ec0SAndreas Gohr            $ver  = $m[1];
96614d99ec0SAndreas Gohr            $name = 'svn';
96714d99ec0SAndreas Gohr        }
96814d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
96914d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
97014d99ec0SAndreas Gohr            $type = 'browser';
97114d99ec0SAndreas Gohr            $ver  = $m[1];
97214d99ec0SAndreas Gohr            $name = 'netscape';
97314d99ec0SAndreas Gohr        }
97414d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
97514d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
97614d99ec0SAndreas Gohr            $type = 'browser';
97714d99ec0SAndreas Gohr            $ver  = $m[2];
97814d99ec0SAndreas Gohr            $name = 'netscape';
97914d99ec0SAndreas Gohr        }else{
98014d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
98114d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
98214d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
98314d99ec0SAndreas Gohr                    // it's a browser!
98414d99ec0SAndreas Gohr                    $type = 'browser';
98514d99ec0SAndreas Gohr                    $name = strtolower($regex);
98614d99ec0SAndreas Gohr                    break;
98714d99ec0SAndreas Gohr                }
98814d99ec0SAndreas Gohr            }
98914d99ec0SAndreas Gohr        }
99014d99ec0SAndreas Gohr
99175fa767dSAndreas Gohr        // check versions for Safari and Opera
99275fa767dSAndreas Gohr        if($name == 'safari'){
99375fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
99475fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
99575fa767dSAndreas Gohr            }
99675fa767dSAndreas Gohr        }elseif($name == 'opera'){
99775fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
99875fa767dSAndreas Gohr                $ver = $match[1];
99975fa767dSAndreas Gohr            }
100075fa767dSAndreas Gohr        }
100175fa767dSAndreas Gohr
100275fa767dSAndreas Gohr
100314d99ec0SAndreas Gohr        // check OS for browsers
100414d99ec0SAndreas Gohr        if($type == 'browser'){
100514d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
100614d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
100714d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
100814d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
100914d99ec0SAndreas Gohr                    break;
101014d99ec0SAndreas Gohr                }
101114d99ec0SAndreas Gohr            }
101214d99ec0SAndreas Gohr
101314d99ec0SAndreas Gohr        }
101414d99ec0SAndreas Gohr
101514d99ec0SAndreas Gohr        // are we done now?
101614d99ec0SAndreas Gohr        if($name) return $name;
101714d99ec0SAndreas Gohr
101814d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
101914d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
102014d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
102114d99ec0SAndreas Gohr                    // it's a robot!
102214d99ec0SAndreas Gohr                    $type = 'robot';
102314d99ec0SAndreas Gohr                    return strtolower($regex);
102414d99ec0SAndreas Gohr            }
102514d99ec0SAndreas Gohr        }
102614d99ec0SAndreas Gohr
102714d99ec0SAndreas Gohr        // dunno
10281878f16fSAndreas Gohr        return '';
10291878f16fSAndreas Gohr    }
10301878f16fSAndreas Gohr
10311878f16fSAndreas Gohr    /**
1032322de360SAndreas Gohr     * Log search queries
103314d99ec0SAndreas Gohr     */
103414d99ec0SAndreas Gohr    function log_search($referer,&$type){
103514d99ec0SAndreas Gohr        $referer = strtolower($referer);
1036673875b1SAndreas Gohr        $ref     = strtr($referer,' +','__');
103714d99ec0SAndreas Gohr
103814d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
103914d99ec0SAndreas Gohr
104014d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
1041673875b1SAndreas Gohr            if(preg_match('/'.$regex.'/',$ref)){
104214d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
1043673875b1SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$ref)){
104414d99ec0SAndreas Gohr                    // it's a search engine!
104514d99ec0SAndreas Gohr                    $type = 'search';
104614d99ec0SAndreas Gohr                    break;
104714d99ec0SAndreas Gohr                }
104814d99ec0SAndreas Gohr            }
104914d99ec0SAndreas Gohr        }
105014d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
105114d99ec0SAndreas Gohr
1052322de360SAndreas Gohr        // extract query
1053322de360SAndreas Gohr        $engine = $SearchEnginesHashID[$regex];
1054322de360SAndreas Gohr        $param = $SearchEnginesKnownUrl[$engine];
1055322de360SAndreas Gohr        if($param && preg_match('/'.$param.'(.*?)[&$]/',$referer,$match)){
1056322de360SAndreas Gohr            $query = array_pop($match);
1057322de360SAndreas Gohr        }elseif(preg_match('/'.$WordsToExtractSearchUrl.'(.*?)[&$]/',$referer,$match)){
1058322de360SAndreas Gohr            $query = array_pop($match);
1059322de360SAndreas Gohr        }
1060322de360SAndreas Gohr        if(!$query) return; // we failed
1061322de360SAndreas Gohr
1062322de360SAndreas Gohr        // clean the query
1063322de360SAndreas Gohr        $query = preg_replace('/^(cache|related):[^\+]+/','',$query);  // non-search queries
1064322de360SAndreas Gohr        $query = preg_replace('/%0[ad]/',' ',$query);                  // LF CR
1065322de360SAndreas Gohr        $query = preg_replace('/%2[02789abc]/',' ',$query);            // space " ' ( ) * + ,
1066322de360SAndreas Gohr        $query = preg_replace('/%3a/',' ',$query);                     // :
1067673875b1SAndreas Gohr        $query = strtr($query,'+\'()"*,:','        ');                 // badly encoded
1068322de360SAndreas Gohr        $query = preg_replace('/ +/',' ',$query);                      // ws compact
1069322de360SAndreas Gohr        $query = trim($query);
1070322de360SAndreas Gohr        $query = urldecode($query);
1071322de360SAndreas Gohr        if(!utf8_check($query)) $query = utf8_encode($query);          // assume latin1 if not utf8
1072322de360SAndreas Gohr        $query = utf8_strtolower($query);
1073322de360SAndreas Gohr
1074322de360SAndreas Gohr        // log it!
1075322de360SAndreas Gohr        $page  = addslashes($_REQUEST['p']);
1076322de360SAndreas Gohr        $query = addslashes($query);
1077673875b1SAndreas Gohr        $sql  = "INSERT INTO ".$this->getConf('db_prefix')."search
1078322de360SAndreas Gohr                    SET dt       = NOW(),
1079322de360SAndreas Gohr                        page     = '$page',
1080322de360SAndreas Gohr                        query    = '$query',
1081322de360SAndreas Gohr                        engine   = '$engine'";
1082322de360SAndreas Gohr        $id = $this->runSQL($sql);
1083322de360SAndreas Gohr        if(is_null($id)){
1084322de360SAndreas Gohr            global $MSG;
1085322de360SAndreas Gohr            print_r($MSG);
1086322de360SAndreas Gohr            return;
1087322de360SAndreas Gohr        }
1088322de360SAndreas Gohr
1089322de360SAndreas Gohr        // log single keywords
1090322de360SAndreas Gohr        $words = explode(' ',utf8_stripspecials($query,' ','\._\-:\*'));
1091322de360SAndreas Gohr        foreach($words as $word){
1092673875b1SAndreas Gohr            if(!$word) continue;
1093322de360SAndreas Gohr            $word = addslashes($word);
1094322de360SAndreas Gohr            $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."searchwords
1095322de360SAndreas Gohr                       SET sid  = $id,
1096322de360SAndreas Gohr                           word = '$word'";
1097322de360SAndreas Gohr            $ok = $this->runSQL($sql);
1098322de360SAndreas Gohr            if(is_null($ok)){
1099322de360SAndreas Gohr                global $MSG;
1100322de360SAndreas Gohr                print_r($MSG);
1101322de360SAndreas Gohr            }
1102322de360SAndreas Gohr        }
110314d99ec0SAndreas Gohr    }
110414d99ec0SAndreas Gohr
110514d99ec0SAndreas Gohr    /**
110614d99ec0SAndreas Gohr     * Resolve IP to country/city
110714d99ec0SAndreas Gohr     */
110814d99ec0SAndreas Gohr    function log_ip($ip){
110914d99ec0SAndreas Gohr        // check if IP already known and up-to-date
111014d99ec0SAndreas Gohr        $sql = "SELECT ip
111114d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
111214d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
111314d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
111414d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
111514d99ec0SAndreas Gohr        if($result[0]['ip']) return;
111614d99ec0SAndreas Gohr
111714d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
111814d99ec0SAndreas Gohr        $http->timeout = 10;
111914d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
112014d99ec0SAndreas Gohr
112114d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
112214d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
112314d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
112414d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
112514d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
112614d99ec0SAndreas Gohr            $ip      = addslashes($ip);
112714d99ec0SAndreas Gohr
112814d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
112914d99ec0SAndreas Gohr                        SET ip = '$ip',
113014d99ec0SAndreas Gohr                            country = '$country',
113114d99ec0SAndreas Gohr                            code    = '$code',
113214d99ec0SAndreas Gohr                            city    = '$city',
113314d99ec0SAndreas Gohr                            host    = '$host'";
113414d99ec0SAndreas Gohr            $this->runSQL($sql);
113514d99ec0SAndreas Gohr        }
113614d99ec0SAndreas Gohr    }
113714d99ec0SAndreas Gohr
113814d99ec0SAndreas Gohr    /**
1139e25286daSAndreas Gohr     * log a click on an external link
1140e25286daSAndreas Gohr     *
1141e25286daSAndreas Gohr     * called from log.php
1142e25286daSAndreas Gohr     */
1143e25286daSAndreas Gohr    function log_outgoing(){
1144e25286daSAndreas Gohr        if(!$_REQUEST['ol']) return;
1145e25286daSAndreas Gohr
1146e25286daSAndreas Gohr        $link_md5 = md5($link);
1147e25286daSAndreas Gohr        $link     = addslashes($_REQUEST['ol']);
1148e25286daSAndreas Gohr        $session  = addslashes(session_id());
1149d8c4d85eSAndreas Gohr        $page     = addslashes($_REQUEST['p']);
1150e25286daSAndreas Gohr
1151e25286daSAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks
1152e25286daSAndreas Gohr                    SET dt       = NOW(),
1153e25286daSAndreas Gohr                        session  = '$session',
1154d8c4d85eSAndreas Gohr                        page     = '$page',
1155e25286daSAndreas Gohr                        link_md5 = '$link_md5',
1156e25286daSAndreas Gohr                        link     = '$link'";
1157e25286daSAndreas Gohr        $ok = $this->runSQL($sql);
1158e25286daSAndreas Gohr        if(is_null($ok)){
1159e25286daSAndreas Gohr            global $MSG;
1160e25286daSAndreas Gohr            print_r($MSG);
1161e25286daSAndreas Gohr        }
1162e25286daSAndreas Gohr    }
1163e25286daSAndreas Gohr
1164e25286daSAndreas Gohr    /**
11651878f16fSAndreas Gohr     * log a page access
11661878f16fSAndreas Gohr     *
11671878f16fSAndreas Gohr     * called from log.php
11681878f16fSAndreas Gohr     */
11691878f16fSAndreas Gohr    function log_access(){
117094171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
117194171ff3SAndreas Gohr
117214d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
117314d99ec0SAndreas Gohr
117414d99ec0SAndreas Gohr        // handle referer
117514d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
117614d99ec0SAndreas Gohr        if($referer){
117714d99ec0SAndreas Gohr            $ref     = addslashes($referer);
117814d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
117914d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
118014d99ec0SAndreas Gohr                $ref_type = 'internal';
118114d99ec0SAndreas Gohr            }else{
118214d99ec0SAndreas Gohr                $ref_type = 'external';
118314d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
118414d99ec0SAndreas Gohr            }
118514d99ec0SAndreas Gohr        }else{
118614d99ec0SAndreas Gohr            $ref      = '';
118714d99ec0SAndreas Gohr            $ref_md5  = '';
118814d99ec0SAndreas Gohr            $ref_type = '';
118914d99ec0SAndreas Gohr        }
119014d99ec0SAndreas Gohr
119114d99ec0SAndreas Gohr        // handle user agent
119214d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
119314d99ec0SAndreas Gohr
119414d99ec0SAndreas Gohr        $ua      = addslashes($agent);
119514d99ec0SAndreas Gohr        $ua_type = '';
119614d99ec0SAndreas Gohr        $ua_ver  = '';
119714d99ec0SAndreas Gohr        $os      = '';
119814d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
119914d99ec0SAndreas Gohr
12001878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
12011878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
12021878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
12031878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
12041878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
12051878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
120675fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
12073c0acc14SAndreas Gohr        $uid     = addslashes($_REQUEST['uid']);
12081878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
12091878f16fSAndreas Gohr        $session = addslashes(session_id());
12103c0acc14SAndreas Gohr        if(!$uid) $uid = $session;
12111878f16fSAndreas Gohr
121294171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
121375fa767dSAndreas Gohr                    SET dt       = NOW(),
121475fa767dSAndreas Gohr                        page     = '$page',
12151878f16fSAndreas Gohr                        ip       = '$ip',
12161878f16fSAndreas Gohr                        ua       = '$ua',
12171878f16fSAndreas Gohr                        ua_info  = '$ua_info',
121814d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
121914d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
122014d99ec0SAndreas Gohr                        os       = '$os',
12211878f16fSAndreas Gohr                        ref      = '$ref',
122294171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
122314d99ec0SAndreas Gohr                        ref_type = '$ref_type',
12241878f16fSAndreas Gohr                        screen_x = '$sx',
12251878f16fSAndreas Gohr                        screen_y = '$sy',
12261878f16fSAndreas Gohr                        view_x   = '$vx',
12271878f16fSAndreas Gohr                        view_y   = '$vy',
122875fa767dSAndreas Gohr                        js       = '$js',
12291878f16fSAndreas Gohr                        user     = '$user',
12303c0acc14SAndreas Gohr                        session  = '$session',
12313c0acc14SAndreas Gohr                        uid      = '$uid'";
12321878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
12331878f16fSAndreas Gohr        if(is_null($ok)){
12341878f16fSAndreas Gohr            global $MSG;
12351878f16fSAndreas Gohr            print_r($MSG);
12361878f16fSAndreas Gohr        }
123714d99ec0SAndreas Gohr
1238*2ee939eeSAndreas Gohr        $sql = "INSERT DELAYED IGNORE INTO ".$this->getConf('db_prefix')."refseen
1239*2ee939eeSAndreas Gohr                   SET ref_md5  = '$ref_md5',
1240*2ee939eeSAndreas Gohr                       dt       = NOW()";
1241*2ee939eeSAndreas Gohr        $ok = $this->runSQL($sql);
1242*2ee939eeSAndreas Gohr        if(is_null($ok)){
1243*2ee939eeSAndreas Gohr            global $MSG;
1244*2ee939eeSAndreas Gohr            print_r($MSG);
1245*2ee939eeSAndreas Gohr        }
1246*2ee939eeSAndreas Gohr
124714d99ec0SAndreas Gohr        // resolve the IP
124814d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
12491878f16fSAndreas Gohr    }
12501878f16fSAndreas Gohr
12511878f16fSAndreas Gohr    /**
12521878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
12531878f16fSAndreas Gohr     *
12541878f16fSAndreas Gohr     * @called from log.php
12551878f16fSAndreas Gohr     *
12561878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
12571878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
12581878f16fSAndreas Gohr     */
12591878f16fSAndreas Gohr    function sendGIF(){
12601878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
12611878f16fSAndreas Gohr        header('Content-Type: image/gif');
12621878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
12631878f16fSAndreas Gohr        header('Connection: Close');
12641878f16fSAndreas Gohr        print $img;
12651878f16fSAndreas Gohr        flush();
12661878f16fSAndreas Gohr        // Browser should drop connection after this
12671878f16fSAndreas Gohr        // Thinks it's got the whole image
12681878f16fSAndreas Gohr    }
12691878f16fSAndreas Gohr
12701878f16fSAndreas Gohr}
1271