xref: /plugin/statistics/admin.php (revision 79b4a855df8e3d289667660c51fb6d836cfa6560)
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    /**
68*79b4a855SAndreas Gohr     * Output the Statistics
691878f16fSAndreas Gohr     */
701878f16fSAndreas Gohr    function html() {
71264f1744SAndreas Gohr        echo '<h1>Access Statistics</h1>';
72264f1744SAndreas Gohr        $this->html_timeselect();
73264f1744SAndreas Gohr
74*79b4a855SAndreas Gohr        $method = 'html_'.$this->opt;
75*79b4a855SAndreas Gohr        if(method_exists($this,$method)){
76*79b4a855SAndreas Gohr            $this->$method();
77*79b4a855SAndreas Gohr        }else{
789da6395dSAndreas Gohr            $this->html_dashboard();
7914d99ec0SAndreas Gohr        }
8014d99ec0SAndreas Gohr    }
8114d99ec0SAndreas Gohr
8247ffcf7dSAndreas Gohr    function getTOC(){
8347ffcf7dSAndreas Gohr        $pages = array('dashboard','page','referer','newreferer','outlinks',
8447ffcf7dSAndreas Gohr                       'searchphrases','searchwords','searchengines','browser',
8547ffcf7dSAndreas Gohr                       'os','country','resolution');
869da6395dSAndreas Gohr
8747ffcf7dSAndreas Gohr        $toc = array();
8847ffcf7dSAndreas Gohr        foreach($pages as $page){
8947ffcf7dSAndreas Gohr            $toc[] = array(
9047ffcf7dSAndreas Gohr                    'link'  => '?do=admin&amp;page=statistics&amp;opt='.$page.'&amp;f='.$this->from.'&amp;t='.$this->to,
9147ffcf7dSAndreas Gohr                    'title' => $this->getLang($page),
9247ffcf7dSAndreas Gohr                    'level' => 1,
9347ffcf7dSAndreas Gohr                    'type'  => 'ul'
9447ffcf7dSAndreas Gohr            );
9547ffcf7dSAndreas Gohr        }
9647ffcf7dSAndreas Gohr        return $toc;
979da6395dSAndreas Gohr    }
989da6395dSAndreas Gohr
992507f8e0SAndreas Gohr    function html_pager($limit,$next){
1002507f8e0SAndreas Gohr        echo '<div class="plg_stats_pager">';
1012507f8e0SAndreas Gohr
1022507f8e0SAndreas Gohr        if($this->start > 0){
1032507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
1042507f8e0SAndreas 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>';
1052507f8e0SAndreas Gohr        }
1062507f8e0SAndreas Gohr
1072507f8e0SAndreas Gohr        if($next){
1082507f8e0SAndreas Gohr            $go = $this->start + $limit;
1092507f8e0SAndreas 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>';
1102507f8e0SAndreas Gohr        }
1112507f8e0SAndreas Gohr        echo '</div>';
1122507f8e0SAndreas Gohr    }
1132507f8e0SAndreas Gohr
114264f1744SAndreas Gohr    /**
115264f1744SAndreas Gohr     * Print the time selection menu
116264f1744SAndreas Gohr     */
11714d99ec0SAndreas Gohr    function html_timeselect(){
118264f1744SAndreas Gohr        $now   = date('Y-m-d');
119264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
120264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
121264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
12214d99ec0SAndreas Gohr
123264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
124264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
125264f1744SAndreas Gohr        echo '<ul>';
126264f1744SAndreas Gohr
127264f1744SAndreas Gohr        echo '<li>';
1282507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'">';
129264f1744SAndreas Gohr        echo 'today';
130264f1744SAndreas Gohr        echo '</a>';
131264f1744SAndreas Gohr        echo '</li>';
132264f1744SAndreas Gohr
133264f1744SAndreas Gohr        echo '<li>';
1342507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'">';
135264f1744SAndreas Gohr        echo 'yesterday';
136264f1744SAndreas Gohr        echo '</a>';
137264f1744SAndreas Gohr        echo '</li>';
138264f1744SAndreas Gohr
139264f1744SAndreas Gohr        echo '<li>';
1402507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'">';
141264f1744SAndreas Gohr        echo 'last 7 days';
142264f1744SAndreas Gohr        echo '</a>';
143264f1744SAndreas Gohr        echo '</li>';
144264f1744SAndreas Gohr
145264f1744SAndreas Gohr        echo '<li>';
1462507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'">';
147264f1744SAndreas Gohr        echo 'last 30 days';
148264f1744SAndreas Gohr        echo '</a>';
149264f1744SAndreas Gohr        echo '</li>';
150264f1744SAndreas Gohr
151264f1744SAndreas Gohr        echo '</ul>';
152264f1744SAndreas Gohr
153264f1744SAndreas Gohr
154264f1744SAndreas Gohr        echo '<form action="" method="get">';
155264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
156264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
157264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
158264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
159264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
160264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
16114d99ec0SAndreas Gohr        echo '</form>';
162264f1744SAndreas Gohr
163264f1744SAndreas Gohr        echo '</div>';
16414d99ec0SAndreas Gohr    }
16514d99ec0SAndreas Gohr
16614d99ec0SAndreas Gohr
167f5f32cbfSAndreas Gohr    /**
168f5f32cbfSAndreas Gohr     * Print an introductionary screen
169f5f32cbfSAndreas Gohr     */
17014d99ec0SAndreas Gohr    function html_dashboard(){
1712812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
1722812a751SAndreas Gohr              choose a topic from the list.</p>';
1732812a751SAndreas Gohr
1742812a751SAndreas Gohr
175264f1744SAndreas Gohr        echo '<div class="plg_stats_dashboard">';
176264f1744SAndreas Gohr
1772812a751SAndreas Gohr        // general info
1782812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
1792812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
1802812a751SAndreas Gohr        echo '<ul>';
1812812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views </li>';
1823c0acc14SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>';
1833c0acc14SAndreas Gohr        echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>';
1842812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
1852812a751SAndreas Gohr
1862812a751SAndreas Gohr        echo '</ul>';
1872812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
1882812a751SAndreas Gohr        echo '</div>';
1892812a751SAndreas Gohr
19014d99ec0SAndreas Gohr
19187d5e44bSAndreas Gohr        // top pages today
192264f1744SAndreas Gohr        echo '<div>';
193264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
19495eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
1952812a751SAndreas Gohr        $this->html_resulttable($result);
1962507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
197264f1744SAndreas Gohr        echo '</div>';
19887d5e44bSAndreas Gohr
19987d5e44bSAndreas Gohr        // top referer today
200264f1744SAndreas Gohr        echo '<div>';
201e7a2f1e0SAndreas Gohr        echo '<h2>Newest incoming links</h2>';
202e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,15);
2032812a751SAndreas Gohr        $this->html_resulttable($result);
2042507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
205264f1744SAndreas Gohr        echo '</div>';
20654f6c432SAndreas Gohr
20729dea504SAndreas Gohr        // top searches today
208264f1744SAndreas Gohr        echo '<div>';
20929dea504SAndreas Gohr        echo '<h2>Top search phrases</h2>';
21029dea504SAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,15);
21129dea504SAndreas Gohr        $this->html_resulttable($result);
21229dea504SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchphrases&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
213264f1744SAndreas Gohr        echo '</div>';
214264f1744SAndreas Gohr
215264f1744SAndreas Gohr        echo '</div>';
21614d99ec0SAndreas Gohr    }
21714d99ec0SAndreas Gohr
2189da6395dSAndreas Gohr    function html_country(){
2199da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2209da6395dSAndreas Gohr        echo '<h2>Visitor\'s Countries</h2>';
221bd4217d3SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=country&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
2229da6395dSAndreas Gohr        $result = $this->sql_countries($this->tlimit,$this->start,150);
2232507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2249da6395dSAndreas Gohr        echo '</div>';
2259da6395dSAndreas Gohr    }
2269da6395dSAndreas Gohr
2279da6395dSAndreas Gohr    function html_page(){
2289da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2299da6395dSAndreas Gohr        echo '<h2>Popular Pages</h2>';
2309da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
2312507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2329da6395dSAndreas Gohr        echo '</div>';
2339da6395dSAndreas Gohr    }
2349da6395dSAndreas Gohr
23575fa767dSAndreas Gohr    function html_browser(){
23675fa767dSAndreas Gohr        echo '<div class="plg_stats_full">';
23775fa767dSAndreas Gohr        echo '<h2>Browser Shootout</h2>';
23875fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
23975fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
2402507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
24175fa767dSAndreas Gohr        echo '</div>';
24275fa767dSAndreas Gohr    }
24375fa767dSAndreas Gohr
244bd4217d3SAndreas Gohr    function html_os(){
245bd4217d3SAndreas Gohr        echo '<div class="plg_stats_full">';
246bd4217d3SAndreas Gohr        echo '<h2>Operating Systems</h2>';
247bd4217d3SAndreas Gohr        $result = $this->sql_os($this->tlimit,$this->start,150,true);
2482507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
249bd4217d3SAndreas Gohr        echo '</div>';
250bd4217d3SAndreas Gohr    }
251bd4217d3SAndreas Gohr
2529da6395dSAndreas Gohr    function html_referer(){
2539da6395dSAndreas Gohr        echo '<div class="plg_stats_full">';
2549da6395dSAndreas Gohr        echo '<h2>Incoming Links</h2>';
2552812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2562812a751SAndreas Gohr
2572812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
2582812a751SAndreas Gohr
25994023548SAndreas Gohr        if($all){
2602812a751SAndreas Gohr            printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
2612812a751SAndreas Gohr                    %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
2622812a751SAndreas Gohr                    links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
2632812a751SAndreas Gohr                    $result['search'],(100*$result['search']/$all),$result['external'],
2642812a751SAndreas Gohr                    (100*$result['external']/$all));
26594023548SAndreas Gohr        }
2662812a751SAndreas Gohr
2679da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
2682507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2699da6395dSAndreas Gohr        echo '</div>';
2709da6395dSAndreas Gohr    }
2719da6395dSAndreas Gohr
272e7a2f1e0SAndreas Gohr    function html_newreferer(){
273e7a2f1e0SAndreas Gohr        echo '<div class="plg_stats_full">';
274e7a2f1e0SAndreas Gohr        echo '<h2>New Incoming Links</h2>';
275e7a2f1e0SAndreas Gohr        echo '<p>The following incoming links where first logged in the selected time frame,
276e7a2f1e0SAndreas Gohr              and have never been seen before.</p>';
277e7a2f1e0SAndreas Gohr
278e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,150);
2792507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
280e7a2f1e0SAndreas Gohr        echo '</div>';
281e7a2f1e0SAndreas Gohr    }
282e7a2f1e0SAndreas Gohr
283e25286daSAndreas Gohr    function html_outlinks(){
284e25286daSAndreas Gohr        echo '<div class="plg_stats_full">';
285e25286daSAndreas Gohr        echo '<h2>Outgoing Links</h2>';
286e25286daSAndreas Gohr
287e25286daSAndreas Gohr        $result = $this->sql_outlinks($this->tlimit,$this->start,150);
288e25286daSAndreas Gohr        $this->html_resulttable($result,'',150);
289e25286daSAndreas Gohr        echo '</div>';
290e25286daSAndreas Gohr    }
291e25286daSAndreas Gohr
29212dcdeccSAndreas Gohr    function html_searchphrases(){
29312dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
29412dcdeccSAndreas Gohr        echo '<h2>Search Phrases</h2>';
29512dcdeccSAndreas Gohr
29612dcdeccSAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,150);
29712dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
29812dcdeccSAndreas Gohr        echo '</div>';
29912dcdeccSAndreas Gohr    }
30012dcdeccSAndreas Gohr
30112dcdeccSAndreas Gohr    function html_searchwords(){
30212dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
30312dcdeccSAndreas Gohr        echo '<h2>Search Words</h2>';
30412dcdeccSAndreas Gohr
30512dcdeccSAndreas Gohr        $result = $this->sql_searchwords($this->tlimit,$this->start,150);
30612dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
30712dcdeccSAndreas Gohr        echo '</div>';
30812dcdeccSAndreas Gohr    }
30912dcdeccSAndreas Gohr
31012dcdeccSAndreas Gohr    function html_searchengines(){
31112dcdeccSAndreas Gohr        echo '<div class="plg_stats_full">';
31212dcdeccSAndreas Gohr        echo '<h2>Search Engines</h2>';
31312dcdeccSAndreas Gohr
31412dcdeccSAndreas Gohr        $result = $this->sql_searchengines($this->tlimit,$this->start,150);
31512dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
31612dcdeccSAndreas Gohr        echo '</div>';
31712dcdeccSAndreas Gohr    }
31812dcdeccSAndreas Gohr
319e25286daSAndreas Gohr
320c73e16f1SAndreas Gohr    function html_resolution(){
321c73e16f1SAndreas Gohr        echo '<div class="plg_stats_full">';
322c73e16f1SAndreas Gohr        echo '<h2>Resolution</h2>';
323c73e16f1SAndreas Gohr        $result = $this->sql_resolution($this->tlimit,$this->start,150);
324c73e16f1SAndreas Gohr        $this->html_resulttable($result,'',150);
325c73e16f1SAndreas Gohr
326c73e16f1SAndreas Gohr        echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you
327c73e16f1SAndreas Gohr              much about about the real size of their browser windows. The graphic below shows the size distribution of
328c73e16f1SAndreas Gohr              the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged
329c73e16f1SAndreas Gohr              in all browsers. Because users may resize their browser window while browsing your site the statistics may
330c73e16f1SAndreas Gohr              be flawed. Take it with a grain of salt.</p>';
331c73e16f1SAndreas Gohr
332c73e16f1SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
333c73e16f1SAndreas Gohr        echo '</div>';
334c73e16f1SAndreas Gohr    }
3359da6395dSAndreas Gohr
3369da6395dSAndreas Gohr
33714d99ec0SAndreas Gohr    /**
33814d99ec0SAndreas Gohr     * Display a result in a HTML table
33914d99ec0SAndreas Gohr     */
3402507f8e0SAndreas Gohr    function html_resulttable($result,$header='',$pager=0){
34114d99ec0SAndreas Gohr        echo '<table>';
3422812a751SAndreas Gohr        if(is_array($header)){
34314d99ec0SAndreas Gohr            echo '<tr>';
34414d99ec0SAndreas Gohr            foreach($header as $h){
34514d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
34614d99ec0SAndreas Gohr            }
34714d99ec0SAndreas Gohr            echo '</tr>';
3482812a751SAndreas Gohr        }
34914d99ec0SAndreas Gohr
3502507f8e0SAndreas Gohr        $count = 0;
3512ee939eeSAndreas Gohr        if(is_array($result)) foreach($result as $row){
35214d99ec0SAndreas Gohr            echo '<tr>';
35314d99ec0SAndreas Gohr            foreach($row as $k => $v){
3542812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
35514d99ec0SAndreas Gohr                if($k == 'page'){
35614d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
35714d99ec0SAndreas Gohr                    echo hsc($v);
35814d99ec0SAndreas Gohr                    echo '</a>';
35914d99ec0SAndreas Gohr                }elseif($k == 'url'){
36054f6c432SAndreas Gohr                    $url = hsc($v);
36183b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/','',$url);
3622812a751SAndreas Gohr                    if(strlen($url) > 45){
3632812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
36454f6c432SAndreas Gohr                    }
36514d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
36654f6c432SAndreas Gohr                    echo $url;
36714d99ec0SAndreas Gohr                    echo '</a>';
36829dea504SAndreas Gohr                }elseif($k == 'lookup'){
36929dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q='.rawurlencode($v).'">';
37029dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/google.png" alt="lookup in Google" border="0" />';
37129dea504SAndreas Gohr                    echo '</a> ';
37229dea504SAndreas Gohr
37329dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p='.rawurlencode($v).'">';
37429dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/yahoo.png" alt="lookup in Yahoo" border="0" />';
37529dea504SAndreas Gohr                    echo '</a> ';
37629dea504SAndreas Gohr
37729dea504SAndreas Gohr                    echo '<a href="http://search.msn.com/results.aspx?q='.rawurlencode($v).'">';
37829dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/msn.png" alt="lookup in MSN Live" border="0" />';
37929dea504SAndreas Gohr                    echo '</a> ';
38029dea504SAndreas Gohr
38112dcdeccSAndreas Gohr                }elseif($k == 'engine'){
38212dcdeccSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/search_engines.php');
38312dcdeccSAndreas Gohr                    echo $SearchEnginesHashLib[$v];
38475fa767dSAndreas Gohr                }elseif($k == 'browser'){
38575fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
38675fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
38775fa767dSAndreas Gohr                }elseif($k == 'bflag'){
38875fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
38975fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
390bd4217d3SAndreas Gohr                }elseif($k == 'os'){
391bd4217d3SAndreas Gohr                    if(empty($v)){
392bd4217d3SAndreas Gohr                        echo 'unknown';
393bd4217d3SAndreas Gohr                    }else{
394bd4217d3SAndreas Gohr                        include_once(dirname(__FILE__).'/inc/operating_systems.php');
395bd4217d3SAndreas Gohr                        echo $OSHashLib[$v];
396bd4217d3SAndreas Gohr                    }
397bd4217d3SAndreas Gohr                }elseif($k == 'osflag'){
398bd4217d3SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />';
39975fa767dSAndreas Gohr                }elseif($k == 'cflag'){
40075fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
40114d99ec0SAndreas Gohr                }elseif($k == 'html'){
40214d99ec0SAndreas Gohr                    echo $v;
40314d99ec0SAndreas Gohr                }else{
40414d99ec0SAndreas Gohr                    echo hsc($v);
40514d99ec0SAndreas Gohr                }
40614d99ec0SAndreas Gohr                echo '</td>';
40714d99ec0SAndreas Gohr            }
40814d99ec0SAndreas Gohr            echo '</tr>';
4092507f8e0SAndreas Gohr
4102507f8e0SAndreas Gohr            if($pager && ($count == $pager)) break;
4112507f8e0SAndreas Gohr            $count++;
41214d99ec0SAndreas Gohr        }
41314d99ec0SAndreas Gohr        echo '</table>';
4142507f8e0SAndreas Gohr
4152507f8e0SAndreas Gohr        if($pager) $this->html_pager($pager,count($result) > $pager);
4161878f16fSAndreas Gohr    }
4171878f16fSAndreas Gohr
41895eb68e6SAndreas Gohr    /**
41995eb68e6SAndreas Gohr     * Create an image
42095eb68e6SAndreas Gohr     */
42195eb68e6SAndreas Gohr    function img_build($img){
42295eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
42395eb68e6SAndreas Gohr
42495eb68e6SAndreas Gohr        switch($img){
42595eb68e6SAndreas Gohr            case 'country':
42695eb68e6SAndreas Gohr                // build top countries + other
42795eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
42895eb68e6SAndreas Gohr                $data = array();
42995eb68e6SAndreas Gohr                $top = 0;
43095eb68e6SAndreas Gohr                foreach($result as $row){
43195eb68e6SAndreas Gohr                    if($top < 7){
43295eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
43395eb68e6SAndreas Gohr                    }else{
43495eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
43595eb68e6SAndreas Gohr                    }
43695eb68e6SAndreas Gohr                    $top++;
43795eb68e6SAndreas Gohr                }
43895eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
43995eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
44095eb68e6SAndreas Gohr                $pie->setProp("showval",false);
44195eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
44295eb68e6SAndreas Gohr                $pie->setProp("type","pie");
44395eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
44495eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
44595eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
44695eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
44795eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
44895eb68e6SAndreas Gohr                @$pie->graph();
44995eb68e6SAndreas Gohr                $pie->showGraph();
45095eb68e6SAndreas Gohr                break;
45175fa767dSAndreas Gohr            case 'browser':
45275fa767dSAndreas Gohr                // build top browsers + other
45375fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
45475fa767dSAndreas Gohr
45575fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
45675fa767dSAndreas Gohr                $data = array();
45775fa767dSAndreas Gohr                $top = 0;
45875fa767dSAndreas Gohr                foreach($result as $row){
45975fa767dSAndreas Gohr                    if($top < 5){
46075fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
46175fa767dSAndreas Gohr                    }else{
46275fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
46375fa767dSAndreas Gohr                    }
46475fa767dSAndreas Gohr                    $top++;
46575fa767dSAndreas Gohr                }
46675fa767dSAndreas Gohr                $pie = new AGC(300, 200);
46775fa767dSAndreas Gohr                $pie->setProp("showkey",true);
46875fa767dSAndreas Gohr                $pie->setProp("showval",false);
46975fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
47075fa767dSAndreas Gohr                $pie->setProp("type","pie");
47175fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
47275fa767dSAndreas Gohr                $pie->setProp("keysize",8);
47375fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
47475fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
47575fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
47675fa767dSAndreas Gohr                @$pie->graph();
47775fa767dSAndreas Gohr                $pie->showGraph();
47875fa767dSAndreas Gohr                break;
479c73e16f1SAndreas Gohr            case 'view':
480c73e16f1SAndreas Gohr
481c73e16f1SAndreas Gohr                $graph = new AGC(400, 200);
482c73e16f1SAndreas Gohr                $graph->setColor('color',0,'blue');
483c73e16f1SAndreas Gohr                $graph->setColor('color',1,'red');
484c73e16f1SAndreas Gohr                $graph->setProp("showkey",true);
485c73e16f1SAndreas Gohr                $graph->setProp("key",'view port width',0);
486c73e16f1SAndreas Gohr                $graph->setProp("key",'view port height',1);
487c73e16f1SAndreas Gohr
488c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,true);
489c73e16f1SAndreas Gohr                foreach($result as $row){
490c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_x'],0);
491c73e16f1SAndreas Gohr                }
492c73e16f1SAndreas Gohr
493c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,false);
494c73e16f1SAndreas Gohr                foreach($result as $row){
495c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_y'],1);
496c73e16f1SAndreas Gohr                }
497c73e16f1SAndreas Gohr
498c73e16f1SAndreas Gohr                @$graph->graph();
499c73e16f1SAndreas Gohr                $graph->showGraph();
500c73e16f1SAndreas Gohr
501c73e16f1SAndreas Gohr                break;
5022812a751SAndreas Gohr            case 'trend':
5032812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
5042812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
5052812a751SAndreas Gohr                $data1   = array();
5062812a751SAndreas Gohr                $data2   = array();
5072812a751SAndreas Gohr
5082812a751SAndreas Gohr                $graph = new AGC(400, 150);
5092812a751SAndreas Gohr                $graph->setProp("type","bar");
5102812a751SAndreas Gohr                $graph->setProp("showgrid",false);
5112812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
51275fa767dSAndreas Gohr
5132812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
5142812a751SAndreas Gohr                $graph->setColor('color',1,'red');
5153c0acc14SAndreas Gohr                $graph->setColor('color',2,'yellow');
5162812a751SAndreas Gohr
5172812a751SAndreas Gohr                if($hours){
5182812a751SAndreas Gohr                    //preset $hours
5192812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
5202812a751SAndreas Gohr                        $data1[$i] = 0;
5212812a751SAndreas Gohr                        $data2[$i] = 0;
5223c0acc14SAndreas Gohr                        $data3[$i] = 0;
5232812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
5242812a751SAndreas Gohr                    }
5252812a751SAndreas Gohr                }else{
5262812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
5272812a751SAndreas Gohr                }
5282812a751SAndreas Gohr
5292812a751SAndreas Gohr                foreach($result as $row){
5302812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
5312812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
5323c0acc14SAndreas Gohr                    $data3[$row['time']] = $row['visitors'];
5332812a751SAndreas Gohr                }
5342812a751SAndreas Gohr
5352812a751SAndreas Gohr                foreach($data1 as $key => $val){
5362812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
5372812a751SAndreas Gohr                }
5382812a751SAndreas Gohr                foreach($data2 as $key => $val){
5392812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
5402812a751SAndreas Gohr                }
5413c0acc14SAndreas Gohr                foreach($data3 as $key => $val){
5423c0acc14SAndreas Gohr                    $graph->addPoint($val,$key,2);
5433c0acc14SAndreas Gohr                }
5442812a751SAndreas Gohr
5452812a751SAndreas Gohr                @$graph->graph();
5462812a751SAndreas Gohr                $graph->showGraph();
5472812a751SAndreas Gohr
54895eb68e6SAndreas Gohr            default:
54995eb68e6SAndreas Gohr                $this->sendGIF();
55095eb68e6SAndreas Gohr        }
55195eb68e6SAndreas Gohr    }
55295eb68e6SAndreas Gohr
55395eb68e6SAndreas Gohr
5542812a751SAndreas Gohr    /**
5552812a751SAndreas Gohr     * Return some aggregated statistics
5562812a751SAndreas Gohr     */
5572812a751SAndreas Gohr    function sql_aggregate($tlimit){
5582812a751SAndreas Gohr        $data = array();
5592812a751SAndreas Gohr
5602812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
5612812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5622812a751SAndreas Gohr                 WHERE $tlimit
5632812a751SAndreas Gohr                   AND ua_type = 'browser'
5642812a751SAndreas Gohr              GROUP BY ref_type";
5652812a751SAndreas Gohr        $result = $this->runSQL($sql);
5662812a751SAndreas Gohr
5672ee939eeSAndreas Gohr        if(is_array($result)) foreach($result as $row){
5682812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
5692812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
5702812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
5712812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
5722812a751SAndreas Gohr        }
5732812a751SAndreas Gohr
5742812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
5752812a751SAndreas Gohr                       COUNT(session) as views,
5763c0acc14SAndreas Gohr                       COUNT(DISTINCT user) as users,
5773c0acc14SAndreas Gohr                       COUNT(DISTINCT uid) as visitors
5782812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5792812a751SAndreas Gohr                 WHERE $tlimit
5802812a751SAndreas Gohr                   AND ua_type = 'browser'";
5812812a751SAndreas Gohr        $result = $this->runSQL($sql);
5822812a751SAndreas Gohr
58375fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
5842812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
5852812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
5863c0acc14SAndreas Gohr        $data['visitors']  = $result[0]['visitors'];
5872812a751SAndreas Gohr
5882812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
5892812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5902812a751SAndreas Gohr                 WHERE $tlimit
5912812a751SAndreas Gohr                   AND ua_type = 'robot'";
5922812a751SAndreas Gohr        $result = $this->runSQL($sql);
5932812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
5942812a751SAndreas Gohr
5952812a751SAndreas Gohr        return $data;
5962812a751SAndreas Gohr    }
5972812a751SAndreas Gohr
598bd4217d3SAndreas Gohr    /**
599bd4217d3SAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
600bd4217d3SAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
601bd4217d3SAndreas Gohr     */
6022812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
6032812a751SAndreas Gohr        if($hours){
6042812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
6052812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6063c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6073c0acc14SAndreas Gohr                           COUNT(DISTINCT uid) as visitors
6082812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6092812a751SAndreas Gohr                     WHERE $tlimit
6102812a751SAndreas Gohr                       AND ua_type = 'browser'
6112812a751SAndreas Gohr                  GROUP BY HOUR(dt)
6122812a751SAndreas Gohr                  ORDER BY time";
6132812a751SAndreas Gohr        }else{
6142812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
6152812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
6163c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
6173c0acc14SAndreas Gohr                            COUNT(DISTINCT uid) as visitors
6182812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
6192812a751SAndreas Gohr                     WHERE $tlimit
6202812a751SAndreas Gohr                       AND ua_type = 'browser'
6212812a751SAndreas Gohr                  GROUP BY DATE(dt)
6222812a751SAndreas Gohr                  ORDER BY time";
6232812a751SAndreas Gohr        }
6242812a751SAndreas Gohr        return $this->runSQL($sql);
6252812a751SAndreas Gohr    }
6262812a751SAndreas Gohr
62712dcdeccSAndreas Gohr    function sql_searchengines($tlimit,$start=0,$limit=20){
62812dcdeccSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, engine
62912dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
63012dcdeccSAndreas Gohr                 WHERE $tlimit
63112dcdeccSAndreas Gohr              GROUP BY engine
63212dcdeccSAndreas Gohr              ORDER BY cnt DESC, engine".
63312dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
63412dcdeccSAndreas Gohr        return $this->runSQL($sql);
63512dcdeccSAndreas Gohr    }
63612dcdeccSAndreas Gohr
63712dcdeccSAndreas Gohr    function sql_searchphrases($tlimit,$start=0,$limit=20){
63829dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, query, query as lookup
63912dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
64012dcdeccSAndreas Gohr                 WHERE $tlimit
64112dcdeccSAndreas Gohr              GROUP BY query
64212dcdeccSAndreas Gohr              ORDER BY cnt DESC, query".
64312dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
64412dcdeccSAndreas Gohr        return $this->runSQL($sql);
64512dcdeccSAndreas Gohr    }
64612dcdeccSAndreas Gohr
64712dcdeccSAndreas Gohr    function sql_searchwords($tlimit,$start=0,$limit=20){
64829dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, word, word as lookup
64912dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A,
65012dcdeccSAndreas Gohr                       ".$this->getConf('db_prefix')."searchwords as B
65112dcdeccSAndreas Gohr                 WHERE $tlimit
65212dcdeccSAndreas Gohr                   AND A.id = B.sid
65312dcdeccSAndreas Gohr              GROUP BY word
65412dcdeccSAndreas Gohr              ORDER BY cnt DESC, word".
65512dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
65612dcdeccSAndreas Gohr        return $this->runSQL($sql);
65712dcdeccSAndreas Gohr    }
65812dcdeccSAndreas Gohr
659e25286daSAndreas Gohr    function sql_outlinks($tlimit,$start=0,$limit=20){
660e25286daSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, link as url
661e25286daSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."outlinks as A
662e25286daSAndreas Gohr                 WHERE $tlimit
663e25286daSAndreas Gohr              GROUP BY link
664e25286daSAndreas Gohr              ORDER BY cnt DESC, link".
665e25286daSAndreas Gohr              $this->sql_limit($start,$limit);
666e25286daSAndreas Gohr        return $this->runSQL($sql);
667e25286daSAndreas Gohr    }
668e25286daSAndreas Gohr
66995eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
6702812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
67195eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
67295eb68e6SAndreas Gohr                 WHERE $tlimit
67395eb68e6SAndreas Gohr                   AND ua_type = 'browser'
67495eb68e6SAndreas Gohr              GROUP BY page
67595eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
67695eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
67795eb68e6SAndreas Gohr        return $this->runSQL($sql);
67895eb68e6SAndreas Gohr    }
67995eb68e6SAndreas Gohr
68095eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
6812812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
68295eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
68395eb68e6SAndreas Gohr                 WHERE $tlimit
68495eb68e6SAndreas Gohr                   AND ua_type = 'browser'
68595eb68e6SAndreas Gohr                   AND ref_type = 'external'
68695eb68e6SAndreas Gohr              GROUP BY ref_md5
68795eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
68895eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
68995eb68e6SAndreas Gohr        return $this->runSQL($sql);
69095eb68e6SAndreas Gohr    }
69195eb68e6SAndreas Gohr
692e7a2f1e0SAndreas Gohr    function sql_newreferer($tlimit,$start=0,$limit=20){
693e7a2f1e0SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
6942ee939eeSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as B,
6952ee939eeSAndreas Gohr                       ".$this->getConf('db_prefix')."refseen as A
6962ee939eeSAndreas Gohr                 WHERE $tlimit
6972ee939eeSAndreas Gohr                   AND ua_type = 'browser'
698e7a2f1e0SAndreas Gohr                   AND ref_type = 'external'
6992ee939eeSAndreas Gohr                   AND A.ref_md5 = B.ref_md5
7002ee939eeSAndreas Gohr              GROUP BY A.ref_md5
701e7a2f1e0SAndreas Gohr              ORDER BY cnt DESC, url".
702e7a2f1e0SAndreas Gohr              $this->sql_limit($start,$limit);
703e7a2f1e0SAndreas Gohr        return $this->runSQL($sql);
704e7a2f1e0SAndreas Gohr    }
705e7a2f1e0SAndreas Gohr
70695eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
707bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
70895eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
70995eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
71095eb68e6SAndreas Gohr                 WHERE $tlimit
71195eb68e6SAndreas Gohr                   AND A.ip = B.ip
71295eb68e6SAndreas Gohr              GROUP BY B.country
71395eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
71495eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
71595eb68e6SAndreas Gohr        return $this->runSQL($sql);
71695eb68e6SAndreas Gohr    }
71795eb68e6SAndreas Gohr
71875fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
71975fa767dSAndreas Gohr        if($ext){
72075fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
72175fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
72275fa767dSAndreas Gohr        }else{
72375fa767dSAndreas Gohr            $grp = 'ua_info';
72475fa767dSAndreas Gohr            $sel = 'ua_info';
72575fa767dSAndreas Gohr        }
72675fa767dSAndreas Gohr
727bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
72875fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
72975fa767dSAndreas Gohr                 WHERE $tlimit
73075fa767dSAndreas Gohr                   AND ua_type = 'browser'
73175fa767dSAndreas Gohr              GROUP BY $grp
73275fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
73375fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
73475fa767dSAndreas Gohr        return $this->runSQL($sql);
73575fa767dSAndreas Gohr    }
73675fa767dSAndreas Gohr
737bd4217d3SAndreas Gohr    function sql_os($tlimit,$start=0,$limit=20){
738bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
739bd4217d3SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
740bd4217d3SAndreas Gohr                 WHERE $tlimit
741bd4217d3SAndreas Gohr                   AND ua_type = 'browser'
742bd4217d3SAndreas Gohr              GROUP BY os
743bd4217d3SAndreas Gohr              ORDER BY cnt DESC, os".
744bd4217d3SAndreas Gohr              $this->sql_limit($start,$limit);
745bd4217d3SAndreas Gohr        return $this->runSQL($sql);
746bd4217d3SAndreas Gohr    }
747bd4217d3SAndreas Gohr
748c73e16f1SAndreas Gohr    function sql_resolution($tlimit,$start=0,$limit=20){
749c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res
750c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
751c73e16f1SAndreas Gohr                 WHERE $tlimit
752c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
753c73e16f1SAndreas Gohr                   AND screen_x != 0
754c73e16f1SAndreas Gohr              GROUP BY screen_x, screen_y
755c73e16f1SAndreas Gohr              ORDER BY cnt DESC, screen_x".
756c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
757c73e16f1SAndreas Gohr        return $this->runSQL($sql);
758c73e16f1SAndreas Gohr    }
759c73e16f1SAndreas Gohr
760c73e16f1SAndreas Gohr    function sql_viewport($tlimit,$start=0,$limit=20,$x=true){
761c73e16f1SAndreas Gohr        if($x){
762c73e16f1SAndreas Gohr            $col = 'view_x';
763c73e16f1SAndreas Gohr            $res = 'res_x';
764c73e16f1SAndreas Gohr        }else{
765c73e16f1SAndreas Gohr            $col = 'view_y';
766c73e16f1SAndreas Gohr            $res = 'res_y';
767c73e16f1SAndreas Gohr        }
768c73e16f1SAndreas Gohr
769c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt,
770c73e16f1SAndreas Gohr                       ROUND($col/10)*10 as $res
771c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
772c73e16f1SAndreas Gohr                 WHERE $tlimit
773c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
774c73e16f1SAndreas Gohr                   AND $col != 0
775c73e16f1SAndreas Gohr              GROUP BY $res
776c73e16f1SAndreas Gohr              ORDER BY cnt DESC, $res".
777c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
778c73e16f1SAndreas Gohr        return $this->runSQL($sql);
779c73e16f1SAndreas Gohr    }
780c73e16f1SAndreas Gohr
78175fa767dSAndreas Gohr
78295eb68e6SAndreas Gohr    /**
78395eb68e6SAndreas Gohr     * Builds a limit clause
78495eb68e6SAndreas Gohr     */
78595eb68e6SAndreas Gohr    function sql_limit($start,$limit){
78695eb68e6SAndreas Gohr        $start = (int) $start;
78795eb68e6SAndreas Gohr        $limit = (int) $limit;
78895eb68e6SAndreas Gohr        if($limit){
7892507f8e0SAndreas Gohr            $limit += 1;
79095eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
79195eb68e6SAndreas Gohr        }elseif($start){
79295eb68e6SAndreas Gohr            return " OFFSET $start";
79395eb68e6SAndreas Gohr        }
79495eb68e6SAndreas Gohr        return '';
79595eb68e6SAndreas Gohr    }
7961878f16fSAndreas Gohr
7971878f16fSAndreas Gohr    /**
79814d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
7991878f16fSAndreas Gohr     */
80014d99ec0SAndreas Gohr    function dbLink(){
8011878f16fSAndreas Gohr        // connect to DB if needed
8021878f16fSAndreas Gohr        if(!$this->dblink){
8031878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
8041878f16fSAndreas Gohr                                          $this->getConf('db_user'),
8051878f16fSAndreas Gohr                                          $this->getConf('db_password'));
8061878f16fSAndreas Gohr            if(!$this->dblink){
8071878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
8081878f16fSAndreas Gohr                return null;
8091878f16fSAndreas Gohr            }
8101878f16fSAndreas Gohr            // set utf-8
8111878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
8121878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
8131878f16fSAndreas Gohr                return null;
8141878f16fSAndreas Gohr            }
8151878f16fSAndreas Gohr        }
81614d99ec0SAndreas Gohr        return $this->dblink;
81714d99ec0SAndreas Gohr    }
8181878f16fSAndreas Gohr
81914d99ec0SAndreas Gohr    /**
82014d99ec0SAndreas Gohr     * Simple function to run a DB query
82114d99ec0SAndreas Gohr     */
82214d99ec0SAndreas Gohr    function runSQL($sql_string) {
82314d99ec0SAndreas Gohr        $link = $this->dbLink();
82414d99ec0SAndreas Gohr
82514d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
82694171ff3SAndreas Gohr        if(!$result){
8272812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
8281878f16fSAndreas Gohr            return null;
8291878f16fSAndreas Gohr        }
8301878f16fSAndreas Gohr
8311878f16fSAndreas Gohr        $resultarray = array();
8321878f16fSAndreas Gohr
8331878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
8341878f16fSAndreas Gohr        if ($result != 1) {
8351878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
8361878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
8371878f16fSAndreas Gohr                $resultarray[]=$temparray;
8381878f16fSAndreas Gohr            }
8391878f16fSAndreas Gohr            mysql_free_result($result);
8401878f16fSAndreas Gohr        }
8411878f16fSAndreas Gohr
84214d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
84314d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
8441878f16fSAndreas Gohr        }
8451878f16fSAndreas Gohr
8461878f16fSAndreas Gohr        return $resultarray;
8471878f16fSAndreas Gohr    }
8481878f16fSAndreas Gohr
8491878f16fSAndreas Gohr    /**
85014d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
8511878f16fSAndreas Gohr     */
85214d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
85314d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
85414d99ec0SAndreas Gohr        $ua = strtolower($ua);
85514d99ec0SAndreas Gohr
85614d99ec0SAndreas Gohr        // common browsers
85714d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
85814d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
85914d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
86014d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
86114d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
86214d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
86314d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
86414d99ec0SAndreas Gohr
86514d99ec0SAndreas Gohr        $name = '';
86614d99ec0SAndreas Gohr        # IE ?
86714d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
86814d99ec0SAndreas Gohr            $type = 'browser';
86914d99ec0SAndreas Gohr            $ver  = $m[2];
87014d99ec0SAndreas Gohr            $name = 'msie';
87114d99ec0SAndreas Gohr        }
87214d99ec0SAndreas Gohr        # Firefox ?
87314d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
87414d99ec0SAndreas Gohr            $type = 'browser';
87514d99ec0SAndreas Gohr            $ver  = $m[1];
87614d99ec0SAndreas Gohr            $name = 'firefox';
87714d99ec0SAndreas Gohr        }
87814d99ec0SAndreas Gohr        # Subversion ?
87914d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
88014d99ec0SAndreas Gohr            $type = 'rcs';
88114d99ec0SAndreas Gohr            $ver  = $m[1];
88214d99ec0SAndreas Gohr            $name = 'svn';
88314d99ec0SAndreas Gohr        }
88414d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
88514d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
88614d99ec0SAndreas Gohr            $type = 'browser';
88714d99ec0SAndreas Gohr            $ver  = $m[1];
88814d99ec0SAndreas Gohr            $name = 'netscape';
88914d99ec0SAndreas Gohr        }
89014d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
89114d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
89214d99ec0SAndreas Gohr            $type = 'browser';
89314d99ec0SAndreas Gohr            $ver  = $m[2];
89414d99ec0SAndreas Gohr            $name = 'netscape';
89514d99ec0SAndreas Gohr        }else{
89614d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
89714d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
89814d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
89914d99ec0SAndreas Gohr                    // it's a browser!
90014d99ec0SAndreas Gohr                    $type = 'browser';
90114d99ec0SAndreas Gohr                    $name = strtolower($regex);
90214d99ec0SAndreas Gohr                    break;
90314d99ec0SAndreas Gohr                }
90414d99ec0SAndreas Gohr            }
90514d99ec0SAndreas Gohr        }
90614d99ec0SAndreas Gohr
90775fa767dSAndreas Gohr        // check versions for Safari and Opera
90875fa767dSAndreas Gohr        if($name == 'safari'){
90975fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
91075fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
91175fa767dSAndreas Gohr            }
91275fa767dSAndreas Gohr        }elseif($name == 'opera'){
91375fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
91475fa767dSAndreas Gohr                $ver = $match[1];
91575fa767dSAndreas Gohr            }
91675fa767dSAndreas Gohr        }
91775fa767dSAndreas Gohr
91875fa767dSAndreas Gohr
91914d99ec0SAndreas Gohr        // check OS for browsers
92014d99ec0SAndreas Gohr        if($type == 'browser'){
92114d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
92214d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
92314d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
92414d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
92514d99ec0SAndreas Gohr                    break;
92614d99ec0SAndreas Gohr                }
92714d99ec0SAndreas Gohr            }
92814d99ec0SAndreas Gohr
92914d99ec0SAndreas Gohr        }
93014d99ec0SAndreas Gohr
93114d99ec0SAndreas Gohr        // are we done now?
93214d99ec0SAndreas Gohr        if($name) return $name;
93314d99ec0SAndreas Gohr
93414d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
93514d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
93614d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
93714d99ec0SAndreas Gohr                    // it's a robot!
93814d99ec0SAndreas Gohr                    $type = 'robot';
93914d99ec0SAndreas Gohr                    return strtolower($regex);
94014d99ec0SAndreas Gohr            }
94114d99ec0SAndreas Gohr        }
94214d99ec0SAndreas Gohr
94314d99ec0SAndreas Gohr        // dunno
9441878f16fSAndreas Gohr        return '';
9451878f16fSAndreas Gohr    }
9461878f16fSAndreas Gohr
9471878f16fSAndreas Gohr    /**
948322de360SAndreas Gohr     * Log search queries
94914d99ec0SAndreas Gohr     */
95014d99ec0SAndreas Gohr    function log_search($referer,&$type){
95114d99ec0SAndreas Gohr        $referer = strtolower($referer);
952673875b1SAndreas Gohr        $ref     = strtr($referer,' +','__');
95314d99ec0SAndreas Gohr
95414d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
95514d99ec0SAndreas Gohr
95614d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
957673875b1SAndreas Gohr            if(preg_match('/'.$regex.'/',$ref)){
95814d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
959673875b1SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$ref)){
96014d99ec0SAndreas Gohr                    // it's a search engine!
96114d99ec0SAndreas Gohr                    $type = 'search';
96214d99ec0SAndreas Gohr                    break;
96314d99ec0SAndreas Gohr                }
96414d99ec0SAndreas Gohr            }
96514d99ec0SAndreas Gohr        }
96614d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
96714d99ec0SAndreas Gohr
968322de360SAndreas Gohr        // extract query
969322de360SAndreas Gohr        $engine = $SearchEnginesHashID[$regex];
970322de360SAndreas Gohr        $param = $SearchEnginesKnownUrl[$engine];
971322de360SAndreas Gohr        if($param && preg_match('/'.$param.'(.*?)[&$]/',$referer,$match)){
972322de360SAndreas Gohr            $query = array_pop($match);
973322de360SAndreas Gohr        }elseif(preg_match('/'.$WordsToExtractSearchUrl.'(.*?)[&$]/',$referer,$match)){
974322de360SAndreas Gohr            $query = array_pop($match);
975322de360SAndreas Gohr        }
976322de360SAndreas Gohr        if(!$query) return; // we failed
977322de360SAndreas Gohr
978322de360SAndreas Gohr        // clean the query
979322de360SAndreas Gohr        $query = preg_replace('/^(cache|related):[^\+]+/','',$query);  // non-search queries
980322de360SAndreas Gohr        $query = preg_replace('/%0[ad]/',' ',$query);                  // LF CR
981322de360SAndreas Gohr        $query = preg_replace('/%2[02789abc]/',' ',$query);            // space " ' ( ) * + ,
982322de360SAndreas Gohr        $query = preg_replace('/%3a/',' ',$query);                     // :
983673875b1SAndreas Gohr        $query = strtr($query,'+\'()"*,:','        ');                 // badly encoded
984322de360SAndreas Gohr        $query = preg_replace('/ +/',' ',$query);                      // ws compact
985322de360SAndreas Gohr        $query = trim($query);
986322de360SAndreas Gohr        $query = urldecode($query);
987322de360SAndreas Gohr        if(!utf8_check($query)) $query = utf8_encode($query);          // assume latin1 if not utf8
988322de360SAndreas Gohr        $query = utf8_strtolower($query);
989322de360SAndreas Gohr
990322de360SAndreas Gohr        // log it!
991322de360SAndreas Gohr        $page  = addslashes($_REQUEST['p']);
992322de360SAndreas Gohr        $query = addslashes($query);
993673875b1SAndreas Gohr        $sql  = "INSERT INTO ".$this->getConf('db_prefix')."search
994322de360SAndreas Gohr                    SET dt       = NOW(),
995322de360SAndreas Gohr                        page     = '$page',
996322de360SAndreas Gohr                        query    = '$query',
997322de360SAndreas Gohr                        engine   = '$engine'";
998322de360SAndreas Gohr        $id = $this->runSQL($sql);
999322de360SAndreas Gohr        if(is_null($id)){
1000322de360SAndreas Gohr            global $MSG;
1001322de360SAndreas Gohr            print_r($MSG);
1002322de360SAndreas Gohr            return;
1003322de360SAndreas Gohr        }
1004322de360SAndreas Gohr
1005322de360SAndreas Gohr        // log single keywords
1006322de360SAndreas Gohr        $words = explode(' ',utf8_stripspecials($query,' ','\._\-:\*'));
1007322de360SAndreas Gohr        foreach($words as $word){
1008673875b1SAndreas Gohr            if(!$word) continue;
1009322de360SAndreas Gohr            $word = addslashes($word);
1010322de360SAndreas Gohr            $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."searchwords
1011322de360SAndreas Gohr                       SET sid  = $id,
1012322de360SAndreas Gohr                           word = '$word'";
1013322de360SAndreas Gohr            $ok = $this->runSQL($sql);
1014322de360SAndreas Gohr            if(is_null($ok)){
1015322de360SAndreas Gohr                global $MSG;
1016322de360SAndreas Gohr                print_r($MSG);
1017322de360SAndreas Gohr            }
1018322de360SAndreas Gohr        }
101914d99ec0SAndreas Gohr    }
102014d99ec0SAndreas Gohr
102114d99ec0SAndreas Gohr    /**
102214d99ec0SAndreas Gohr     * Resolve IP to country/city
102314d99ec0SAndreas Gohr     */
102414d99ec0SAndreas Gohr    function log_ip($ip){
102514d99ec0SAndreas Gohr        // check if IP already known and up-to-date
102614d99ec0SAndreas Gohr        $sql = "SELECT ip
102714d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
102814d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
102914d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
103014d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
103114d99ec0SAndreas Gohr        if($result[0]['ip']) return;
103214d99ec0SAndreas Gohr
103314d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
103414d99ec0SAndreas Gohr        $http->timeout = 10;
103514d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
103614d99ec0SAndreas Gohr
103714d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
103814d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
103914d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
104014d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
104114d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
104214d99ec0SAndreas Gohr            $ip      = addslashes($ip);
104314d99ec0SAndreas Gohr
104414d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
104514d99ec0SAndreas Gohr                        SET ip = '$ip',
104614d99ec0SAndreas Gohr                            country = '$country',
104714d99ec0SAndreas Gohr                            code    = '$code',
104814d99ec0SAndreas Gohr                            city    = '$city',
104914d99ec0SAndreas Gohr                            host    = '$host'";
105014d99ec0SAndreas Gohr            $this->runSQL($sql);
105114d99ec0SAndreas Gohr        }
105214d99ec0SAndreas Gohr    }
105314d99ec0SAndreas Gohr
105414d99ec0SAndreas Gohr    /**
1055e25286daSAndreas Gohr     * log a click on an external link
1056e25286daSAndreas Gohr     *
1057e25286daSAndreas Gohr     * called from log.php
1058e25286daSAndreas Gohr     */
1059e25286daSAndreas Gohr    function log_outgoing(){
1060e25286daSAndreas Gohr        if(!$_REQUEST['ol']) return;
1061e25286daSAndreas Gohr
1062e25286daSAndreas Gohr        $link_md5 = md5($link);
1063e25286daSAndreas Gohr        $link     = addslashes($_REQUEST['ol']);
1064e25286daSAndreas Gohr        $session  = addslashes(session_id());
1065d8c4d85eSAndreas Gohr        $page     = addslashes($_REQUEST['p']);
1066e25286daSAndreas Gohr
1067e25286daSAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks
1068e25286daSAndreas Gohr                    SET dt       = NOW(),
1069e25286daSAndreas Gohr                        session  = '$session',
1070d8c4d85eSAndreas Gohr                        page     = '$page',
1071e25286daSAndreas Gohr                        link_md5 = '$link_md5',
1072e25286daSAndreas Gohr                        link     = '$link'";
1073e25286daSAndreas Gohr        $ok = $this->runSQL($sql);
1074e25286daSAndreas Gohr        if(is_null($ok)){
1075e25286daSAndreas Gohr            global $MSG;
1076e25286daSAndreas Gohr            print_r($MSG);
1077e25286daSAndreas Gohr        }
1078e25286daSAndreas Gohr    }
1079e25286daSAndreas Gohr
1080e25286daSAndreas Gohr    /**
10811878f16fSAndreas Gohr     * log a page access
10821878f16fSAndreas Gohr     *
10831878f16fSAndreas Gohr     * called from log.php
10841878f16fSAndreas Gohr     */
10851878f16fSAndreas Gohr    function log_access(){
108694171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
108794171ff3SAndreas Gohr
108814d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
108914d99ec0SAndreas Gohr
109014d99ec0SAndreas Gohr        // handle referer
109114d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
109214d99ec0SAndreas Gohr        if($referer){
109314d99ec0SAndreas Gohr            $ref     = addslashes($referer);
109414d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
109514d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
109614d99ec0SAndreas Gohr                $ref_type = 'internal';
109714d99ec0SAndreas Gohr            }else{
109814d99ec0SAndreas Gohr                $ref_type = 'external';
109914d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
110014d99ec0SAndreas Gohr            }
110114d99ec0SAndreas Gohr        }else{
110214d99ec0SAndreas Gohr            $ref      = '';
110314d99ec0SAndreas Gohr            $ref_md5  = '';
110414d99ec0SAndreas Gohr            $ref_type = '';
110514d99ec0SAndreas Gohr        }
110614d99ec0SAndreas Gohr
110714d99ec0SAndreas Gohr        // handle user agent
110814d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
110914d99ec0SAndreas Gohr
111014d99ec0SAndreas Gohr        $ua      = addslashes($agent);
111114d99ec0SAndreas Gohr        $ua_type = '';
111214d99ec0SAndreas Gohr        $ua_ver  = '';
111314d99ec0SAndreas Gohr        $os      = '';
111414d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
111514d99ec0SAndreas Gohr
11161878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
11171878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
11181878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
11191878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
11201878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
11211878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
112275fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
11233c0acc14SAndreas Gohr        $uid     = addslashes($_REQUEST['uid']);
11241878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
11251878f16fSAndreas Gohr        $session = addslashes(session_id());
11263c0acc14SAndreas Gohr        if(!$uid) $uid = $session;
11271878f16fSAndreas Gohr
112894171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
112975fa767dSAndreas Gohr                    SET dt       = NOW(),
113075fa767dSAndreas Gohr                        page     = '$page',
11311878f16fSAndreas Gohr                        ip       = '$ip',
11321878f16fSAndreas Gohr                        ua       = '$ua',
11331878f16fSAndreas Gohr                        ua_info  = '$ua_info',
113414d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
113514d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
113614d99ec0SAndreas Gohr                        os       = '$os',
11371878f16fSAndreas Gohr                        ref      = '$ref',
113894171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
113914d99ec0SAndreas Gohr                        ref_type = '$ref_type',
11401878f16fSAndreas Gohr                        screen_x = '$sx',
11411878f16fSAndreas Gohr                        screen_y = '$sy',
11421878f16fSAndreas Gohr                        view_x   = '$vx',
11431878f16fSAndreas Gohr                        view_y   = '$vy',
114475fa767dSAndreas Gohr                        js       = '$js',
11451878f16fSAndreas Gohr                        user     = '$user',
11463c0acc14SAndreas Gohr                        session  = '$session',
11473c0acc14SAndreas Gohr                        uid      = '$uid'";
11481878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
11491878f16fSAndreas Gohr        if(is_null($ok)){
11501878f16fSAndreas Gohr            global $MSG;
11511878f16fSAndreas Gohr            print_r($MSG);
11521878f16fSAndreas Gohr        }
115314d99ec0SAndreas Gohr
11542ee939eeSAndreas Gohr        $sql = "INSERT DELAYED IGNORE INTO ".$this->getConf('db_prefix')."refseen
11552ee939eeSAndreas Gohr                   SET ref_md5  = '$ref_md5',
11562ee939eeSAndreas Gohr                       dt       = NOW()";
11572ee939eeSAndreas Gohr        $ok = $this->runSQL($sql);
11582ee939eeSAndreas Gohr        if(is_null($ok)){
11592ee939eeSAndreas Gohr            global $MSG;
11602ee939eeSAndreas Gohr            print_r($MSG);
11612ee939eeSAndreas Gohr        }
11622ee939eeSAndreas Gohr
116314d99ec0SAndreas Gohr        // resolve the IP
116414d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
11651878f16fSAndreas Gohr    }
11661878f16fSAndreas Gohr
11671878f16fSAndreas Gohr    /**
11681878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
11691878f16fSAndreas Gohr     *
11701878f16fSAndreas Gohr     * @called from log.php
11711878f16fSAndreas Gohr     *
11721878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
11731878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
11741878f16fSAndreas Gohr     */
11751878f16fSAndreas Gohr    function sendGIF(){
11761878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
11771878f16fSAndreas Gohr        header('Content-Type: image/gif');
11781878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
11791878f16fSAndreas Gohr        header('Connection: Close');
11801878f16fSAndreas Gohr        print $img;
11811878f16fSAndreas Gohr        flush();
11821878f16fSAndreas Gohr        // Browser should drop connection after this
11831878f16fSAndreas Gohr        // Thinks it's got the whole image
11841878f16fSAndreas Gohr    }
11851878f16fSAndreas Gohr
11861878f16fSAndreas Gohr}
1187