xref: /plugin/statistics/admin.php (revision a901d721234c7d3da6f2ec1f5c2bc6d2dfadebdd)
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 {
20*a901d721SAndreas Gohr    public    $dblink = null;
21*a901d721SAndreas Gohr    protected $opt    = '';
22*a901d721SAndreas Gohr    protected $from   = '';
23*a901d721SAndreas Gohr    protected $to     = '';
24*a901d721SAndreas Gohr    protected $start  = '';
25*a901d721SAndreas Gohr    protected $tlimit = '';
26*a901d721SAndreas Gohr
27*a901d721SAndreas Gohr    /**
28*a901d721SAndreas Gohr     * Available statistic pages
29*a901d721SAndreas Gohr     */
30*a901d721SAndreas Gohr    protected $pages  = array('dashboard','page','referer','newreferer',
31*a901d721SAndreas Gohr                              'outlinks','searchphrases','searchwords',
32*a901d721SAndreas Gohr                              'searchengines','browser','os','country',
33*a901d721SAndreas Gohr                              'resolution');
341878f16fSAndreas Gohr
351878f16fSAndreas Gohr    /**
361878f16fSAndreas Gohr     * Access for managers allowed
371878f16fSAndreas Gohr     */
381878f16fSAndreas Gohr    function forAdminOnly(){
391878f16fSAndreas Gohr        return false;
401878f16fSAndreas Gohr    }
411878f16fSAndreas Gohr
421878f16fSAndreas Gohr    /**
431878f16fSAndreas Gohr     * return sort order for position in admin menu
441878f16fSAndreas Gohr     */
451878f16fSAndreas Gohr    function getMenuSort() {
4614d99ec0SAndreas Gohr        return 150;
471878f16fSAndreas Gohr    }
481878f16fSAndreas Gohr
491878f16fSAndreas Gohr    /**
501878f16fSAndreas Gohr     * handle user request
511878f16fSAndreas Gohr     */
521878f16fSAndreas Gohr    function handle() {
53264f1744SAndreas Gohr        $this->opt = preg_replace('/[^a-z]+/','',$_REQUEST['opt']);
54*a901d721SAndreas Gohr        if(!in_array($this->opt,$this->pages)) $this->opt = 'dashboard';
55*a901d721SAndreas Gohr
5695eb68e6SAndreas Gohr        $this->start = (int) $_REQUEST['s'];
57e8699bceSAndreas Gohr        $this->setTimeframe($_REQUEST['f'],$_REQUEST['t']);
58e8699bceSAndreas Gohr    }
5995eb68e6SAndreas Gohr
60e8699bceSAndreas Gohr    /**
61e8699bceSAndreas Gohr     * set limit clause
62e8699bceSAndreas Gohr     */
63e8699bceSAndreas Gohr    function setTimeframe($from,$to){
64264f1744SAndreas Gohr        // fixme add better sanity checking here:
65e8699bceSAndreas Gohr        $from = preg_replace('/[^\d\-]+/','',$from);
66e8699bceSAndreas Gohr        $to   = preg_replace('/[^\d\-]+/','',$to);
67e8699bceSAndreas Gohr        if(!$from) $from = date('Y-m-d');
68e8699bceSAndreas Gohr        if(!$to)   $to   = date('Y-m-d');
69264f1744SAndreas Gohr
70264f1744SAndreas Gohr        //setup limit clause
712ee939eeSAndreas Gohr        $tlimit = "A.dt >= '$from 00:00:00' AND A.dt <= '$to 23:59:59'";
72e8699bceSAndreas Gohr        $this->tlimit = $tlimit;
73e8699bceSAndreas Gohr        $this->from   = $from;
74e8699bceSAndreas Gohr        $this->to     = $to;
751878f16fSAndreas Gohr    }
761878f16fSAndreas Gohr
771878f16fSAndreas Gohr    /**
7879b4a855SAndreas Gohr     * Output the Statistics
791878f16fSAndreas Gohr     */
801878f16fSAndreas Gohr    function html() {
81264f1744SAndreas Gohr        echo '<h1>Access Statistics</h1>';
82264f1744SAndreas Gohr        $this->html_timeselect();
83264f1744SAndreas Gohr
8479b4a855SAndreas Gohr        $method = 'html_'.$this->opt;
8579b4a855SAndreas Gohr        if(method_exists($this,$method)){
86*a901d721SAndreas Gohr            echo '<div class="plg_stats_'.$this->opt.'">';
87*a901d721SAndreas Gohr            echo '<h2>'.$this->getLang($this->opt).'</h2>';
8879b4a855SAndreas Gohr            $this->$method();
89*a901d721SAndreas Gohr            echo '</div>';
9014d99ec0SAndreas Gohr        }
9114d99ec0SAndreas Gohr    }
9214d99ec0SAndreas Gohr
9347ffcf7dSAndreas Gohr    function getTOC(){
9447ffcf7dSAndreas Gohr        $toc = array();
95*a901d721SAndreas Gohr        foreach($this->pages as $page){
9647ffcf7dSAndreas Gohr            $toc[] = array(
9747ffcf7dSAndreas Gohr                    'link'  => '?do=admin&amp;page=statistics&amp;opt='.$page.'&amp;f='.$this->from.'&amp;t='.$this->to,
9847ffcf7dSAndreas Gohr                    'title' => $this->getLang($page),
9947ffcf7dSAndreas Gohr                    'level' => 1,
10047ffcf7dSAndreas Gohr                    'type'  => 'ul'
10147ffcf7dSAndreas Gohr            );
10247ffcf7dSAndreas Gohr        }
10347ffcf7dSAndreas Gohr        return $toc;
1049da6395dSAndreas Gohr    }
1059da6395dSAndreas Gohr
1062507f8e0SAndreas Gohr    function html_pager($limit,$next){
1072507f8e0SAndreas Gohr        echo '<div class="plg_stats_pager">';
1082507f8e0SAndreas Gohr
1092507f8e0SAndreas Gohr        if($this->start > 0){
1102507f8e0SAndreas Gohr            $go = max($this->start - $limit, 0);
1112507f8e0SAndreas 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>';
1122507f8e0SAndreas Gohr        }
1132507f8e0SAndreas Gohr
1142507f8e0SAndreas Gohr        if($next){
1152507f8e0SAndreas Gohr            $go = $this->start + $limit;
1162507f8e0SAndreas 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>';
1172507f8e0SAndreas Gohr        }
1182507f8e0SAndreas Gohr        echo '</div>';
1192507f8e0SAndreas Gohr    }
1202507f8e0SAndreas Gohr
121264f1744SAndreas Gohr    /**
122264f1744SAndreas Gohr     * Print the time selection menu
123264f1744SAndreas Gohr     */
12414d99ec0SAndreas Gohr    function html_timeselect(){
125264f1744SAndreas Gohr        $now   = date('Y-m-d');
126264f1744SAndreas Gohr        $yday  = date('Y-m-d',time()-(60*60*24));
127264f1744SAndreas Gohr        $week  = date('Y-m-d',time()-(60*60*24*7));
128264f1744SAndreas Gohr        $month = date('Y-m-d',time()-(60*60*24*30));
12914d99ec0SAndreas Gohr
130264f1744SAndreas Gohr        echo '<div class="plg_stats_timeselect">';
131264f1744SAndreas Gohr        echo '<span>Select the timeframe:</span>';
132264f1744SAndreas Gohr        echo '<ul>';
133264f1744SAndreas Gohr
134264f1744SAndreas Gohr        echo '<li>';
1352507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$now.'&amp;t='.$now.'">';
136264f1744SAndreas Gohr        echo 'today';
137264f1744SAndreas Gohr        echo '</a>';
138264f1744SAndreas Gohr        echo '</li>';
139264f1744SAndreas Gohr
140264f1744SAndreas Gohr        echo '<li>';
1412507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$yday.'&amp;t='.$yday.'">';
142264f1744SAndreas Gohr        echo 'yesterday';
143264f1744SAndreas Gohr        echo '</a>';
144264f1744SAndreas Gohr        echo '</li>';
145264f1744SAndreas Gohr
146264f1744SAndreas Gohr        echo '<li>';
1472507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$week.'&amp;t='.$now.'">';
148264f1744SAndreas Gohr        echo 'last 7 days';
149264f1744SAndreas Gohr        echo '</a>';
150264f1744SAndreas Gohr        echo '</li>';
151264f1744SAndreas Gohr
152264f1744SAndreas Gohr        echo '<li>';
1532507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt='.$this->opt.'&amp;f='.$month.'&amp;t='.$now.'">';
154264f1744SAndreas Gohr        echo 'last 30 days';
155264f1744SAndreas Gohr        echo '</a>';
156264f1744SAndreas Gohr        echo '</li>';
157264f1744SAndreas Gohr
158264f1744SAndreas Gohr        echo '</ul>';
159264f1744SAndreas Gohr
160264f1744SAndreas Gohr
161264f1744SAndreas Gohr        echo '<form action="" method="get">';
162264f1744SAndreas Gohr        echo '<input type="hidden" name="do" value="admin" />';
163264f1744SAndreas Gohr        echo '<input type="hidden" name="page" value="statistics" />';
164264f1744SAndreas Gohr        echo '<input type="hidden" name="opt" value="'.$this->opt.'" />';
165264f1744SAndreas Gohr        echo '<input type="text" name="f" value="'.$this->from.'" class="edit" />';
166264f1744SAndreas Gohr        echo '<input type="text" name="t" value="'.$this->to.'" class="edit" />';
167264f1744SAndreas Gohr        echo '<input type="submit" value="go" class="button" />';
16814d99ec0SAndreas Gohr        echo '</form>';
169264f1744SAndreas Gohr
170264f1744SAndreas Gohr        echo '</div>';
17114d99ec0SAndreas Gohr    }
17214d99ec0SAndreas Gohr
17314d99ec0SAndreas Gohr
174f5f32cbfSAndreas Gohr    /**
175f5f32cbfSAndreas Gohr     * Print an introductionary screen
176f5f32cbfSAndreas Gohr     */
17714d99ec0SAndreas Gohr    function html_dashboard(){
1782812a751SAndreas Gohr        echo '<p>This page gives you a quick overview on what is happening in your Wiki. For detailed lists
1792812a751SAndreas Gohr              choose a topic from the list.</p>';
1802812a751SAndreas Gohr
1812812a751SAndreas Gohr        // general info
1822812a751SAndreas Gohr        echo '<div class="plg_stats_top">';
1832812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
1842812a751SAndreas Gohr        echo '<ul>';
1852812a751SAndreas Gohr        echo '<li><span>'.$result['pageviews'].'</span> page views </li>';
1863c0acc14SAndreas Gohr        echo '<li><span>'.$result['sessions'].'</span> visits (sessions) </li>';
1873c0acc14SAndreas Gohr        echo '<li><span>'.$result['visitors'].'</span> unique visitors </li>';
1882812a751SAndreas Gohr        echo '<li><span>'.$result['users'].'</span> logged in users</li>';
1892812a751SAndreas Gohr
1902812a751SAndreas Gohr        echo '</ul>';
1912812a751SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=trend&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
1922812a751SAndreas Gohr        echo '</div>';
1932812a751SAndreas Gohr
19414d99ec0SAndreas Gohr
19587d5e44bSAndreas Gohr        // top pages today
196264f1744SAndreas Gohr        echo '<div>';
197264f1744SAndreas Gohr        echo '<h2>Most popular pages</h2>';
19895eb68e6SAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,15);
1992812a751SAndreas Gohr        $this->html_resulttable($result);
2002507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=page&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
201264f1744SAndreas Gohr        echo '</div>';
20287d5e44bSAndreas Gohr
20387d5e44bSAndreas Gohr        // top referer today
204264f1744SAndreas Gohr        echo '<div>';
205e7a2f1e0SAndreas Gohr        echo '<h2>Newest incoming links</h2>';
206e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,15);
2072812a751SAndreas Gohr        $this->html_resulttable($result);
2082507f8e0SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=newreferer&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
209264f1744SAndreas Gohr        echo '</div>';
21054f6c432SAndreas Gohr
21129dea504SAndreas Gohr        // top searches today
212264f1744SAndreas Gohr        echo '<div>';
21329dea504SAndreas Gohr        echo '<h2>Top search phrases</h2>';
21429dea504SAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,15);
21529dea504SAndreas Gohr        $this->html_resulttable($result);
21629dea504SAndreas Gohr        echo '<a href="?do=admin&amp;page=statistics&amp;opt=searchphrases&amp;f='.$this->from.'&amp;t='.$this->to.'" class="more">more</a>';
217264f1744SAndreas Gohr        echo '</div>';
21814d99ec0SAndreas Gohr    }
21914d99ec0SAndreas Gohr
2209da6395dSAndreas Gohr    function html_country(){
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    }
2259da6395dSAndreas Gohr
2269da6395dSAndreas Gohr    function html_page(){
2279da6395dSAndreas Gohr        $result = $this->sql_pages($this->tlimit,$this->start,150);
2282507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2299da6395dSAndreas Gohr    }
2309da6395dSAndreas Gohr
23175fa767dSAndreas Gohr    function html_browser(){
23275fa767dSAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=browser&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
23375fa767dSAndreas Gohr        $result = $this->sql_browsers($this->tlimit,$this->start,150,true);
2342507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
23575fa767dSAndreas Gohr    }
23675fa767dSAndreas Gohr
237bd4217d3SAndreas Gohr    function html_os(){
238bd4217d3SAndreas Gohr        $result = $this->sql_os($this->tlimit,$this->start,150,true);
2392507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
240bd4217d3SAndreas Gohr    }
241bd4217d3SAndreas Gohr
2429da6395dSAndreas Gohr    function html_referer(){
2432812a751SAndreas Gohr        $result = $this->sql_aggregate($this->tlimit);
2442812a751SAndreas Gohr
2452812a751SAndreas Gohr        $all    = $result['search']+$result['external']+$result['direct'];
2462812a751SAndreas Gohr
24794023548SAndreas Gohr        if($all){
2482812a751SAndreas Gohr            printf("<p>Of all %d external visits, %d (%.1f%%) were bookmarked (direct) accesses,
2492812a751SAndreas Gohr                    %d (%.1f%%) came from search engines and %d (%.1f%%) were referred through
2502812a751SAndreas Gohr                    links from other pages.</p>",$all,$result['direct'],(100*$result['direct']/$all),
2512812a751SAndreas Gohr                    $result['search'],(100*$result['search']/$all),$result['external'],
2522812a751SAndreas Gohr                    (100*$result['external']/$all));
25394023548SAndreas Gohr        }
2542812a751SAndreas Gohr
2559da6395dSAndreas Gohr        $result = $this->sql_referer($this->tlimit,$this->start,150);
2562507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
2579da6395dSAndreas Gohr    }
2589da6395dSAndreas Gohr
259e7a2f1e0SAndreas Gohr    function html_newreferer(){
260e7a2f1e0SAndreas Gohr        echo '<p>The following incoming links where first logged in the selected time frame,
261e7a2f1e0SAndreas Gohr              and have never been seen before.</p>';
262e7a2f1e0SAndreas Gohr
263e7a2f1e0SAndreas Gohr        $result = $this->sql_newreferer($this->tlimit,$this->start,150);
2642507f8e0SAndreas Gohr        $this->html_resulttable($result,'',150);
265e7a2f1e0SAndreas Gohr    }
266e7a2f1e0SAndreas Gohr
267e25286daSAndreas Gohr    function html_outlinks(){
268e25286daSAndreas Gohr        $result = $this->sql_outlinks($this->tlimit,$this->start,150);
269e25286daSAndreas Gohr        $this->html_resulttable($result,'',150);
270e25286daSAndreas Gohr    }
271e25286daSAndreas Gohr
27212dcdeccSAndreas Gohr    function html_searchphrases(){
27312dcdeccSAndreas Gohr        $result = $this->sql_searchphrases($this->tlimit,$this->start,150);
27412dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
27512dcdeccSAndreas Gohr    }
27612dcdeccSAndreas Gohr
27712dcdeccSAndreas Gohr    function html_searchwords(){
27812dcdeccSAndreas Gohr        $result = $this->sql_searchwords($this->tlimit,$this->start,150);
27912dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
28012dcdeccSAndreas Gohr    }
28112dcdeccSAndreas Gohr
28212dcdeccSAndreas Gohr    function html_searchengines(){
28312dcdeccSAndreas Gohr        $result = $this->sql_searchengines($this->tlimit,$this->start,150);
28412dcdeccSAndreas Gohr        $this->html_resulttable($result,'',150);
28512dcdeccSAndreas Gohr    }
28612dcdeccSAndreas Gohr
287e25286daSAndreas Gohr
288c73e16f1SAndreas Gohr    function html_resolution(){
289c73e16f1SAndreas Gohr        $result = $this->sql_resolution($this->tlimit,$this->start,150);
290c73e16f1SAndreas Gohr        $this->html_resulttable($result,'',150);
291c73e16f1SAndreas Gohr
292c73e16f1SAndreas Gohr        echo '<p>While the data above gives you some info about the resolution your visitors use, it does not tell you
293c73e16f1SAndreas Gohr              much about about the real size of their browser windows. The graphic below shows the size distribution of
294c73e16f1SAndreas Gohr              the view port (document area) of your visitor\'s browsers. Please note that this data can not be logged
295c73e16f1SAndreas Gohr              in all browsers. Because users may resize their browser window while browsing your site the statistics may
296c73e16f1SAndreas Gohr              be flawed. Take it with a grain of salt.</p>';
297c73e16f1SAndreas Gohr
298c73e16f1SAndreas Gohr        echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/img.php?img=view&amp;f='.$this->from.'&amp;t='.$this->to.'" />';
299c73e16f1SAndreas Gohr    }
3009da6395dSAndreas Gohr
3019da6395dSAndreas Gohr
30214d99ec0SAndreas Gohr    /**
30314d99ec0SAndreas Gohr     * Display a result in a HTML table
30414d99ec0SAndreas Gohr     */
3052507f8e0SAndreas Gohr    function html_resulttable($result,$header='',$pager=0){
30614d99ec0SAndreas Gohr        echo '<table>';
3072812a751SAndreas Gohr        if(is_array($header)){
30814d99ec0SAndreas Gohr            echo '<tr>';
30914d99ec0SAndreas Gohr            foreach($header as $h){
31014d99ec0SAndreas Gohr                echo '<th>'.hsc($h).'</th>';
31114d99ec0SAndreas Gohr            }
31214d99ec0SAndreas Gohr            echo '</tr>';
3132812a751SAndreas Gohr        }
31414d99ec0SAndreas Gohr
3152507f8e0SAndreas Gohr        $count = 0;
3162ee939eeSAndreas Gohr        if(is_array($result)) foreach($result as $row){
31714d99ec0SAndreas Gohr            echo '<tr>';
31814d99ec0SAndreas Gohr            foreach($row as $k => $v){
3192812a751SAndreas Gohr                echo '<td class="plg_stats_X'.$k.'">';
32014d99ec0SAndreas Gohr                if($k == 'page'){
32114d99ec0SAndreas Gohr                    echo '<a href="'.wl($v).'" class="wikilink1">';
32214d99ec0SAndreas Gohr                    echo hsc($v);
32314d99ec0SAndreas Gohr                    echo '</a>';
32414d99ec0SAndreas Gohr                }elseif($k == 'url'){
32554f6c432SAndreas Gohr                    $url = hsc($v);
32683b63546SAndreas Gohr                    $url = preg_replace('/^https?:\/\/(www\.)?/','',$url);
3272812a751SAndreas Gohr                    if(strlen($url) > 45){
3282812a751SAndreas Gohr                        $url = substr($url,0,30).' &hellip; '.substr($url,-15);
32954f6c432SAndreas Gohr                    }
33014d99ec0SAndreas Gohr                    echo '<a href="'.$v.'" class="urlextern">';
33154f6c432SAndreas Gohr                    echo $url;
33214d99ec0SAndreas Gohr                    echo '</a>';
33329dea504SAndreas Gohr                }elseif($k == 'lookup'){
33429dea504SAndreas Gohr                    echo '<a href="http://www.google.com/search?q='.rawurlencode($v).'">';
33529dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/google.png" alt="lookup in Google" border="0" />';
33629dea504SAndreas Gohr                    echo '</a> ';
33729dea504SAndreas Gohr
33829dea504SAndreas Gohr                    echo '<a href="http://search.yahoo.com/search?p='.rawurlencode($v).'">';
33929dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/yahoo.png" alt="lookup in Yahoo" border="0" />';
34029dea504SAndreas Gohr                    echo '</a> ';
34129dea504SAndreas Gohr
34229dea504SAndreas Gohr                    echo '<a href="http://search.msn.com/results.aspx?q='.rawurlencode($v).'">';
34329dea504SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/search/msn.png" alt="lookup in MSN Live" border="0" />';
34429dea504SAndreas Gohr                    echo '</a> ';
34529dea504SAndreas Gohr
34612dcdeccSAndreas Gohr                }elseif($k == 'engine'){
34712dcdeccSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/search_engines.php');
34812dcdeccSAndreas Gohr                    echo $SearchEnginesHashLib[$v];
34975fa767dSAndreas Gohr                }elseif($k == 'browser'){
35075fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
35175fa767dSAndreas Gohr                    echo $BrowsersHashIDLib[$v];
35275fa767dSAndreas Gohr                }elseif($k == 'bflag'){
35375fa767dSAndreas Gohr                    include_once(dirname(__FILE__).'/inc/browsers.php');
35475fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/browser/'.$BrowsersHashIcon[$v].'.png" alt="'.hsc($v).'" />';
355bd4217d3SAndreas Gohr                }elseif($k == 'os'){
356bd4217d3SAndreas Gohr                    if(empty($v)){
357bd4217d3SAndreas Gohr                        echo 'unknown';
358bd4217d3SAndreas Gohr                    }else{
359bd4217d3SAndreas Gohr                        include_once(dirname(__FILE__).'/inc/operating_systems.php');
360bd4217d3SAndreas Gohr                        echo $OSHashLib[$v];
361bd4217d3SAndreas Gohr                    }
362bd4217d3SAndreas Gohr                }elseif($k == 'osflag'){
363bd4217d3SAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/os/'.hsc($v).'.png" alt="'.hsc($v).'" />';
36475fa767dSAndreas Gohr                }elseif($k == 'cflag'){
36575fa767dSAndreas Gohr                    echo '<img src="'.DOKU_BASE.'lib/plugins/statistics/ico/flags/'.hsc($v).'.png" alt="'.hsc($v).'" width="18" height="12" />';
36614d99ec0SAndreas Gohr                }elseif($k == 'html'){
36714d99ec0SAndreas Gohr                    echo $v;
36814d99ec0SAndreas Gohr                }else{
36914d99ec0SAndreas Gohr                    echo hsc($v);
37014d99ec0SAndreas Gohr                }
37114d99ec0SAndreas Gohr                echo '</td>';
37214d99ec0SAndreas Gohr            }
37314d99ec0SAndreas Gohr            echo '</tr>';
3742507f8e0SAndreas Gohr
3752507f8e0SAndreas Gohr            if($pager && ($count == $pager)) break;
3762507f8e0SAndreas Gohr            $count++;
37714d99ec0SAndreas Gohr        }
37814d99ec0SAndreas Gohr        echo '</table>';
3792507f8e0SAndreas Gohr
3802507f8e0SAndreas Gohr        if($pager) $this->html_pager($pager,count($result) > $pager);
3811878f16fSAndreas Gohr    }
3821878f16fSAndreas Gohr
38395eb68e6SAndreas Gohr    /**
38495eb68e6SAndreas Gohr     * Create an image
38595eb68e6SAndreas Gohr     */
38695eb68e6SAndreas Gohr    function img_build($img){
38795eb68e6SAndreas Gohr        include(dirname(__FILE__).'/inc/AGC.class.php');
38895eb68e6SAndreas Gohr
38995eb68e6SAndreas Gohr        switch($img){
39095eb68e6SAndreas Gohr            case 'country':
39195eb68e6SAndreas Gohr                // build top countries + other
39295eb68e6SAndreas Gohr                $result = $this->sql_countries($this->tlimit,$this->start,0);
39395eb68e6SAndreas Gohr                $data = array();
39495eb68e6SAndreas Gohr                $top = 0;
39595eb68e6SAndreas Gohr                foreach($result as $row){
39695eb68e6SAndreas Gohr                    if($top < 7){
39795eb68e6SAndreas Gohr                        $data[$row['country']] = $row['cnt'];
39895eb68e6SAndreas Gohr                    }else{
39995eb68e6SAndreas Gohr                        $data['other'] += $row['cnt'];
40095eb68e6SAndreas Gohr                    }
40195eb68e6SAndreas Gohr                    $top++;
40295eb68e6SAndreas Gohr                }
40395eb68e6SAndreas Gohr                $pie = new AGC(300, 200);
40495eb68e6SAndreas Gohr                $pie->setProp("showkey",true);
40595eb68e6SAndreas Gohr                $pie->setProp("showval",false);
40695eb68e6SAndreas Gohr                $pie->setProp("showgrid",false);
40795eb68e6SAndreas Gohr                $pie->setProp("type","pie");
40895eb68e6SAndreas Gohr                $pie->setProp("keyinfo",1);
40995eb68e6SAndreas Gohr                $pie->setProp("keysize",8);
41095eb68e6SAndreas Gohr                $pie->setProp("keywidspc",-50);
41195eb68e6SAndreas Gohr                $pie->setProp("key",array_keys($data));
41295eb68e6SAndreas Gohr                $pie->addBulkPoints(array_values($data));
41395eb68e6SAndreas Gohr                @$pie->graph();
41495eb68e6SAndreas Gohr                $pie->showGraph();
41595eb68e6SAndreas Gohr                break;
41675fa767dSAndreas Gohr            case 'browser':
41775fa767dSAndreas Gohr                // build top browsers + other
41875fa767dSAndreas Gohr                include_once(dirname(__FILE__).'/inc/browsers.php');
41975fa767dSAndreas Gohr
42075fa767dSAndreas Gohr                $result = $this->sql_browsers($this->tlimit,$this->start,0,false);
42175fa767dSAndreas Gohr                $data = array();
42275fa767dSAndreas Gohr                $top = 0;
42375fa767dSAndreas Gohr                foreach($result as $row){
42475fa767dSAndreas Gohr                    if($top < 5){
42575fa767dSAndreas Gohr                        $data[strip_tags($BrowsersHashIDLib[$row['ua_info']])] = $row['cnt'];
42675fa767dSAndreas Gohr                    }else{
42775fa767dSAndreas Gohr                        $data['other'] += $row['cnt'];
42875fa767dSAndreas Gohr                    }
42975fa767dSAndreas Gohr                    $top++;
43075fa767dSAndreas Gohr                }
43175fa767dSAndreas Gohr                $pie = new AGC(300, 200);
43275fa767dSAndreas Gohr                $pie->setProp("showkey",true);
43375fa767dSAndreas Gohr                $pie->setProp("showval",false);
43475fa767dSAndreas Gohr                $pie->setProp("showgrid",false);
43575fa767dSAndreas Gohr                $pie->setProp("type","pie");
43675fa767dSAndreas Gohr                $pie->setProp("keyinfo",1);
43775fa767dSAndreas Gohr                $pie->setProp("keysize",8);
43875fa767dSAndreas Gohr                $pie->setProp("keywidspc",-50);
43975fa767dSAndreas Gohr                $pie->setProp("key",array_keys($data));
44075fa767dSAndreas Gohr                $pie->addBulkPoints(array_values($data));
44175fa767dSAndreas Gohr                @$pie->graph();
44275fa767dSAndreas Gohr                $pie->showGraph();
44375fa767dSAndreas Gohr                break;
444c73e16f1SAndreas Gohr            case 'view':
445c73e16f1SAndreas Gohr
446c73e16f1SAndreas Gohr                $graph = new AGC(400, 200);
447c73e16f1SAndreas Gohr                $graph->setColor('color',0,'blue');
448c73e16f1SAndreas Gohr                $graph->setColor('color',1,'red');
449c73e16f1SAndreas Gohr                $graph->setProp("showkey",true);
450c73e16f1SAndreas Gohr                $graph->setProp("key",'view port width',0);
451c73e16f1SAndreas Gohr                $graph->setProp("key",'view port height',1);
452c73e16f1SAndreas Gohr
453c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,true);
454c73e16f1SAndreas Gohr                foreach($result as $row){
455c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_x'],0);
456c73e16f1SAndreas Gohr                }
457c73e16f1SAndreas Gohr
458c73e16f1SAndreas Gohr                $result = $this->sql_viewport($this->tlimit,0,0,false);
459c73e16f1SAndreas Gohr                foreach($result as $row){
460c73e16f1SAndreas Gohr                    $graph->addPoint($row['cnt'],$row['res_y'],1);
461c73e16f1SAndreas Gohr                }
462c73e16f1SAndreas Gohr
463c73e16f1SAndreas Gohr                @$graph->graph();
464c73e16f1SAndreas Gohr                $graph->showGraph();
465c73e16f1SAndreas Gohr
466c73e16f1SAndreas Gohr                break;
4672812a751SAndreas Gohr            case 'trend':
4682812a751SAndreas Gohr                $hours  = ($this->from == $this->to);
4692812a751SAndreas Gohr                $result = $this->sql_trend($this->tlimit,$hours);
4702812a751SAndreas Gohr                $data1   = array();
4712812a751SAndreas Gohr                $data2   = array();
4722812a751SAndreas Gohr
4732812a751SAndreas Gohr                $graph = new AGC(400, 150);
4742812a751SAndreas Gohr                $graph->setProp("type","bar");
4752812a751SAndreas Gohr                $graph->setProp("showgrid",false);
4762812a751SAndreas Gohr                $graph->setProp("barwidth",.8);
47775fa767dSAndreas Gohr
4782812a751SAndreas Gohr                $graph->setColor('color',0,'blue');
4792812a751SAndreas Gohr                $graph->setColor('color',1,'red');
4803c0acc14SAndreas Gohr                $graph->setColor('color',2,'yellow');
4812812a751SAndreas Gohr
4822812a751SAndreas Gohr                if($hours){
4832812a751SAndreas Gohr                    //preset $hours
4842812a751SAndreas Gohr                    for($i=0;$i<24;$i++){
4852812a751SAndreas Gohr                        $data1[$i] = 0;
4862812a751SAndreas Gohr                        $data2[$i] = 0;
4873c0acc14SAndreas Gohr                        $data3[$i] = 0;
4882812a751SAndreas Gohr                        $graph->setProp("scale",array(' 0h','   4h','   8h','    12h','    16h','    20h','    24h'));
4892812a751SAndreas Gohr                    }
4902812a751SAndreas Gohr                }else{
4912812a751SAndreas Gohr                    $graph->setProp("scale",array(next(array_keys($data1)),$this->to));
4922812a751SAndreas Gohr                }
4932812a751SAndreas Gohr
4942812a751SAndreas Gohr                foreach($result as $row){
4952812a751SAndreas Gohr                    $data1[$row['time']] = $row['pageviews'];
4962812a751SAndreas Gohr                    $data2[$row['time']] = $row['sessions'];
4973c0acc14SAndreas Gohr                    $data3[$row['time']] = $row['visitors'];
4982812a751SAndreas Gohr                }
4992812a751SAndreas Gohr
5002812a751SAndreas Gohr                foreach($data1 as $key => $val){
5012812a751SAndreas Gohr                    $graph->addPoint($val,$key,0);
5022812a751SAndreas Gohr                }
5032812a751SAndreas Gohr                foreach($data2 as $key => $val){
5042812a751SAndreas Gohr                    $graph->addPoint($val,$key,1);
5052812a751SAndreas Gohr                }
5063c0acc14SAndreas Gohr                foreach($data3 as $key => $val){
5073c0acc14SAndreas Gohr                    $graph->addPoint($val,$key,2);
5083c0acc14SAndreas Gohr                }
5092812a751SAndreas Gohr
5102812a751SAndreas Gohr                @$graph->graph();
5112812a751SAndreas Gohr                $graph->showGraph();
5122812a751SAndreas Gohr
51395eb68e6SAndreas Gohr            default:
51495eb68e6SAndreas Gohr                $this->sendGIF();
51595eb68e6SAndreas Gohr        }
51695eb68e6SAndreas Gohr    }
51795eb68e6SAndreas Gohr
51895eb68e6SAndreas Gohr
5192812a751SAndreas Gohr    /**
5202812a751SAndreas Gohr     * Return some aggregated statistics
5212812a751SAndreas Gohr     */
5222812a751SAndreas Gohr    function sql_aggregate($tlimit){
5232812a751SAndreas Gohr        $data = array();
5242812a751SAndreas Gohr
5252812a751SAndreas Gohr        $sql = "SELECT ref_type, COUNT(*) as cnt
5262812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5272812a751SAndreas Gohr                 WHERE $tlimit
5282812a751SAndreas Gohr                   AND ua_type = 'browser'
5292812a751SAndreas Gohr              GROUP BY ref_type";
5302812a751SAndreas Gohr        $result = $this->runSQL($sql);
5312812a751SAndreas Gohr
5322ee939eeSAndreas Gohr        if(is_array($result)) foreach($result as $row){
5332812a751SAndreas Gohr            if($row['ref_type'] == 'search')   $data['search']   = $row['cnt'];
5342812a751SAndreas Gohr            if($row['ref_type'] == 'external') $data['external'] = $row['cnt'];
5352812a751SAndreas Gohr            if($row['ref_type'] == 'internal') $data['internal'] = $row['cnt'];
5362812a751SAndreas Gohr            if($row['ref_type'] == '')         $data['direct']   = $row['cnt'];
5372812a751SAndreas Gohr        }
5382812a751SAndreas Gohr
5392812a751SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as sessions,
5402812a751SAndreas Gohr                       COUNT(session) as views,
5413c0acc14SAndreas Gohr                       COUNT(DISTINCT user) as users,
5423c0acc14SAndreas Gohr                       COUNT(DISTINCT uid) as visitors
5432812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5442812a751SAndreas Gohr                 WHERE $tlimit
5452812a751SAndreas Gohr                   AND ua_type = 'browser'";
5462812a751SAndreas Gohr        $result = $this->runSQL($sql);
5472812a751SAndreas Gohr
54875fa767dSAndreas Gohr        $data['users']     = max($result[0]['users'] - 1,0); // subtract empty user
5492812a751SAndreas Gohr        $data['sessions']  = $result[0]['sessions'];
5502812a751SAndreas Gohr        $data['pageviews'] = $result[0]['views'];
5513c0acc14SAndreas Gohr        $data['visitors']  = $result[0]['visitors'];
5522812a751SAndreas Gohr
5532812a751SAndreas Gohr        $sql = "SELECT COUNT(id) as robots
5542812a751SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
5552812a751SAndreas Gohr                 WHERE $tlimit
5562812a751SAndreas Gohr                   AND ua_type = 'robot'";
5572812a751SAndreas Gohr        $result = $this->runSQL($sql);
5582812a751SAndreas Gohr        $data['robots'] = $result[0]['robots'];
5592812a751SAndreas Gohr
5602812a751SAndreas Gohr        return $data;
5612812a751SAndreas Gohr    }
5622812a751SAndreas Gohr
563bd4217d3SAndreas Gohr    /**
564bd4217d3SAndreas Gohr     * standard statistics follow, only accesses made by browsers are counted
565bd4217d3SAndreas Gohr     * for general stats like browser or OS only visitors not pageviews are counted
566bd4217d3SAndreas Gohr     */
5672812a751SAndreas Gohr    function sql_trend($tlimit,$hours=false){
5682812a751SAndreas Gohr        if($hours){
5692812a751SAndreas Gohr            $sql = "SELECT HOUR(dt) as time,
5702812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
5713c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
5723c0acc14SAndreas Gohr                           COUNT(DISTINCT uid) as visitors
5732812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
5742812a751SAndreas Gohr                     WHERE $tlimit
5752812a751SAndreas Gohr                       AND ua_type = 'browser'
5762812a751SAndreas Gohr                  GROUP BY HOUR(dt)
5772812a751SAndreas Gohr                  ORDER BY time";
5782812a751SAndreas Gohr        }else{
5792812a751SAndreas Gohr            $sql = "SELECT DATE(dt) as time,
5802812a751SAndreas Gohr                           COUNT(DISTINCT session) as sessions,
5813c0acc14SAndreas Gohr                           COUNT(session) as pageviews,
5823c0acc14SAndreas Gohr                            COUNT(DISTINCT uid) as visitors
5832812a751SAndreas Gohr                      FROM ".$this->getConf('db_prefix')."access as A
5842812a751SAndreas Gohr                     WHERE $tlimit
5852812a751SAndreas Gohr                       AND ua_type = 'browser'
5862812a751SAndreas Gohr                  GROUP BY DATE(dt)
5872812a751SAndreas Gohr                  ORDER BY time";
5882812a751SAndreas Gohr        }
5892812a751SAndreas Gohr        return $this->runSQL($sql);
5902812a751SAndreas Gohr    }
5912812a751SAndreas Gohr
59212dcdeccSAndreas Gohr    function sql_searchengines($tlimit,$start=0,$limit=20){
59312dcdeccSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, engine
59412dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
59512dcdeccSAndreas Gohr                 WHERE $tlimit
59612dcdeccSAndreas Gohr              GROUP BY engine
59712dcdeccSAndreas Gohr              ORDER BY cnt DESC, engine".
59812dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
59912dcdeccSAndreas Gohr        return $this->runSQL($sql);
60012dcdeccSAndreas Gohr    }
60112dcdeccSAndreas Gohr
60212dcdeccSAndreas Gohr    function sql_searchphrases($tlimit,$start=0,$limit=20){
60329dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, query, query as lookup
60412dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A
60512dcdeccSAndreas Gohr                 WHERE $tlimit
60612dcdeccSAndreas Gohr              GROUP BY query
60712dcdeccSAndreas Gohr              ORDER BY cnt DESC, query".
60812dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
60912dcdeccSAndreas Gohr        return $this->runSQL($sql);
61012dcdeccSAndreas Gohr    }
61112dcdeccSAndreas Gohr
61212dcdeccSAndreas Gohr    function sql_searchwords($tlimit,$start=0,$limit=20){
61329dea504SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, word, word as lookup
61412dcdeccSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."search as A,
61512dcdeccSAndreas Gohr                       ".$this->getConf('db_prefix')."searchwords as B
61612dcdeccSAndreas Gohr                 WHERE $tlimit
61712dcdeccSAndreas Gohr                   AND A.id = B.sid
61812dcdeccSAndreas Gohr              GROUP BY word
61912dcdeccSAndreas Gohr              ORDER BY cnt DESC, word".
62012dcdeccSAndreas Gohr              $this->sql_limit($start,$limit);
62112dcdeccSAndreas Gohr        return $this->runSQL($sql);
62212dcdeccSAndreas Gohr    }
62312dcdeccSAndreas Gohr
624e25286daSAndreas Gohr    function sql_outlinks($tlimit,$start=0,$limit=20){
625e25286daSAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, link as url
626e25286daSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."outlinks as A
627e25286daSAndreas Gohr                 WHERE $tlimit
628e25286daSAndreas Gohr              GROUP BY link
629e25286daSAndreas Gohr              ORDER BY cnt DESC, link".
630e25286daSAndreas Gohr              $this->sql_limit($start,$limit);
631e25286daSAndreas Gohr        return $this->runSQL($sql);
632e25286daSAndreas Gohr    }
633e25286daSAndreas Gohr
63495eb68e6SAndreas Gohr    function sql_pages($tlimit,$start=0,$limit=20){
6352812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, page
63695eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
63795eb68e6SAndreas Gohr                 WHERE $tlimit
63895eb68e6SAndreas Gohr                   AND ua_type = 'browser'
63995eb68e6SAndreas Gohr              GROUP BY page
64095eb68e6SAndreas Gohr              ORDER BY cnt DESC, page".
64195eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
64295eb68e6SAndreas Gohr        return $this->runSQL($sql);
64395eb68e6SAndreas Gohr    }
64495eb68e6SAndreas Gohr
64595eb68e6SAndreas Gohr    function sql_referer($tlimit,$start=0,$limit=20){
6462812a751SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
64795eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
64895eb68e6SAndreas Gohr                 WHERE $tlimit
64995eb68e6SAndreas Gohr                   AND ua_type = 'browser'
65095eb68e6SAndreas Gohr                   AND ref_type = 'external'
65195eb68e6SAndreas Gohr              GROUP BY ref_md5
65295eb68e6SAndreas Gohr              ORDER BY cnt DESC, url".
65395eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
65495eb68e6SAndreas Gohr        return $this->runSQL($sql);
65595eb68e6SAndreas Gohr    }
65695eb68e6SAndreas Gohr
657e7a2f1e0SAndreas Gohr    function sql_newreferer($tlimit,$start=0,$limit=20){
658e7a2f1e0SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt, ref as url
6592ee939eeSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as B,
6602ee939eeSAndreas Gohr                       ".$this->getConf('db_prefix')."refseen as A
6612ee939eeSAndreas Gohr                 WHERE $tlimit
6622ee939eeSAndreas Gohr                   AND ua_type = 'browser'
663e7a2f1e0SAndreas Gohr                   AND ref_type = 'external'
6642ee939eeSAndreas Gohr                   AND A.ref_md5 = B.ref_md5
6652ee939eeSAndreas Gohr              GROUP BY A.ref_md5
666e7a2f1e0SAndreas Gohr              ORDER BY cnt DESC, url".
667e7a2f1e0SAndreas Gohr              $this->sql_limit($start,$limit);
668e7a2f1e0SAndreas Gohr        return $this->runSQL($sql);
669e7a2f1e0SAndreas Gohr    }
670e7a2f1e0SAndreas Gohr
67195eb68e6SAndreas Gohr    function sql_countries($tlimit,$start=0,$limit=20){
672bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, B.code AS cflag, B.country
67395eb68e6SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A,
67495eb68e6SAndreas Gohr                       ".$this->getConf('db_prefix')."iplocation as B
67595eb68e6SAndreas Gohr                 WHERE $tlimit
67695eb68e6SAndreas Gohr                   AND A.ip = B.ip
67795eb68e6SAndreas Gohr              GROUP BY B.country
67895eb68e6SAndreas Gohr              ORDER BY cnt DESC, B.country".
67995eb68e6SAndreas Gohr              $this->sql_limit($start,$limit);
68095eb68e6SAndreas Gohr        return $this->runSQL($sql);
68195eb68e6SAndreas Gohr    }
68295eb68e6SAndreas Gohr
68375fa767dSAndreas Gohr    function sql_browsers($tlimit,$start=0,$limit=20,$ext=true){
68475fa767dSAndreas Gohr        if($ext){
68575fa767dSAndreas Gohr            $sel = 'ua_info as bflag, ua_info as browser, ua_ver';
68675fa767dSAndreas Gohr            $grp = 'ua_info, ua_ver';
68775fa767dSAndreas Gohr        }else{
68875fa767dSAndreas Gohr            $grp = 'ua_info';
68975fa767dSAndreas Gohr            $sel = 'ua_info';
69075fa767dSAndreas Gohr        }
69175fa767dSAndreas Gohr
692bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, $sel
69375fa767dSAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
69475fa767dSAndreas Gohr                 WHERE $tlimit
69575fa767dSAndreas Gohr                   AND ua_type = 'browser'
69675fa767dSAndreas Gohr              GROUP BY $grp
69775fa767dSAndreas Gohr              ORDER BY cnt DESC, ua_info".
69875fa767dSAndreas Gohr              $this->sql_limit($start,$limit);
69975fa767dSAndreas Gohr        return $this->runSQL($sql);
70075fa767dSAndreas Gohr    }
70175fa767dSAndreas Gohr
702bd4217d3SAndreas Gohr    function sql_os($tlimit,$start=0,$limit=20){
703bd4217d3SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, os as osflag, os
704bd4217d3SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
705bd4217d3SAndreas Gohr                 WHERE $tlimit
706bd4217d3SAndreas Gohr                   AND ua_type = 'browser'
707bd4217d3SAndreas Gohr              GROUP BY os
708bd4217d3SAndreas Gohr              ORDER BY cnt DESC, os".
709bd4217d3SAndreas Gohr              $this->sql_limit($start,$limit);
710bd4217d3SAndreas Gohr        return $this->runSQL($sql);
711bd4217d3SAndreas Gohr    }
712bd4217d3SAndreas Gohr
713c73e16f1SAndreas Gohr    function sql_resolution($tlimit,$start=0,$limit=20){
714c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(DISTINCT session) as cnt, CONCAT(screen_x,'x',screen_y) as res
715c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
716c73e16f1SAndreas Gohr                 WHERE $tlimit
717c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
718c73e16f1SAndreas Gohr                   AND screen_x != 0
719c73e16f1SAndreas Gohr              GROUP BY screen_x, screen_y
720c73e16f1SAndreas Gohr              ORDER BY cnt DESC, screen_x".
721c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
722c73e16f1SAndreas Gohr        return $this->runSQL($sql);
723c73e16f1SAndreas Gohr    }
724c73e16f1SAndreas Gohr
725c73e16f1SAndreas Gohr    function sql_viewport($tlimit,$start=0,$limit=20,$x=true){
726c73e16f1SAndreas Gohr        if($x){
727c73e16f1SAndreas Gohr            $col = 'view_x';
728c73e16f1SAndreas Gohr            $res = 'res_x';
729c73e16f1SAndreas Gohr        }else{
730c73e16f1SAndreas Gohr            $col = 'view_y';
731c73e16f1SAndreas Gohr            $res = 'res_y';
732c73e16f1SAndreas Gohr        }
733c73e16f1SAndreas Gohr
734c73e16f1SAndreas Gohr        $sql = "SELECT COUNT(*) as cnt,
735c73e16f1SAndreas Gohr                       ROUND($col/10)*10 as $res
736c73e16f1SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."access as A
737c73e16f1SAndreas Gohr                 WHERE $tlimit
738c73e16f1SAndreas Gohr                   AND ua_type  = 'browser'
739c73e16f1SAndreas Gohr                   AND $col != 0
740c73e16f1SAndreas Gohr              GROUP BY $res
741c73e16f1SAndreas Gohr              ORDER BY cnt DESC, $res".
742c73e16f1SAndreas Gohr              $this->sql_limit($start,$limit);
743c73e16f1SAndreas Gohr        return $this->runSQL($sql);
744c73e16f1SAndreas Gohr    }
745c73e16f1SAndreas Gohr
74675fa767dSAndreas Gohr
74795eb68e6SAndreas Gohr    /**
74895eb68e6SAndreas Gohr     * Builds a limit clause
74995eb68e6SAndreas Gohr     */
75095eb68e6SAndreas Gohr    function sql_limit($start,$limit){
75195eb68e6SAndreas Gohr        $start = (int) $start;
75295eb68e6SAndreas Gohr        $limit = (int) $limit;
75395eb68e6SAndreas Gohr        if($limit){
7542507f8e0SAndreas Gohr            $limit += 1;
75595eb68e6SAndreas Gohr            return " LIMIT $start,$limit";
75695eb68e6SAndreas Gohr        }elseif($start){
75795eb68e6SAndreas Gohr            return " OFFSET $start";
75895eb68e6SAndreas Gohr        }
75995eb68e6SAndreas Gohr        return '';
76095eb68e6SAndreas Gohr    }
7611878f16fSAndreas Gohr
7621878f16fSAndreas Gohr    /**
76314d99ec0SAndreas Gohr     * Return a link to the DB, opening the connection if needed
7641878f16fSAndreas Gohr     */
76514d99ec0SAndreas Gohr    function dbLink(){
7661878f16fSAndreas Gohr        // connect to DB if needed
7671878f16fSAndreas Gohr        if(!$this->dblink){
7681878f16fSAndreas Gohr            $this->dblink = mysql_connect($this->getConf('db_server'),
7691878f16fSAndreas Gohr                                          $this->getConf('db_user'),
7701878f16fSAndreas Gohr                                          $this->getConf('db_password'));
7711878f16fSAndreas Gohr            if(!$this->dblink){
7721878f16fSAndreas Gohr                msg('DB Error: connection failed',-1);
7731878f16fSAndreas Gohr                return null;
7741878f16fSAndreas Gohr            }
7751878f16fSAndreas Gohr            // set utf-8
7761878f16fSAndreas Gohr            if(!mysql_db_query($this->getConf('db_database'),'set names utf8',$this->dblink)){
7771878f16fSAndreas Gohr                msg('DB Error: could not set UTF-8 ('.mysql_error($this->dblink).')',-1);
7781878f16fSAndreas Gohr                return null;
7791878f16fSAndreas Gohr            }
7801878f16fSAndreas Gohr        }
78114d99ec0SAndreas Gohr        return $this->dblink;
78214d99ec0SAndreas Gohr    }
7831878f16fSAndreas Gohr
78414d99ec0SAndreas Gohr    /**
78514d99ec0SAndreas Gohr     * Simple function to run a DB query
78614d99ec0SAndreas Gohr     */
78714d99ec0SAndreas Gohr    function runSQL($sql_string) {
78814d99ec0SAndreas Gohr        $link = $this->dbLink();
78914d99ec0SAndreas Gohr
79014d99ec0SAndreas Gohr        $result = mysql_db_query($this->conf['db_database'],$sql_string,$link);
79194171ff3SAndreas Gohr        if(!$result){
7922812a751SAndreas Gohr            msg('DB Error: '.mysql_error($link).' '.hsc($sql_string),-1);
7931878f16fSAndreas Gohr            return null;
7941878f16fSAndreas Gohr        }
7951878f16fSAndreas Gohr
7961878f16fSAndreas Gohr        $resultarray = array();
7971878f16fSAndreas Gohr
7981878f16fSAndreas Gohr        //mysql_db_query returns 1 on a insert statement -> no need to ask for results
7991878f16fSAndreas Gohr        if ($result != 1) {
8001878f16fSAndreas Gohr            for($i=0; $i< mysql_num_rows($result); $i++) {
8011878f16fSAndreas Gohr                $temparray = mysql_fetch_assoc($result);
8021878f16fSAndreas Gohr                $resultarray[]=$temparray;
8031878f16fSAndreas Gohr            }
8041878f16fSAndreas Gohr            mysql_free_result($result);
8051878f16fSAndreas Gohr        }
8061878f16fSAndreas Gohr
80714d99ec0SAndreas Gohr        if (mysql_insert_id($link)) {
80814d99ec0SAndreas Gohr            $resultarray = mysql_insert_id($link); //give back ID on insert
8091878f16fSAndreas Gohr        }
8101878f16fSAndreas Gohr
8111878f16fSAndreas Gohr        return $resultarray;
8121878f16fSAndreas Gohr    }
8131878f16fSAndreas Gohr
8141878f16fSAndreas Gohr    /**
81514d99ec0SAndreas Gohr     * Returns a short name for a User Agent and sets type, version and os info
8161878f16fSAndreas Gohr     */
81714d99ec0SAndreas Gohr    function ua_info($ua,&$type,&$ver,&$os){
81814d99ec0SAndreas Gohr        $ua = strtr($ua,' +','__');
81914d99ec0SAndreas Gohr        $ua = strtolower($ua);
82014d99ec0SAndreas Gohr
82114d99ec0SAndreas Gohr        // common browsers
82214d99ec0SAndreas Gohr        $regvermsie     = '/msie([+_ ]|)([\d\.]*)/i';
82314d99ec0SAndreas Gohr        $regvernetscape = '/netscape.?\/([\d\.]*)/i';
82414d99ec0SAndreas Gohr        $regverfirefox  = '/firefox\/([\d\.]*)/i';
82514d99ec0SAndreas Gohr        $regversvn      = '/svn\/([\d\.]*)/i';
82614d99ec0SAndreas Gohr        $regvermozilla  = '/mozilla(\/|)([\d\.]*)/i';
82714d99ec0SAndreas Gohr        $regnotie       = '/webtv|omniweb|opera/i';
82814d99ec0SAndreas Gohr        $regnotnetscape = '/gecko|compatible|opera|galeon|safari/i';
82914d99ec0SAndreas Gohr
83014d99ec0SAndreas Gohr        $name = '';
83114d99ec0SAndreas Gohr        # IE ?
83214d99ec0SAndreas Gohr        if(preg_match($regvermsie,$ua,$m) && !preg_match($regnotie,$ua)){
83314d99ec0SAndreas Gohr            $type = 'browser';
83414d99ec0SAndreas Gohr            $ver  = $m[2];
83514d99ec0SAndreas Gohr            $name = 'msie';
83614d99ec0SAndreas Gohr        }
83714d99ec0SAndreas Gohr        # Firefox ?
83814d99ec0SAndreas Gohr        elseif (preg_match($regverfirefox,$ua,$m)){
83914d99ec0SAndreas Gohr            $type = 'browser';
84014d99ec0SAndreas Gohr            $ver  = $m[1];
84114d99ec0SAndreas Gohr            $name = 'firefox';
84214d99ec0SAndreas Gohr        }
84314d99ec0SAndreas Gohr        # Subversion ?
84414d99ec0SAndreas Gohr        elseif (preg_match($regversvn,$ua,$m)){
84514d99ec0SAndreas Gohr            $type = 'rcs';
84614d99ec0SAndreas Gohr            $ver  = $m[1];
84714d99ec0SAndreas Gohr            $name = 'svn';
84814d99ec0SAndreas Gohr        }
84914d99ec0SAndreas Gohr        # Netscape 6.x, 7.x ... ?
85014d99ec0SAndreas Gohr        elseif (preg_match($regvernetscape,$ua,$m)){
85114d99ec0SAndreas Gohr            $type = 'browser';
85214d99ec0SAndreas Gohr            $ver  = $m[1];
85314d99ec0SAndreas Gohr            $name = 'netscape';
85414d99ec0SAndreas Gohr        }
85514d99ec0SAndreas Gohr        # Netscape 3.x, 4.x ... ?
85614d99ec0SAndreas Gohr        elseif(preg_match($regvermozilla,$ua,$m) && !preg_match($regnotnetscape,$ua)){
85714d99ec0SAndreas Gohr            $type = 'browser';
85814d99ec0SAndreas Gohr            $ver  = $m[2];
85914d99ec0SAndreas Gohr            $name = 'netscape';
86014d99ec0SAndreas Gohr        }else{
86114d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/browsers.php');
86214d99ec0SAndreas Gohr            foreach($BrowsersSearchIDOrder as $regex){
86314d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
86414d99ec0SAndreas Gohr                    // it's a browser!
86514d99ec0SAndreas Gohr                    $type = 'browser';
86614d99ec0SAndreas Gohr                    $name = strtolower($regex);
86714d99ec0SAndreas Gohr                    break;
86814d99ec0SAndreas Gohr                }
86914d99ec0SAndreas Gohr            }
87014d99ec0SAndreas Gohr        }
87114d99ec0SAndreas Gohr
87275fa767dSAndreas Gohr        // check versions for Safari and Opera
87375fa767dSAndreas Gohr        if($name == 'safari'){
87475fa767dSAndreas Gohr            if(preg_match('/safari\/([\d\.]*)/i',$ua,$match)){
87575fa767dSAndreas Gohr                $ver = $BrowsersSafariBuildToVersionHash[$match[1]];
87675fa767dSAndreas Gohr            }
87775fa767dSAndreas Gohr        }elseif($name == 'opera'){
87875fa767dSAndreas Gohr            if(preg_match('/opera[\/ ]([\d\.]*)/i',$ua,$match)){
87975fa767dSAndreas Gohr                $ver = $match[1];
88075fa767dSAndreas Gohr            }
88175fa767dSAndreas Gohr        }
88275fa767dSAndreas Gohr
88375fa767dSAndreas Gohr
88414d99ec0SAndreas Gohr        // check OS for browsers
88514d99ec0SAndreas Gohr        if($type == 'browser'){
88614d99ec0SAndreas Gohr            include(dirname(__FILE__).'/inc/operating_systems.php');
88714d99ec0SAndreas Gohr            foreach($OSSearchIDOrder as $regex){
88814d99ec0SAndreas Gohr                if(preg_match('/'.$regex.'/',$ua)){
88914d99ec0SAndreas Gohr                    $os = $OSHashID[$regex];
89014d99ec0SAndreas Gohr                    break;
89114d99ec0SAndreas Gohr                }
89214d99ec0SAndreas Gohr            }
89314d99ec0SAndreas Gohr
89414d99ec0SAndreas Gohr        }
89514d99ec0SAndreas Gohr
89614d99ec0SAndreas Gohr        // are we done now?
89714d99ec0SAndreas Gohr        if($name) return $name;
89814d99ec0SAndreas Gohr
89914d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/robots.php');
90014d99ec0SAndreas Gohr        foreach($RobotsSearchIDOrder as $regex){
90114d99ec0SAndreas Gohr            if(preg_match('/'.$regex.'/',$ua)){
90214d99ec0SAndreas Gohr                    // it's a robot!
90314d99ec0SAndreas Gohr                    $type = 'robot';
90414d99ec0SAndreas Gohr                    return strtolower($regex);
90514d99ec0SAndreas Gohr            }
90614d99ec0SAndreas Gohr        }
90714d99ec0SAndreas Gohr
90814d99ec0SAndreas Gohr        // dunno
9091878f16fSAndreas Gohr        return '';
9101878f16fSAndreas Gohr    }
9111878f16fSAndreas Gohr
9121878f16fSAndreas Gohr    /**
913322de360SAndreas Gohr     * Log search queries
91414d99ec0SAndreas Gohr     */
91514d99ec0SAndreas Gohr    function log_search($referer,&$type){
91614d99ec0SAndreas Gohr        $referer = strtolower($referer);
917673875b1SAndreas Gohr        $ref     = strtr($referer,' +','__');
91814d99ec0SAndreas Gohr
91914d99ec0SAndreas Gohr        include(dirname(__FILE__).'/inc/search_engines.php');
92014d99ec0SAndreas Gohr
92114d99ec0SAndreas Gohr        foreach($SearchEnginesSearchIDOrder as $regex){
922673875b1SAndreas Gohr            if(preg_match('/'.$regex.'/',$ref)){
92314d99ec0SAndreas Gohr                if(!$NotSearchEnginesKeys[$regex] ||
924673875b1SAndreas Gohr                   !preg_match('/'.$NotSearchEnginesKeys[$regex].'/',$ref)){
92514d99ec0SAndreas Gohr                    // it's a search engine!
92614d99ec0SAndreas Gohr                    $type = 'search';
92714d99ec0SAndreas Gohr                    break;
92814d99ec0SAndreas Gohr                }
92914d99ec0SAndreas Gohr            }
93014d99ec0SAndreas Gohr        }
93114d99ec0SAndreas Gohr        if($type != 'search') return; // we're done here
93214d99ec0SAndreas Gohr
933322de360SAndreas Gohr        // extract query
934322de360SAndreas Gohr        $engine = $SearchEnginesHashID[$regex];
935322de360SAndreas Gohr        $param = $SearchEnginesKnownUrl[$engine];
936322de360SAndreas Gohr        if($param && preg_match('/'.$param.'(.*?)[&$]/',$referer,$match)){
937322de360SAndreas Gohr            $query = array_pop($match);
938322de360SAndreas Gohr        }elseif(preg_match('/'.$WordsToExtractSearchUrl.'(.*?)[&$]/',$referer,$match)){
939322de360SAndreas Gohr            $query = array_pop($match);
940322de360SAndreas Gohr        }
941322de360SAndreas Gohr        if(!$query) return; // we failed
942322de360SAndreas Gohr
943322de360SAndreas Gohr        // clean the query
944322de360SAndreas Gohr        $query = preg_replace('/^(cache|related):[^\+]+/','',$query);  // non-search queries
945322de360SAndreas Gohr        $query = preg_replace('/%0[ad]/',' ',$query);                  // LF CR
946322de360SAndreas Gohr        $query = preg_replace('/%2[02789abc]/',' ',$query);            // space " ' ( ) * + ,
947322de360SAndreas Gohr        $query = preg_replace('/%3a/',' ',$query);                     // :
948673875b1SAndreas Gohr        $query = strtr($query,'+\'()"*,:','        ');                 // badly encoded
949322de360SAndreas Gohr        $query = preg_replace('/ +/',' ',$query);                      // ws compact
950322de360SAndreas Gohr        $query = trim($query);
951322de360SAndreas Gohr        $query = urldecode($query);
952322de360SAndreas Gohr        if(!utf8_check($query)) $query = utf8_encode($query);          // assume latin1 if not utf8
953322de360SAndreas Gohr        $query = utf8_strtolower($query);
954322de360SAndreas Gohr
955322de360SAndreas Gohr        // log it!
956322de360SAndreas Gohr        $page  = addslashes($_REQUEST['p']);
957322de360SAndreas Gohr        $query = addslashes($query);
958673875b1SAndreas Gohr        $sql  = "INSERT INTO ".$this->getConf('db_prefix')."search
959322de360SAndreas Gohr                    SET dt       = NOW(),
960322de360SAndreas Gohr                        page     = '$page',
961322de360SAndreas Gohr                        query    = '$query',
962322de360SAndreas Gohr                        engine   = '$engine'";
963322de360SAndreas Gohr        $id = $this->runSQL($sql);
964322de360SAndreas Gohr        if(is_null($id)){
965322de360SAndreas Gohr            global $MSG;
966322de360SAndreas Gohr            print_r($MSG);
967322de360SAndreas Gohr            return;
968322de360SAndreas Gohr        }
969322de360SAndreas Gohr
970322de360SAndreas Gohr        // log single keywords
971322de360SAndreas Gohr        $words = explode(' ',utf8_stripspecials($query,' ','\._\-:\*'));
972322de360SAndreas Gohr        foreach($words as $word){
973673875b1SAndreas Gohr            if(!$word) continue;
974322de360SAndreas Gohr            $word = addslashes($word);
975322de360SAndreas Gohr            $sql = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."searchwords
976322de360SAndreas Gohr                       SET sid  = $id,
977322de360SAndreas Gohr                           word = '$word'";
978322de360SAndreas Gohr            $ok = $this->runSQL($sql);
979322de360SAndreas Gohr            if(is_null($ok)){
980322de360SAndreas Gohr                global $MSG;
981322de360SAndreas Gohr                print_r($MSG);
982322de360SAndreas Gohr            }
983322de360SAndreas Gohr        }
98414d99ec0SAndreas Gohr    }
98514d99ec0SAndreas Gohr
98614d99ec0SAndreas Gohr    /**
98714d99ec0SAndreas Gohr     * Resolve IP to country/city
98814d99ec0SAndreas Gohr     */
98914d99ec0SAndreas Gohr    function log_ip($ip){
99014d99ec0SAndreas Gohr        // check if IP already known and up-to-date
99114d99ec0SAndreas Gohr        $sql = "SELECT ip
99214d99ec0SAndreas Gohr                  FROM ".$this->getConf('db_prefix')."iplocation
99314d99ec0SAndreas Gohr                 WHERE ip ='".addslashes($ip)."'
99414d99ec0SAndreas Gohr                   AND lastupd > DATE_SUB(CURDATE(),INTERVAL 30 DAY)";
99514d99ec0SAndreas Gohr        $result = $this->runSQL($sql);
99614d99ec0SAndreas Gohr        if($result[0]['ip']) return;
99714d99ec0SAndreas Gohr
99814d99ec0SAndreas Gohr        $http = new DokuHTTPClient();
99914d99ec0SAndreas Gohr        $http->timeout = 10;
100014d99ec0SAndreas Gohr        $data = $http->get('http://api.hostip.info/get_html.php?ip='.$ip);
100114d99ec0SAndreas Gohr
100214d99ec0SAndreas Gohr        if(preg_match('/^Country: (.*?) \((.*?)\)\nCity: (.*?)$/s',$data,$match)){
100314d99ec0SAndreas Gohr            $country = addslashes(trim($match[1]));
100414d99ec0SAndreas Gohr            $code    = addslashes(strtolower(trim($match[2])));
100514d99ec0SAndreas Gohr            $city    = addslashes(trim($match[3]));
100614d99ec0SAndreas Gohr            $host    = addslashes(gethostbyaddr($ip));
100714d99ec0SAndreas Gohr            $ip      = addslashes($ip);
100814d99ec0SAndreas Gohr
100914d99ec0SAndreas Gohr            $sql = "REPLACE INTO ".$this->getConf('db_prefix')."iplocation
101014d99ec0SAndreas Gohr                        SET ip = '$ip',
101114d99ec0SAndreas Gohr                            country = '$country',
101214d99ec0SAndreas Gohr                            code    = '$code',
101314d99ec0SAndreas Gohr                            city    = '$city',
101414d99ec0SAndreas Gohr                            host    = '$host'";
101514d99ec0SAndreas Gohr            $this->runSQL($sql);
101614d99ec0SAndreas Gohr        }
101714d99ec0SAndreas Gohr    }
101814d99ec0SAndreas Gohr
101914d99ec0SAndreas Gohr    /**
1020e25286daSAndreas Gohr     * log a click on an external link
1021e25286daSAndreas Gohr     *
1022e25286daSAndreas Gohr     * called from log.php
1023e25286daSAndreas Gohr     */
1024e25286daSAndreas Gohr    function log_outgoing(){
1025e25286daSAndreas Gohr        if(!$_REQUEST['ol']) return;
1026e25286daSAndreas Gohr
1027e25286daSAndreas Gohr        $link_md5 = md5($link);
1028e25286daSAndreas Gohr        $link     = addslashes($_REQUEST['ol']);
1029e25286daSAndreas Gohr        $session  = addslashes(session_id());
1030d8c4d85eSAndreas Gohr        $page     = addslashes($_REQUEST['p']);
1031e25286daSAndreas Gohr
1032e25286daSAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."outlinks
1033e25286daSAndreas Gohr                    SET dt       = NOW(),
1034e25286daSAndreas Gohr                        session  = '$session',
1035d8c4d85eSAndreas Gohr                        page     = '$page',
1036e25286daSAndreas Gohr                        link_md5 = '$link_md5',
1037e25286daSAndreas Gohr                        link     = '$link'";
1038e25286daSAndreas Gohr        $ok = $this->runSQL($sql);
1039e25286daSAndreas Gohr        if(is_null($ok)){
1040e25286daSAndreas Gohr            global $MSG;
1041e25286daSAndreas Gohr            print_r($MSG);
1042e25286daSAndreas Gohr        }
1043e25286daSAndreas Gohr    }
1044e25286daSAndreas Gohr
1045e25286daSAndreas Gohr    /**
10461878f16fSAndreas Gohr     * log a page access
10471878f16fSAndreas Gohr     *
10481878f16fSAndreas Gohr     * called from log.php
10491878f16fSAndreas Gohr     */
10501878f16fSAndreas Gohr    function log_access(){
105194171ff3SAndreas Gohr        if(!$_REQUEST['p']) return;
105294171ff3SAndreas Gohr
105314d99ec0SAndreas Gohr        # FIXME check referer against blacklist and drop logging for bad boys
105414d99ec0SAndreas Gohr
105514d99ec0SAndreas Gohr        // handle referer
105614d99ec0SAndreas Gohr        $referer = trim($_REQUEST['r']);
105714d99ec0SAndreas Gohr        if($referer){
105814d99ec0SAndreas Gohr            $ref     = addslashes($referer);
105914d99ec0SAndreas Gohr            $ref_md5 = ($ref) ? md5($referer) : '';
106014d99ec0SAndreas Gohr            if(strpos($referer,DOKU_URL) === 0){
106114d99ec0SAndreas Gohr                $ref_type = 'internal';
106214d99ec0SAndreas Gohr            }else{
106314d99ec0SAndreas Gohr                $ref_type = 'external';
106414d99ec0SAndreas Gohr                $this->log_search($referer,$ref_type);
106514d99ec0SAndreas Gohr            }
106614d99ec0SAndreas Gohr        }else{
106714d99ec0SAndreas Gohr            $ref      = '';
106814d99ec0SAndreas Gohr            $ref_md5  = '';
106914d99ec0SAndreas Gohr            $ref_type = '';
107014d99ec0SAndreas Gohr        }
107114d99ec0SAndreas Gohr
107214d99ec0SAndreas Gohr        // handle user agent
107314d99ec0SAndreas Gohr        $agent   = trim($_SERVER['HTTP_USER_AGENT']);
107414d99ec0SAndreas Gohr
107514d99ec0SAndreas Gohr        $ua      = addslashes($agent);
107614d99ec0SAndreas Gohr        $ua_type = '';
107714d99ec0SAndreas Gohr        $ua_ver  = '';
107814d99ec0SAndreas Gohr        $os      = '';
107914d99ec0SAndreas Gohr        $ua_info = addslashes($this->ua_info($agent,$ua_type,$ua_ver,$os));
108014d99ec0SAndreas Gohr
10811878f16fSAndreas Gohr        $page    = addslashes($_REQUEST['p']);
10821878f16fSAndreas Gohr        $ip      = addslashes($_SERVER['REMOTE_ADDR']);
10831878f16fSAndreas Gohr        $sx      = (int) $_REQUEST['sx'];
10841878f16fSAndreas Gohr        $sy      = (int) $_REQUEST['sy'];
10851878f16fSAndreas Gohr        $vx      = (int) $_REQUEST['vx'];
10861878f16fSAndreas Gohr        $vy      = (int) $_REQUEST['vy'];
108775fa767dSAndreas Gohr        $js      = (int) $_REQUEST['js'];
10883c0acc14SAndreas Gohr        $uid     = addslashes($_REQUEST['uid']);
10891878f16fSAndreas Gohr        $user    = addslashes($_SERVER['REMOTE_USER']);
10901878f16fSAndreas Gohr        $session = addslashes(session_id());
10913c0acc14SAndreas Gohr        if(!$uid) $uid = $session;
10921878f16fSAndreas Gohr
109394171ff3SAndreas Gohr        $sql  = "INSERT DELAYED INTO ".$this->getConf('db_prefix')."access
109475fa767dSAndreas Gohr                    SET dt       = NOW(),
109575fa767dSAndreas Gohr                        page     = '$page',
10961878f16fSAndreas Gohr                        ip       = '$ip',
10971878f16fSAndreas Gohr                        ua       = '$ua',
10981878f16fSAndreas Gohr                        ua_info  = '$ua_info',
109914d99ec0SAndreas Gohr                        ua_type  = '$ua_type',
110014d99ec0SAndreas Gohr                        ua_ver   = '$ua_ver',
110114d99ec0SAndreas Gohr                        os       = '$os',
11021878f16fSAndreas Gohr                        ref      = '$ref',
110394171ff3SAndreas Gohr                        ref_md5  = '$ref_md5',
110414d99ec0SAndreas Gohr                        ref_type = '$ref_type',
11051878f16fSAndreas Gohr                        screen_x = '$sx',
11061878f16fSAndreas Gohr                        screen_y = '$sy',
11071878f16fSAndreas Gohr                        view_x   = '$vx',
11081878f16fSAndreas Gohr                        view_y   = '$vy',
110975fa767dSAndreas Gohr                        js       = '$js',
11101878f16fSAndreas Gohr                        user     = '$user',
11113c0acc14SAndreas Gohr                        session  = '$session',
11123c0acc14SAndreas Gohr                        uid      = '$uid'";
11131878f16fSAndreas Gohr        $ok = $this->runSQL($sql);
11141878f16fSAndreas Gohr        if(is_null($ok)){
11151878f16fSAndreas Gohr            global $MSG;
11161878f16fSAndreas Gohr            print_r($MSG);
11171878f16fSAndreas Gohr        }
111814d99ec0SAndreas Gohr
11192ee939eeSAndreas Gohr        $sql = "INSERT DELAYED IGNORE INTO ".$this->getConf('db_prefix')."refseen
11202ee939eeSAndreas Gohr                   SET ref_md5  = '$ref_md5',
11212ee939eeSAndreas Gohr                       dt       = NOW()";
11222ee939eeSAndreas Gohr        $ok = $this->runSQL($sql);
11232ee939eeSAndreas Gohr        if(is_null($ok)){
11242ee939eeSAndreas Gohr            global $MSG;
11252ee939eeSAndreas Gohr            print_r($MSG);
11262ee939eeSAndreas Gohr        }
11272ee939eeSAndreas Gohr
112814d99ec0SAndreas Gohr        // resolve the IP
112914d99ec0SAndreas Gohr        $this->log_ip($_SERVER['REMOTE_ADDR']);
11301878f16fSAndreas Gohr    }
11311878f16fSAndreas Gohr
11321878f16fSAndreas Gohr    /**
11331878f16fSAndreas Gohr     * Just send a 1x1 pixel blank gif to the browser
11341878f16fSAndreas Gohr     *
11351878f16fSAndreas Gohr     * @called from log.php
11361878f16fSAndreas Gohr     *
11371878f16fSAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
11381878f16fSAndreas Gohr     * @author Harry Fuecks <fuecks@gmail.com>
11391878f16fSAndreas Gohr     */
11401878f16fSAndreas Gohr    function sendGIF(){
11411878f16fSAndreas Gohr        $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
11421878f16fSAndreas Gohr        header('Content-Type: image/gif');
11431878f16fSAndreas Gohr        header('Content-Length: '.strlen($img));
11441878f16fSAndreas Gohr        header('Connection: Close');
11451878f16fSAndreas Gohr        print $img;
11461878f16fSAndreas Gohr        flush();
11471878f16fSAndreas Gohr        // Browser should drop connection after this
11481878f16fSAndreas Gohr        // Thinks it's got the whole image
11491878f16fSAndreas Gohr    }
11501878f16fSAndreas Gohr
11511878f16fSAndreas Gohr}
1152