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
|
---|
13 | */
|
---|
14 | class WP_Filesystem_Base {
|
---|
15 | /**
|
---|
16 | * Whether to display debug data for the connection or not.
|
---|
17 | *
|
---|
18 | * @since 2.5
|
---|
19 | * @access public
|
---|
20 | * @var bool
|
---|
21 | */
|
---|
22 | var $verbose = false;
|
---|
23 | /**
|
---|
24 | * Cached list of local filepaths to maped remote filepaths.
|
---|
25 | *
|
---|
26 | * @since 2.7
|
---|
27 | * @access private
|
---|
28 | * @var array
|
---|
29 | */
|
---|
30 | var $cache = array();
|
---|
31 |
|
---|
32 | /**
|
---|
33 | * The Access method of the current connection, Set automatically.
|
---|
34 | *
|
---|
35 | * @since 2.5
|
---|
36 | * @access public
|
---|
37 | * @var string
|
---|
38 | */
|
---|
39 | var $method = '';
|
---|
40 |
|
---|
41 | /**
|
---|
42 | * Returns the path on the remote filesystem of ABSPATH
|
---|
43 | *
|
---|
44 | * @since 2.7
|
---|
45 | * @access public
|
---|
46 | * @return string The location of the remote path.
|
---|
47 | */
|
---|
48 | function abspath() {
|
---|
49 | $folder = $this->find_folder(ABSPATH);
|
---|
50 | //Perhaps the FTP folder is rooted at the WordPress install, Check for wp-includes folder in root, Could have some false positives, but rare.
|
---|
51 | if ( ! $folder && $this->is_dir('/wp-includes') )
|
---|
52 | $folder = '/';
|
---|
53 | return $folder;
|
---|
54 | }
|
---|
55 | /**
|
---|
56 | * Returns the path on the remote filesystem of WP_CONTENT_DIR
|
---|
57 | *
|
---|
58 | * @since 2.7
|
---|
59 | * @access public
|
---|
60 | * @return string The location of the remote path.
|
---|
61 | */
|
---|
62 | function wp_content_dir() {
|
---|
63 | return $this->find_folder(WP_CONTENT_DIR);
|
---|
64 | }
|
---|
65 | /**
|
---|
66 | * Returns the path on the remote filesystem of WP_PLUGIN_DIR
|
---|
67 | *
|
---|
68 | * @since 2.7
|
---|
69 | * @access public
|
---|
70 | *
|
---|
71 | * @return string The location of the remote path.
|
---|
72 | */
|
---|
73 | function wp_plugins_dir() {
|
---|
74 | return $this->find_folder(WP_PLUGIN_DIR);
|
---|
75 | }
|
---|
76 | /**
|
---|
77 | * Returns the path on the remote filesystem of the Themes Directory
|
---|
78 | *
|
---|
79 | * @since 2.7
|
---|
80 | * @access public
|
---|
81 | *
|
---|
82 | * @return string The location of the remote path.
|
---|
83 | */
|
---|
84 | function wp_themes_dir() {
|
---|
85 | return $this->wp_content_dir() . '/themes';
|
---|
86 | }
|
---|
87 |
|
---|
88 | /**
|
---|
89 | * Locates a folder on the remote filesystem.
|
---|
90 | *
|
---|
91 | * Deprecated; use WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir() methods instead.
|
---|
92 | *
|
---|
93 | * @since 2.5
|
---|
94 | * @deprecated 2.7
|
---|
95 | * @access public
|
---|
96 | *
|
---|
97 | * @param string $base The folder to start searching from
|
---|
98 | * @param bool $echo True to display debug information
|
---|
99 | * @return string The location of the remote path.
|
---|
100 | */
|
---|
101 | function find_base_dir($base = '.', $echo = false) {
|
---|
102 | _deprecated_function(__FUNCTION__, '2.7', 'WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir()' );
|
---|
103 | $this->verbose = $echo;
|
---|
104 | return $this->abspath();
|
---|
105 | }
|
---|
106 | /**
|
---|
107 | * Locates a folder on the remote filesystem.
|
---|
108 | *
|
---|
109 | * Deprecated; use WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir() methods instead.
|
---|
110 | *
|
---|
111 | * @since 2.5
|
---|
112 | * @deprecated 2.7
|
---|
113 | * @access public
|
---|
114 | *
|
---|
115 | * @param string $base The folder to start searching from
|
---|
116 | * @param bool $echo True to display debug information
|
---|
117 | * @return string The location of the remote path.
|
---|
118 | */
|
---|
119 | function get_base_dir($base = '.', $echo = false) {
|
---|
120 | _deprecated_function(__FUNCTION__, '2.7', 'WP_Filesystem::abspath() or WP_Filesystem::wp_*_dir()' );
|
---|
121 | $this->verbose = $echo;
|
---|
122 | return $this->abspath();
|
---|
123 | }
|
---|
124 |
|
---|
125 | /**
|
---|
126 | * Locates a folder on the remote filesystem.
|
---|
127 | *
|
---|
128 | * Assumes that on Windows systems, Stripping off the Drive letter is OK
|
---|
129 | * Sanitizes \\ to / in windows filepaths.
|
---|
130 | *
|
---|
131 | * @since 2.7
|
---|
132 | * @access public
|
---|
133 | *
|
---|
134 | * @param string $folder the folder to locate
|
---|
135 | * @return string The location of the remote path.
|
---|
136 | */
|
---|
137 | function find_folder($folder) {
|
---|
138 |
|
---|
139 | if ( strpos($this->method, 'ftp') !== false ) {
|
---|
140 | $constant_overrides = array( 'FTP_BASE' => ABSPATH, 'FTP_CONTENT_DIR' => WP_CONTENT_DIR, 'FTP_PLUGIN_DIR' => WP_PLUGIN_DIR );
|
---|
141 | foreach ( $constant_overrides as $constant => $dir )
|
---|
142 | if ( defined($constant) && $folder === $dir )
|
---|
143 | return trailingslashit(constant($constant));
|
---|
144 | } elseif ( 'direct' == $this->method ) {
|
---|
145 | return trailingslashit($folder);
|
---|
146 | }
|
---|
147 |
|
---|
148 | $folder = preg_replace('|^([a-z]{1}):|i', '', $folder); //Strip out windows driveletter if its there.
|
---|
149 | $folder = str_replace('\\', '/', $folder); //Windows path sanitiation
|
---|
150 |
|
---|
151 | if ( isset($this->cache[ $folder ] ) )
|
---|
152 | return $this->cache[ $folder ];
|
---|
153 |
|
---|
154 | if ( $this->exists($folder) ) { //Folder exists at that absolute path.
|
---|
155 | $folder = trailingslashit($folder);
|
---|
156 | $this->cache[ $folder ] = $folder;
|
---|
157 | return $folder;
|
---|
158 | }
|
---|
159 | if( $return = $this->search_for_folder($folder) )
|
---|
160 | $this->cache[ $folder ] = $return;
|
---|
161 | return $return;
|
---|
162 | }
|
---|
163 |
|
---|
164 | /**
|
---|
165 | * Locates a folder on the remote filesystem.
|
---|
166 | *
|
---|
167 | * Expects Windows sanitized path
|
---|
168 | *
|
---|
169 | * @since 2.7
|
---|
170 | * @access private
|
---|
171 | *
|
---|
172 | * @param string $folder the folder to locate
|
---|
173 | * @param string $base the folder to start searching from
|
---|
174 | * @param bool $loop if the function has recursed, Internal use only
|
---|
175 | * @return string The location of the remote path.
|
---|
176 | */
|
---|
177 | function search_for_folder($folder, $base = '.', $loop = false ) {
|
---|
178 | if ( empty( $base ) || '.' == $base )
|
---|
179 | $base = trailingslashit($this->cwd());
|
---|
180 |
|
---|
181 | $folder = untrailingslashit($folder);
|
---|
182 |
|
---|
183 | $folder_parts = explode('/', $folder);
|
---|
184 | $last_path = $folder_parts[ count($folder_parts) - 1 ];
|
---|
185 |
|
---|
186 | $files = $this->dirlist( $base );
|
---|
187 |
|
---|
188 | foreach ( $folder_parts as $key ) {
|
---|
189 | if ( $key == $last_path )
|
---|
190 | continue; //We want this to be caught by the next code block.
|
---|
191 |
|
---|
192 | //Working from /home/ to /user/ to /wordpress/ see if that file exists within the current folder,
|
---|
193 | // If its found, change into it and follow through looking for it.
|
---|
194 | // If it cant find WordPress down that route, it'll continue onto the next folder level, and see if that matches, and so on.
|
---|
195 | // If it reaches the end, and still cant find it, it'll return false for the entire function.
|
---|
196 | if ( isset($files[ $key ]) ){
|
---|
197 | //Lets try that folder:
|
---|
198 | $newdir = trailingslashit(path_join($base, $key));
|
---|
199 | if ( $this->verbose )
|
---|
200 | printf( __('Changing to %s') . '<br/>', $newdir );
|
---|
201 | if ( $ret = $this->search_for_folder( $folder, $newdir, $loop) )
|
---|
202 | return $ret;
|
---|
203 | }
|
---|
204 | }
|
---|
205 |
|
---|
206 | //Only check this as a last resort, to prevent locating the incorrect install. All above proceeedures will fail quickly if this is the right branch to take.
|
---|
207 | if (isset( $files[ $last_path ] ) ) {
|
---|
208 | if ( $this->verbose )
|
---|
209 | printf( __('Found %s') . '<br/>', $base . $last_path );
|
---|
210 | return trailingslashit($base . $last_path);
|
---|
211 | }
|
---|
212 | if ( $loop )
|
---|
213 | return false;//Prevent tihs function looping again.
|
---|
214 | //As an extra last resort, Change back to / if the folder wasnt found. This comes into effect when the CWD is /home/user/ but WP is at /var/www/.... mainly dedicated setups.
|
---|
215 | return $this->search_for_folder($folder, '/', true);
|
---|
216 |
|
---|
217 | }
|
---|
218 |
|
---|
219 | /**
|
---|
220 | * Returns the *nix style file permissions for a file
|
---|
221 | *
|
---|
222 | * From the PHP documentation page for fileperms()
|
---|
223 | *
|
---|
224 | * @link http://docs.php.net/fileperms
|
---|
225 | * @since 2.5
|
---|
226 | * @access public
|
---|
227 | *
|
---|
228 | * @param string $file string filename
|
---|
229 | * @return int octal representation of permissions
|
---|
230 | */
|
---|
231 | function gethchmod($file){
|
---|
232 | $perms = $this->getchmod($file);
|
---|
233 | if (($perms & 0xC000) == 0xC000) // Socket
|
---|
234 | $info = 's';
|
---|
235 | elseif (($perms & 0xA000) == 0xA000) // Symbolic Link
|
---|
236 | $info = 'l';
|
---|
237 | elseif (($perms & 0x8000) == 0x8000) // Regular
|
---|
238 | $info = '-';
|
---|
239 | elseif (($perms & 0x6000) == 0x6000) // Block special
|
---|
240 | $info = 'b';
|
---|
241 | elseif (($perms & 0x4000) == 0x4000) // Directory
|
---|
242 | $info = 'd';
|
---|
243 | elseif (($perms & 0x2000) == 0x2000) // Character special
|
---|
244 | $info = 'c';
|
---|
245 | elseif (($perms & 0x1000) == 0x1000)// FIFO pipe
|
---|
246 | $info = 'p';
|
---|
247 | else // Unknown
|
---|
248 | $info = 'u';
|
---|
249 |
|
---|
250 | // Owner
|
---|
251 | $info .= (($perms & 0x0100) ? 'r' : '-');
|
---|
252 | $info .= (($perms & 0x0080) ? 'w' : '-');
|
---|
253 | $info .= (($perms & 0x0040) ?
|
---|
254 | (($perms & 0x0800) ? 's' : 'x' ) :
|
---|
255 | (($perms & 0x0800) ? 'S' : '-'));
|
---|
256 |
|
---|
257 | // Group
|
---|
258 | $info .= (($perms & 0x0020) ? 'r' : '-');
|
---|
259 | $info .= (($perms & 0x0010) ? 'w' : '-');
|
---|
260 | $info .= (($perms & 0x0008) ?
|
---|
261 | (($perms & 0x0400) ? 's' : 'x' ) :
|
---|
262 | (($perms & 0x0400) ? 'S' : '-'));
|
---|
263 |
|
---|
264 | // World
|
---|
265 | $info .= (($perms & 0x0004) ? 'r' : '-');
|
---|
266 | $info .= (($perms & 0x0002) ? 'w' : '-');
|
---|
267 | $info .= (($perms & 0x0001) ?
|
---|
268 | (($perms & 0x0200) ? 't' : 'x' ) :
|
---|
269 | (($perms & 0x0200) ? 'T' : '-'));
|
---|
270 | return $info;
|
---|
271 | }
|
---|
272 |
|
---|
273 | /**
|
---|
274 | * Converts *nix style file permissions to a octal number.
|
---|
275 | *
|
---|
276 | * Converts '-rw-r--r--' to 0644
|
---|
277 | * From "info at rvgate dot nl"'s comment on the PHP documentation for chmod()
|
---|
278 | *
|
---|
279 | * @link http://docs.php.net/manual/en/function.chmod.php#49614
|
---|
280 | * @since 2.5
|
---|
281 | * @access public
|
---|
282 | *
|
---|
283 | * @param string $mode string *nix style file permission
|
---|
284 | * @return int octal representation
|
---|
285 | */
|
---|
286 | function getnumchmodfromh($mode) {
|
---|
287 | $realmode = '';
|
---|
288 | $legal = array('', 'w', 'r', 'x', '-');
|
---|
289 | $attarray = preg_split('//', $mode);
|
---|
290 |
|
---|
291 | for($i=0; $i < count($attarray); $i++)
|
---|
292 | if($key = array_search($attarray[$i], $legal))
|
---|
293 | $realmode .= $legal[$key];
|
---|
294 |
|
---|
295 | $mode = str_pad($realmode, 9, '-');
|
---|
296 | $trans = array('-'=>'0', 'r'=>'4', 'w'=>'2', 'x'=>'1');
|
---|
297 | $mode = strtr($mode,$trans);
|
---|
298 |
|
---|
299 | $newmode = '';
|
---|
300 | $newmode .= $mode[0] + $mode[1] + $mode[2];
|
---|
301 | $newmode .= $mode[3] + $mode[4] + $mode[5];
|
---|
302 | $newmode .= $mode[6] + $mode[7] + $mode[8];
|
---|
303 | return $newmode;
|
---|
304 | }
|
---|
305 |
|
---|
306 | /**
|
---|
307 | * Determines if the string provided contains binary characters.
|
---|
308 | *
|
---|
309 | * @since 2.7
|
---|
310 | * @access private
|
---|
311 | *
|
---|
312 | * @param string $text String to test against
|
---|
313 | * @return bool true if string is binary, false otherwise
|
---|
314 | */
|
---|
315 | function is_binary( $text ) {
|
---|
316 | return (bool) preg_match('|[^\x20-\x7E]|', $text); //chr(32)..chr(127)
|
---|
317 | }
|
---|
318 | }
|
---|
319 |
|
---|
320 | ?>
|
---|