xref: /dokuwiki/inc/io.php (revision 3dc3a5f166aa2c4e345b27f6811db5889261c3d4)
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 * Returns content of $file as cleaned string.
61 *
62 * Uses gzip if extension is .gz
63 *
64 * @author  Andreas Gohr <andi@splitbrain.org>
65 */
66function io_readFile($file){
67  $ret = '';
68  if(@file_exists($file)){
69    if(substr($file,-3) == '.gz'){
70      $ret = join('',gzfile($file));
71    }else{
72      $ret = join('',file($file));
73    }
74  }
75  return cleanText($ret);
76}
77
78/**
79 * Saves $content to $file.
80 *
81 * Uses gzip if extension is .gz
82 *
83 * @author  Andreas Gohr <andi@splitbrain.org>
84 * @return bool true on success
85 */
86function io_saveFile($file,$content){
87  io_makeFileDir($file);
88  if(substr($file,-3) == '.gz'){
89    $fh = @gzopen($file,'wb9');
90    if(!$fh){
91      msg("Writing $file failed",-1);
92      return false;
93    }
94    gzwrite($fh, $content);
95    gzclose($fh);
96  }else{
97    $fh = @fopen($file,'wb');
98    if(!$fh){
99      msg("Writing $file failed",-1);
100      return false;
101    }
102    fwrite($fh, $content);
103    fclose($fh);
104  }
105  return true;
106}
107
108/**
109 * Create the directory needed for the given file
110 *
111 * @author  Andreas Gohr <andi@splitbrain.org>
112 */
113function io_makeFileDir($file){
114  global $conf;
115
116  $dir = dirname($file);
117  if($conf['safemodehack']){
118    preg_replace('/^'.preg_quote(realpath($conf['ftp']['root']),'/').'/','',$dir);
119  }
120  umask($conf['dmask']);
121  if(!is_dir($dir)){
122    io_mkdir_p($dir) || msg("Creating directory $dir failed",-1);
123  }
124  umask($conf['umask']);
125}
126
127/**
128 * Creates a directory hierachy.
129 *
130 * @link    http://www.php.net/manual/en/function.mkdir.php
131 * @author  <saint@corenova.com>
132 * @author  Andreas Gohr <andi@splitbrain.org>
133 */
134function io_mkdir_p($target){
135  global $conf;
136  if (is_dir($target)||empty($target)) return 1; // best case check first
137  if (@file_exists($target) && !is_dir($target)) return 0;
138  //recursion
139  if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){
140    if($conf['safemodehack']){
141      return io_mkdir_ftp($target);
142    }else{
143      return @mkdir($target,0777); // crawl back up & create dir tree
144    }
145  }
146  return 0;
147}
148
149/**
150 * Creates a directory using FTP
151 *
152 * This is used when the safemode workaround is enabled
153 *
154 * @author <andi@splitbrain.org>
155 */
156function io_mkdir_ftp($dir){
157  global $conf;
158
159  if(!function_exists('ftp_connect')){
160    msg("FTP support not found - safemode workaround not usable",-1);
161    return false;
162  }
163
164  $conn = @ftp_connect($conf['ftp']['host'],$conf['ftp']['port'],10);
165  if(!$conn){
166    msg("FTP connection failed",-1);
167    return false;
168  }
169
170  if(!@ftp_login($conn, $conf['ftp']['user'], $conf['ftp']['pass'])){
171    msg("FTP login failed",-1);
172    return false;
173  }
174
175  //create directory
176  $ok = @ftp_mkdir($conn, $dir);
177  //set permissions (using the directory umask)
178  @ftp_site($conn,sprintf("CHMOD %04o %s",$perm & (0777 - $conf['dmask']),$dir));
179
180  ftp_close($conn);
181  return $ok;
182}
183
184/**
185 * Runs an external command and returns it's output as string
186 *
187 * @author Harry Brueckner <harry_b@eml.cc>
188 * @author Andreas Gohr <andi@splitbrain.org>
189 * @deprecated
190 */
191function io_runcmd($cmd){
192  $fh = popen($cmd, "r");
193  if(!$fh) return false;
194  $ret = '';
195  while (!feof($fh)) {
196    $ret .= fread($fh, 8192);
197  }
198  pclose($fh);
199  return $ret;
200}
201
202?>
203