Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 418 lines (372 sloc) 12.779 kb
c29dc6e @splitbrain updatecheck feature
authored
1 <?php
2 /**
3 * Information and debugging functions
4 *
5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author Andreas Gohr <andi@splitbrain.org>
7 */
fa8adff @splitbrain removed some illogical path setups
authored
8 if(!defined('DOKU_INC')) die('meh.');
3d7760a @splitbrain update for updatecheck function
authored
9 if(!defined('DOKU_MESSAGEURL')) define('DOKU_MESSAGEURL','http://update.dokuwiki.org/check/');
c29dc6e @splitbrain updatecheck feature
authored
10
11 /**
12 * Check for new messages from upstream
13 *
14 * @author Andreas Gohr <andi@splitbrain.org>
15 */
16 function checkUpdateMessages(){
17 global $conf;
18 global $INFO;
ef362bb @selfthinker moved update message from its own file (conf/msg) into doku.php (FS#1…
selfthinker authored
19 global $updateVersion;
c29dc6e @splitbrain updatecheck feature
authored
20 if(!$conf['updatecheck']) return;
f8cc712 @splitbrain manager user/group
authored
21 if($conf['useacl'] && !$INFO['ismanager']) return;
c29dc6e @splitbrain updatecheck feature
authored
22
23 $cf = $conf['cachedir'].'/messages.txt';
24 $lm = @filemtime($cf);
25
26 // check if new messages needs to be fetched
ef362bb @selfthinker moved update message from its own file (conf/msg) into doku.php (FS#1…
selfthinker authored
27 if($lm < time()-(60*60*24) || $lm < @filemtime(DOKU_INC.'doku.php')){
c29dc6e @splitbrain updatecheck feature
authored
28 $http = new DokuHTTPClient();
29 $http->timeout = 8;
ef362bb @selfthinker moved update message from its own file (conf/msg) into doku.php (FS#1…
selfthinker authored
30 $data = $http->get(DOKU_MESSAGEURL.$updateVersion);
c29dc6e @splitbrain updatecheck feature
authored
31 io_saveFile($cf,$data);
32 }else{
33 $data = io_readFile($cf);
34 }
35
36 // show messages through the usual message mechanism
37 $msgs = explode("\n%\n",$data);
38 foreach($msgs as $msg){
39 if($msg) msg($msg,2);
40 }
41 }
42
43
44 /**
25c07f9 @selfthinker added getVersionData() additionally to getVersion() to get version da…
selfthinker authored
45 * Return DokuWiki's version (split up in date and type)
c29dc6e @splitbrain updatecheck feature
authored
46 *
47 * @author Andreas Gohr <andi@splitbrain.org>
48 */
25c07f9 @selfthinker added getVersionData() additionally to getVersion() to get version da…
selfthinker authored
49 function getVersionData(){
50 $version = array();
db959ae @splitbrain Coding Standard Cleanup
authored
51 //import version string
52 if(@file_exists(DOKU_INC.'VERSION')){
53 //official release
25c07f9 @selfthinker added getVersionData() additionally to getVersion() to get version da…
selfthinker authored
54 $version['date'] = trim(io_readfile(DOKU_INC.'VERSION'));
55 $version['type'] = 'Release';
5cf3192 @splitbrain Read version from last Git log
authored
56 }elseif(is_dir(DOKU_INC.'.git')){
57 $version['type'] = 'Git';
58 $version['date'] = 'unknown';
afc5e13 @adrianheine Grab version from darcs correctly and simpler
adrianheine authored
59
5cf3192 @splitbrain Read version from last Git log
authored
60 $inventory = DOKU_INC.'.git/logs/HEAD';
61 if(is_file($inventory)){
62 $sz = filesize($inventory);
63 $seek = max(0,$sz-2000); // read from back of the file
64 $fh = fopen($inventory,'rb');
65 fseek($fh,$seek);
66 $chunk = fread($fh,2000);
67 fclose($fh);
68 $chunk = trim($chunk);
b838050 added new plugins config cascade and added plugin.info.txt
Piyush Mishra authored
69 $chunk = @array_pop(explode("\n",$chunk)); //last log line
70 $chunk = @array_shift(explode("\t",$chunk)); //strip commit msg
5cf3192 @splitbrain Read version from last Git log
authored
71 $chunk = explode(" ",$chunk);
72 array_pop($chunk); //strip timezone
73 $date = date('Y-m-d',array_pop($chunk));
74 if($date) $version['date'] = $date;
75 }
db959ae @splitbrain Coding Standard Cleanup
authored
76 }else{
25c07f9 @selfthinker added getVersionData() additionally to getVersion() to get version da…
selfthinker authored
77 $version['date'] = 'unknown';
78 $version['type'] = 'snapshot?';
db959ae @splitbrain Coding Standard Cleanup
authored
79 }
5cf3192 @splitbrain Read version from last Git log
authored
80 return $version;
c29dc6e @splitbrain updatecheck feature
authored
81 }
82
83 /**
25c07f9 @selfthinker added getVersionData() additionally to getVersion() to get version da…
selfthinker authored
84 * Return DokuWiki's version (as a string)
85 *
86 * @author Anika Henke <anika@selfthinker.org>
87 */
88 function getVersion(){
89 $version = getVersionData();
90 return $version['type'].' '.$version['date'];
91 }
92
93 /**
c29dc6e @splitbrain updatecheck feature
authored
94 * Run a few sanity checks
95 *
96 * @author Andreas Gohr <andi@splitbrain.org>
97 */
98 function check(){
db959ae @splitbrain Coding Standard Cleanup
authored
99 global $conf;
100 global $INFO;
101
3f803e5 @foosel FS#1878: Hide Dokuwiki version information from metadata and only sho…
foosel authored
102 if ($INFO['isadmin'] || $INFO['ismanager']){
103 msg('DokuWiki version: '.getVersion(),1);
104 }
db959ae @splitbrain Coding Standard Cleanup
authored
105
ab91da8 @splitbrain set required PHP release to 5.1.2
authored
106 if(version_compare(phpversion(),'5.1.2','<')){
107 msg('Your PHP version is too old ('.phpversion().' vs. 5.1.2+ needed)',-1);
db959ae @splitbrain Coding Standard Cleanup
authored
108 }else{
109 msg('PHP version '.phpversion(),1);
110 }
111
112 $mem = (int) php_to_byte(ini_get('memory_limit'));
113 if($mem){
114 if($mem < 16777216){
115 msg('PHP is limited to less than 16MB RAM ('.$mem.' bytes). Increase memory_limit in php.ini',-1);
116 }elseif($mem < 20971520){
117 msg('PHP is limited to less than 20MB RAM ('.$mem.' bytes), you might encounter problems with bigger pages. Increase memory_limit in php.ini',-1);
118 }elseif($mem < 33554432){
119 msg('PHP is limited to less than 32MB RAM ('.$mem.' bytes), but that should be enough in most cases. If not, increase memory_limit in php.ini',0);
120 }else{
121 msg('More than 32MB RAM ('.$mem.' bytes) available.',1);
122 }
123 }
124
125 if(is_writable($conf['changelog'])){
126 msg('Changelog is writable',1);
127 }else{
128 if (@file_exists($conf['changelog'])) {
129 msg('Changelog is not writable',-1);
130 }
131 }
132
133 if (isset($conf['changelog_old']) && @file_exists($conf['changelog_old'])) {
134 msg('Old changelog exists', 0);
135 }
136
137 if (@file_exists($conf['changelog'].'_failed')) {
138 msg('Importing old changelog failed', -1);
139 } else if (@file_exists($conf['changelog'].'_importing')) {
140 msg('Importing old changelog now.', 0);
141 } else if (@file_exists($conf['changelog'].'_import_ok')) {
142 msg('Old changelog imported', 1);
143 if (!plugin_isdisabled('importoldchangelog')) {
144 msg('Importoldchangelog plugin not disabled after import', -1);
145 }
146 }
147
148 if(is_writable($conf['datadir'])){
149 msg('Datadir is writable',1);
150 }else{
151 msg('Datadir is not writable',-1);
152 }
153
154 if(is_writable($conf['olddir'])){
155 msg('Attic is writable',1);
156 }else{
157 msg('Attic is not writable',-1);
158 }
159
160 if(is_writable($conf['mediadir'])){
161 msg('Mediadir is writable',1);
162 }else{
163 msg('Mediadir is not writable',-1);
164 }
165
166 if(is_writable($conf['cachedir'])){
167 msg('Cachedir is writable',1);
73038c4 @splitbrain Check memory settings on ?do
authored
168 }else{
db959ae @splitbrain Coding Standard Cleanup
authored
169 msg('Cachedir is not writable',-1);
73038c4 @splitbrain Check memory settings on ?do
authored
170 }
171
db959ae @splitbrain Coding Standard Cleanup
authored
172 if(is_writable($conf['lockdir'])){
173 msg('Lockdir is writable',1);
174 }else{
175 msg('Lockdir is not writable',-1);
176 }
73038c4 @splitbrain Check memory settings on ?do
authored
177
db959ae @splitbrain Coding Standard Cleanup
authored
178 if($conf['authtype'] == 'plain'){
defb7d5 @selfthinker fixed some missing config_cascade occurrences (FS#2235)
selfthinker authored
179 global $config_cascade;
180 if(is_writable($config_cascade['plainauth.users']['default'])){
db959ae @splitbrain Coding Standard Cleanup
authored
181 msg('conf/users.auth.php is writable',1);
182 }else{
183 msg('conf/users.auth.php is not writable',0);
184 }
c29dc6e @splitbrain updatecheck feature
authored
185 }
db959ae @splitbrain Coding Standard Cleanup
authored
186
187 if(function_exists('mb_strpos')){
188 if(defined('UTF8_NOMBSTRING')){
189 msg('mb_string extension is available but will not be used',0);
190 }else{
191 msg('mb_string extension is available and will be used',1);
192 if(ini_get('mbstring.func_overload') != 0){
193 msg('mb_string function overloading is enabled, this will cause problems and should be disabled',-1);
194 }
195 }
196 }else{
197 msg('mb_string extension not available - PHP only replacements will be used',0);
c29dc6e @splitbrain updatecheck feature
authored
198 }
db959ae @splitbrain Coding Standard Cleanup
authored
199
200 if($conf['allowdebug']){
201 msg('Debugging support is enabled. If you don\'t need it you should set $conf[\'allowdebug\'] = 0',-1);
0d487d8 @splitbrain no write check for users.auth.php when non-plain backend is used FS#1271
authored
202 }else{
db959ae @splitbrain Coding Standard Cleanup
authored
203 msg('Debugging support is disabled',1);
0d487d8 @splitbrain no write check for users.auth.php when non-plain backend is used FS#1271
authored
204 }
c29dc6e @splitbrain updatecheck feature
authored
205
db959ae @splitbrain Coding Standard Cleanup
authored
206 if($INFO['userinfo']['name']){
207 msg('You are currently logged in as '.$_SERVER['REMOTE_USER'].' ('.$INFO['userinfo']['name'].')',0);
208 msg('You are part of the groups '.join($INFO['userinfo']['grps'],', '),0);
c29dc6e @splitbrain updatecheck feature
authored
209 }else{
db959ae @splitbrain Coding Standard Cleanup
authored
210 msg('You are currently not logged in',0);
211 }
212
213 msg('Your current permission for this page is '.$INFO['perm'],0);
214
215 if(is_writable($INFO['filepath'])){
216 msg('The current page is writable by the webserver',0);
217 }else{
218 msg('The current page is not writable by the webserver',0);
219 }
220
221 if($INFO['writable']){
222 msg('The current page is writable by you',0);
223 }else{
224 msg('The current page is not writable by you',0);
225 }
226
227 $check = wl('','',true).'data/_dummy';
228 $http = new DokuHTTPClient();
229 $http->timeout = 6;
230 $res = $http->get($check);
231 if(strpos($res,'data directory') !== false){
232 msg('It seems like the data directory is accessible from the web.
233 Make sure this directory is properly protected
234 (See <a href="http://www.dokuwiki.org/security">security</a>)',-1);
235 }elseif($http->status == 404 || $http->status == 403){
236 msg('The data directory seems to be properly protected',1);
237 }else{
238 msg('Failed to check if the data directory is accessible from the web.
239 Make sure this directory is properly protected
240 (See <a href="http://www.dokuwiki.org/security">security</a>)',-1);
c29dc6e @splitbrain updatecheck feature
authored
241 }
26f7dbf @michitux Add a test to do=check that should detect search index corruption
michitux authored
242
243 // Check for corrupted search index
244 $lengths = idx_listIndexLengths();
245 $index_corrupted = false;
246 foreach ($lengths as $length) {
247 if (count(idx_getIndex('w', $length)) != count(idx_getIndex('i', $length))) {
248 $index_corrupted = true;
249 break;
250 }
251 }
252
253 foreach (idx_getIndex('metadata', '') as $index) {
254 if (count(idx_getIndex($index.'_w', '')) != count(idx_getIndex($index.'_i', ''))) {
255 $index_corrupted = true;
256 break;
257 }
258 }
259
260 if ($index_corrupted)
3d94d9e @michitux Fix the wording of the search index check messages
michitux authored
261 msg('The search index is corrupted. It might produce wrong results and most
262 probably needs to be rebuilt. See
26f7dbf @michitux Add a test to do=check that should detect search index corruption
michitux authored
263 <a href="http://www.dokuwiki.org/faq:searchindex">faq:searchindex</a>
3d94d9e @michitux Fix the wording of the search index check messages
michitux authored
264 for ways to rebuild the search index.', -1);
26f7dbf @michitux Add a test to do=check that should detect search index corruption
michitux authored
265 elseif (!empty($lengths))
3d94d9e @michitux Fix the wording of the search index check messages
michitux authored
266 msg('The search index seems to be working', 1);
26f7dbf @michitux Add a test to do=check that should detect search index corruption
michitux authored
267 else
3d94d9e @michitux Fix the wording of the search index check messages
michitux authored
268 msg('The search index is empty. See
26f7dbf @michitux Add a test to do=check that should detect search index corruption
michitux authored
269 <a href="http://www.dokuwiki.org/faq:searchindex">faq:searchindex</a>
3d94d9e @michitux Fix the wording of the search index check messages
michitux authored
270 for help on how to fix the search index. If the default indexer
271 isn\'t used or the wiki is actually empty this is normal.');
c29dc6e @splitbrain updatecheck feature
authored
272 }
273
274 /**
275 * print a message
276 *
277 * If HTTP headers were not sent yet the message is added
278 * to the global message array else it's printed directly
279 * using html_msgarea()
280 *
281 *
282 * Levels can be:
283 *
284 * -1 error
285 * 0 info
286 * 1 success
287 *
288 * @author Andreas Gohr <andi@splitbrain.org>
289 * @see html_msgarea
290 */
291 function msg($message,$lvl=0,$line='',$file=''){
cc58224 @michitux Fix msg() calls when messages have already been printed
michitux authored
292 global $MSG, $MSG_shown;
db959ae @splitbrain Coding Standard Cleanup
authored
293 $errors[-1] = 'error';
294 $errors[0] = 'info';
295 $errors[1] = 'success';
296 $errors[2] = 'notify';
297
298 if($line || $file) $message.=' ['.basename($file).':'.$line.']';
299
69266de @dom-mel fixed handling of MSG
dom-mel authored
300 if(!isset($MSG)) $MSG = array();
301 $MSG[]=array('lvl' => $errors[$lvl], 'msg' => $message);
cc58224 @michitux Fix msg() calls when messages have already been printed
michitux authored
302 if(isset($MSG_shown) || headers_sent()){
db959ae @splitbrain Coding Standard Cleanup
authored
303 if(function_exists('html_msgarea')){
304 html_msgarea();
305 }else{
306 print "ERROR($lvl) $message";
307 }
69266de @dom-mel fixed handling of MSG
dom-mel authored
308 unset($GLOBALS['MSG']);
c29dc6e @splitbrain updatecheck feature
authored
309 }
310 }
311
312 /**
313 * print debug messages
314 *
315 * little function to print the content of a var
316 *
317 * @author Andreas Gohr <andi@splitbrain.org>
318 */
319 function dbg($msg,$hidden=false){
1349379 @splitbrain run dbg() output through htmlspecialchars
authored
320 if($hidden){
321 echo "<!--\n";
322 print_r($msg);
323 echo "\n-->";
324 }else{
325 echo '<pre class="dbg">';
326 echo hsc(print_r($msg,true));
327 echo '</pre>';
328 }
c29dc6e @splitbrain updatecheck feature
authored
329 }
330
331 /**
332 * Print info to a log file
333 *
334 * @author Andreas Gohr <andi@splitbrain.org>
335 */
0699d73 @splitbrain optional additional header for dbglog()
authored
336 function dbglog($msg,$header=''){
db959ae @splitbrain Coding Standard Cleanup
authored
337 global $conf;
5bd930f @michitux Write the debug log only when debugging is enabled
michitux authored
338 // The debug log isn't automatically cleaned thus only write it when
339 // debugging has been enabled by the user.
340 if($conf['allowdebug'] !== 1) return;
db959ae @splitbrain Coding Standard Cleanup
authored
341 if(is_object($msg) || is_array($msg)){
342 $msg = print_r($msg,true);
343 }
344
345 if($header) $msg = "$header\n$msg";
346
347 $file = $conf['cachedir'].'/debug.log';
348 $fh = fopen($file,'a');
349 if($fh){
350 fwrite($fh,date('H:i:s ').$_SERVER['REMOTE_ADDR'].': '.$msg."\n");
351 fclose($fh);
352 }
c29dc6e @splitbrain updatecheck feature
authored
353 }
354
db09e31 @splitbrain dbg_backtrace() function added
authored
355 /**
356 * Print a reversed, prettyprinted backtrace
357 *
358 * @author Gary Owen <gary_owen@bigfoot.com>
359 */
360 function dbg_backtrace(){
db959ae @splitbrain Coding Standard Cleanup
authored
361 // Get backtrace
362 $backtrace = debug_backtrace();
363
364 // Unset call to debug_print_backtrace
365 array_shift($backtrace);
366
367 // Iterate backtrace
368 $calls = array();
369 $depth = count($backtrace) - 1;
370 foreach ($backtrace as $i => $call) {
371 $location = $call['file'] . ':' . $call['line'];
372 $function = (isset($call['class'])) ?
373 $call['class'] . $call['type'] . $call['function'] : $call['function'];
374
375 $params = array();
376 if (isset($call['args'])){
377 foreach($call['args'] as $arg){
378 if(is_object($arg)){
379 $params[] = '[Object '.get_class($arg).']';
380 }elseif(is_array($arg)){
381 $params[] = '[Array]';
382 }elseif(is_null($arg)){
383 $param[] = '[NULL]';
384 }else{
385 $params[] = (string) '"'.$arg.'"';
386 }
8259f1a @splitbrain fix dbg_backtrace when arguments are an array or object
authored
387 }
388 }
db959ae @splitbrain Coding Standard Cleanup
authored
389 $params = implode(', ',$params);
db09e31 @splitbrain dbg_backtrace() function added
authored
390
db959ae @splitbrain Coding Standard Cleanup
authored
391 $calls[$depth - $i] = sprintf('%s(%s) called at %s',
392 $function,
393 str_replace("\n", '\n', $params),
394 $location);
395 }
396 ksort($calls);
db09e31 @splitbrain dbg_backtrace() function added
authored
397
db959ae @splitbrain Coding Standard Cleanup
authored
398 return implode("\n", $calls);
db09e31 @splitbrain dbg_backtrace() function added
authored
399 }
400
24297a6 @splitbrain remove sensitive data from debug output more aggressively
authored
401 /**
402 * Remove all data from an array where the key seems to point to sensitive data
403 *
404 * This is used to remove passwords, mail addresses and similar data from the
405 * debug output
406 *
407 * @author Andreas Gohr <andi@splitbrain.org>
408 */
409 function debug_guard(&$data){
410 foreach($data as $key => $value){
411 if(preg_match('/(notify|pass|auth|secret|ftp|userinfo|token|buid|mail|proxy)/i',$key)){
412 $data[$key] = '***';
413 continue;
414 }
415 if(is_array($value)) debug_guard($data[$key]);
416 }
417 }
Something went wrong with that request. Please try again.