3 * WordPress Direct Filesystem.
6 * @subpackage Filesystem
10 * WordPress Filesystem Class for direct PHP file and folder manipulation.
14 * @subpackage Filesystem
15 * @uses WP_Filesystem_Base Extends class
17 class WP_Filesystem_Direct extends WP_Filesystem_Base {
24 * @param mixed $arg ignored argument
26 public function __construct($arg) {
27 $this->method = 'direct';
28 $this->errors = new WP_Error();
32 * Reads entire file into a string
36 * @param string $file Name of the file to read.
37 * @return string|bool The function returns the read data or false on failure.
39 public function get_contents($file) {
40 return @file_get_contents($file);
44 * Reads entire file into an array
48 * @param string $file Path to the file.
49 * @return array|bool the file contents in an array or false on failure.
51 public function get_contents_array($file) {
56 * Write a string to a file
60 * @param string $file Remote path to the file where to write the data.
61 * @param string $contents The data to write.
62 * @param int $mode Optional. The file permissions as octal number, usually 0644.
64 * @return bool False upon failure, true otherwise.
66 public function put_contents( $file, $contents, $mode = false ) {
67 $fp = @fopen( $file, 'wb' );
71 mbstring_binary_safe_encoding();
73 $data_length = strlen( $contents );
75 $bytes_written = fwrite( $fp, $contents );
77 reset_mbstring_encoding();
81 if ( $data_length !== $bytes_written )
84 $this->chmod( $file, $mode );
90 * Gets the current working directory
94 * @return string|bool the current working directory on success, or false on failure.
96 public function cwd() {
105 * @param string $dir The new current directory.
106 * @return bool Returns true on success or false on failure.
108 public function chdir($dir) {
117 * @param string $file Path to the file.
118 * @param mixed $group A group name or number.
119 * @param bool $recursive Optional. If set True changes file group recursively. Default false.
120 * @return bool Returns true on success or false on failure.
122 public function chgrp($file, $group, $recursive = false) {
123 if ( ! $this->exists($file) )
126 return @chgrp($file, $group);
127 if ( ! $this->is_dir($file) )
128 return @chgrp($file, $group);
129 // Is a directory, and we want recursive
130 $file = trailingslashit($file);
131 $filelist = $this->dirlist($file);
132 foreach ($filelist as $filename)
133 $this->chgrp($file . $filename, $group, $recursive);
139 * Changes filesystem permissions
143 * @param string $file Path to the file.
144 * @param int $mode Optional. The permissions as octal number, usually 0644 for files,
145 * 0755 for dirs. Default false.
146 * @param bool $recursive Optional. If set True changes file group recursively. Default false.
147 * @return bool Returns true on success or false on failure.
149 public function chmod($file, $mode = false, $recursive = false) {
151 if ( $this->is_file($file) )
152 $mode = FS_CHMOD_FILE;
153 elseif ( $this->is_dir($file) )
154 $mode = FS_CHMOD_DIR;
159 if ( ! $recursive || ! $this->is_dir($file) )
160 return @chmod($file, $mode);
161 // Is a directory, and we want recursive
162 $file = trailingslashit($file);
163 $filelist = $this->dirlist($file);
164 foreach ( (array)$filelist as $filename => $filemeta)
165 $this->chmod($file . $filename, $mode, $recursive);
175 * @param string $file Path to the file.
176 * @param mixed $owner A user name or number.
177 * @param bool $recursive Optional. If set True changes file owner recursively.
179 * @return bool Returns true on success or false on failure.
181 public function chown($file, $owner, $recursive = false) {
182 if ( ! $this->exists($file) )
185 return @chown($file, $owner);
186 if ( ! $this->is_dir($file) )
187 return @chown($file, $owner);
188 // Is a directory, and we want recursive
189 $filelist = $this->dirlist($file);
190 foreach ($filelist as $filename) {
191 $this->chown($file . '/' . $filename, $owner, $recursive);
201 * @param string $file Path to the file.
202 * @return string|bool Username of the user or false on error.
204 public function owner($file) {
205 $owneruid = @fileowner($file);
208 if ( ! function_exists('posix_getpwuid') )
210 $ownerarray = posix_getpwuid($owneruid);
211 return $ownerarray['name'];
215 * Gets file permissions
217 * FIXME does not handle errors in fileperms()
221 * @param string $file Path to the file.
222 * @return string Mode of the file (last 3 digits).
224 public function getchmod($file) {
225 return substr( decoct( @fileperms( $file ) ), -3 );
231 * @param string $file
232 * @return string|false
234 public function group($file) {
235 $gid = @filegroup($file);
238 if ( ! function_exists('posix_getgrgid') )
240 $grouparray = posix_getgrgid($gid);
241 return $grouparray['name'];
247 * @param string $source
248 * @param string $destination
249 * @param bool $overwrite
253 public function copy($source, $destination, $overwrite = false, $mode = false) {
254 if ( ! $overwrite && $this->exists($destination) )
257 $rtval = copy($source, $destination);
259 $this->chmod($destination, $mode);
266 * @param string $source
267 * @param string $destination
268 * @param bool $overwrite
271 public function move($source, $destination, $overwrite = false) {
272 if ( ! $overwrite && $this->exists($destination) )
275 // Try using rename first. if that fails (for example, source is read only) try copy.
276 if ( @rename($source, $destination) )
279 if ( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ) {
280 $this->delete($source);
290 * @param string $file
291 * @param bool $recursive
292 * @param string $type
295 public function delete($file, $recursive = false, $type = false) {
296 if ( empty( $file ) ) // Some filesystems report this as /, which can cause non-expected recursive deletion of all files in the filesystem.
298 $file = str_replace( '\\', '/', $file ); // for win32, occasional problems deleting files otherwise
300 if ( 'f' == $type || $this->is_file($file) )
301 return @unlink($file);
302 if ( ! $recursive && $this->is_dir($file) )
303 return @rmdir($file);
305 // At this point it's a folder, and we're in recursive mode
306 $file = trailingslashit($file);
307 $filelist = $this->dirlist($file, true);
310 if ( is_array( $filelist ) ) {
311 foreach ( $filelist as $filename => $fileinfo ) {
312 if ( ! $this->delete($file . $filename, $recursive, $fileinfo['type']) )
317 if ( file_exists($file) && ! @rmdir($file) )
325 * @param string $file
328 public function exists($file) {
329 return @file_exists($file);
334 * @param string $file
337 public function is_file($file) {
338 return @is_file($file);
343 * @param string $path
346 public function is_dir($path) {
347 return @is_dir($path);
353 * @param string $file
356 public function is_readable($file) {
357 return @is_readable($file);
363 * @param string $file
366 public function is_writable($file) {
367 return @is_writable($file);
373 * @param string $file
376 public function atime($file) {
377 return @fileatime($file);
383 * @param string $file
386 public function mtime($file) {
387 return @filemtime($file);
393 * @param string $file
396 public function size($file) {
397 return @filesize($file);
403 * @param string $file
408 public function touch($file, $time = 0, $atime = 0) {
413 return @touch($file, $time, $atime);
419 * @param string $path
420 * @param mixed $chmod
421 * @param mixed $chown
422 * @param mixed $chgrp
425 public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
426 // Safe mode fails with a trailing slash under certain PHP versions.
427 $path = untrailingslashit($path);
432 $chmod = FS_CHMOD_DIR;
434 if ( ! @mkdir($path) )
436 $this->chmod($path, $chmod);
438 $this->chown($path, $chown);
440 $this->chgrp($path, $chgrp);
447 * @param string $path
448 * @param bool $recursive
451 public function rmdir($path, $recursive = false) {
452 return $this->delete($path, $recursive);
458 * @param string $path
459 * @param bool $include_hidden
460 * @param bool $recursive
463 public function dirlist($path, $include_hidden = true, $recursive = false) {
464 if ( $this->is_file($path) ) {
465 $limit_file = basename($path);
466 $path = dirname($path);
471 if ( ! $this->is_dir($path) )
480 while (false !== ($entry = $dir->read()) ) {
482 $struc['name'] = $entry;
484 if ( '.' == $struc['name'] || '..' == $struc['name'] )
487 if ( ! $include_hidden && '.' == $struc['name'][0] )
490 if ( $limit_file && $struc['name'] != $limit_file)
493 $struc['perms'] = $this->gethchmod($path.'/'.$entry);
494 $struc['permsn'] = $this->getnumchmodfromh($struc['perms']);
495 $struc['number'] = false;
496 $struc['owner'] = $this->owner($path.'/'.$entry);
497 $struc['group'] = $this->group($path.'/'.$entry);
498 $struc['size'] = $this->size($path.'/'.$entry);
499 $struc['lastmodunix']= $this->mtime($path.'/'.$entry);
500 $struc['lastmod'] = date('M j',$struc['lastmodunix']);
501 $struc['time'] = date('h:i:s',$struc['lastmodunix']);
502 $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd' : 'f';
504 if ( 'd' == $struc['type'] ) {
506 $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
508 $struc['files'] = array();
511 $ret[ $struc['name'] ] = $struc;