xref: /dokuwiki/lib/plugins/popularity/helper.php (revision 2f1d4a94ebb4e5c412ea4332751e2a6104c7f26b)
1<?php
2/**
3 * Popularity Feedback Plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 */
7
8class helper_plugin_popularity extends Dokuwiki_Plugin {
9    /**
10     * The url where the data should be sent
11     */
12    var $submitUrl = 'http://update.dokuwiki.org/popularity.php';
13
14    /**
15     * Name of the file which determine if the the autosubmit is enabled,
16     * and when it was submited for the las time
17     */
18    var $autosubmitFile;
19
20    /**
21     * File where the last error which happened when we tried to autosubmit, will be log
22     */
23    var $autosubmitErrorFile;
24
25    function helper_plugin_popularity(){
26        global $conf;
27        $this->autosubmitFile = $conf['cachedir'].'/autosubmit.txt';
28        $this->autosubmitErrorFile = $conf['cachedir'].'/autosubmitError.txt';
29    }
30
31    function getMethods(){
32        $result = array();
33        $result[] = array(
34                'name'   => 'isAutoSubmitEnabled',
35                'desc'   => 'Check if autosubmit is enabled',
36                'params' => array(),
37                'return' => array('result' => 'bool')
38                );
39        $result[] = array(
40                'name'   => 'sendData',
41                'desc'   => 'Send the popularity data',
42                'params' => array('data' => 'string'),
43                'return' => array()
44                );
45        $result[] = array(
46                'name' => 'gatherAsString',
47                'desc' => 'Gather the popularity data',
48                'params' => array(),
49                'return' => array('data' => 'string')
50                );
51        return $result;
52
53    }
54
55    /**
56     * Check if autosubmit is enabled
57     * @return TRUE if we should send data once a month, FALSE otherwise
58     */
59    function isAutoSubmitEnabled(){
60        return @file_exists($this->autosubmitFile);
61    }
62
63    /**
64     * Send the data, to the submit url
65     * @param string $data The popularity data
66     * @return An empty string if everything worked fine, a string describing the error otherwise
67     */
68    function sendData($data){
69        $error = '';
70        $httpClient = new DokuHTTPClient();
71        $status = $httpClient->sendRequest($this->submitUrl, $data, 'POST');
72        if ( ! $status ){
73            $error = $httpClient->error;
74        }
75        return $error;
76    }
77
78    /**
79     * Gather all information
80     * @return The popularity data as a string
81     */
82    function gatherAsString(){
83        $data = $this->_gather();
84        $string = '';
85        foreach($data as $key => $val){
86            if(is_array($val)) foreach($val as $v){
87                $string .=  hsc($key)."\t".hsc($v)."\n";
88            }else{
89                $string .= hsc($key)."\t".hsc($val)."\n";
90            }
91        }
92        return $string;
93    }
94
95    /**
96     * Gather all information
97     * @return The popularity data as an array
98     */
99    function _gather(){
100        global $conf;
101        global $auth;
102        $data = array();
103        $phptime = ini_get('max_execution_time');
104        @set_time_limit(0);
105
106        // version
107        $data['anon_id'] = md5(auth_cookiesalt());
108        $data['version'] = getVersion();
109        $data['popversion'] = $this->version;
110        $data['language'] = $conf['lang'];
111        $data['now']      = time();
112
113        // some config values
114        $data['conf_useacl']   = $conf['useacl'];
115        $data['conf_authtype'] = $conf['authtype'];
116        $data['conf_template'] = $conf['template'];
117
118        // number and size of pages
119        $list = array();
120        search($list,$conf['datadir'],array($this,'_search_count'),'','');
121        $data['page_count']    = $list['file_count'];
122        $data['page_size']     = $list['file_size'];
123        $data['page_biggest']  = $list['file_max'];
124        $data['page_smallest'] = $list['file_min'];
125        $data['page_nscount']  = $list['dir_count'];
126        $data['page_nsnest']   = $list['dir_nest'];
127        if($list['file_count']) $data['page_avg'] = $list['file_size'] / $list['file_count'];
128        $data['page_oldest']   = $list['file_oldest'];
129        unset($list);
130
131        // number and size of media
132        $list = array();
133        search($list,$conf['mediadir'],array($this,'_search_count'),array('all'=>true));
134        $data['media_count']    = $list['file_count'];
135        $data['media_size']     = $list['file_size'];
136        $data['media_biggest']  = $list['file_max'];
137        $data['media_smallest'] = $list['file_min'];
138        $data['media_nscount']  = $list['dir_count'];
139        $data['media_nsnest']   = $list['dir_nest'];
140        if($list['file_count']) $data['media_avg'] = $list['file_size'] / $list['file_count'];
141        unset($list);
142
143        // number and size of cache
144        $list = array();
145        search($list,$conf['cachedir'],array($this,'_search_count'),array('all'=>true));
146        $data['cache_count']    = $list['file_count'];
147        $data['cache_size']     = $list['file_size'];
148        $data['cache_biggest']  = $list['file_max'];
149        $data['cache_smallest'] = $list['file_min'];
150        if($list['file_count']) $data['cache_avg'] = $list['file_size'] / $list['file_count'];
151        unset($list);
152
153        // number and size of index
154        $list = array();
155        search($list,$conf['indexdir'],array($this,'_search_count'),array('all'=>true));
156        $data['index_count']    = $list['file_count'];
157        $data['index_size']     = $list['file_size'];
158        $data['index_biggest']  = $list['file_max'];
159        $data['index_smallest'] = $list['file_min'];
160        if($list['file_count']) $data['index_avg'] = $list['file_size'] / $list['file_count'];
161        unset($list);
162
163        // number and size of meta
164        $list = array();
165        search($list,$conf['metadir'],array($this,'_search_count'),array('all'=>true));
166        $data['meta_count']    = $list['file_count'];
167        $data['meta_size']     = $list['file_size'];
168        $data['meta_biggest']  = $list['file_max'];
169        $data['meta_smallest'] = $list['file_min'];
170        if($list['file_count']) $data['meta_avg'] = $list['file_size'] / $list['file_count'];
171        unset($list);
172
173        // number and size of attic
174        $list = array();
175        search($list,$conf['olddir'],array($this,'_search_count'),array('all'=>true));
176        $data['attic_count']    = $list['file_count'];
177        $data['attic_size']     = $list['file_size'];
178        $data['attic_biggest']  = $list['file_max'];
179        $data['attic_smallest'] = $list['file_min'];
180        if($list['file_count']) $data['attic_avg'] = $list['file_size'] / $list['file_count'];
181        $data['attic_oldest']   = $list['file_oldest'];
182        unset($list);
183
184        // user count
185        if($auth && $auth->canDo('getUserCount')){
186            $data['user_count'] = $auth->getUserCount();
187        }
188
189        // calculate edits per day
190        $list = @file($conf['metadir'].'/_dokuwiki.changes');
191        $count = count($list);
192        if($count > 2){
193            $first = (int) substr(array_shift($list),0,10);
194            $last  = (int) substr(array_pop($list),0,10);
195            $dur = ($last - $first)/(60*60*24); // number of days in the changelog
196            $data['edits_per_day'] = $count/$dur;
197        }
198        unset($list);
199
200        // plugins
201        $data['plugin'] = plugin_list();
202
203        // pcre info
204        if(defined('PCRE_VERSION')) $data['pcre_version'] = PCRE_VERSION;
205        $data['pcre_backtrack'] = ini_get('pcre.backtrack_limit');
206        $data['pcre_recursion'] = ini_get('pcre.recursion_limit');
207
208        // php info
209        $data['os'] = PHP_OS;
210        $data['webserver'] = $_SERVER['SERVER_SOFTWARE'];
211        $data['php_version'] = phpversion();
212        $data['php_sapi'] = php_sapi_name();
213        $data['php_memory'] = $this->_to_byte(ini_get('memory_limit'));
214        $data['php_exectime'] = $phptime;
215        $data['php_extension'] = get_loaded_extensions();
216
217        return $data;
218    }
219
220    function _search_count(&$data,$base,$file,$type,$lvl,$opts){
221        // traverse
222        if($type == 'd'){
223            if($data['dir_nest'] < $lvl) $data['dir_nest'] = $lvl;
224            $data['dir_count']++;
225            return true;
226        }
227
228        //only search txt files if 'all' option not set
229        if($opts['all'] || substr($file,-4) == '.txt'){
230            $size = filesize($base.'/'.$file);
231            $date = filemtime($base.'/'.$file);
232            $data['file_count']++;
233            $data['file_size'] += $size;
234            if(!isset($data['file_min']) || $data['file_min'] > $size) $data['file_min'] = $size;
235            if($data['file_max'] < $size) $data['file_max'] = $size;
236            if(!isset($data['file_oldest']) || $data['file_oldest'] > $date) $data['file_oldest'] = $date;
237        }
238
239        return false;
240    }
241
242    /**
243     * Convert php.ini shorthands to byte
244     *
245     * @author <gilthans dot NO dot SPAM at gmail dot com>
246     * @link   http://de3.php.net/manual/en/ini.core.php#79564
247     */
248    function _to_byte($v){
249        $l = substr($v, -1);
250        $ret = substr($v, 0, -1);
251        switch(strtoupper($l)){
252            case 'P':
253                $ret *= 1024;
254            case 'T':
255                $ret *= 1024;
256            case 'G':
257                $ret *= 1024;
258            case 'M':
259                $ret *= 1024;
260            case 'K':
261                $ret *= 1024;
262            break;
263        }
264        return $ret;
265    }
266}
267