1<?php
2// must be run within Dokuwiki
3if(!defined('DOKU_INC')) die();
4
5if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
6require_once(DOKU_PLUGIN.'admin.php');
7        //error_reporting(E_ALL);
8       //ini_set('display_errors',true);
9
10/**
11 * All DokuWiki plugins to extend the admin function
12 * need to inherit from this class
13 */
14class admin_plugin_botbouncer_statistics extends DokuWiki_Admin_Plugin {
15
16    /**
17     * return some info
18     */
19    function getInfo() {
20        return confToHash(dirname(__FILE__).'/../plugin.info.txt');
21    }
22
23    /**
24     * Access for managers allowed
25     */
26    function forAdminOnly() {
27        return false;
28    }
29
30    function getMenuText($language) {
31        return $this->getLang('menu_statistics');
32    }
33
34    /**
35     * return sort order for position in admin menu
36     */
37    function getMenuSort() {
38        return 150;
39    }
40
41    /**
42     * handle user request
43     */
44    function handle() {
45    }
46
47    /**
48     * output appropriate html
49     */
50    function html() {
51        $this->_stats();
52    }
53
54
55    function _stats() {
56        print $this->locale_xhtml('stats');
57
58        $days = 7;
59        $list = $this->_readlines($days);
60        $all = $whitelisted = 0;
61        $stats = array();
62        foreach ($list as $line){
63            if (!$line) continue;
64            if (preg_match('/is whitelisted$/',$line)) {
65              $stats['whitelisted'] += 1;
66            } elseif (preg_match('/no match$/',$line)) {
67              $stats['not spam'] += 1;
68            } else {
69              $data = explode("\t",$line);
70              $stats[$data[1].' '.$data[2]] = (int) $stats[$data[1].' '.$data[2]] + 1;
71              $all++;
72            }
73        }
74        arsort($stats);
75
76        printf('<p><b>'.$this->getLang('blocked').'</b></p>',$all,$days);
77
78        echo '<table class="inline">';
79        echo '<tr>';
80        echo '<th>'.$this->getLang('percent').'</th>';
81        echo '<th>'.$this->getLang('count').'</th>';
82        echo '<th>'.$this->getLang('reason').'</th>';
83        echo '</tr>';
84        foreach ($stats as $code => $count){
85            echo '<tr>';
86            echo '<td>';
87            printf("%.2f%%",100*$count/$all);
88            echo '</td>';
89            echo '<td>';
90            echo $count;
91            echo '</td>';
92            echo '<td>';
93            echo $code;
94            echo '</td>';
95            echo '</tr>';
96        }
97        echo '</table>';
98    }
99
100    /**
101     * Read loglines backward
102     *
103     * taken from dokuwiki captcha plugin
104     */
105    function _readlines($days=7){
106        global $conf;
107        $file = $conf['cachedir'].'/botbouncer.log';
108
109        $date  = time() - ($days*24*60*60);
110
111        $data  = array();
112        $lines = array();
113        $chunk_size = 8192;
114
115        if (!@file_exists($file)) return $data;
116        $fp = fopen($file, 'rb');
117        if ($fp===false) return $data;
118
119        //seek to end
120        fseek($fp, 0, SEEK_END);
121        $pos = ftell($fp);
122        $chunk = '';
123
124        while($pos){
125
126            // how much to read? Set pointer
127            if ($pos > $chunk_size){
128                $pos -= $chunk_size;
129                $read = $chunk_size;
130            } else {
131                $read = $pos;
132                $pos  = 0;
133            }
134            fseek($fp,$pos);
135
136            $tmp = fread($fp,$read);
137            if($tmp === false) break;
138            $chunk = $tmp.$chunk;
139
140            // now split the chunk
141            $cparts = explode("\n",$chunk);
142
143            // keep the first part in chunk (may be incomplete)
144            if($pos) $chunk = array_shift($cparts);
145
146            // no more parts available, read on
147            if(!count($cparts)) continue;
148
149            // put the new lines on the stack
150            $lines = array_merge($cparts,$lines);
151
152            // check date of first line:
153            list($cdate) = explode("\t",$cparts[0]);
154            if ($cdate < $date) break; // we have enough
155        }
156        fclose($fp);
157
158        return $lines;
159    }
160}
161//Setup VIM: ex: et ts=4 :
162