~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-admin/includes/class-wp-filesystem-direct.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.0
 
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
        public 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
        public 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
        public 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
        public 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
        public 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
        public 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
        public 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
        public 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
        public 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
        public 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 3 digits).
 
198
         */
 
199
        public function getchmod($file) {
 
200
                return substr( decoct( @fileperms( $file ) ), -3 );
 
201
        }
 
202
 
 
203
        public 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
        public 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
        public 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
        public 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
        public function exists($file) {
 
268
                return @file_exists($file);
 
269
        }
 
270
 
 
271
        public function is_file($file) {
 
272
                return @is_file($file);
 
273
        }
 
274
 
 
275
        public function is_dir($path) {
 
276
                return @is_dir($path);
 
277
        }
 
278
 
 
279
        public function is_readable($file) {
 
280
                return @is_readable($file);
 
281
        }
 
282
 
 
283
        public function is_writable($file) {
 
284
                return @is_writable($file);
 
285
        }
 
286
 
 
287
        public function atime($file) {
 
288
                return @fileatime($file);
 
289
        }
 
290
 
 
291
        public function mtime($file) {
 
292
                return @filemtime($file);
 
293
        }
 
294
 
 
295
        public function size($file) {
 
296
                return @filesize($file);
 
297
        }
 
298
 
 
299
        public 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
        public 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
        public function rmdir($path, $recursive = false) {
 
327
                return $this->delete($path, $recursive);
 
328
        }
 
329
 
 
330
        public 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
}