1<?php 2/** 3 * File IO 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.'inc/common.php'); 11 require_once(DOKU_INC.'inc/parser.php'); 12 13/** 14 * Returns the parsed text from the given sourcefile. Uses cache 15 * if exists. Creates it if not. 16 * 17 * @author Andreas Gohr <andi@splitbrain.org> 18 */ 19function io_cacheParse($file){ 20 global $conf; 21 global $CACHEGROUP; 22 global $parser; //we read parser options 23 $parsed = ''; 24 $cache = $conf['datadir'].'/_cache/'; 25 $cache .= md5($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].$CACHEGROUP); 26 $purge = $conf['datadir'].'/_cache/purgefile'; 27 28 // check if cache can be used 29 $cachetime = @filemtime($cache); 30 31 if( @file_exists($cache) // does the cachefile exist 32 && @file_exists($file) // and does the source exist 33 && !isset($_REQUEST['purge']) // no purge param was set 34 && filesize($cache) // and contains the cachefile any data 35 && ((time() - $cachetime) < $conf['cachetime']) // and is cachefile young enough 36 && ($cachetime > filemtime($file)) // and newer than the source 37 && ($cachetime > @filemtime($purge)) // and newer than the purgefile 38 && ($cachetime > filemtime('conf/dokuwiki.php')) // and newer than the config file 39 && ($cachetime > @filemtime('conf/local.php')) // and newer than the local config file 40 && ($cachetime > filemtime('inc/parser.php')) // and newer than the parser 41 && ($cachetime > filemtime('inc/format.php'))) // and newer than the formating functions 42 { 43 $parsed = io_readFile($cache); //give back cache 44 $parsed .= "\n<!-- cachefile $cache used -->\n"; 45 }elseif(@file_exists($file)){ 46 $parsed = parse(io_readFile($file)); //sets global parseroptions 47 if($parser['cache']){ 48 io_saveFile($cache,$parsed); //save cachefile 49 $parsed .= "\n<!-- no cachefile used, but created -->\n"; 50 }else{ 51 @unlink($cache); //try to delete cachefile 52 $parsed .= "\n<!-- no cachefile used, caching forbidden -->\n"; 53 } 54 } 55 56 return $parsed; 57} 58 59/** 60 * Removes empty directories 61 * 62 * @todo use safemode hack 63 * @author Andreas Gohr <andi@splitbrain.org> 64 */ 65function io_sweepNS($id){ 66 global $conf; 67 68 //scan all namespaces 69 while(($id = getNS($id)) !== false){ 70 $dir = $conf['datadir'].'/'.str_replace(':','/',$id); 71 $dir = utf8_encodeFN($dir); 72 73 //try to delete dir else return 74 if(!@rmdir($dir)) return; 75 } 76} 77 78/** 79 * Returns content of $file as cleaned string. 80 * 81 * Uses gzip if extension is .gz 82 * 83 * @author Andreas Gohr <andi@splitbrain.org> 84 */ 85function io_readFile($file){ 86 $ret = ''; 87 if(@file_exists($file)){ 88 if(substr($file,-3) == '.gz'){ 89 $ret = join('',gzfile($file)); 90 }else{ 91 $ret = join('',file($file)); 92 } 93 } 94 return cleanText($ret); 95} 96 97/** 98 * Saves $content to $file. 99 * 100 * Uses gzip if extension is .gz 101 * 102 * @author Andreas Gohr <andi@splitbrain.org> 103 * @return bool true on success 104 */ 105function io_saveFile($file,$content){ 106 io_makeFileDir($file); 107 if(substr($file,-3) == '.gz'){ 108 $fh = @gzopen($file,'wb9'); 109 if(!$fh){ 110 msg("Writing $file failed",-1); 111 return false; 112 } 113 gzwrite($fh, $content); 114 gzclose($fh); 115 }else{ 116 $fh = @fopen($file,'wb'); 117 if(!$fh){ 118 msg("Writing $file failed",-1); 119 return false; 120 } 121 fwrite($fh, $content); 122 fclose($fh); 123 } 124 return true; 125} 126 127/** 128 * Create the directory needed for the given file 129 * 130 * @author Andreas Gohr <andi@splitbrain.org> 131 */ 132function io_makeFileDir($file){ 133 global $conf; 134 135 $dir = dirname($file); 136 if($conf['safemodehack']){ 137 preg_replace('/^'.preg_quote(realpath($conf['ftp']['root']),'/').'/','',$dir); 138 } 139 umask($conf['dmask']); 140 if(!is_dir($dir)){ 141 io_mkdir_p($dir) || msg("Creating directory $dir failed",-1); 142 } 143 umask($conf['umask']); 144} 145 146/** 147 * Creates a directory hierachy. 148 * 149 * @link http://www.php.net/manual/en/function.mkdir.php 150 * @author <saint@corenova.com> 151 * @author Andreas Gohr <andi@splitbrain.org> 152 */ 153function io_mkdir_p($target){ 154 global $conf; 155 if (is_dir($target)||empty($target)) return 1; // best case check first 156 if (@file_exists($target) && !is_dir($target)) return 0; 157 //recursion 158 if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){ 159 if($conf['safemodehack']){ 160 return io_mkdir_ftp($target); 161 }else{ 162 return @mkdir($target,0777); // crawl back up & create dir tree 163 } 164 } 165 return 0; 166} 167 168/** 169 * Creates a directory using FTP 170 * 171 * This is used when the safemode workaround is enabled 172 * 173 * @author <andi@splitbrain.org> 174 */ 175function io_mkdir_ftp($dir){ 176 global $conf; 177 178 if(!function_exists('ftp_connect')){ 179 msg("FTP support not found - safemode workaround not usable",-1); 180 return false; 181 } 182 183 $conn = @ftp_connect($conf['ftp']['host'],$conf['ftp']['port'],10); 184 if(!$conn){ 185 msg("FTP connection failed",-1); 186 return false; 187 } 188 189 if(!@ftp_login($conn, $conf['ftp']['user'], $conf['ftp']['pass'])){ 190 msg("FTP login failed",-1); 191 return false; 192 } 193 194 //create directory 195 $ok = @ftp_mkdir($conn, $dir); 196 //set permissions (using the directory umask) 197 @ftp_site($conn,sprintf("CHMOD %04o %s",$perm & (0777 - $conf['dmask']),$dir)); 198 199 ftp_close($conn); 200 return $ok; 201} 202 203/** 204 * Runs an external command and returns it's output as string 205 * 206 * @author Harry Brueckner <harry_b@eml.cc> 207 * @author Andreas Gohr <andi@splitbrain.org> 208 * @deprecated 209 */ 210function io_runcmd($cmd){ 211 $fh = popen($cmd, "r"); 212 if(!$fh) return false; 213 $ret = ''; 214 while (!feof($fh)) { 215 $ret .= fread($fh, 8192); 216 } 217 pclose($fh); 218 return $ret; 219} 220 221?> 222