xref: /plugin/statistics/admin.php (revision 47ffcf7d3aad0c8053a5e1d70d026d6bbcb3f292)
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     * Access for managers allowed
291878f16fSAndreas Gohr     */
301878f16fSAndreas Gohr    function forAdminOnly(){
311878f16fSAndreas Gohr        return false;
321878f16fSAndreas Gohr    }
331878f16fSAndreas Gohr
341878f16fSAndreas Gohr    /**
351878f16fSAndreas Gohr     * return sort order for position in admin menu
361878f16fSAndreas Gohr     */
371878f16fSAndreas Gohr    function getMenuSort() {
3814d99ec0SAndreas Gohr        return 150;
391878f16fSAndreas Gohr    }
401878f16fSAndreas Gohr
411878f16fSAndreas Gohr    /**
421878f16fSAndreas Gohr     * handle user request
431878f16fSAndreas Gohr     */
441878f16fSAndreas Gohr    function handle() {
45264f1744SAndreas Gohr        $this->opt = preg_replace('/[^a-z]+/','',$_REQUEST['opt']);
4695eb68e6SAndreas Gohr        $this->start = (int) $_REQUEST['s'];
47e8699bceSAndreas Gohr        $this->setTimeframe($_REQUEST['f'],$_REQUEST['t']);
48e8699bceSAndreas Gohr    }
4995eb68e6SAndreas Gohr
50e8699bceSAndreas Gohr    /**
51e8699bceSAndreas Gohr     * set limit clause
52e8699bceSAndreas Gohr     */
53e8699bceSAndreas Gohr    function setTimeframe($from,$to){
54264f1744SAndreas Gohr        // fixme add better sanity checking here:
55e8699bceSAndreas Gohr        $from = preg_replace('/[^\d\-]+/','',$from);
56e8699bceSAndreas Gohr        $to   = preg_replace('/[^\d\-]+/','',$to);
57e8699bceSAndreas Gohr        if(!$from) $from = date('Y-m-d');
58e8699bceSAndreas Gohr        if(!$to)   $to   = date('Y-m-d');
59264f1744SAndreas Gohr
60264f1744SAndreas Gohr        //setup limit clause
612ee939eeSAndreas Gohr        $tlimit = "A.dt >= '$from 00:00:00' AND A.dt <= '$to 23:59:59'";
62e8699bceSAndreas Gohr        $this->tlimit = $tlimit;
63e8699bceSAndreas Gohr        $this->from   = $from;
64e8699bceSAndreas Gohr        $this->to     = $to;
651878f16fSAndreas Gohr    }
661878f16fSAndreas Gohr
671878f16fSAndreas Gohr    /**
6894171ff3SAndreas Gohr     * fixme build statistics here
691878f16fSAndreas Gohr     */
701878f16fSAndreas Gohr    function html() {
71264f1744SAndreas Gohr        echo '<h1>Access Statistics</h1>';
72264f1744SAndreas Gohr        $this->html_timeselect();
73264f1744SAndreas Gohr
74264f1744SAndreas Gohr        switch($this->opt){
759da6395dSAndreas Gohr            case 'country':
769da6395dSAndreas Gohr                $this->html_country();
779da6395dSAndreas Gohr                break;
789da6395dSAndreas Gohr            case 'page':
799da6395dSAndreas Gohr                $this->html_page();
809da6395dSAndreas Gohr                break;
8175fa767dSAndreas Gohr            case 'browser':
8275fa767dSAndreas Gohr                $this->html_browser();
8375fa767dSAndreas Gohr                break;
84bd4217d3SAndreas Gohr            case 'os':
85bd4217d3SAndreas Gohr                $this->html_os();
86bd4217d3SAndreas Gohr                break;
879da6395dSAndreas Gohr            case 'referer':
889da6395dSAndreas Gohr                $this->html_referer();
899da6395dSAndreas Gohr                break;
90e7a2f1e0SAndreas Gohr            case 'newreferer':
91e7a2f1e0SAndreas Gohr                $this->html_newreferer();
92e7a2f1e0SAndreas Gohr                break;
93e25286daSAndreas Gohr            case 'outlinks':
94e25286daSAndreas Gohr                $this->html_outlinks();
95e25286daSAndreas Gohr                break;
96c73e16f1SAndreas Gohr            case 'resolution':
97c73e16f1SAndreas Gohr                $this->html_resolution();
98c73e16f1SAndreas Gohr                break;
9912dcdeccSAndreas Gohr            case 'searchphrases':
10012dcdeccSAndreas Gohr                $this->html_searchphrases();
10112dcdeccSAndreas Gohr                break;
10212dcdeccSAndreas Gohr            case 'searchwords':
10312dcdeccSAndreas Gohr                $this->html_searchwords();
10412dcdeccSAndreas Gohr                break;
10512dcdeccSAndreas Gohr            case 'searchengines':
10612dcdeccSAndreas Gohr                $this->html_searchengines();
10712dcdeccSAndreas Gohr                break;
10814d99ec0SAndreas Gohr            default:
1099da6395dSAndreas Gohr                $this->html_dashboard();
11014d99ec0SAndreas Gohr        }
11114d99ec0SAndreas Gohr    }
11214d99ec0SAndreas Gohr
113*47ffcf7dSAndreas Gohr    function getTOC(){
114*47ffcf7dSAndreas Gohr        $pages = array('dashboard','page','referer','newreferer','outlinks',
115*47ffcf7dSAndreas Gohr                       'searchphrases','searchwords','searchengines','browser',
116*47ffcf7dSAndreas Gohr                       'os','country','resolution');
1179da6395dSAndreas Gohr
118*47ffcf7dSAndreas Gohr        $toc = array();
119*47ffcf7dSAndreas Gohr        foreach($pages as $page){
120*47ffcf7dSAndreas Gohr            $toc[] = array(
121*47ffcf7dSAndreas Gohr                    'link'  => '?do=admin&amp;page=statistics&amp;opt='.$page.'&amp;f='.$this->from.'&amp;t='.$this->to,
122*47ffcf7dSAndreas Gohr                    'title' => $this->getLang($page),
123*47ffcf7dSAndreas Gohr                    'level' => 1,
124*47ffcf7dSAndreas Gohr                    'type'  => 'ul'
125*47ffcf7dSAndreas Gohr            );
126*47ffcf7dSAndreas Gohr        }
127*47ffcf7dSAndreas Gohr        return $toc;
1289da6395dSAndreas Gohr    }
1299da6395dSAndreas Gohr
1302507f8e0SAndreas Gohr    function html_pager($limit,$next){
1312507f8e0SAndreas Gohr        echo '<div class="plg_stats_pager">';
1322507f8e0SAndreas Gohr
1332507f8e0SAndreas Gohr        if($this->start > 0){
1342507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
1352507f8e0SAndreas 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>';
1362507f8e0SAndreas Gohr        }
1372507f8e0SAndreas Gohr
1382507f8e0SAndreas Gohr        if($next){
1392507f8e0SAndreas Gohr            $go = $this->start + $limit;
1402507f8e0SAndreas 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>';
1412507f8e0SAndreas Gohr        }
1422507f8e0SAndreas Gohr        echo '</div>';
1432507f8e0SAndreas Gohr    }
1442507f8e0SAndreas Gohr
145264f1744SAndreas Gohr    /**
146264f1744SAndreas Gohr     * Print the time selection menu
147264f1744SAndreas Gohr     */
14814d99ec0SAndreas Gohr    function html_timeselect(){
149264f1744SAndreas Gohr        $now   = date('Y-m-d');
150264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
151264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
152264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
15314d99ec0SAndreas Gohr
154264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
155264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
156264f1744SAndreas Gohr        echo '<ul>';
157264f1744SAndreas Gohr
158264f1744SAndreas Gohr        echo '<li>';
1592507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'">';
160264f1744SAndreas Gohr        echo 'today';
161264f1744SAndreas Gohr        echo '</a>';
162264f1744SAndreas Gohr        echo '</li>';
163264f1744SAndreas Gohr
164264f1744SAndreas Gohr        echo '<li>';
1652507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'">';
166264f1744SAndreas Gohr        echo 'yesterday';
167264f1744SAndreas Gohr        echo '</a>';
168264f1744SAndreas Gohr        echo '</li>';
169264f1744SAndreas Gohr
170264f1744SAndreas Gohr        echo '<li>';
1712507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'">';
172264f1744SAndreas Gohr        echo 'last 7 days';
173264f1744SAndreas Gohr        echo '</a>';
174264f1744SAndreas Gohr        echo '</li>';
175264f1744SAndreas Gohr
176264f1744SAndreas Gohr        echo '<li>';
1772507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'">';
178264f1744SAndreas Gohr        echo 'last 30 days';
179264f1744SAndreas Gohr        echo '</a>';
180264f1744SAndreas Gohr        echo '</li>';
181264f1744SAndreas Gohr
182264f1744SAndreas Gohr        echo '</ul>';
183264f1744SAndreas Gohr
184264f1744SAndreas Gohr
185264f1744SAndreas Gohr        echo '<form action="" method="get">';
186264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
187264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
188264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
189264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
190264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
191264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
19214d99ec0SAndreas Gohr        echo '</form>';
193264f1744SAndreas Gohr
194264f1744SAndreas Gohr        echo '</div>';
19514d99ec0SAndreas Gohr    }
19614d99ec0SAndreas Gohr
19714d99ec0SAndreas Gohr
198f5f32cbfSAndreas Gohr    /**
199f5f32cbfSAndreas Gohr     * Print an introductionary screen
200f5f32cbfSAndreas Gohr     */
20114d99ec0SAndreas Gohr    function html_dashboard(){
2022812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
2032812a751SAndreas Gohr              choose a topic from the list.</p>';
2042812a751SAndreas Gohr
2052812a751SAndreas Gohr
206264f1744SAndreas Gohr        echo '<div class="plg_stats_dashboard">';
207264f1744SAndreas Gohr
2082812a751SAndreas Gohr        // general info
2092812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
2102812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2112812a751SAndreas Gohr        echo '<ul>';
2122812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views </li>';
2133c0acc14SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>';
2143c0acc14SAndreas Gohr        echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>';
2152812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
2162812a751SAndreas Gohr
2172812a751SAndreas Gohr        echo '</ul>';
2182812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2192812a751SAndreas Gohr        echo '</div>';
2202812a751SAndreas Gohr
22114d99ec0SAndreas Gohr
22287d5e44bSAndreas Gohr        // top pages today
223264f1744SAndreas Gohr        echo '<div>';
224264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
22595eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
2262812a751SAndreas Gohr        $this->html_resulttable($result);
2272507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
228264f1744SAndreas Gohr        echo '</div>';
22987d5e44bSAndreas Gohr
23087d5e44bSAndreas Gohr        // top referer today
231264f1744SAndreas Gohr        echo '<div>';
232e7a2f1e0SAndreas Gohr        echo '<h2>Newest incoming links</h2>';
233e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,15);
2342812a751SAndreas Gohr        $this->html_resulttable($result);
2352507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
236264f1744SAndreas Gohr        echo '</div>';
23754f6c432SAndreas Gohr
23829dea504SAndreas Gohr        // top searches today
239264f1744SAndreas Gohr        echo '<div>';
24029dea504SAndreas Gohr        echo '<h2>Top search phrases</h2>';
24129dea504SAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,15);
24229dea504SAndreas Gohr        $this->html_resulttable($result);
24329dea504SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchphrases&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
244264f1744SAndreas Gohr        echo '</div>';
245264f1744SAndreas Gohr
246264f1744SAndreas Gohr        echo '</div>';
24714d99ec0SAndreas Gohr    }
24814d99ec0SAndreas Gohr
2499da6395dSAndreas Gohr    function html_country(){
2509da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2519da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
252bd4217d3SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2539da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
2542507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2559da6395dSAndreas Gohr        echo '</div>';
2569da6395dSAndreas Gohr    }
2579da6395dSAndreas Gohr
2589da6395dSAndreas Gohr    function html_page(){
2599da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2609da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
2619da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
2622507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2639da6395dSAndreas Gohr        echo '</div>';
2649da6395dSAndreas Gohr    }
2659da6395dSAndreas Gohr
26675fa767dSAndreas Gohr    function html_browser(){
26775fa767dSAndreas Gohr        echo '<div class="plg_stats_full">';
26875fa767dSAndreas Gohr        echo '<h2>Browser Shootout</h2>';
26975fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
27075fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
2712507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
27275fa767dSAndreas Gohr        echo '</div>';
27375fa767dSAndreas Gohr    }
27475fa767dSAndreas Gohr
275bd4217d3SAndreas Gohr    function html_os(){
276bd4217d3SAndreas Gohr        echo '<div class="plg_stats_full">';
277bd4217d3SAndreas Gohr        echo '<h2>Operating Systems</h2>';
278bd4217d3SAndreas Gohr        $result = $this->sql_os($this->tlimit,$this->start,150,true);
2792507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
280bd4217d3SAndreas Gohr        echo '</div>';
281bd4217d3SAndreas Gohr    }
282bd4217d3SAndreas Gohr
2839da6395dSAndreas Gohr    function html_referer(){
2849da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2859da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
2862812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2872812a751SAndreas Gohr
2882812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
2892812a751SAndreas Gohr
29094023548SAndreas Gohr        if($all){
2912812a751SAndreas Gohr            printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
2922812a751SAndreas Gohr                    %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
2932812a751SAndreas Gohr                    links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
2942812a751SAndreas Gohr                    $result['search'],(100*$result['search']/$all),$result['external'],
2952812a751SAndreas Gohr                    (100*$result['external']/$all));
29694023548SAndreas Gohr        }
2972812a751SAndreas Gohr
2989da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
2992507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
3009da6395dSAndreas Gohr        echo '</div>';
3019da6395dSAndreas Gohr    }
3029da6395dSAndreas Gohr
303e7a2f1e0SAndreas Gohr    function html_newreferer(){
304e7a2f1e0SAndreas Gohr        echo '<div class="plg_stats_full">';
305e7a2f1e0SAndreas Gohr        echo '<h2>New Incoming Links</h2>';
306e7a2f1e0SAndreas Gohr        echo '<p>The following incoming links where first logged in the selected time frame,
307e7a2f1e0SAndreas Gohr              and have never been seen before.</p>';
308e7a2f1e0SAndreas Gohr
309e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,150);
3102507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
311e7a2f1e0SAndreas Gohr        echo '</div>';
312e7a2f1e0SAndreas Gohr    }
313e7a2f1e0SAndreas Gohr
314e25286daSAndreas Gohr    function html_outlinks(){
315e25286daSAndreas Gohr        echo '<div class="plg_stats_full">';
316e25286daSAndreas Gohr        echo '<h2>Outgoing Links</h2>';
317e25286daSAndreas Gohr
318e25286daSAndreas Gohr        $result = $this->sql_outlinks($this->tlimit,$this->start,150);
319e25286daSAndreas Gohr        $this->html_resulttable($result,'',150);
320e25286daSAndreas Gohr        echo '</div>';
321e25286daSAndreas Gohr    }
322e25286daSAndreas Gohr
32312dcdeccSAndreas Gohr    function html_searchphrases(){
32412dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
32512dcdeccSAndreas Gohr        echo '<h2>Search Phrases</h2>';
32612dcdeccSAndreas Gohr
32712dcdeccSAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,150);
32812dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
32912dcdeccSAndreas Gohr        echo '</div>';
33012dcdeccSAndreas Gohr    }
33112dcdeccSAndreas Gohr
33212dcdeccSAndreas Gohr    function html_searchwords(){
33312dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
33412dcdeccSAndreas Gohr        echo '<h2>Search Words</h2>';
33512dcdeccSAndreas Gohr
33612dcdeccSAndreas Gohr        $result = $this->sql_searchwords($this->tlimit,$this->start,150);
33712dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
33812dcdeccSAndreas Gohr        echo '</div>';
33912dcdeccSAndreas Gohr    }
34012dcdeccSAndreas Gohr
34112dcdeccSAndreas Gohr    function html_searchengines(){
34212dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
34312dcdeccSAndreas Gohr        echo '<h2>Search Engines</h2>';
34412dcdeccSAndreas Gohr
34512dcdeccSAndreas Gohr        $result = $this->sql_searchengines($this->tlimit,$this->start,150);
34612dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
34712dcdeccSAndreas Gohr        echo '</div>';
34812dcdeccSAndreas Gohr    }
34912dcdeccSAndreas Gohr
350e25286daSAndreas Gohr
351c73e16f1SAndreas Gohr    function html_resolution(){
352c73e16f1SAndreas Gohr        echo '<div class="plg_stats_full">';
353c73e16f1SAndreas Gohr        echo '<h2>Resolution</h2>';
354c73e16f1SAndreas Gohr        $result = $this->sql_resolution($this->tlimit,$this->start,150);
355c73e16f1SAndreas Gohr        $this->html_resulttable($result,'',150);
356c73e16f1SAndreas Gohr
357c73e16f1SAndreas Gohr        echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you
358c73e16f1SAndreas Gohr              much about about the real size of their browser windows. The graphic below shows the size distribution of
359c73e16f1SAndreas Gohr              the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged
360c73e16f1SAndreas Gohr              in all browsers. Because users may resize their browser window while browsing your site the statistics may
361c73e16f1SAndreas Gohr              be flawed. Take it with a grain of salt.</p>';
362c73e16f1SAndreas Gohr
363c73e16f1SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
364c73e16f1SAndreas Gohr        echo '</div>';
365c73e16f1SAndreas Gohr    }
3669da6395dSAndreas Gohr
3679da6395dSAndreas Gohr
36814d99ec0SAndreas Gohr    /**
36914d99ec0SAndreas Gohr     * Display a result in a HTML table
37014d99ec0SAndreas Gohr     */
3712507f8e0SAndreas Gohr    function html_resulttable($result,$header='',$pager=0){
37214d99ec0SAndreas Gohr        echo '<table>';
3732812a751SAndreas Gohr        if(is_array($header)){
37414d99ec0SAndreas Gohr            echo '<tr>';
37514d99ec0SAndreas Gohr            foreach($header as $h){
37614d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
37714d99ec0SAndreas Gohr            }
37814d99ec0SAndreas Gohr            echo '</tr>';
3792812a751SAndreas Gohr        }
38014d99ec0SAndreas Gohr
3812507f8e0SAndreas Gohr        $count = 0;
3822ee939eeSAndreas Gohr        if(is_array($result)) foreach($result as $row){
38314d99ec0SAndreas Gohr            echo '<tr>';
38414d99ec0SAndreas Gohr            foreach($row as $k => $v){
3852812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
38614d99ec0SAndreas Gohr                if($k == 'page'){
38714d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
38814d99ec0SAndreas Gohr                    echo hsc($v);
38914d99ec0SAndreas Gohr                    echo '</a>';
39014d99ec0SAndreas Gohr                }elseif($k == 'url'){
39154f6c432SAndreas Gohr                    $url = hsc($v);
39283b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/','',$url);
3932812a751SAndreas Gohr                    if(strlen($url) > 45){
3942812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
39554f6c432SAndreas Gohr                    }
39614d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
39754f6c432SAndreas Gohr                    echo $url;
39814d99ec0SAndreas Gohr                    echo '</a>';
39929dea504SAndreas Gohr                }elseif($k == 'lookup'){
40029dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q='.rawurlencode($v).'">';
40129dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/google.png" alt="lookup in Google" border="0" />';
40229dea504SAndreas Gohr                    echo '</a> ';
40329dea504SAndreas Gohr
40429dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p='.rawurlencode($v).'">';
40529dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/yahoo.png" alt="lookup in Yahoo" border="0" />';
40629dea504SAndreas Gohr                    echo '</a> ';
40729dea504SAndreas Gohr
40829dea504SAndreas Gohr                    echo '<a href="http://search.msn.com/results.aspx?q='.rawurlencode($v).'">';
40929dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/msn.png" alt="lookup in MSN Live" border="0" />';
41029dea504SAndreas Gohr                    echo '</a> ';
41129dea504SAndreas Gohr
41212dcdeccSAndreas Gohr                }elseif($k == 'engine'){
41312dcdeccSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/search_engines.php');
41412dcdeccSAndreas Gohr                    echo $SearchEnginesHashLib[$v];
41575fa767dSAndreas Gohr                }elseif($k == 'browser'){
41675fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
41775fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
41875fa767dSAndreas Gohr                }elseif($k == 'bflag'){
41975fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
42075fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
421bd4217d3SAndreas Gohr                }elseif($k == 'os'){
422bd4217d3SAndreas Gohr                    if(empty($v)){
423bd4217d3SAndreas Gohr                        echo 'unknown';
424bd4217d3SAndreas Gohr                    }else{
425bd4217d3SAndreas Gohr                        include_once(dirname(__FILE__).'/inc/operating_systems.php');
426bd4217d3SAndreas Gohr                        echo $OSHashLib[$v];
427bd4217d3SAndreas Gohr                    }
428bd4217d3SAndreas Gohr                }elseif($k == 'osflag'){
429bd4217d3SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />';
43075fa767dSAndreas Gohr                }elseif($k == 'cflag'){
43175fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
43214d99ec0SAndreas Gohr                }elseif($k == 'html'){
43314d99ec0SAndreas Gohr                    echo $v;
43414d99ec0SAndreas Gohr                }else{
43514d99ec0SAndreas Gohr                    echo hsc($v);
43614d99ec0SAndreas Gohr                }
43714d99ec0SAndreas Gohr                echo '</td>';
43814d99ec0SAndreas Gohr            }
43914d99ec0SAndreas Gohr            echo '</tr>';
4402507f8e0SAndreas Gohr
4412507f8e0SAndreas Gohr            if($pager && ($count == $pager)) break;
4422507f8e0SAndreas Gohr            $count++;
44314d99ec0SAndreas Gohr        }
44414d99ec0SAndreas Gohr        echo '</table>';
4452507f8e0SAndreas Gohr
4462507f8e0SAndreas Gohr        if($pager) $this->html_pager($pager,count($result) > $pager);
4471878f16fSAndreas Gohr    }
4481878f16fSAndreas Gohr
44995eb68e6SAndreas Gohr    /**
45095eb68e6SAndreas Gohr     * Create an image
45195eb68e6SAndreas Gohr     */
45295eb68e6SAndreas Gohr    function img_build($img){
45395eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
45495eb68e6SAndreas Gohr
45595eb68e6SAndreas Gohr        switch($img){
45695eb68e6SAndreas Gohr            case 'country':
45795eb68e6SAndreas Gohr                // build top countries + other
45895eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
45995eb68e6SAndreas Gohr                $data = array();
46095eb68e6SAndreas Gohr                $top = 0;
46195eb68e6SAndreas Gohr                foreach($result as $row){
46295eb68e6SAndreas Gohr                    if($top < 7){
46395eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
46495eb68e6SAndreas Gohr                    }else{
46595eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
46695eb68e6SAndreas Gohr                    }
46795eb68e6SAndreas Gohr                    $top++;
46895eb68e6SAndreas Gohr                }
46995eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
47095eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
47195eb68e6SAndreas Gohr                $pie->setProp("showval",false);
47295eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
47395eb68e6SAndreas Gohr                $pie->setProp("type","pie");
47495eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
47595eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
47695eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
47795eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
47895eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
47995eb68e6SAndreas Gohr                @$pie->graph();
48095eb68e6SAndreas Gohr                $pie->showGraph();
48195eb68e6SAndreas Gohr                break;
48275fa767dSAndreas Gohr            case 'browser':
48375fa767dSAndreas Gohr                // build top browsers + other
48475fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
48575fa767dSAndreas Gohr
48675fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
48775fa767dSAndreas Gohr                $data = array();
48875fa767dSAndreas Gohr                $top = 0;
48975fa767dSAndreas Gohr                foreach($result as $row){
49075fa767dSAndreas Gohr                    if($top < 5){
49175fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
49275fa767dSAndreas Gohr                    }else{
49375fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
49475fa767dSAndreas Gohr                    }
49575fa767dSAndreas Gohr                    $top++;
49675fa767dSAndreas Gohr                }
49775fa767dSAndreas Gohr                $pie = new AGC(300, 200);
49875fa767dSAndreas Gohr                $pie->setProp("showkey",true);
49975fa767dSAndreas Gohr                $pie->setProp("showval",false);
50075fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
50175fa767dSAndreas Gohr                $pie->setProp("type","pie");
50275fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
50375fa767dSAndreas Gohr                $pie->setProp("keysize",8);
50475fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
50575fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
50675fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
50775fa767dSAndreas Gohr                @$pie->graph();
50875fa767dSAndreas Gohr                $pie->showGraph();
50975fa767dSAndreas Gohr                break;
510c73e16f1SAndreas Gohr            case 'view':
511c73e16f1SAndreas Gohr
512c73e16f1SAndreas Gohr                $graph = new AGC(400, 200);
513c73e16f1SAndreas Gohr                $graph->setColor('color',0,'blue');
514c73e16f1SAndreas Gohr                $graph->setColor('color',1,'red');
515c73e16f1SAndreas Gohr                $graph->setProp("showkey",true);
516c73e16f1SAndreas Gohr                $graph->setProp("key",'view port width',0);
517c73e16f1SAndreas Gohr                $graph->setProp("key",'view port height',1);
518c73e16f1SAndreas Gohr
519c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,true);
520c73e16f1SAndreas Gohr                foreach($result as $row){
521c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_x'],0);
522c73e16f1SAndreas Gohr                }
523c73e16f1SAndreas Gohr
524c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,false);
525c73e16f1SAndreas Gohr                foreach($result as $row){
526c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_y'],1);
527c73e16f1SAndreas Gohr                }
528c73e16f1SAndreas Gohr
529c73e16f1SAndreas Gohr                @$graph->graph();
530c73e16f1SAndreas Gohr                $graph->showGraph();
531c73e16f1SAndreas Gohr
532c73e16f1SAndreas Gohr                break;
5332812a751SAndreas Gohr            case 'trend':
5342812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
5352812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
5362812a751SAndreas Gohr                $data1   = array();
5372812a751SAndreas Gohr                $data2   = array();
5382812a751SAndreas Gohr
5392812a751SAndreas Gohr                $graph = new AGC(400, 150);
5402812a751SAndreas Gohr                $graph->setProp("type","bar");
5412812a751SAndreas Gohr                $graph->setProp("showgrid",false);
5422812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
54375fa767dSAndreas Gohr
5442812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
5452812a751SAndreas Gohr                $graph->setColor('color',1,'red');
5463c0acc14SAndreas Gohr                $graph->setColor('color',2,'yellow');
5472812a751SAndreas Gohr
5482812a751SAndreas Gohr                if($hours){
5492812a751SAndreas Gohr                    //preset $hours
5502812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
5512812a751SAndreas Gohr                        $data1[$i] = 0;
5522812a751SAndreas Gohr                        $data2[$i] = 0;
5533c0acc14SAndreas Gohr                        $data3[$i] = 0;
5542812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
5552812a751SAndreas Gohr                    }
5562812a751SAndreas Gohr                }else{
5572812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
5582812a751SAndreas Gohr                }
5592812a751SAndreas Gohr
5602812a751SAndreas Gohr                foreach($result as $row){
5612812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
5622812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
5633c0acc14SAndreas Gohr                    $data3[$row['time']] = $row['visitors'];
5642812a751SAndreas Gohr                }
5652812a751SAndreas Gohr
5662812a751SAndreas Gohr                foreach($data1 as $key => $val){
5672812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
5682812a751SAndreas Gohr                }
5692812a751SAndreas Gohr                foreach($data2 as $key => $val){
5702812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
5712812a751SAndreas Gohr                }
5723c0acc14SAndreas Gohr                foreach($data3 as $key => $val){
5733c0acc14SAndreas Gohr                    $graph->addPoint($val,$key,2);
5743c0acc14SAndreas Gohr                }
5752812a751SAndreas Gohr
5762812a751SAndreas Gohr                @$graph->graph();
5772812a751SAndreas Gohr                $graph->showGraph();
5782812a751SAndreas Gohr
57995eb68e6SAndreas Gohr            default:
58095eb68e6SAndreas Gohr                $this->sendGIF();
58195eb68e6SAndreas Gohr        }
58295eb68e6SAndreas Gohr    }
58395eb68e6SAndreas Gohr
58495eb68e6SAndreas Gohr
5852812a751SAndreas Gohr    /**
5862812a751SAndreas Gohr     * Return some aggregated statistics
5872812a751SAndreas Gohr     */
5882812a751SAndreas Gohr    function sql_aggregate($tlimit){
5892812a751SAndreas Gohr        $data = array();
5902812a751SAndreas Gohr
5912812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
5922812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5932812a751SAndreas Gohr                 WHERE $tlimit
5942812a751SAndreas Gohr                   AND ua_type = 'browser'
5952812a751SAndreas Gohr              GROUP BY ref_type";
5962812a751SAndreas Gohr        $result = $this->runSQL($sql);
5972812a751SAndreas Gohr
5982ee939eeSAndreas Gohr        if(is_array($result)) foreach($result as $row){
5992812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
6002812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
6012812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
6022812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
6032812a751SAndreas Gohr        }
6042812a751SAndreas Gohr
6052812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
6062812a751SAndreas Gohr                       COUNT(session) as views,
6073c0acc14SAndreas Gohr                       COUNT(DISTINCT user) as users,
6083c0acc14SAndreas Gohr                       COUNT(DISTINCT uid) as visitors
6092812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6102812a751SAndreas Gohr                 WHERE $tlimit
6112812a751SAndreas Gohr                   AND ua_type = 'browser'";
6122812a751SAndreas Gohr        $result = $this->runSQL($sql);
6132812a751SAndreas Gohr
61475fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
6152812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
6162812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
6173c0acc14SAndreas Gohr        $data['visitors']  = $result[0]['visitors'];
6182812a751SAndreas Gohr
6192812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
6202812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
6212812a751SAndreas Gohr                 WHERE $tlimit
6222812a751SAndreas Gohr                   AND ua_type = 'robot'";
6232812a751SAndreas Gohr        $result = $this->runSQL($sql);
6242812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
6252812a751SAndreas Gohr
6262812a751SAndreas Gohr        return $data;
6272812a751SAndreas Gohr    }
6282812a751SAndreas Gohr
629bd4217d3SAndreas Gohr    /**
630bd4217d3SAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
631bd4217d3SAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
632bd4217d3SAndreas Gohr     */
6332812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
6342812a751SAndreas Gohr        if($hours){
6352812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
6362812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6373c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6383c0acc14SAndreas Gohr                           COUNT(DISTINCT uid) as visitors
6392812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6402812a751SAndreas Gohr                     WHERE $tlimit
6412812a751SAndreas Gohr                       AND ua_type = 'browser'
6422812a751SAndreas Gohr                  GROUP BY HOUR(dt)
6432812a751SAndreas Gohr                  ORDER BY time";
6442812a751SAndreas Gohr        }else{
6452812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
6462812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6473c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6483c0acc14SAndreas Gohr                            COUNT(DISTINCT uid) as visitors
6492812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6502812a751SAndreas Gohr                     WHERE $tlimit
6512812a751SAndreas Gohr                       AND ua_type = 'browser'
6522812a751SAndreas Gohr                  GROUP BY DATE(dt)
6532812a751SAndreas Gohr                  ORDER BY time";
6542812a751SAndreas Gohr        }
6552812a751SAndreas Gohr        return $this->runSQL($sql);
6562812a751SAndreas Gohr    }
6572812a751SAndreas Gohr
65812dcdeccSAndreas Gohr    function sql_searchengines($tlimit,$start=0,$limit=20){
65912dcdeccSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, engine
66012dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
66112dcdeccSAndreas Gohr                 WHERE $tlimit
66212dcdeccSAndreas Gohr              GROUP BY engine
66312dcdeccSAndreas Gohr              ORDER BY cnt DESC, engine".
66412dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
66512dcdeccSAndreas Gohr        return $this->runSQL($sql);
66612dcdeccSAndreas Gohr    }
66712dcdeccSAndreas Gohr
66812dcdeccSAndreas Gohr    function sql_searchphrases($tlimit,$start=0,$limit=20){
66929dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, query, query as lookup
67012dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
67112dcdeccSAndreas Gohr                 WHERE $tlimit
67212dcdeccSAndreas Gohr              GROUP BY query
67312dcdeccSAndreas Gohr              ORDER BY cnt DESC, query".
67412dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
67512dcdeccSAndreas Gohr        return $this->runSQL($sql);
67612dcdeccSAndreas Gohr    }
67712dcdeccSAndreas Gohr
67812dcdeccSAndreas Gohr    function sql_searchwords($tlimit,$start=0,$limit=20){
67929dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, word, word as lookup
68012dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A,
68112dcdeccSAndreas Gohr                       ".$this->getConf('db_prefix')."searchwords as B
68212dcdeccSAndreas Gohr                 WHERE $tlimit
68312dcdeccSAndreas Gohr                   AND A.id = B.sid
68412dcdeccSAndreas Gohr              GROUP BY word
68512dcdeccSAndreas Gohr              ORDER BY cnt DESC, word".
68612dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
68712dcdeccSAndreas Gohr        return $this->runSQL($sql);
68812dcdeccSAndreas Gohr    }
68912dcdeccSAndreas Gohr
690e25286daSAndreas Gohr    function sql_outlinks($tlimit,$start=0,$limit=20){
691e25286daSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, link as url
692e25286daSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."outlinks as A
693e25286daSAndreas Gohr                 WHERE $tlimit
694e25286daSAndreas Gohr              GROUP BY link
695e25286daSAndreas Gohr              ORDER BY cnt DESC, link".
696e25286daSAndreas Gohr              $this->sql_limit($start,$limit);
697e25286daSAndreas Gohr        return $this->runSQL($sql);
698e25286daSAndreas Gohr    }
699e25286daSAndreas Gohr
70095eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
7012812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
70295eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
70395eb68e6SAndreas Gohr                 WHERE $tlimit
70495eb68e6SAndreas Gohr                   AND ua_type = 'browser'
70595eb68e6SAndreas Gohr              GROUP BY page
70695eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
70795eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
70895eb68e6SAndreas Gohr        return $this->runSQL($sql);
70995eb68e6SAndreas Gohr    }
71095eb68e6SAndreas Gohr
71195eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
7122812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
71395eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
71495eb68e6SAndreas Gohr                 WHERE $tlimit
71595eb68e6SAndreas Gohr                   AND ua_type = 'browser'
71695eb68e6SAndreas Gohr                   AND ref_type = 'external'
71795eb68e6SAndreas Gohr              GROUP BY ref_md5
71895eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
71995eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
72095eb68e6SAndreas Gohr        return $this->runSQL($sql);
72195eb68e6SAndreas Gohr    }
72295eb68e6SAndreas Gohr
723e7a2f1e0SAndreas Gohr    function sql_newreferer($tlimit,$start=0,$limit=20){
724e7a2f1e0SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
7252ee939eeSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as B,
7262ee939eeSAndreas Gohr                       ".$this->getConf('db_prefix')."refseen as A
7272ee939eeSAndreas Gohr                 WHERE $tlimit
7282ee939eeSAndreas Gohr                   AND ua_type = 'browser'
729e7a2f1e0SAndreas Gohr                   AND ref_type = 'external'
7302ee939eeSAndreas Gohr                   AND A.ref_md5 = B.ref_md5
7312ee939eeSAndreas Gohr              GROUP BY A.ref_md5
732e7a2f1e0SAndreas Gohr              ORDER BY cnt DESC, url".
733e7a2f1e0SAndreas Gohr              $this->sql_limit($start,$limit);
734e7a2f1e0SAndreas Gohr        return $this->runSQL($sql);
735e7a2f1e0SAndreas Gohr    }
736e7a2f1e0SAndreas Gohr
73795eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
738bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
73995eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
74095eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
74195eb68e6SAndreas Gohr                 WHERE $tlimit
74295eb68e6SAndreas Gohr                   AND A.ip = B.ip
74395eb68e6SAndreas Gohr              GROUP BY B.country
74495eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
74595eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
74695eb68e6SAndreas Gohr        return $this->runSQL($sql);
74795eb68e6SAndreas Gohr    }
74895eb68e6SAndreas Gohr
74975fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
75075fa767dSAndreas Gohr        if($ext){
75175fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
75275fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
75375fa767dSAndreas Gohr        }else{
75475fa767dSAndreas Gohr            $grp = 'ua_info';
75575fa767dSAndreas Gohr            $sel = 'ua_info';
75675fa767dSAndreas Gohr        }
75775fa767dSAndreas Gohr
758bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
75975fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
76075fa767dSAndreas Gohr                 WHERE $tlimit
76175fa767dSAndreas Gohr                   AND ua_type = 'browser'
76275fa767dSAndreas Gohr              GROUP BY $grp
76375fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
76475fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
76575fa767dSAndreas Gohr        return $this->runSQL($sql);
76675fa767dSAndreas Gohr    }
76775fa767dSAndreas Gohr
768bd4217d3SAndreas Gohr    function sql_os($tlimit,$start=0,$limit=20){
769bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
770bd4217d3SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
771bd4217d3SAndreas Gohr                 WHERE $tlimit
772bd4217d3SAndreas Gohr                   AND ua_type = 'browser'
773bd4217d3SAndreas Gohr              GROUP BY os
774bd4217d3SAndreas Gohr              ORDER BY cnt DESC, os".
775bd4217d3SAndreas Gohr              $this->sql_limit($start,$limit);
776bd4217d3SAndreas Gohr        return $this->runSQL($sql);
777bd4217d3SAndreas Gohr    }
778bd4217d3SAndreas Gohr
779c73e16f1SAndreas Gohr    function sql_resolution($tlimit,$start=0,$limit=20){
780c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res
781c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
782c73e16f1SAndreas Gohr                 WHERE $tlimit
783c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
784c73e16f1SAndreas Gohr                   AND screen_x != 0
785c73e16f1SAndreas Gohr              GROUP BY screen_x, screen_y
786c73e16f1SAndreas Gohr              ORDER BY cnt DESC, screen_x".
787c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
788c73e16f1SAndreas Gohr        return $this->runSQL($sql);
789c73e16f1SAndreas Gohr    }
790c73e16f1SAndreas Gohr
791c73e16f1SAndreas Gohr    function sql_viewport($tlimit,$start=0,$limit=20,$x=true){
792c73e16f1SAndreas Gohr        if($x){
793c73e16f1SAndreas Gohr            $col = 'view_x';
794c73e16f1SAndreas Gohr            $res = 'res_x';
795c73e16f1SAndreas Gohr        }else{
796c73e16f1SAndreas Gohr            $col = 'view_y';
797c73e16f1SAndreas Gohr            $res = 'res_y';
798c73e16f1SAndreas Gohr        }
799c73e16f1SAndreas Gohr
800c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt,
801c73e16f1SAndreas Gohr                       ROUND($col/10)*10 as $res
802c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
803c73e16f1SAndreas Gohr                 WHERE $tlimit
804c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
805c73e16f1SAndreas Gohr                   AND $col != 0
806c73e16f1SAndreas Gohr              GROUP BY $res
807c73e16f1SAndreas Gohr              ORDER BY cnt DESC, $res".
808c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
809c73e16f1SAndreas Gohr        return $this->runSQL($sql);
810c73e16f1SAndreas Gohr    }
811c73e16f1SAndreas Gohr
81275fa767dSAndreas Gohr
81395eb68e6SAndreas Gohr    /**
81495eb68e6SAndreas Gohr     * Builds a limit clause
81595eb68e6SAndreas Gohr     */
81695eb68e6SAndreas Gohr    function sql_limit($start,$limit){
81795eb68e6SAndreas Gohr        $start = (int) $start;
81895eb68e6SAndreas Gohr        $limit = (int) $limit;
81995eb68e6SAndreas Gohr        if($limit){
8202507f8e0SAndreas Gohr            $limit += 1;
82195eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
82295eb68e6SAndreas Gohr        }elseif($start){
82395eb68e6SAndreas Gohr            return " OFFSET $start";
82495eb68e6SAndreas Gohr        }
82595eb68e6SAndreas Gohr        return '';
82695eb68e6SAndreas Gohr    }
8271878f16fSAndreas Gohr
8281878f16fSAndreas Gohr    /**
82914d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
8301878f16fSAndreas Gohr     */
83114d99ec0SAndreas Gohr    function dbLink(){
8321878f16fSAndreas Gohr        // connect to DB if needed
8331878f16fSAndreas Gohr        if(!$this->dblink){
8341878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
8351878f16fSAndreas Gohr                                          $this->getConf('db_user'),
8361878f16fSAndreas Gohr                                          $this->getConf('db_password'));
8371878f16fSAndreas Gohr            if(!$this->dblink){
8381878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
8391878f16fSAndreas Gohr                return null;
8401878f16fSAndreas Gohr            }
8411878f16fSAndreas Gohr            // set utf-8
8421878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
8431878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
8441878f16fSAndreas Gohr                return null;
8451878f16fSAndreas Gohr            }
8461878f16fSAndreas Gohr        }
84714d99ec0SAndreas Gohr        return $this->dblink;
84814d99ec0SAndreas Gohr    }
8491878f16fSAndreas Gohr
85014d99ec0SAndreas Gohr    /**
85114d99ec0SAndreas Gohr     * Simple function to run a DB query
85214d99ec0SAndreas Gohr     */
85314d99ec0SAndreas Gohr    function runSQL($sql_string) {
85414d99ec0SAndreas Gohr        $link = $this->dbLink();
85514d99ec0SAndreas Gohr
85614d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
85794171ff3SAndreas Gohr        if(!$result){
8582812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
8591878f16fSAndreas Gohr            return null;
8601878f16fSAndreas Gohr        }
8611878f16fSAndreas Gohr
8621878f16fSAndreas Gohr        $resultarray = array();
8631878f16fSAndreas Gohr
8641878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
8651878f16fSAndreas Gohr        if ($result != 1) {
8661878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
8671878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
8681878f16fSAndreas Gohr                $resultarray[]=$temparray;
8691878f16fSAndreas Gohr            }
8701878f16fSAndreas Gohr            mysql_free_result($result);
8711878f16fSAndreas Gohr        }
8721878f16fSAndreas Gohr
87314d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
87414d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
8751878f16fSAndreas Gohr        }
8761878f16fSAndreas Gohr
8771878f16fSAndreas Gohr        return $resultarray;
8781878f16fSAndreas Gohr    }
8791878f16fSAndreas Gohr
8801878f16fSAndreas Gohr    /**
88114d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
8821878f16fSAndreas Gohr     */
88314d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
88414d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
88514d99ec0SAndreas Gohr        $ua = strtolower($ua);
88614d99ec0SAndreas Gohr
88714d99ec0SAndreas Gohr        // common browsers
88814d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
88914d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
89014d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
89114d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
89214d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
89314d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
89414d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
89514d99ec0SAndreas Gohr
89614d99ec0SAndreas Gohr        $name = '';
89714d99ec0SAndreas Gohr        # IE ?
89814d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
89914d99ec0SAndreas Gohr            $type = 'browser';
90014d99ec0SAndreas Gohr            $ver  = $m[2];
90114d99ec0SAndreas Gohr            $name = 'msie';
90214d99ec0SAndreas Gohr        }
90314d99ec0SAndreas Gohr        # Firefox ?
90414d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
90514d99ec0SAndreas Gohr            $type = 'browser';
90614d99ec0SAndreas Gohr            $ver  = $m[1];
90714d99ec0SAndreas Gohr            $name = 'firefox';
90814d99ec0SAndreas Gohr        }
90914d99ec0SAndreas Gohr        # Subversion ?
91014d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
91114d99ec0SAndreas Gohr            $type = 'rcs';
91214d99ec0SAndreas Gohr            $ver  = $m[1];
91314d99ec0SAndreas Gohr            $name = 'svn';
91414d99ec0SAndreas Gohr        }
91514d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
91614d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
91714d99ec0SAndreas Gohr            $type = 'browser';
91814d99ec0SAndreas Gohr            $ver  = $m[1];
91914d99ec0SAndreas Gohr            $name = 'netscape';
92014d99ec0SAndreas Gohr        }
92114d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
92214d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
92314d99ec0SAndreas Gohr            $type = 'browser';
92414d99ec0SAndreas Gohr            $ver  = $m[2];
92514d99ec0SAndreas Gohr            $name = 'netscape';
92614d99ec0SAndreas Gohr        }else{
92714d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
92814d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
92914d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
93014d99ec0SAndreas Gohr                    // it's a browser!
93114d99ec0SAndreas Gohr                    $type = 'browser';
93214d99ec0SAndreas Gohr                    $name = strtolower($regex);
93314d99ec0SAndreas Gohr                    break;
93414d99ec0SAndreas Gohr                }
93514d99ec0SAndreas Gohr            }
93614d99ec0SAndreas Gohr        }
93714d99ec0SAndreas Gohr
93875fa767dSAndreas Gohr        // check versions for Safari and Opera
93975fa767dSAndreas Gohr        if($name == 'safari'){
94075fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
94175fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
94275fa767dSAndreas Gohr            }
94375fa767dSAndreas Gohr        }elseif($name == 'opera'){
94475fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
94575fa767dSAndreas Gohr                $ver = $match[1];
94675fa767dSAndreas Gohr            }
94775fa767dSAndreas Gohr        }
94875fa767dSAndreas Gohr
94975fa767dSAndreas Gohr
95014d99ec0SAndreas Gohr        // check OS for browsers
95114d99ec0SAndreas Gohr        if($type == 'browser'){
95214d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
95314d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
95414d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
95514d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
95614d99ec0SAndreas Gohr                    break;
95714d99ec0SAndreas Gohr                }
95814d99ec0SAndreas Gohr            }
95914d99ec0SAndreas Gohr
96014d99ec0SAndreas Gohr        }
96114d99ec0SAndreas Gohr
96214d99ec0SAndreas Gohr        // are we done now?
96314d99ec0SAndreas Gohr        if($name) return $name;
96414d99ec0SAndreas Gohr
96514d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
96614d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
96714d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
96814d99ec0SAndreas Gohr                    // it's a robot!
96914d99ec0SAndreas Gohr                    $type = 'robot';
97014d99ec0SAndreas Gohr                    return strtolower($regex);
97114d99ec0SAndreas Gohr            }
97214d99ec0SAndreas Gohr        }
97314d99ec0SAndreas Gohr
97414d99ec0SAndreas Gohr        // dunno
9751878f16fSAndreas Gohr        return '';
9761878f16fSAndreas Gohr    }
9771878f16fSAndreas Gohr
9781878f16fSAndreas Gohr    /**
979322de360SAndreas Gohr     * Log search queries
98014d99ec0SAndreas Gohr     */
98114d99ec0SAndreas Gohr    function log_search($referer,&$type){
98214d99ec0SAndreas Gohr        $referer = strtolower($referer);
983673875b1SAndreas Gohr        $ref     = strtr($referer,' +','__');
98414d99ec0SAndreas Gohr
98514d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
98614d99ec0SAndreas Gohr
98714d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
988673875b1SAndreas Gohr            if(preg_match('/'.$regex.'/',$ref)){
98914d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
990673875b1SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$ref)){
99114d99ec0SAndreas Gohr                    // it's a search engine!
99214d99ec0SAndreas Gohr                    $type = 'search';
99314d99ec0SAndreas Gohr                    break;
99414d99ec0SAndreas Gohr                }
99514d99ec0SAndreas Gohr            }
99614d99ec0SAndreas Gohr        }
99714d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
99814d99ec0SAndreas Gohr
999322de360SAndreas Gohr        // extract query
1000322de360SAndreas Gohr        $engine = $SearchEnginesHashID[$regex];
1001322de360SAndreas Gohr        $param = $SearchEnginesKnownUrl[$engine];
1002322de360SAndreas Gohr        if($param && preg_match('/'.$param.'(.*?)[&$]/',$referer,$match)){
1003322de360SAndreas Gohr            $query = array_pop($match);
1004322de360SAndreas Gohr        }elseif(preg_match('/'.$WordsToExtractSearchUrl.'(.*?)[&$]/',$referer,$match)){
1005322de360SAndreas Gohr            $query = array_pop($match);
1006322de360SAndreas Gohr        }
1007322de360SAndreas Gohr        if(!$query) return; // we failed
1008322de360SAndreas Gohr
1009322de360SAndreas Gohr        // clean the query
1010322de360SAndreas Gohr        $query = preg_replace('/^(cache|related):[^\+]+/','',$query);  // non-search queries
1011322de360SAndreas Gohr        $query = preg_replace('/%0[ad]/',' ',$query);                  // LF CR
1012322de360SAndreas Gohr        $query = preg_replace('/%2[02789abc]/',' ',$query);            // space " ' ( ) * + ,
1013322de360SAndreas Gohr        $query = preg_replace('/%3a/',' ',$query);                     // :
1014673875b1SAndreas Gohr        $query = strtr($query,'+\'()"*,:','        ');                 // badly encoded
1015322de360SAndreas Gohr        $query = preg_replace('/ +/',' ',$query);                      // ws compact
1016322de360SAndreas Gohr        $query = trim($query);
1017322de360SAndreas Gohr        $query = urldecode($query);
1018322de360SAndreas Gohr        if(!utf8_check($query)) $query = utf8_encode($query);          // assume latin1 if not utf8
1019322de360SAndreas Gohr        $query = utf8_strtolower($query);
1020322de360SAndreas Gohr
1021322de360SAndreas Gohr        // log it!
1022322de360SAndreas Gohr        $page  = addslashes($_REQUEST['p']);
1023322de360SAndreas Gohr        $query = addslashes($query);
1024673875b1SAndreas Gohr        $sql  = "INSERT INTO ".$this->getConf('db_prefix')."search
1025322de360SAndreas Gohr                    SET dt       = NOW(),
1026322de360SAndreas Gohr                        page     = '$page',
1027322de360SAndreas Gohr                        query    = '$query',
1028322de360SAndreas Gohr                        engine   = '$engine'";
1029322de360SAndreas Gohr        $id = $this->runSQL($sql);
1030322de360SAndreas Gohr        if(is_null($id)){
1031322de360SAndreas Gohr            global $MSG;
1032322de360SAndreas Gohr            print_r($MSG);
1033322de360SAndreas Gohr            return;
1034322de360SAndreas Gohr        }
1035322de360SAndreas Gohr
1036322de360SAndreas Gohr        // log single keywords
1037322de360SAndreas Gohr        $words = explode(' ',utf8_stripspecials($query,' ','\._\-:\*'));
1038322de360SAndreas Gohr        foreach($words as $word){
1039673875b1SAndreas Gohr            if(!$word) continue;
1040322de360SAndreas Gohr            $word = addslashes($word);
1041322de360SAndreas Gohr            $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."searchwords
1042322de360SAndreas Gohr                       SET sid  = $id,
1043322de360SAndreas Gohr                           word = '$word'";
1044322de360SAndreas Gohr            $ok = $this->runSQL($sql);
1045322de360SAndreas Gohr            if(is_null($ok)){
1046322de360SAndreas Gohr                global $MSG;
1047322de360SAndreas Gohr                print_r($MSG);
1048322de360SAndreas Gohr            }
1049322de360SAndreas Gohr        }
105014d99ec0SAndreas Gohr    }
105114d99ec0SAndreas Gohr
105214d99ec0SAndreas Gohr    /**
105314d99ec0SAndreas Gohr     * Resolve IP to country/city
105414d99ec0SAndreas Gohr     */
105514d99ec0SAndreas Gohr    function log_ip($ip){
105614d99ec0SAndreas Gohr        // check if IP already known and up-to-date
105714d99ec0SAndreas Gohr        $sql = "SELECT ip
105814d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
105914d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
106014d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
106114d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
106214d99ec0SAndreas Gohr        if($result[0]['ip']) return;
106314d99ec0SAndreas Gohr
106414d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
106514d99ec0SAndreas Gohr        $http->timeout = 10;
106614d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
106714d99ec0SAndreas Gohr
106814d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
106914d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
107014d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
107114d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
107214d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
107314d99ec0SAndreas Gohr            $ip      = addslashes($ip);
107414d99ec0SAndreas Gohr
107514d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
107614d99ec0SAndreas Gohr                        SET ip = '$ip',
107714d99ec0SAndreas Gohr                            country = '$country',
107814d99ec0SAndreas Gohr                            code    = '$code',
107914d99ec0SAndreas Gohr                            city    = '$city',
108014d99ec0SAndreas Gohr                            host    = '$host'";
108114d99ec0SAndreas Gohr            $this->runSQL($sql);
108214d99ec0SAndreas Gohr        }
108314d99ec0SAndreas Gohr    }
108414d99ec0SAndreas Gohr
108514d99ec0SAndreas Gohr    /**
1086e25286daSAndreas Gohr     * log a click on an external link
1087e25286daSAndreas Gohr     *
1088e25286daSAndreas Gohr     * called from log.php
1089e25286daSAndreas Gohr     */
1090e25286daSAndreas Gohr    function log_outgoing(){
1091e25286daSAndreas Gohr        if(!$_REQUEST['ol']) return;
1092e25286daSAndreas Gohr
1093e25286daSAndreas Gohr        $link_md5 = md5($link);
1094e25286daSAndreas Gohr        $link     = addslashes($_REQUEST['ol']);
1095e25286daSAndreas Gohr        $session  = addslashes(session_id());
1096d8c4d85eSAndreas Gohr        $page     = addslashes($_REQUEST['p']);
1097e25286daSAndreas Gohr
1098e25286daSAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks
1099e25286daSAndreas Gohr                    SET dt       = NOW(),
1100e25286daSAndreas Gohr                        session  = '$session',
1101d8c4d85eSAndreas Gohr                        page     = '$page',
1102e25286daSAndreas Gohr                        link_md5 = '$link_md5',
1103e25286daSAndreas Gohr                        link     = '$link'";
1104e25286daSAndreas Gohr        $ok = $this->runSQL($sql);
1105e25286daSAndreas Gohr        if(is_null($ok)){
1106e25286daSAndreas Gohr            global $MSG;
1107e25286daSAndreas Gohr            print_r($MSG);
1108e25286daSAndreas Gohr        }
1109e25286daSAndreas Gohr    }
1110e25286daSAndreas Gohr
1111e25286daSAndreas Gohr    /**
11121878f16fSAndreas Gohr     * log a page access
11131878f16fSAndreas Gohr     *
11141878f16fSAndreas Gohr     * called from log.php
11151878f16fSAndreas Gohr     */
11161878f16fSAndreas Gohr    function log_access(){
111794171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
111894171ff3SAndreas Gohr
111914d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
112014d99ec0SAndreas Gohr
112114d99ec0SAndreas Gohr        // handle referer
112214d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
112314d99ec0SAndreas Gohr        if($referer){
112414d99ec0SAndreas Gohr            $ref     = addslashes($referer);
112514d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
112614d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
112714d99ec0SAndreas Gohr                $ref_type = 'internal';
112814d99ec0SAndreas Gohr            }else{
112914d99ec0SAndreas Gohr                $ref_type = 'external';
113014d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
113114d99ec0SAndreas Gohr            }
113214d99ec0SAndreas Gohr        }else{
113314d99ec0SAndreas Gohr            $ref      = '';
113414d99ec0SAndreas Gohr            $ref_md5  = '';
113514d99ec0SAndreas Gohr            $ref_type = '';
113614d99ec0SAndreas Gohr        }
113714d99ec0SAndreas Gohr
113814d99ec0SAndreas Gohr        // handle user agent
113914d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
114014d99ec0SAndreas Gohr
114114d99ec0SAndreas Gohr        $ua      = addslashes($agent);
114214d99ec0SAndreas Gohr        $ua_type = '';
114314d99ec0SAndreas Gohr        $ua_ver  = '';
114414d99ec0SAndreas Gohr        $os      = '';
114514d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
114614d99ec0SAndreas Gohr
11471878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
11481878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
11491878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
11501878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
11511878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
11521878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
115375fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
11543c0acc14SAndreas Gohr        $uid     = addslashes($_REQUEST['uid']);
11551878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
11561878f16fSAndreas Gohr        $session = addslashes(session_id());
11573c0acc14SAndreas Gohr        if(!$uid) $uid = $session;
11581878f16fSAndreas Gohr
115994171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
116075fa767dSAndreas Gohr                    SET dt       = NOW(),
116175fa767dSAndreas Gohr                        page     = '$page',
11621878f16fSAndreas Gohr                        ip       = '$ip',
11631878f16fSAndreas Gohr                        ua       = '$ua',
11641878f16fSAndreas Gohr                        ua_info  = '$ua_info',
116514d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
116614d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
116714d99ec0SAndreas Gohr                        os       = '$os',
11681878f16fSAndreas Gohr                        ref      = '$ref',
116994171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
117014d99ec0SAndreas Gohr                        ref_type = '$ref_type',
11711878f16fSAndreas Gohr                        screen_x = '$sx',
11721878f16fSAndreas Gohr                        screen_y = '$sy',
11731878f16fSAndreas Gohr                        view_x   = '$vx',
11741878f16fSAndreas Gohr                        view_y   = '$vy',
117575fa767dSAndreas Gohr                        js       = '$js',
11761878f16fSAndreas Gohr                        user     = '$user',
11773c0acc14SAndreas Gohr                        session  = '$session',
11783c0acc14SAndreas Gohr                        uid      = '$uid'";
11791878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
11801878f16fSAndreas Gohr        if(is_null($ok)){
11811878f16fSAndreas Gohr            global $MSG;
11821878f16fSAndreas Gohr            print_r($MSG);
11831878f16fSAndreas Gohr        }
118414d99ec0SAndreas Gohr
11852ee939eeSAndreas Gohr        $sql = "INSERT DELAYED IGNORE INTO ".$this->getConf('db_prefix')."refseen
11862ee939eeSAndreas Gohr                   SET ref_md5  = '$ref_md5',
11872ee939eeSAndreas Gohr                       dt       = NOW()";
11882ee939eeSAndreas Gohr        $ok = $this->runSQL($sql);
11892ee939eeSAndreas Gohr        if(is_null($ok)){
11902ee939eeSAndreas Gohr            global $MSG;
11912ee939eeSAndreas Gohr            print_r($MSG);
11922ee939eeSAndreas Gohr        }
11932ee939eeSAndreas Gohr
119414d99ec0SAndreas Gohr        // resolve the IP
119514d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
11961878f16fSAndreas Gohr    }
11971878f16fSAndreas Gohr
11981878f16fSAndreas Gohr    /**
11991878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
12001878f16fSAndreas Gohr     *
12011878f16fSAndreas Gohr     * @called from log.php
12021878f16fSAndreas Gohr     *
12031878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
12041878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
12051878f16fSAndreas Gohr     */
12061878f16fSAndreas Gohr    function sendGIF(){
12071878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
12081878f16fSAndreas Gohr        header('Content-Type: image/gif');
12091878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
12101878f16fSAndreas Gohr        header('Connection: Close');
12111878f16fSAndreas Gohr        print $img;
12121878f16fSAndreas Gohr        flush();
12131878f16fSAndreas Gohr        // Browser should drop connection after this
12141878f16fSAndreas Gohr        // Thinks it's got the whole image
12151878f16fSAndreas Gohr    }
12161878f16fSAndreas Gohr
12171878f16fSAndreas Gohr}
1218