WordPress 4.5
[autoinstalls/wordpress.git] / wp-admin / includes / class-wp-filesystem-base.php
1 <?php
2 /**
3  * Base WordPress Filesystem
4  *
5  * @package WordPress
6  * @subpackage Filesystem
7  */
8
9 /**
10  * Base WordPress Filesystem class for which Filesystem implementations extend
11  *
12  * @since 2.5.0
13  */
14 class WP_Filesystem_Base {
15         /**
16          * Whether to display debug data for the connection.
17          *
18          * @access public
19          * @since 2.5.0
20          * @var bool
21          */
22         public $verbose = false;
23
24         /**
25          * Cached list of local filepaths to mapped remote filepaths.
26          *
27          * @access public
28          * @since 2.7.0
29          * @var array
30          */
31         public $cache = array();
32
33         /**
34          * The Access method of the current connection, Set automatically.
35          *
36          * @access public
37          * @since 2.5.0
38          * @var string
39          */
40         public $method = '';
41
42         /**
43          * @access public
44          */
45         public $errors = null;
46
47         /**
48          * @access public
49          */
50         public $options = array();
51
52         /**
53          * Return the path on the remote filesystem of ABSPATH.
54          *
55          * @access public
56          * @since 2.7.0
57          *
58          * @return string The location of the remote path.
59          */
60         public function abspath() {
61                 $folder = $this->find_folder(ABSPATH);
62                 // Perhaps the FTP folder is rooted at the WordPress install, Check for wp-includes folder in root, Could have some false positives, but rare.
63                 if ( ! $folder && $this->is_dir( '/' . WPINC ) )
64                         $folder = '/';
65                 return $folder;
66         }
67
68         /**
69          * Return the path on the remote filesystem of WP_CONTENT_DIR.
70          *
71          * @access public
72          * @since 2.7.0
73          *
74          * @return string The location of the remote path.
75          */
76         public function wp_content_dir() {
77                 return $this->find_folder(WP_CONTENT_DIR);
78         }
79
80         /**
81          * Return the path on the remote filesystem of WP_PLUGIN_DIR.
82          *
83          * @access public
84          * @since 2.7.0
85          *
86          * @return string The location of the remote path.
87          */
88         public function wp_plugins_dir() {
89                 return $this->find_folder(WP_PLUGIN_DIR);
90         }
91
92         /**
93          * Return the path on the remote filesystem of the Themes Directory.
94          *
95          * @access public
96          * @since 2.7.0
97          *
98          * @param string $theme The Theme stylesheet or template for the directory.
99          * @return string The location of the remote path.
100          */
101         public function wp_themes_dir( $theme = false ) {
102                 $theme_root = get_theme_root( $theme );
103
104                 // Account for relative theme roots
105                 if ( '/themes' == $theme_root || ! is_dir( $theme_root ) )
106                         $theme_root = WP_CONTENT_DIR . $theme_root;
107
108                 return $this->find_folder( $theme_root );
109         }
110
111         /**
112          * Return the path on the remote filesystem of WP_LANG_DIR.
113          *
114          * @access public
115          * @since 3.2.0
116          *
117          * @return string The location of the remote path.
118          */
119         public function wp_lang_dir() {
120                 return $this->find_folder(WP_LANG_DIR);
121         }
122
123         /**
124          * Locate a folder on the remote filesystem.
125          *
126          * @access public
127          * @since 2.5.0
128          * @deprecated 2.7.0 use WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir() instead.
129          * @see WP_Filesystem::abspath()
130          * @see WP_Filesystem::wp_content_dir()
131          * @see WP_Filesystem::wp_plugins_dir()
132          * @see WP_Filesystem::wp_themes_dir()
133          * @see WP_Filesystem::wp_lang_dir()
134          *
135          * @param string $base The folder to start searching from.
136          * @param bool   $echo True to display debug information.
137          *                     Default false.
138          * @return string The location of the remote path.
139          */
140         public function find_base_dir( $base = '.', $echo = false ) {
141                 _deprecated_function(__FUNCTION__, '2.7', 'WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir()' );
142                 $this->verbose = $echo;
143                 return $this->abspath();
144         }
145
146         /**
147          * Locate a folder on the remote filesystem.
148          *
149          * @access public
150          * @since 2.5.0
151          * @deprecated 2.7.0 use WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir() methods instead.
152          * @see WP_Filesystem::abspath()
153          * @see WP_Filesystem::wp_content_dir()
154          * @see WP_Filesystem::wp_plugins_dir()
155          * @see WP_Filesystem::wp_themes_dir()
156          * @see WP_Filesystem::wp_lang_dir()
157          *
158          * @param string $base The folder to start searching from.
159          * @param bool   $echo True to display debug information.
160          * @return string The location of the remote path.
161          */
162         public function get_base_dir( $base = '.', $echo = false ) {
163                 _deprecated_function(__FUNCTION__, '2.7', 'WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir()' );
164                 $this->verbose = $echo;
165                 return $this->abspath();
166         }
167
168         /**
169          * Locate a folder on the remote filesystem.
170          *
171          * Assumes that on Windows systems, Stripping off the Drive
172          * letter is OK Sanitizes \\ to / in windows filepaths.
173          *
174          * @access public
175          * @since 2.7.0
176          *
177          * @param string $folder the folder to locate.
178          * @return string|false The location of the remote path, false on failure.
179          */
180         public function find_folder( $folder ) {
181                 if ( isset( $this->cache[ $folder ] ) )
182                         return $this->cache[ $folder ];
183
184                 if ( stripos($this->method, 'ftp') !== false ) {
185                         $constant_overrides = array(
186                                 'FTP_BASE' => ABSPATH,
187                                 'FTP_CONTENT_DIR' => WP_CONTENT_DIR,
188                                 'FTP_PLUGIN_DIR' => WP_PLUGIN_DIR,
189                                 'FTP_LANG_DIR' => WP_LANG_DIR
190                         );
191
192                         // Direct matches ( folder = CONSTANT/ )
193                         foreach ( $constant_overrides as $constant => $dir ) {
194                                 if ( ! defined( $constant ) )
195                                         continue;
196                                 if ( $folder === $dir )
197                                         return trailingslashit( constant( $constant ) );
198                         }
199
200                         // Prefix Matches ( folder = CONSTANT/subdir )
201                         foreach ( $constant_overrides as $constant => $dir ) {
202                                 if ( ! defined( $constant ) )
203                                         continue;
204                                 if ( 0 === stripos( $folder, $dir ) ) { // $folder starts with $dir
205                                         $potential_folder = preg_replace( '#^' . preg_quote( $dir, '#' ) . '/#i', trailingslashit( constant( $constant ) ), $folder );
206                                         $potential_folder = trailingslashit( $potential_folder );
207
208                                         if ( $this->is_dir( $potential_folder ) ) {
209                                                 $this->cache[ $folder ] = $potential_folder;
210                                                 return $potential_folder;
211                                         }
212                                 }
213                         }
214                 } elseif ( 'direct' == $this->method ) {
215                         $folder = str_replace('\\', '/', $folder); // Windows path sanitisation
216                         return trailingslashit($folder);
217                 }
218
219                 $folder = preg_replace('|^([a-z]{1}):|i', '', $folder); // Strip out windows drive letter if it's there.
220                 $folder = str_replace('\\', '/', $folder); // Windows path sanitisation
221
222                 if ( isset($this->cache[ $folder ] ) )
223                         return $this->cache[ $folder ];
224
225                 if ( $this->exists($folder) ) { // Folder exists at that absolute path.
226                         $folder = trailingslashit($folder);
227                         $this->cache[ $folder ] = $folder;
228                         return $folder;
229                 }
230                 if ( $return = $this->search_for_folder($folder) )
231                         $this->cache[ $folder ] = $return;
232                 return $return;
233         }
234
235         /**
236          * Locate a folder on the remote filesystem.
237          *
238          * Expects Windows sanitized path.
239          *
240          * @access public
241          * @since 2.7.0
242          *
243          * @param string $folder The folder to locate.
244          * @param string $base   The folder to start searching from.
245          * @param bool   $loop   If the function has recursed, Internal use only.
246          * @return string|false The location of the remote path, false to cease looping.
247          */
248         public function search_for_folder( $folder, $base = '.', $loop = false ) {
249                 if ( empty( $base ) || '.' == $base )
250                         $base = trailingslashit($this->cwd());
251
252                 $folder = untrailingslashit($folder);
253
254                 if ( $this->verbose ) {
255                         /* translators: 1: folder to locate, 2: folder to start searching from */
256                         printf( "\n" . __( 'Looking for %1$s in %2$s' ) . "<br/>\n", $folder, $base );
257                 }
258
259                 $folder_parts = explode('/', $folder);
260                 $folder_part_keys = array_keys( $folder_parts );
261                 $last_index = array_pop( $folder_part_keys );
262                 $last_path = $folder_parts[ $last_index ];
263
264                 $files = $this->dirlist( $base );
265
266                 foreach ( $folder_parts as $index => $key ) {
267                         if ( $index == $last_index )
268                                 continue; // We want this to be caught by the next code block.
269
270                         /*
271                          * Working from /home/ to /user/ to /wordpress/ see if that file exists within
272                          * the current folder, If it's found, change into it and follow through looking
273                          * for it. If it cant find WordPress down that route, it'll continue onto the next
274                          * folder level, and see if that matches, and so on. If it reaches the end, and still
275                          * cant find it, it'll return false for the entire function.
276                          */
277                         if ( isset($files[ $key ]) ){
278
279                                 // Let's try that folder:
280                                 $newdir = trailingslashit(path_join($base, $key));
281                                 if ( $this->verbose ) {
282                                         /* translators: %s: directory name */
283                                         printf( "\n" . __( 'Changing to %s' ) . "<br/>\n", $newdir );
284                                 }
285
286                                 // Only search for the remaining path tokens in the directory, not the full path again.
287                                 $newfolder = implode( '/', array_slice( $folder_parts, $index + 1 ) );
288                                 if ( $ret = $this->search_for_folder( $newfolder, $newdir, $loop) )
289                                         return $ret;
290                         }
291                 }
292
293                 // Only check this as a last resort, to prevent locating the incorrect install.
294                 // All above procedures will fail quickly if this is the right branch to take.
295                 if (isset( $files[ $last_path ] ) ) {
296                         if ( $this->verbose ) {
297                                 /* translators: %s: directory name */
298                                 printf( "\n" . __( 'Found %s' ) . "<br/>\n",  $base . $last_path );
299                         }
300                         return trailingslashit($base . $last_path);
301                 }
302
303                 // Prevent this function from looping again.
304                 // No need to proceed if we've just searched in /
305                 if ( $loop || '/' == $base )
306                         return false;
307
308                 // As an extra last resort, Change back to / if the folder wasn't found.
309                 // This comes into effect when the CWD is /home/user/ but WP is at /var/www/....
310                 return $this->search_for_folder( $folder, '/', true );
311
312         }
313
314         /**
315          * Return the *nix-style file permissions for a file.
316          *
317          * From the PHP documentation page for fileperms().
318          *
319          * @link http://docs.php.net/fileperms
320          *
321          * @access public
322          * @since 2.5.0
323          *
324          * @param string $file String filename.
325          * @return string The *nix-style representation of permissions.
326          */
327         public function gethchmod( $file ){
328                 $perms = intval( $this->getchmod( $file ), 8 );
329                 if (($perms & 0xC000) == 0xC000) // Socket
330                         $info = 's';
331                 elseif (($perms & 0xA000) == 0xA000) // Symbolic Link
332                         $info = 'l';
333                 elseif (($perms & 0x8000) == 0x8000) // Regular
334                         $info = '-';
335                 elseif (($perms & 0x6000) == 0x6000) // Block special
336                         $info = 'b';
337                 elseif (($perms & 0x4000) == 0x4000) // Directory
338                         $info = 'd';
339                 elseif (($perms & 0x2000) == 0x2000) // Character special
340                         $info = 'c';
341                 elseif (($perms & 0x1000) == 0x1000) // FIFO pipe
342                         $info = 'p';
343                 else // Unknown
344                         $info = 'u';
345
346                 // Owner
347                 $info .= (($perms & 0x0100) ? 'r' : '-');
348                 $info .= (($perms & 0x0080) ? 'w' : '-');
349                 $info .= (($perms & 0x0040) ?
350                                         (($perms & 0x0800) ? 's' : 'x' ) :
351                                         (($perms & 0x0800) ? 'S' : '-'));
352
353                 // Group
354                 $info .= (($perms & 0x0020) ? 'r' : '-');
355                 $info .= (($perms & 0x0010) ? 'w' : '-');
356                 $info .= (($perms & 0x0008) ?
357                                         (($perms & 0x0400) ? 's' : 'x' ) :
358                                         (($perms & 0x0400) ? 'S' : '-'));
359
360                 // World
361                 $info .= (($perms & 0x0004) ? 'r' : '-');
362                 $info .= (($perms & 0x0002) ? 'w' : '-');
363                 $info .= (($perms & 0x0001) ?
364                                         (($perms & 0x0200) ? 't' : 'x' ) :
365                                         (($perms & 0x0200) ? 'T' : '-'));
366                 return $info;
367         }
368
369         /**
370          * Gets the permissions of the specified file or filepath in their octal format
371          *
372          * @access public
373          * @since 2.5.0
374          * @param string $file
375          * @return string the last 3 characters of the octal number
376          */
377         public function getchmod( $file ) {
378                 return '777';
379         }
380
381         /**
382          * Convert *nix-style file permissions to a octal number.
383          *
384          * Converts '-rw-r--r--' to 0644
385          * From "info at rvgate dot nl"'s comment on the PHP documentation for chmod()
386          *
387          * @link http://docs.php.net/manual/en/function.chmod.php#49614
388          *
389          * @access public
390          * @since 2.5.0
391          *
392          * @param string $mode string The *nix-style file permission.
393          * @return int octal representation
394          */
395         public function getnumchmodfromh( $mode ) {
396                 $realmode = '';
397                 $legal =  array('', 'w', 'r', 'x', '-');
398                 $attarray = preg_split('//', $mode);
399
400                 for ( $i = 0, $c = count( $attarray ); $i < $c; $i++ ) {
401                    if ($key = array_search($attarray[$i], $legal)) {
402                            $realmode .= $legal[$key];
403                    }
404                 }
405
406                 $mode = str_pad($realmode, 10, '-', STR_PAD_LEFT);
407                 $trans = array('-'=>'0', 'r'=>'4', 'w'=>'2', 'x'=>'1');
408                 $mode = strtr($mode,$trans);
409
410                 $newmode = $mode[0];
411                 $newmode .= $mode[1] + $mode[2] + $mode[3];
412                 $newmode .= $mode[4] + $mode[5] + $mode[6];
413                 $newmode .= $mode[7] + $mode[8] + $mode[9];
414                 return $newmode;
415         }
416
417         /**
418          * Determine if the string provided contains binary characters.
419          *
420          * @access public
421          * @since 2.7.0
422          *
423          * @param string $text String to test against.
424          * @return bool true if string is binary, false otherwise.
425          */
426         public function is_binary( $text ) {
427                 return (bool) preg_match( '|[^\x20-\x7E]|', $text ); // chr(32)..chr(127)
428         }
429
430         /**
431          * Change the ownership of a file / folder.
432          *
433          * Default behavior is to do nothing, override this in your subclass, if desired.
434          *
435          * @access public
436          * @since 2.5.0
437          *
438          * @param string $file      Path to the file.
439          * @param mixed  $owner     A user name or number.
440          * @param bool   $recursive Optional. If set True changes file owner recursivly. Defaults to False.
441          * @return bool Returns true on success or false on failure.
442          */
443         public function chown( $file, $owner, $recursive = false ) {
444                 return false;
445         }
446
447         /**
448          * Connect filesystem.
449          *
450          * @access public
451          * @since 2.5.0
452          * @abstract
453          *
454          * @return bool True on success or false on failure (always true for WP_Filesystem_Direct).
455          */
456         public function connect() {
457                 return true;
458         }
459
460         /**
461          * Read entire file into a string.
462          *
463          * @access public
464          * @since 2.5.0
465          * @abstract
466          *
467          * @param string $file Name of the file to read.
468          * @return mixed|bool Returns the read data or false on failure.
469          */
470         public function get_contents( $file ) {
471                 return false;
472         }
473
474         /**
475          * Read entire file into an array.
476          *
477          * @access public
478          * @since 2.5.0
479          * @abstract
480          *
481          * @param string $file Path to the file.
482          * @return array|bool the file contents in an array or false on failure.
483          */
484         public function get_contents_array( $file ) {
485                 return false;
486         }
487
488         /**
489          * Write a string to a file.
490          *
491          * @access public
492          * @since 2.5.0
493          * @abstract
494          *
495          * @param string $file     Remote path to the file where to write the data.
496          * @param string $contents The data to write.
497          * @param int    $mode     Optional. The file permissions as octal number, usually 0644.
498          * @return bool False on failure.
499          */
500         public function put_contents( $file, $contents, $mode = false ) {
501                 return false;
502         }
503
504         /**
505          * Get the current working directory.
506          *
507          * @access public
508          * @since 2.5.0
509          * @abstract
510          *
511          * @return string|bool The current working directory on success, or false on failure.
512          */
513         public function cwd() {
514                 return false;
515         }
516
517         /**
518          * Change current directory.
519          *
520          * @access public
521          * @since 2.5.0
522          * @abstract
523          *
524          * @param string $dir The new current directory.
525          * @return bool|string
526          */
527         public function chdir( $dir ) {
528                 return false;
529         }
530
531         /**
532          * Change the file group.
533          *
534          * @access public
535          * @since 2.5.0
536          * @abstract
537          *
538          * @param string $file      Path to the file.
539          * @param mixed  $group     A group name or number.
540          * @param bool   $recursive Optional. If set True changes file group recursively. Defaults to False.
541          * @return bool|string
542          */
543         public function chgrp( $file, $group, $recursive = false ) {
544                 return false;
545         }
546
547         /**
548          * Change filesystem permissions.
549          *
550          * @access public
551          * @since 2.5.0
552          * @abstract
553          *
554          * @param string $file      Path to the file.
555          * @param int    $mode      Optional. The permissions as octal number, usually 0644 for files, 0755 for dirs.
556          * @param bool   $recursive Optional. If set True changes file group recursively. Defaults to False.
557          * @return bool|string
558          */
559         public function chmod( $file, $mode = false, $recursive = false ) {
560                 return false;
561         }
562
563         /**
564          * Get the file owner.
565          *
566          * @access public
567          * @since 2.5.0
568          * @abstract
569          * 
570          * @param string $file Path to the file.
571          * @return string|bool Username of the user or false on error.
572          */
573         public function owner( $file ) {
574                 return false;
575         }
576
577         /**
578          * Get the file's group.
579          *
580          * @access public
581          * @since 2.5.0
582          * @abstract
583          *
584          * @param string $file Path to the file.
585          * @return string|bool The group or false on error.
586          */
587         public function group( $file ) {
588                 return false;
589         }
590
591         /**
592          * Copy a file.
593          *
594          * @access public
595          * @since 2.5.0
596          * @abstract
597          *
598          * @param string $source      Path to the source file.
599          * @param string $destination Path to the destination file.
600          * @param bool   $overwrite   Optional. Whether to overwrite the destination file if it exists.
601          *                            Default false.
602          * @param int    $mode        Optional. The permissions as octal number, usually 0644 for files, 0755 for dirs.
603          *                            Default false.
604          * @return bool True if file copied successfully, False otherwise.
605          */
606         public function copy( $source, $destination, $overwrite = false, $mode = false ) {
607                 return false;
608         }
609
610         /**
611          * Move a file.
612          *
613          * @access public
614          * @since 2.5.0
615          * @abstract
616          *
617          * @param string $source      Path to the source file.
618          * @param string $destination Path to the destination file.
619          * @param bool   $overwrite   Optional. Whether to overwrite the destination file if it exists.
620          *                            Default false.
621          * @return bool True if file copied successfully, False otherwise.
622          */
623         public function move( $source, $destination, $overwrite = false ) {
624                 return false;
625         }
626
627         /**
628          * Delete a file or directory.
629          *
630          * @access public
631          * @since 2.5.0
632          * @abstract
633          *
634          * @param string $file      Path to the file.
635          * @param bool   $recursive Optional. If set True changes file group recursively. Defaults to False.
636          *                          Default false.
637          * @param bool   $type      Type of resource. 'f' for file, 'd' for directory.
638          *                          Default false.
639          * @return bool True if the file or directory was deleted, false on failure.
640          */
641         public function delete( $file, $recursive = false, $type = false ) {
642                 return false;
643         }
644
645         /**
646          * Check if a file or directory exists.
647          *
648          * @access public
649          * @since 2.5.0
650          * @abstract
651          *
652          * @param string $file Path to file/directory.
653          * @return bool Whether $file exists or not.
654          */
655         public function exists( $file ) {
656                 return false;
657         }
658
659         /**
660          * Check if resource is a file.
661          *
662          * @access public
663          * @since 2.5.0
664          * @abstract
665          *
666          * @param string $file File path.
667          * @return bool Whether $file is a file.
668          */
669         public function is_file( $file ) {
670                 return false;
671         }
672
673         /**
674          * Check if resource is a directory.
675          *
676          * @access public
677          * @since 2.5.0
678          * @abstract
679          *
680          * @param string $path Directory path.
681          * @return bool Whether $path is a directory.
682          */
683         public function is_dir( $path ) {
684                 return false;
685         }
686
687         /**
688          * Check if a file is readable.
689          *
690          * @access public
691          * @since 2.5.0
692          * @abstract
693          *
694          * @param string $file Path to file.
695          * @return bool Whether $file is readable.
696          */
697         public function is_readable( $file ) {
698                 return false;
699         }
700
701         /**
702          * Check if a file or directory is writable.
703          *
704          * @access public
705          * @since 2.5.0
706          * @abstract
707          *
708          * @param string $file Path to file.
709          * @return bool Whether $file is writable.
710          */
711         public function is_writable( $file ) {
712                 return false;
713         }
714
715         /**
716          * Gets the file's last access time.
717          *
718          * @access public
719          * @since 2.5.0
720          * @abstract
721          *
722          * @param string $file Path to file.
723          * @return int|bool Unix timestamp representing last access time.
724          */
725         public function atime( $file ) {
726                 return false;
727         }
728
729         /**
730          * Gets the file modification time.
731          *
732          * @access public
733          * @since 2.5.0
734          * @abstract
735          *
736          * @param string $file Path to file.
737          * @return int|bool Unix timestamp representing modification time.
738          */
739         public function mtime( $file ) {
740                 return false;
741         }
742
743         /**
744          * Gets the file size (in bytes).
745          *
746          * @access public
747          * @since 2.5.0
748          * @abstract
749          *
750          * @param string $file Path to file.
751          * @return int|bool Size of the file in bytes.
752          */
753         public function size( $file ) {
754                 return false;
755         }
756
757         /**
758          * Set the access and modification times of a file.
759          *
760          * Note: If $file doesn't exist, it will be created.
761          *
762          * @access public
763          * @since 2.5.0
764          * @abstract
765          *
766          * @param string $file  Path to file.
767          * @param int    $time  Optional. Modified time to set for file.
768          *                      Default 0.
769          * @param int    $atime Optional. Access time to set for file.
770          *                      Default 0.
771          * @return bool Whether operation was successful or not.
772          */
773         public function touch( $file, $time = 0, $atime = 0 ) {
774                 return false;
775         }
776
777         /**
778          * Create a directory.
779          *
780          * @access public
781          * @since 2.5.0
782          * @abstract
783          *
784          * @param string $path  Path for new directory.
785          * @param mixed  $chmod Optional. The permissions as octal number, (or False to skip chmod)
786          *                      Default false.
787          * @param mixed  $chown Optional. A user name or number (or False to skip chown)
788          *                      Default false.
789          * @param mixed  $chgrp Optional. A group name or number (or False to skip chgrp).
790          *                      Default false.
791          * @return bool False if directory cannot be created, true otherwise.
792          */
793         public function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) {
794                 return false;
795         }
796
797         /**
798          * Delete a directory.
799          *
800          * @access public
801          * @since 2.5.0
802          * @abstract
803          *
804          * @param string $path      Path to directory.
805          * @param bool   $recursive Optional. Whether to recursively remove files/directories.
806          *                          Default false.
807          * @return bool Whether directory is deleted successfully or not.
808          */
809         public function rmdir( $path, $recursive = false ) {
810                 return false;
811         }
812
813         /**
814          * Get details for files in a directory or a specific file.
815          *
816          * @access public
817          * @since 2.5.0
818          * @abstract
819          *
820          * @param string $path           Path to directory or file.
821          * @param bool   $include_hidden Optional. Whether to include details of hidden ("." prefixed) files.
822          *                               Default true.
823          * @param bool   $recursive      Optional. Whether to recursively include file details in nested directories.
824          *                               Default false.
825          * @return array|bool {
826          *     Array of files. False if unable to list directory contents.
827          *
828          *     @type string $name        Name of the file/directory.
829          *     @type string $perms       *nix representation of permissions.
830          *     @type int    $permsn      Octal representation of permissions.
831          *     @type string $owner       Owner name or ID.
832          *     @type int    $size        Size of file in bytes.
833          *     @type int    $lastmodunix Last modified unix timestamp.
834          *     @type mixed  $lastmod     Last modified month (3 letter) and day (without leading 0).
835          *     @type int    $time        Last modified time.
836          *     @type string $type        Type of resource. 'f' for file, 'd' for directory.
837          *     @type mixed  $files       If a directory and $recursive is true, contains another array of files.
838          * }
839          */
840         public function dirlist( $path, $include_hidden = true, $recursive = false ) {
841                 return false;
842         }
843
844 } // WP_Filesystem_Base