Failed Conditions
Push — psr2-config ( c6639e )
by Andreas
06:39 queued 03:33
created

helper_plugin_popularity::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Popularity Feedback Plugin
4
 *
5
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6
 */
7
8
class helper_plugin_popularity extends Dokuwiki_Plugin
9
{
10
    /**
11
     * The url where the data should be sent
12
     */
13
    public $submitUrl = 'http://update.dokuwiki.org/popularity.php';
14
15
    /**
16
     * Name of the file which determine if the the autosubmit is enabled,
17
     * and when it was submited for the last time
18
     */
19
    public $autosubmitFile;
20
21
    /**
22
     * File where the last error which happened when we tried to autosubmit, will be log
23
     */
24
    public $autosubmitErrorFile;
25
26
    /**
27
     * Name of the file which determine when the popularity data was manually
28
     * submitted for the last time
29
     * (If this file doesn't exist, the data has never been sent)
30
     */
31
    public $popularityLastSubmitFile;
32
33
    /**
34
     * helper_plugin_popularity constructor.
35
     */
36
    public function __construct()
37
    {
38
        global $conf;
39
        $this->autosubmitFile = $conf['cachedir'].'/autosubmit.txt';
40
        $this->autosubmitErrorFile = $conf['cachedir'].'/autosubmitError.txt';
41
        $this->popularityLastSubmitFile = $conf['cachedir'].'/lastSubmitTime.txt';
42
    }
43
44
    /**
45
     * Check if autosubmit is enabled
46
     *
47
     * @return boolean TRUE if we should send data once a month, FALSE otherwise
48
     */
49
    public function isAutoSubmitEnabled()
50
    {
51
        return file_exists($this->autosubmitFile);
52
    }
53
54
    /**
55
     * Send the data, to the submit url
56
     *
57
     * @param string $data The popularity data
58
     * @return string An empty string if everything worked fine, a string describing the error otherwise
59
     */
60
    public function sendData($data)
61
    {
62
        $error = '';
63
        $httpClient = new DokuHTTPClient();
64
        $status = $httpClient->sendRequest($this->submitUrl, array('data' => $data), 'POST');
65
        if (! $status) {
66
            $error = $httpClient->error;
67
        }
68
        return $error;
69
    }
70
71
    /**
72
     * Compute the last time the data was sent. If it has never been sent, we return 0.
73
     *
74
     * @return int
75
     */
76
    public function lastSentTime()
77
    {
78
        $manualSubmission = @filemtime($this->popularityLastSubmitFile);
79
        $autoSubmission   = @filemtime($this->autosubmitFile);
80
81
        return max((int) $manualSubmission, (int) $autoSubmission);
82
    }
83
84
    /**
85
     * Gather all information
86
     *
87
     * @return string The popularity data as a string
88
     */
89
    public function gatherAsString()
90
    {
91
        $data = $this->gather();
92
        $string = '';
93
        foreach ($data as $key => $val) {
94
            if (is_array($val)) foreach ($val as $v) {
95
                $string .=  hsc($key)."\t".hsc($v)."\n";
96
            } else {
97
                $string .= hsc($key)."\t".hsc($val)."\n";
98
            }
99
        }
100
        return $string;
101
    }
102
103
    /**
104
     * Gather all information
105
     *
106
     * @return array The popularity data as an array
107
     */
108
    protected function gather()
109
    {
110
        global $conf;
111
        /** @var $auth DokuWiki_Auth_Plugin */
112
        global $auth;
113
        $data = array();
114
        $phptime = ini_get('max_execution_time');
115
        @set_time_limit(0);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
116
        $pluginInfo = $this->getInfo();
117
118
        // version
119
        $data['anon_id'] = md5(auth_cookiesalt());
120
        $data['version'] = getVersion();
121
        $data['popversion'] = $pluginInfo['date'];
122
        $data['language'] = $conf['lang'];
123
        $data['now']      = time();
124
        $data['popauto']  = (int) $this->isAutoSubmitEnabled();
125
126
        // some config values
127
        $data['conf_useacl']   = $conf['useacl'];
128
        $data['conf_authtype'] = $conf['authtype'];
129
        $data['conf_template'] = $conf['template'];
130
131
        // number and size of pages
132
        $list = array();
133
        search($list, $conf['datadir'], array($this, 'searchCountCallback'), array('all'=>false), '');
134
        $data['page_count']    = $list['file_count'];
135
        $data['page_size']     = $list['file_size'];
136
        $data['page_biggest']  = $list['file_max'];
137
        $data['page_smallest'] = $list['file_min'];
138
        $data['page_nscount']  = $list['dir_count'];
139
        $data['page_nsnest']   = $list['dir_nest'];
140
        if ($list['file_count']) $data['page_avg'] = $list['file_size'] / $list['file_count'];
141
        $data['page_oldest']   = $list['file_oldest'];
142
        unset($list);
143
144
        // number and size of media
145
        $list = array();
146
        search($list, $conf['mediadir'], array($this, 'searchCountCallback'), array('all'=>true));
147
        $data['media_count']    = $list['file_count'];
148
        $data['media_size']     = $list['file_size'];
149
        $data['media_biggest']  = $list['file_max'];
150
        $data['media_smallest'] = $list['file_min'];
151
        $data['media_nscount']  = $list['dir_count'];
152
        $data['media_nsnest']   = $list['dir_nest'];
153
        if ($list['file_count']) $data['media_avg'] = $list['file_size'] / $list['file_count'];
154
        unset($list);
155
156
        // number and size of cache
157
        $list = array();
158
        search($list, $conf['cachedir'], array($this, 'searchCountCallback'), array('all'=>true));
159
        $data['cache_count']    = $list['file_count'];
160
        $data['cache_size']     = $list['file_size'];
161
        $data['cache_biggest']  = $list['file_max'];
162
        $data['cache_smallest'] = $list['file_min'];
163
        if ($list['file_count']) $data['cache_avg'] = $list['file_size'] / $list['file_count'];
164
        unset($list);
165
166
        // number and size of index
167
        $list = array();
168
        search($list, $conf['indexdir'], array($this, 'searchCountCallback'), array('all'=>true));
169
        $data['index_count']    = $list['file_count'];
170
        $data['index_size']     = $list['file_size'];
171
        $data['index_biggest']  = $list['file_max'];
172
        $data['index_smallest'] = $list['file_min'];
173
        if ($list['file_count']) $data['index_avg'] = $list['file_size'] / $list['file_count'];
174
        unset($list);
175
176
        // number and size of meta
177
        $list = array();
178
        search($list, $conf['metadir'], array($this, 'searchCountCallback'), array('all'=>true));
179
        $data['meta_count']    = $list['file_count'];
180
        $data['meta_size']     = $list['file_size'];
181
        $data['meta_biggest']  = $list['file_max'];
182
        $data['meta_smallest'] = $list['file_min'];
183
        if ($list['file_count']) $data['meta_avg'] = $list['file_size'] / $list['file_count'];
184
        unset($list);
185
186
        // number and size of attic
187
        $list = array();
188
        search($list, $conf['olddir'], array($this, 'searchCountCallback'), array('all'=>true));
189
        $data['attic_count']    = $list['file_count'];
190
        $data['attic_size']     = $list['file_size'];
191
        $data['attic_biggest']  = $list['file_max'];
192
        $data['attic_smallest'] = $list['file_min'];
193
        if ($list['file_count']) $data['attic_avg'] = $list['file_size'] / $list['file_count'];
194
        $data['attic_oldest']   = $list['file_oldest'];
195
        unset($list);
196
197
        // user count
198
        if ($auth && $auth->canDo('getUserCount')) {
199
            $data['user_count'] = $auth->getUserCount();
200
        }
201
202
        // calculate edits per day
203
        $list = @file($conf['metadir'].'/_dokuwiki.changes');
204
        $count = count($list);
205
        if ($count > 2) {
206
            $first = (int) substr(array_shift($list), 0, 10);
207
            $last  = (int) substr(array_pop($list), 0, 10);
208
            $dur = ($last - $first)/(60*60*24); // number of days in the changelog
209
            $data['edits_per_day'] = $count/$dur;
210
        }
211
        unset($list);
212
213
        // plugins
214
        $data['plugin'] = plugin_list();
215
216
        // pcre info
217
        if (defined('PCRE_VERSION')) $data['pcre_version'] = PCRE_VERSION;
218
        $data['pcre_backtrack'] = ini_get('pcre.backtrack_limit');
219
        $data['pcre_recursion'] = ini_get('pcre.recursion_limit');
220
221
        // php info
222
        $data['os'] = PHP_OS;
223
        $data['webserver'] = $_SERVER['SERVER_SOFTWARE'];
224
        $data['php_version'] = phpversion();
225
        $data['php_sapi'] = php_sapi_name();
226
        $data['php_memory'] = php_to_byte(ini_get('memory_limit'));
227
        $data['php_exectime'] = $phptime;
228
        $data['php_extension'] = get_loaded_extensions();
229
230
        // plugin usage data
231
        $this->addPluginUsageData($data);
232
233
        return $data;
234
    }
235
236
    /**
237
     * Triggers event to let plugins add their own data
238
     *
239
     * @param $data
240
     */
241
    protected function addPluginUsageData(&$data)
242
    {
243
        $pluginsData = array();
244
        trigger_event('PLUGIN_POPULARITY_DATA_SETUP', $pluginsData);
245
        foreach ($pluginsData as $plugin => $d) {
246
            if (is_array($d)) {
247
                foreach ($d as $key => $value) {
248
                    $data['plugin_' . $plugin . '_' . $key] = $value;
249
                }
250
            } else {
251
                $data['plugin_' . $plugin] = $d;
252
            }
253
        }
254
    }
255
256
    /**
257
     * Callback to search and count the content of directories in DokuWiki
258
     *
259
     * @param array &$data  Reference to the result data structure
260
     * @param string $base  Base usually $conf['datadir']
261
     * @param string $file  current file or directory relative to $base
262
     * @param string $type  Type either 'd' for directory or 'f' for file
263
     * @param int    $lvl   Current recursion depht
264
     * @param array  $opts  option array as given to search()
265
     * @return bool
266
     */
267
    protected function searchCountCallback(&$data, $base, $file, $type, $lvl, $opts)
268
    {
269
        // traverse
270
        if ($type == 'd') {
271
            if ($data['dir_nest'] < $lvl) $data['dir_nest'] = $lvl;
272
            $data['dir_count']++;
273
            return true;
274
        }
275
276
        //only search txt files if 'all' option not set
277
        if ($opts['all'] || substr($file, -4) == '.txt') {
278
            $size = filesize($base.'/'.$file);
279
            $date = filemtime($base.'/'.$file);
280
            $data['file_count']++;
281
            $data['file_size'] += $size;
282
            if (!isset($data['file_min']) || $data['file_min'] > $size) $data['file_min'] = $size;
283
            if ($data['file_max'] < $size) $data['file_max'] = $size;
284
            if (!isset($data['file_oldest']) || $data['file_oldest'] > $date) $data['file_oldest'] = $date;
285
        }
286
287
        return false;
288
    }
289
}
290