WordPress.org

Make WordPress Core

Ticket #20652: fs.php

File fs.php, 4.8 KB (added by dd32, 18 months ago)
Line 
1<?php
2
3include 'wp-load.php';
4include ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
5
6// If you want to dump out $fs or $fs_map
7// ini_set( 'xdebug.var_display_max_depth', 50 );
8// ini_set( 'xdebug.var_display_max_children', -1 );
9
10class WP_Filesystem_Tester extends WP_Filesystem_Base {
11        private $cwd;
12
13        // Holds a array of objects which contain an array of objects, etc.
14        private $fs = null;
15
16        // Holds a array of /path/to/file.php and /path/to/dir/ map to an object in $fs above
17        // a fast more efficient way of determining if a path exists, and access to that node
18        private $fs_map = array();
19
20        var $verbose = true;
21
22        function __construct( $system_prefix = '', $paths = '' ) {
23                $this->fs = (object)array(
24                        'name' => '/', // The "name" of this entry. root is special in that it includes the slash, all others do not
25                        'type' => 'd', // d = directory, f = file
26                        'path' => '/', // Full path to entry, primarily for ::cwd()
27                        'children' => array(), // Any children entries of this directory, unset for files
28                );
29                $this->fs_map[ '/' ] = $this->fs;
30                $this->cwd = $this->fs;
31                $this->setfs( $system_prefix, $paths );
32        }
33
34        function setfs( $system_prefix, $paths ) {
35                if ( ! is_array($paths) )
36                        $paths = explode( "\n", $paths );
37
38                $paths = array_filter( array_map( 'trim', $paths ) );
39
40                foreach ( $paths as $path ) {
41
42                        $prefixless = $system_prefix ? preg_replace( '!^' . preg_quote( untrailingslashit( $system_prefix ), '!' ) . '!i', '', $path ) : $path;
43
44                        if ( '/' == $path[ strlen($prefixless) -1 ] )
45                                $this->mkdir( $prefixless );
46                        else
47                                $this->put_contents( $prefixless );
48                }
49
50        }
51
52        function mkdir( $path ) {
53                $p = array_filter( explode( '/', $path ) );
54                $parent = $this->fs;
55                foreach ( $p as $i => $dir ) {
56                        if ( ! isset( $parent->children[ $dir ] ) ) {
57                                $full_path = '/' . implode( '/', array_slice( $p, 0, $i ) ) . '/';
58                                $parent->children[ $dir ] = (object) array(
59                                        'name' => $dir,
60                                        'type' => 'd',
61                                        'path' => $full_path,
62                                        'children' => array(),
63                                );
64                                $this->fs_map[ $full_path ] = $parent->children[ $dir ];
65                        }
66                        $parent = $parent->children[ $dir ];
67                }
68                return $parent;
69        }
70
71        function put_contents( $file, $contents = '', $mode = null ) {
72                $parent = $this->mkdir( dirname( $file ) );
73
74                $parent->children[ basename( $file ) ] = (object)array(
75                        'name' => basename( $file ),
76                        'type' => 'f',
77                        'path' => $file,
78                        'contents' => $contents,
79                );
80                $this->fs_map[ $file ] = $parent->children[ basename( $file ) ];
81        }
82
83        function get_contents( $file ) {
84                if ( ! $this->is_file( $file ) )
85                        return false;
86                return $this->fs_map[ $file ]->contents;
87        }
88
89        function cwd() {
90                return $this->cwd->path;
91        }
92        function chdir( $path ) {
93                //var_dump( [ __METHOD__, $path ] );
94                if ( ! isset( $this->fs_map[ $path ] ) )
95                        return false;
96
97                $this->cwd = $this->fs_map[ $path ];
98                return true;
99        }
100        function exists( $path ) {
101                //var_dump( [ __METHOD__, $path, isset( $this->fs_map[ $path ] ) ] );
102                return isset( $this->fs_map[ $path ] );
103        }
104        function is_file( $file ) {
105                //var_dump( [ __METHOD__, $file ] );
106                if ( ! isset( $this->fs_map[ $file ] ) )
107                        return false;
108
109                return ( 'f' == $this->fs_map[ $file ]->type );
110        }
111        function is_dir( $path ) {
112                //var_dump( [ __METHOD__, $path ] );
113                if ( ! isset( $this->fs_map[ $path ] ) )
114                        return false;
115
116                return ( 'd' == $this->fs_map[ $path ]->type );
117        }
118       
119        function dirlist( $path = '.', $include_hidden = true, $recursive = false ) {
120
121                if ( empty( $path ) || '.' == $path )
122                        $path = $this->cwd();
123
124                if ( ! isset( $this->fs_map[ $path ] ) )
125                        return false;
126
127                $limit_file = false;
128                if ( $this->is_file( $path ) ) {
129                        $limit_file = basename( $path );
130                        $path = dirname( $path ) . '/';
131                }
132
133                $ret = array();
134                foreach ( $this->fs_map[ $path ]->children as $entry ) {
135                        if ( '.' == $entry->name || '..' == $entry->name )
136                                continue;
137       
138                        if ( ! $include_hidden && '.' == $entry->name )
139                                continue;
140       
141                        if ( $limit_file && $entry->name != $limit_file )
142                                continue;
143
144                        $struc = array();
145                        $struc['name'] = $entry->name;
146                        $struc['type'] = $entry->type;
147       
148                        if ( 'd' == $struc['type'] ) {
149                                if ( $recursive )
150                                        $struc['files'] = $this->dirlist( trailingslashit( $path ) . trailingslashit( $struc['name'] ), $include_hidden, $recursive );
151                                else
152                                        $struc['files'] = array();
153                        }
154       
155                        $ret[ $entry->name ] = $struc;
156                }
157                return $ret;
158        }
159
160
161}
162
163$ftp_root_prefix = '/www/example.com';
164$paths = array(
165        '/www/example.com/example.com/plugins/', // OK
166        '/www/example.com/wp.example.com/wp-content/plugins/', // FAIL
167//      '/www/example.com/wp.example.com/wp-content/plugins/hello.php', // Testing Example only
168);
169$fs = new WP_Filesystem_Tester( $ftp_root_prefix, $paths );
170
171foreach ( $paths as $path ) {
172        $expected = preg_replace( '!^' . preg_quote( untrailingslashit( $ftp_root_prefix ), '!' ) . '!i', '', $path );
173        $actual = $fs->find_folder( $path );
174        var_dump( compact( 'path', 'expected', 'actual' ) );
175}