1<?php 2/** 3 * Common DokuWiki functions 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9 if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/'); 10 require_once(DOKU_INC.'conf/dokuwiki.php'); 11 require_once(DOKU_INC.'inc/io.php'); 12 require_once(DOKU_INC.'inc/utf8.php'); 13 require_once(DOKU_INC.'inc/mail.php'); 14 require_once(DOKU_INC.'inc/parserutils.php'); 15 16/** 17 * Return info about the current document as associative 18 * array. 19 * 20 * @author Andreas Gohr <andi@splitbrain.org> 21 */ 22function pageinfo(){ 23 global $ID; 24 global $REV; 25 global $USERINFO; 26 global $conf; 27 28 if($_SERVER['REMOTE_USER']){ 29 $info['user'] = $_SERVER['REMOTE_USER']; 30 $info['userinfo'] = $USERINFO; 31 $info['perm'] = auth_quickaclcheck($ID); 32 }else{ 33 $info['user'] = ''; 34 $info['perm'] = auth_aclcheck($ID,'',null); 35 } 36 37 $info['namespace'] = getNS($ID); 38 $info['locked'] = checklock($ID); 39 $info['filepath'] = realpath(wikiFN($ID,$REV)); 40 $info['exists'] = @file_exists($info['filepath']); 41 if($REV && !$info['exists']){ 42 //check if current revision was meant 43 $cur = wikiFN($ID); 44 if(@file_exists($cur) && (@filemtime($cur) == $REV)){ 45 $info['filepath'] = realpath($cur); 46 $info['exists'] = true; 47 $REV = ''; 48 } 49 } 50 $info['rev'] = $REV; 51 if($info['exists']){ 52 $info['writable'] = (is_writable($info['filepath']) && 53 ($info['perm'] >= AUTH_EDIT)); 54 }else{ 55 $info['writable'] = ($info['perm'] >= AUTH_CREATE); 56 } 57 $info['editable'] = ($info['writable'] && empty($info['lock'])); 58 $info['lastmod'] = @filemtime($info['filepath']); 59 60 //who's the editor 61 if($REV){ 62 $revinfo = getRevisionInfo($ID,$REV); 63 }else{ 64 $revinfo = getRevisionInfo($ID,$info['lastmod']); 65 } 66 $info['ip'] = $revinfo['ip']; 67 $info['user'] = $revinfo['user']; 68 $info['sum'] = $revinfo['sum']; 69 $info['editor'] = $revinfo['ip']; 70 if($revinfo['user']){ 71 $info['editor'] = $revinfo['user']; 72 }else{ 73 $info['editor'] = $revinfo['ip']; 74 } 75 76 return $info; 77} 78 79/** 80 * print a message 81 * 82 * If HTTP headers were not sent yet the message is added 83 * to the global message array else it's printed directly 84 * using html_msgarea() 85 * 86 * 87 * Levels can be: 88 * 89 * -1 error 90 * 0 info 91 * 1 success 92 * 93 * @author Andreas Gohr <andi@splitbrain.org> 94 * @see html_msgarea 95 */ 96function msg($message,$lvl=0){ 97 global $MSG; 98 $errors[-1] = 'error'; 99 $errors[0] = 'info'; 100 $errors[1] = 'success'; 101 102 if(!headers_sent()){ 103 if(!isset($MSG)) $MSG = array(); 104 $MSG[]=array('lvl' => $errors[$lvl], 'msg' => $message); 105 }else{ 106 $MSG = array(); 107 $MSG[]=array('lvl' => $errors[$lvl], 'msg' => $message); 108 if(function_exists('html_msgarea')){ 109 html_msgarea(); 110 }else{ 111 print "ERROR($lvl) $message"; 112 } 113 } 114} 115 116/** 117 * This builds the breadcrumb trail and returns it as array 118 * 119 * @author Andreas Gohr <andi@splitbrain.org> 120 */ 121function breadcrumbs(){ 122 global $ID; 123 global $ACT; 124 global $conf; 125 $crumbs = $_SESSION[$conf['title']]['bc']; 126 127 //first visit? 128 if (!is_array($crumbs)){ 129 $crumbs = array(); 130 } 131 //we only save on show and existing wiki documents 132 $file = wikiFN($ID); 133 if($ACT != 'show' || !@file_exists($file)){ 134 $_SESSION[$conf['title']]['bc'] = $crumbs; 135 return $crumbs; 136 } 137 138 // page names 139 $name = noNS($ID); 140 if ($conf['useheading']) { 141 // get page title 142 $title = p_get_first_heading($ID); 143 if ($title) { 144 $name = $title; 145 } 146 } 147 148 //remove ID from array 149 if (isset($crumbs[$ID])) { 150 unset($crumbs[$ID]); 151 } 152 153 //add to array 154 $crumbs[$ID] = $name; 155 //reduce size 156 while(count($crumbs) > $conf['breadcrumbs']){ 157 array_shift($crumbs); 158 } 159 //save to session 160 $_SESSION[$conf['title']]['bc'] = $crumbs; 161 return $crumbs; 162} 163 164/** 165 * Filter for page IDs 166 * 167 * This is run on a ID before it is outputted somewhere 168 * currently used to replace the colon with something else 169 * on Windows systems and to have proper URL encoding 170 * 171 * Urlencoding is ommitted when the second parameter is false 172 * 173 * @author Andreas Gohr <andi@splitbrain.org> 174 */ 175function idfilter($id,$ue=true){ 176 global $conf; 177 if ($conf['useslash'] && $conf['userewrite']){ 178 $id = strtr($id,':','/'); 179 }elseif (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && 180 $conf['userewrite']) { 181 $id = strtr($id,':',';'); 182 } 183 if($ue){ 184 $id = urlencode($id); 185 $id = str_replace('%3A',':',$id); //keep as colon 186 $id = str_replace('%2F','/',$id); //keep as slash 187 } 188 return $id; 189} 190 191/** 192 * This builds a link to a wikipage 193 * 194 * It handles URL rewriting and adds additional parameter if 195 * given in $more 196 * 197 * @author Andreas Gohr <andi@splitbrain.org> 198 */ 199function wl($id='',$more='',$abs=false){ 200 global $conf; 201 $more = str_replace(',','&',$more); 202 203 $id = idfilter($id); 204 if($abs){ 205 $xlink = DOKU_URL; 206 }else{ 207 $xlink = DOKU_BASE; 208 } 209 210 if($conf['userewrite'] == 2){ 211 $xlink .= DOKU_SCRIPT.'/'.$id; 212 if($more) $xlink .= '?'.$more; 213 }elseif($conf['userewrite']){ 214 $xlink .= $id; 215 if($more) $xlink .= '?'.$more; 216 }else{ 217 $xlink .= DOKU_SCRIPT.'?id='.$id; 218 if($more) $xlink .= '&'.$more; 219 } 220 221 return $xlink; 222} 223 224/** 225 * Just builds a link to a script 226 * 227 * @todo maybe obsolete 228 * @author Andreas Gohr <andi@splitbrain.org> 229 */ 230function script($script='doku.php'){ 231# $link = getBaseURL(); 232# $link .= $script; 233# return $link; 234 return DOKU_BASE.DOKU_SCRIPT; 235} 236 237/** 238 * Spamcheck against wordlist 239 * 240 * Checks the wikitext against a list of blocked expressions 241 * returns true if the text contains any bad words 242 * 243 * @author Andreas Gohr <andi@splitbrain.org> 244 */ 245function checkwordblock(){ 246 global $TEXT; 247 global $conf; 248 249 if(!$conf['usewordblock']) return false; 250 251 $blockfile = file(DOKU_INC.'conf/wordblock.conf'); 252 //how many lines to read at once (to work around some PCRE limits) 253 if(version_compare(phpversion(),'4.3.0','<')){ 254 //old versions of PCRE define a maximum of parenthesises even if no 255 //backreferences are used - the maximum is 99 256 //this is very bad performancewise and may even be too high still 257 $chunksize = 40; 258 }else{ 259 //read file in chunks of 600 - this should work around the 260 //MAX_PATTERN_SIZE in modern PCRE 261 $chunksize = 600; 262 } 263 while($blocks = array_splice($blockfile,0,$chunksize)){ 264 $re = array(); 265 #build regexp from blocks 266 foreach($blocks as $block){ 267 $block = preg_replace('/#.*$/','',$block); 268 $block = trim($block); 269 if(empty($block)) continue; 270 $re[] = $block; 271 } 272 if(preg_match('#('.join('|',$re).')#si',$TEXT)) return true; 273 } 274 return false; 275} 276 277/** 278 * Return the IP of the client 279 * 280 * Honours X-Forwarded-For Proxy Headers 281 * 282 * @author Andreas Gohr <andi@splitbrain.org> 283 */ 284function clientIP(){ 285 $my = $_SERVER['REMOTE_ADDR']; 286 if($_SERVER['HTTP_X_FORWARDED_FOR']){ 287 $my .= ' ('.$_SERVER['HTTP_X_FORWARDED_FOR'].')'; 288 } 289 return $my; 290} 291 292/** 293 * Checks if a given page is currently locked. 294 * 295 * removes stale lockfiles 296 * 297 * @author Andreas Gohr <andi@splitbrain.org> 298 */ 299function checklock($id){ 300 global $conf; 301 $lock = wikiFN($id).'.lock'; 302 303 //no lockfile 304 if(!@file_exists($lock)) return false; 305 306 //lockfile expired 307 if((time() - filemtime($lock)) > $conf['locktime']){ 308 unlink($lock); 309 return false; 310 } 311 312 //my own lock 313 $ip = io_readFile($lock); 314 if( ($ip == clientIP()) || ($ip == $_SERVER['REMOTE_USER']) ){ 315 return false; 316 } 317 318 return $ip; 319} 320 321/** 322 * Lock a page for editing 323 * 324 * @author Andreas Gohr <andi@splitbrain.org> 325 */ 326function lock($id){ 327 $lock = wikiFN($id).'.lock'; 328 if($_SERVER['REMOTE_USER']){ 329 io_saveFile($lock,$_SERVER['REMOTE_USER']); 330 }else{ 331 io_saveFile($lock,clientIP()); 332 } 333} 334 335/** 336 * Unlock a page if it was locked by the user 337 * 338 * @author Andreas Gohr <andi@splitbrain.org> 339 * @return bool true if a lock was removed 340 */ 341function unlock($id){ 342 $lock = wikiFN($id).'.lock'; 343 if(@file_exists($lock)){ 344 $ip = io_readFile($lock); 345 if( ($ip == clientIP()) || ($ip == $_SERVER['REMOTE_USER']) ){ 346 @unlink($lock); 347 return true; 348 } 349 } 350 return false; 351} 352 353/** 354 * convert line ending to unix format 355 * 356 * @see formText() for 2crlf conversion 357 * @author Andreas Gohr <andi@splitbrain.org> 358 */ 359function cleanText($text){ 360 $text = preg_replace("/(\015\012)|(\015)/","\012",$text); 361 return $text; 362} 363 364/** 365 * Prepares text for print in Webforms by encoding special chars. 366 * It also converts line endings to Windows format which is 367 * pseudo standard for webforms. 368 * 369 * @see cleanText() for 2unix conversion 370 * @author Andreas Gohr <andi@splitbrain.org> 371 */ 372function formText($text){ 373 $text = preg_replace("/\012/","\015\012",$text); 374 return htmlspecialchars($text); 375} 376 377/** 378 * Returns the specified local text in raw format 379 * 380 * @author Andreas Gohr <andi@splitbrain.org> 381 */ 382function rawLocale($id){ 383 return io_readFile(localeFN($id)); 384} 385 386/** 387 * Returns the raw WikiText 388 * 389 * @author Andreas Gohr <andi@splitbrain.org> 390 */ 391function rawWiki($id,$rev=''){ 392 return io_readFile(wikiFN($id,$rev)); 393} 394 395/** 396 * Returns the raw Wiki Text in three slices. 397 * 398 * The range parameter needs to have the form "from-to" 399 * and gives the range of the section in bytes - no 400 * UTF-8 awareness is needed. 401 * The returned order is prefix, section and suffix. 402 * 403 * @author Andreas Gohr <andi@splitbrain.org> 404 */ 405function rawWikiSlices($range,$id,$rev=''){ 406 list($from,$to) = split('-',$range,2); 407 $text = io_readFile(wikiFN($id,$rev)); 408 if(!$from) $from = 0; 409 if(!$to) $to = strlen($text)+1; 410 411 $slices[0] = substr($text,0,$from-1); 412 $slices[1] = substr($text,$from-1,$to-$from); 413 $slices[2] = substr($text,$to); 414 415 return $slices; 416} 417 418/** 419 * Joins wiki text slices 420 * 421 * function to join the text slices with correct lineendings again. 422 * When the pretty parameter is set to true it adds additional empty 423 * lines between sections if needed (used on saving). 424 * 425 * @author Andreas Gohr <andi@splitbrain.org> 426 */ 427function con($pre,$text,$suf,$pretty=false){ 428 429 if($pretty){ 430 if($pre && substr($pre,-1) != "\n") $pre .= "\n"; 431 if($suf && substr($text,-1) != "\n") $text .= "\n"; 432 } 433 434 if($pre) $pre .= "\n"; 435 if($suf) $text .= "\n"; 436 return $pre.$text.$suf; 437} 438 439/** 440 * print debug messages 441 * 442 * little function to print the content of a var 443 * 444 * @author Andreas Gohr <andi@splitbrain.org> 445 */ 446function dbg($msg,$hidden=false){ 447 (!$hidden) ? print '<pre class="dbg">' : print "<!--\n"; 448 print_r($msg); 449 (!$hidden) ? print '</pre>' : print "\n-->"; 450} 451 452/** 453 * Add's an entry to the changelog 454 * 455 * @author Andreas Gohr <andi@splitbrain.org> 456 */ 457function addLogEntry($date,$id,$summary=""){ 458 global $conf; 459 $id = cleanID($id);//FIXME not needed anymore? 460 461 if(!@is_writable($conf['changelog'])){ 462 msg($conf['changelog'].' is not writable!',-1); 463 return; 464 } 465 466 if(!$date) $date = time(); //use current time if none supplied 467 $remote = $_SERVER['REMOTE_ADDR']; 468 $user = $_SERVER['REMOTE_USER']; 469 470 $logline = join("\t",array($date,$remote,$id,$user,$summary))."\n"; 471 472 //FIXME: use adjusted io_saveFile instead 473 $fh = fopen($conf['changelog'],'a'); 474 if($fh){ 475 fwrite($fh,$logline); 476 fclose($fh); 477 } 478} 479 480/** 481 * returns an array of recently changed files using the 482 * changelog 483 * first : first entry in array returned 484 * num : return 'num' entries 485 * 486 * @author Andreas Gohr <andi@splitbrain.org> 487 */ 488function getRecents($first,$num,$incdel=false){ 489 global $conf; 490 $recent = array(); 491 $names = array(); 492 493 if(!$num) 494 return $recent; 495 496 if(!@is_readable($conf['changelog'])){ 497 msg($conf['changelog'].' is not readable',-1); 498 return $recent; 499 } 500 501 $loglines = file($conf['changelog']); 502 rsort($loglines); //reverse sort on timestamp 503 504 foreach ($loglines as $line){ 505 $line = rtrim($line); //remove newline 506 if(empty($line)) continue; //skip empty lines 507 $info = split("\t",$line); //split into parts 508 //add id if not in yet and file still exists and is allowed to read 509 if(!$names[$info[2]] && 510 (@file_exists(wikiFN($info[2])) || $incdel) && 511 (auth_quickaclcheck($info[2]) >= AUTH_READ) 512 ){ 513 $names[$info[2]] = 1; 514 if(--$first >= 0) continue; /* skip "first" entries */ 515 516 $recent[$info[2]]['date'] = $info[0]; 517 $recent[$info[2]]['ip'] = $info[1]; 518 $recent[$info[2]]['user'] = $info[3]; 519 $recent[$info[2]]['sum'] = $info[4]; 520 $recent[$info[2]]['del'] = !@file_exists(wikiFN($info[2])); 521 } 522 if(count($recent) >= $num){ 523 break; //finish if enough items found 524 } 525 } 526 return $recent; 527} 528 529/** 530 * gets additonal informations for a certain pagerevison 531 * from the changelog 532 * 533 * @author Andreas Gohr <andi@splitbrain.org> 534 */ 535function getRevisionInfo($id,$rev){ 536 global $conf; 537 538 if(!$rev) return(null); 539 540 $info = array(); 541 if(!@is_readable($conf['changelog'])){ 542 msg($conf['changelog'].' is not readable',-1); 543 return $recent; 544 } 545 $loglines = file($conf['changelog']); 546 $loglines = preg_grep("/$rev\t\d+\.\d+\.\d+\.\d+\t$id\t/",$loglines); 547 $loglines = array_reverse($loglines); //reverse sort on timestamp (shouldn't be needed) 548 $line = split("\t",$loglines[0]); 549 $info['date'] = $line[0]; 550 $info['ip'] = $line[1]; 551 $info['user'] = $line[3]; 552 $info['sum'] = $line[4]; 553 return $info; 554} 555 556/** 557 * Saves a wikitext by calling io_saveFile 558 * 559 * @author Andreas Gohr <andi@splitbrain.org> 560 */ 561function saveWikiText($id,$text,$summary){ 562 global $conf; 563 global $lang; 564 umask($conf['umask']); 565 // ignore if no changes were made 566 if($text == rawWiki($id,'')){ 567 return; 568 } 569 570 $file = wikiFN($id); 571 $old = saveOldRevision($id); 572 573 if (empty($text)){ 574 // remove empty files 575 @unlink($file); 576 $del = true; 577 //autoset summary on deletion 578 if(empty($summary)) $summary = $lang['deleted']; 579 //remove empty namespaces 580 io_sweepNS($id); 581 }else{ 582 // save file (datadir is created in io_saveFile) 583 io_saveFile($file,$text); 584 $del = false; 585 } 586 587 addLogEntry(@filemtime($file),$id,$summary); 588 notify($id,$old,$summary); 589 590 //purge cache on add by updating the purgefile 591 if($conf['purgeonadd'] && (!$old || $del)){ 592 io_saveFile($conf['datadir'].'/_cache/purgefile',time()); 593 } 594} 595 596/** 597 * moves the current version to the attic and returns its 598 * revision date 599 * 600 * @author Andreas Gohr <andi@splitbrain.org> 601 */ 602function saveOldRevision($id){ 603 global $conf; 604 umask($conf['umask']); 605 $oldf = wikiFN($id); 606 if(!@file_exists($oldf)) return ''; 607 $date = filemtime($oldf); 608 $newf = wikiFN($id,$date); 609 if(substr($newf,-3)=='.gz'){ 610 io_saveFile($newf,rawWiki($id)); 611 }else{ 612 io_makeFileDir($newf); 613 copy($oldf, $newf); 614 } 615 return $date; 616} 617 618/** 619 * Sends a notify mail to the wikiadmin when a page was 620 * changed 621 * 622 * @author Andreas Gohr <andi@splitbrain.org> 623 */ 624function notify($id,$rev="",$summary=""){ 625 global $lang; 626 global $conf; 627 $hdrs =''; 628 if(empty($conf['notify'])) return; //notify enabled? 629 630 $text = rawLocale('mailtext'); 631 $text = str_replace('@DATE@',date($conf['dformat']),$text); 632 $text = str_replace('@BROWSER@',$_SERVER['HTTP_USER_AGENT'],$text); 633 $text = str_replace('@IPADDRESS@',$_SERVER['REMOTE_ADDR'],$text); 634 $text = str_replace('@HOSTNAME@',gethostbyaddr($_SERVER['REMOTE_ADDR']),$text); 635 $text = str_replace('@NEWPAGE@',wl($id,'',true),$text); 636 $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text); 637 $text = str_replace('@SUMMARY@',$summary,$text); 638 $text = str_replace('@USER@',$_SERVER['REMOTE_USER'],$text); 639 640 if($rev){ 641 $subject = $lang['mail_changed'].' '.$id; 642 $text = str_replace('@OLDPAGE@',wl($id,"rev=$rev",true),$text); 643 require_once("inc/DifferenceEngine.php"); 644 $df = new Diff(split("\n",rawWiki($id,$rev)), 645 split("\n",rawWiki($id))); 646 $dformat = new UnifiedDiffFormatter(); 647 $diff = $dformat->format($df); 648 }else{ 649 $subject=$lang['mail_newpage'].' '.$id; 650 $text = str_replace('@OLDPAGE@','none',$text); 651 $diff = rawWiki($id); 652 } 653 $text = str_replace('@DIFF@',$diff,$text); 654 655 mail_send($conf['notify'],$subject,$text,$conf['mailfrom']); 656} 657 658/** 659 * Return a list of available page revisons 660 * 661 * @author Andreas Gohr <andi@splitbrain.org> 662 */ 663function getRevisions($id){ 664 $revd = dirname(wikiFN($id,'foo')); 665 $revs = array(); 666 $clid = cleanID($id); 667 if(strrpos($clid,':')) $clid = substr($clid,strrpos($clid,':')+1); //remove path 668 669 if (is_dir($revd) && $dh = opendir($revd)) { 670 while (($file = readdir($dh)) !== false) { 671 if (is_dir($revd.'/'.$file)) continue; 672 if (preg_match('/^'.$clid.'\.(\d+)\.txt(\.gz)?$/',$file,$match)){ 673 $revs[]=$match[1]; 674 } 675 } 676 closedir($dh); 677 } 678 rsort($revs); 679 return $revs; 680} 681 682/** 683 * extracts the query from a google referer 684 * 685 * @todo should be more generic and support yahoo et al 686 * @author Andreas Gohr <andi@splitbrain.org> 687 */ 688function getGoogleQuery(){ 689 $url = parse_url($_SERVER['HTTP_REFERER']); 690 691 if(!preg_match("#google\.#i",$url['host'])) return ''; 692 $query = array(); 693 parse_str($url['query'],$query); 694 695 return $query['q']; 696} 697 698/** 699 * Try to set correct locale 700 * 701 * @deprecated No longer used 702 * @author Andreas Gohr <andi@splitbrain.org> 703 */ 704function setCorrectLocale(){ 705 global $conf; 706 global $lang; 707 708 $enc = strtoupper($lang['encoding']); 709 foreach ($lang['locales'] as $loc){ 710 //try locale 711 if(@setlocale(LC_ALL,$loc)) return; 712 //try loceale with encoding 713 if(@setlocale(LC_ALL,"$loc.$enc")) return; 714 } 715 //still here? try to set from environment 716 @setlocale(LC_ALL,""); 717} 718 719/** 720 * Return the human readable size of a file 721 * 722 * @param int $size A file size 723 * @param int $dec A number of decimal places 724 * @author Martin Benjamin <b.martin@cybernet.ch> 725 * @author Aidan Lister <aidan@php.net> 726 * @version 1.0.0 727 */ 728function filesize_h($size, $dec = 1){ 729 $sizes = array('B', 'KB', 'MB', 'GB'); 730 $count = count($sizes); 731 $i = 0; 732 733 while ($size >= 1024 && ($i < $count - 1)) { 734 $size /= 1024; 735 $i++; 736 } 737 738 return round($size, $dec) . ' ' . $sizes[$i]; 739} 740 741/** 742 * Run a few sanity checks 743 * 744 * @author Andreas Gohr <andi@splitbrain.org> 745 */ 746function getVersion(){ 747 //import version string 748 if(@file_exists('VERSION')){ 749 //official release 750 return 'Release '.trim(io_readfile('VERSION')); 751 }elseif(is_dir('_darcs')){ 752 //darcs checkout 753 $inv = file('_darcs/inventory'); 754 $inv = preg_grep('#andi@splitbrain\.org\*\*\d{14}#',$inv); 755 $cur = array_pop($inv); 756 preg_match('#\*\*(\d{4})(\d{2})(\d{2})#',$cur,$matches); 757 return 'Darcs '.$matches[1].'-'.$matches[2].'-'.$matches[3]; 758 }else{ 759 return 'snapshot?'; 760 } 761} 762 763/** 764 * Run a few sanity checks 765 * 766 * @author Andreas Gohr <andi@splitbrain.org> 767 */ 768function check(){ 769 global $conf; 770 global $INFO; 771 772 msg('DokuWiki version: '.getVersion(),1); 773 774 if(version_compare(phpversion(),'4.3.0','<')){ 775 msg('Your PHP version is too old ('.phpversion().' vs. 4.3.+ recommended)',-1); 776 }elseif(version_compare(phpversion(),'4.3.10','<')){ 777 msg('Consider upgrading PHP to 4.3.10 or higher for security reasons (your version: '.phpversion().')',0); 778 }else{ 779 msg('PHP version '.phpversion(),1); 780 } 781 782 if(is_writable($conf['changelog'])){ 783 msg('Changelog is writable',1); 784 }else{ 785 msg('Changelog is not writable',-1); 786 } 787 788 if(is_writable($conf['datadir'])){ 789 msg('Datadir is writable',1); 790 }else{ 791 msg('Datadir is not writable',-1); 792 } 793 794 if(is_writable($conf['olddir'])){ 795 msg('Attic is writable',1); 796 }else{ 797 msg('Attic is not writable',-1); 798 } 799 800 if(is_writable($conf['mediadir'])){ 801 msg('Mediadir is writable',1); 802 }else{ 803 msg('Mediadir is not writable',-1); 804 } 805 806 if(is_writable(DOKU_INC.'conf/users.auth.php')){ 807 msg('conf/users.auth.php is writable',1); 808 }else{ 809 msg('conf/users.auth.php is not writable',0); 810 } 811 812 if(function_exists('mb_strpos')){ 813 if(defined('UTF8_NOMBSTRING')){ 814 msg('mb_string extension is available but will not be used',0); 815 }else{ 816 msg('mb_string extension is available and will be used',1); 817 } 818 }else{ 819 msg('mb_string extension not available - PHP only replacements will be used',0); 820 } 821 822 msg('Your current permission for this page is '.$INFO['perm'],0); 823 824 if(is_writable($INFO['filepath'])){ 825 msg('The current page is writable by the webserver',0); 826 }else{ 827 msg('The current page is not writable by the webserver',0); 828 } 829 830 if($INFO['writable']){ 831 msg('The current page is writable by you',0); 832 }else{ 833 msg('The current page is not writable you',0); 834 } 835} 836 837 838//Setup VIM: ex: et ts=2 enc=utf-8 : 839