Wordpress 3.7
[autoinstalls/wordpress.git] / wp-admin / includes / class-wp-filesystem-direct.php
1 <?php
2 /**
3  * WordPress Direct Filesystem.
4  *
5  * @package WordPress
6  * @subpackage Filesystem
7  */
8
9 /**
10  * WordPress Filesystem Class for direct PHP file and folder manipulation.
11  *
12  * @since 2.5
13  * @package WordPress
14  * @subpackage Filesystem
15  * @uses WP_Filesystem_Base Extends class
16  */
17 class WP_Filesystem_Direct extends WP_Filesystem_Base {
18
19         /**
20          * constructor
21          *
22          * @param mixed $arg ignored argument
23          */
24         function __construct($arg) {
25                 $this->method = 'direct';
26                 $this->errors = new WP_Error();
27         }
28
29         /**
30          * Reads entire file into a string
31          *
32          * @param string $file Name of the file to read.
33          * @return string|bool The function returns the read data or false on failure.
34          */
35         function get_contents($file) {
36                 return @file_get_contents($file);
37         }
38
39         /**
40          * Reads entire file into an array
41          *
42          * @param string $file Path to the file.
43          * @return array|bool the file contents in an array or false on failure.
44          */
45         function get_contents_array($file) {
46                 return @file($file);
47         }
48
49         /**
50          * Write a string to a file
51          *
52          * @param string $file Remote path to the file where to write the data.
53          * @param string $contents The data to write.
54          * @param int $mode (optional) The file permissions as octal number, usually 0644.
55          * @return bool False upon failure.
56          */
57         function put_contents( $file, $contents, $mode = false ) {
58                 $fp = @fopen( $file, 'wb' );
59                 if ( ! $fp )
60                         return false;
61
62                 mbstring_binary_safe_encoding();
63
64                 $data_length = strlen( $contents );
65
66                 $bytes_written = fwrite( $fp, $contents );
67
68                 reset_mbstring_encoding();
69
70                 fclose( $fp );
71
72                 if ( $data_length !== $bytes_written )
73                         return false;
74
75                 $this->chmod( $file, $mode );
76
77                 return true;
78         }
79
80         /**
81          * Gets the current working directory
82          *
83          * @return string|bool the current working directory on success, or false on failure.
84          */
85         function cwd() {
86                 return @getcwd();
87         }
88
89         /**
90          * Change directory
91          *
92          * @param string $dir The new current directory.
93          * @return bool Returns true on success or false on failure.
94          */
95         function chdir($dir) {
96                 return @chdir($dir);
97         }
98
99         /**
100          * Changes file group
101          *
102          * @param string $file Path to the file.
103          * @param mixed $group A group name or number.
104          * @param bool $recursive (optional) If set True changes file group recursively. Defaults to False.
105          * @return bool Returns true on success or false on failure.
106          */
107         function chgrp($file, $group, $recursive = false) {
108                 if ( ! $this->exists($file) )
109                         return false;
110                 if ( ! $recursive )
111                         return @chgrp($file, $group);
112                 if ( ! $this->is_dir($file) )
113                         return @chgrp($file, $group);
114                 // Is a directory, and we want recursive
115                 $file = trailingslashit($file);
116                 $filelist = $this->dirlist($file);
117                 foreach ($filelist as $filename)
118                         $this->chgrp($file . $filename, $group, $recursive);
119
120                 return true;
121         }
122
123         /**
124          * Changes filesystem permissions
125          *
126          * @param string $file Path to the file.
127          * @param int $mode (optional) The permissions as octal number, usually 0644 for files, 0755 for dirs.
128          * @param bool $recursive (optional) If set True changes file group recursively. Defaults to False.
129          * @return bool Returns true on success or false on failure.
130          */
131         function chmod($file, $mode = false, $recursive = false) {
132                 if ( ! $mode ) {
133                         if ( $this->is_file($file) )
134                                 $mode = FS_CHMOD_FILE;
135                         elseif ( $this->is_dir($file) )
136                                 $mode = FS_CHMOD_DIR;
137                         else
138                                 return false;
139                 }
140
141                 if ( ! $recursive || ! $this->is_dir($file) )
142                         return @chmod($file, $mode);
143                 // Is a directory, and we want recursive
144                 $file = trailingslashit($file);
145                 $filelist = $this->dirlist($file);
146                 foreach ( (array)$filelist as $filename => $filemeta)
147                         $this->chmod($file . $filename, $mode, $recursive);
148
149                 return true;
150         }
151
152         /**
153          * Changes file owner
154          *
155          * @param string $file Path to the file.
156          * @param mixed $owner A user name or number.
157          * @param bool $recursive (optional) If set True changes file owner recursively. Defaults to False.
158          * @return bool Returns true on success or false on failure.
159          */
160         function chown($file, $owner, $recursive = false) {
161                 if ( ! $this->exists($file) )
162                         return false;
163                 if ( ! $recursive )
164                         return @chown($file, $owner);
165                 if ( ! $this->is_dir($file) )
166                         return @chown($file, $owner);
167                 // Is a directory, and we want recursive
168                 $filelist = $this->dirlist($file);
169                 foreach ($filelist as $filename) {
170                         $this->chown($file . '/' . $filename, $owner, $recursive);
171                 }
172                 return true;
173         }
174
175         /**
176          * Gets file owner
177          *
178          * @param string $file Path to the file.
179          * @return string|bool Username of the user or false on error.
180          */
181         function owner($file) {
182                 $owneruid = @fileowner($file);
183                 if ( ! $owneruid )
184                         return false;
185                 if ( ! function_exists('posix_getpwuid') )
186                         return $owneruid;
187                 $ownerarray = posix_getpwuid($owneruid);
188                 return $ownerarray['name'];
189         }
190
191         /**
192          * Gets file permissions
193          *
194          * FIXME does not handle errors in fileperms()
195          *
196          * @param string $file Path to the file.
197          * @return string Mode of the file (last 4 digits).
198          */
199         function getchmod($file) {
200                 return substr(decoct(@fileperms($file)),3);
201         }
202
203         function group($file) {
204                 $gid = @filegroup($file);
205                 if ( ! $gid )
206                         return false;
207                 if ( ! function_exists('posix_getgrgid') )
208                         return $gid;
209                 $grouparray = posix_getgrgid($gid);
210                 return $grouparray['name'];
211         }
212
213         function copy($source, $destination, $overwrite = false, $mode = false) {
214                 if ( ! $overwrite && $this->exists($destination) )
215                         return false;
216
217                 $rtval = copy($source, $destination);
218                 if ( $mode )
219                         $this->chmod($destination, $mode);
220                 return $rtval;
221         }
222
223         function move($source, $destination, $overwrite = false) {
224                 if ( ! $overwrite && $this->exists($destination) )
225                         return false;
226
227                 // try using rename first. if that fails (for example, source is read only) try copy
228                 if ( @rename($source, $destination) )
229                         return true;
230
231                 if ( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ) {
232                         $this->delete($source);
233                         return true;
234                 } else {
235                         return false;
236                 }
237         }
238
239         function delete($file, $recursive = false, $type = false) {
240                 if ( empty( $file ) ) // Some filesystems report this as /, which can cause non-expected recursive deletion of all files in the filesystem.
241                         return false;
242                 $file = str_replace( '\\', '/', $file ); // for win32, occasional problems deleting files otherwise
243
244                 if ( 'f' == $type || $this->is_file($file) )
245                         return @unlink($file);
246                 if ( ! $recursive && $this->is_dir($file) )
247                         return @rmdir($file);
248
249                 // At this point it's a folder, and we're in recursive mode
250                 $file = trailingslashit($file);
251                 $filelist = $this->dirlist($file, true);
252
253                 $retval = true;
254                 if ( is_array( $filelist ) ) {
255                         foreach ( $filelist as $filename => $fileinfo ) {
256                                 if ( ! $this->delete($file . $filename, $recursive, $fileinfo['type']) )
257                                         $retval = false;
258                         }
259                 }
260
261                 if ( file_exists($file) && ! @rmdir($file) )
262                         $retval = false;
263
264                 return $retval;
265         }
266
267         function exists($file) {
268                 return @file_exists($file);
269         }
270
271         function is_file($file) {
272                 return @is_file($file);
273         }
274
275         function is_dir($path) {
276                 return @is_dir($path);
277         }
278
279         function is_readable($file) {
280                 return @is_readable($file);
281         }
282
283         function is_writable($file) {
284                 return @is_writable($file);
285         }
286
287         function atime($file) {
288                 return @fileatime($file);
289         }
290
291         function mtime($file) {
292                 return @filemtime($file);
293         }
294
295         function size($file) {
296                 return @filesize($file);
297         }
298
299         function touch($file, $time = 0, $atime = 0) {
300                 if ($time == 0)
301                         $time = time();
302                 if ($atime == 0)
303                         $atime = time();
304                 return @touch($file, $time, $atime);
305         }
306
307         function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
308                 // safe mode fails with a trailing slash under certain PHP versions.
309                 $path = untrailingslashit($path);
310                 if ( empty($path) )
311                         return false;
312
313                 if ( ! $chmod )
314                         $chmod = FS_CHMOD_DIR;
315
316                 if ( ! @mkdir($path) )
317                         return false;
318                 $this->chmod($path, $chmod);
319                 if ( $chown )
320                         $this->chown($path, $chown);
321                 if ( $chgrp )
322                         $this->chgrp($path, $chgrp);
323                 return true;
324         }
325
326         function rmdir($path, $recursive = false) {
327                 return $this->delete($path, $recursive);
328         }
329
330         function dirlist($path, $include_hidden = true, $recursive = false) {
331                 if ( $this->is_file($path) ) {
332                         $limit_file = basename($path);
333                         $path = dirname($path);
334                 } else {
335                         $limit_file = false;
336                 }
337
338                 if ( ! $this->is_dir($path) )
339                         return false;
340
341                 $dir = @dir($path);
342                 if ( ! $dir )
343                         return false;
344
345                 $ret = array();
346
347                 while (false !== ($entry = $dir->read()) ) {
348                         $struc = array();
349                         $struc['name'] = $entry;
350
351                         if ( '.' == $struc['name'] || '..' == $struc['name'] )
352                                 continue;
353
354                         if ( ! $include_hidden && '.' == $struc['name'][0] )
355                                 continue;
356
357                         if ( $limit_file && $struc['name'] != $limit_file)
358                                 continue;
359
360                         $struc['perms']         = $this->gethchmod($path.'/'.$entry);
361                         $struc['permsn']        = $this->getnumchmodfromh($struc['perms']);
362                         $struc['number']        = false;
363                         $struc['owner']         = $this->owner($path.'/'.$entry);
364                         $struc['group']         = $this->group($path.'/'.$entry);
365                         $struc['size']          = $this->size($path.'/'.$entry);
366                         $struc['lastmodunix']= $this->mtime($path.'/'.$entry);
367                         $struc['lastmod']   = date('M j',$struc['lastmodunix']);
368                         $struc['time']          = date('h:i:s',$struc['lastmodunix']);
369                         $struc['type']          = $this->is_dir($path.'/'.$entry) ? 'd' : 'f';
370
371                         if ( 'd' == $struc['type'] ) {
372                                 if ( $recursive )
373                                         $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
374                                 else
375                                         $struc['files'] = array();
376                         }
377
378                         $ret[ $struc['name'] ] = $struc;
379                 }
380                 $dir->close();
381                 unset($dir);
382                 return $ret;
383         }
384 }