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