69 ); |
80 ); |
70 return; |
81 return; |
71 } |
82 } |
72 |
83 |
73 // Set defaults: |
84 // Set defaults: |
74 if ( empty($opt['port']) ) |
85 if ( empty( $opt['port'] ) ) { |
75 $this->options['port'] = 22; |
86 $this->options['port'] = 22; |
76 else |
87 } else { |
77 $this->options['port'] = $opt['port']; |
88 $this->options['port'] = $opt['port']; |
78 |
89 } |
79 if ( empty($opt['hostname']) ) |
90 |
80 $this->errors->add('empty_hostname', __('SSH2 hostname is required')); |
91 if ( empty( $opt['hostname'] ) ) { |
81 else |
92 $this->errors->add( 'empty_hostname', __( 'SSH2 hostname is required' ) ); |
|
93 } else { |
82 $this->options['hostname'] = $opt['hostname']; |
94 $this->options['hostname'] = $opt['hostname']; |
|
95 } |
83 |
96 |
84 // Check if the options provided are OK. |
97 // Check if the options provided are OK. |
85 if ( !empty ($opt['public_key']) && !empty ($opt['private_key']) ) { |
98 if ( ! empty( $opt['public_key'] ) && ! empty( $opt['private_key'] ) ) { |
86 $this->options['public_key'] = $opt['public_key']; |
99 $this->options['public_key'] = $opt['public_key']; |
87 $this->options['private_key'] = $opt['private_key']; |
100 $this->options['private_key'] = $opt['private_key']; |
88 |
101 |
89 $this->options['hostkey'] = array('hostkey' => 'ssh-rsa'); |
102 $this->options['hostkey'] = array( 'hostkey' => 'ssh-rsa' ); |
90 |
103 |
91 $this->keys = true; |
104 $this->keys = true; |
92 } elseif ( empty ($opt['username']) ) { |
105 } elseif ( empty( $opt['username'] ) ) { |
93 $this->errors->add('empty_username', __('SSH2 username is required')); |
106 $this->errors->add( 'empty_username', __( 'SSH2 username is required' ) ); |
94 } |
107 } |
95 |
108 |
96 if ( !empty($opt['username']) ) |
109 if ( ! empty( $opt['username'] ) ) { |
97 $this->options['username'] = $opt['username']; |
110 $this->options['username'] = $opt['username']; |
98 |
111 } |
99 if ( empty ($opt['password']) ) { |
112 |
|
113 if ( empty( $opt['password'] ) ) { |
100 // Password can be blank if we are using keys. |
114 // Password can be blank if we are using keys. |
101 if ( !$this->keys ) |
115 if ( ! $this->keys ) { |
102 $this->errors->add('empty_password', __('SSH2 password is required')); |
116 $this->errors->add( 'empty_password', __( 'SSH2 password is required' ) ); |
|
117 } |
103 } else { |
118 } else { |
104 $this->options['password'] = $opt['password']; |
119 $this->options['password'] = $opt['password']; |
105 } |
120 } |
106 } |
121 } |
107 |
122 |
108 /** |
123 /** |
109 * |
124 * Connects filesystem. |
110 * @return bool |
125 * |
|
126 * @since 2.7.0 |
|
127 * |
|
128 * @return bool True on success, false on failure. |
111 */ |
129 */ |
112 public function connect() { |
130 public function connect() { |
113 if ( ! $this->keys ) { |
131 if ( ! $this->keys ) { |
114 $this->link = @ssh2_connect($this->options['hostname'], $this->options['port']); |
132 $this->link = @ssh2_connect( $this->options['hostname'], $this->options['port'] ); |
115 } else { |
133 } else { |
116 $this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']); |
134 $this->link = @ssh2_connect( $this->options['hostname'], $this->options['port'], $this->options['hostkey'] ); |
117 } |
135 } |
118 |
136 |
119 if ( ! $this->link ) { |
137 if ( ! $this->link ) { |
120 $this->errors->add( 'connect', |
138 $this->errors->add( |
|
139 'connect', |
121 /* translators: %s: hostname:port */ |
140 /* translators: %s: hostname:port */ |
122 sprintf( __( 'Failed to connect to SSH2 Server %s' ), |
141 sprintf( |
|
142 __( 'Failed to connect to SSH2 Server %s' ), |
123 $this->options['hostname'] . ':' . $this->options['port'] |
143 $this->options['hostname'] . ':' . $this->options['port'] |
124 ) |
144 ) |
125 ); |
145 ); |
126 return false; |
146 return false; |
127 } |
147 } |
128 |
148 |
129 if ( !$this->keys ) { |
149 if ( ! $this->keys ) { |
130 if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) { |
150 if ( ! @ssh2_auth_password( $this->link, $this->options['username'], $this->options['password'] ) ) { |
131 $this->errors->add( 'auth', |
151 $this->errors->add( |
|
152 'auth', |
132 /* translators: %s: username */ |
153 /* translators: %s: username */ |
133 sprintf( __( 'Username/Password incorrect for %s' ), |
154 sprintf( |
|
155 __( 'Username/Password incorrect for %s' ), |
134 $this->options['username'] |
156 $this->options['username'] |
135 ) |
157 ) |
136 ); |
158 ); |
137 return false; |
159 return false; |
138 } |
160 } |
139 } else { |
161 } else { |
140 if ( ! @ssh2_auth_pubkey_file($this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) { |
162 if ( ! @ssh2_auth_pubkey_file( $this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) { |
141 $this->errors->add( 'auth', |
163 $this->errors->add( |
|
164 'auth', |
142 /* translators: %s: username */ |
165 /* translators: %s: username */ |
143 sprintf( __( 'Public and Private keys incorrect for %s' ), |
166 sprintf( |
|
167 __( 'Public and Private keys incorrect for %s' ), |
144 $this->options['username'] |
168 $this->options['username'] |
145 ) |
169 ) |
146 ); |
170 ); |
147 return false; |
171 return false; |
148 } |
172 } |
149 } |
173 } |
150 |
174 |
151 $this->sftp_link = ssh2_sftp( $this->link ); |
175 $this->sftp_link = ssh2_sftp( $this->link ); |
152 if ( ! $this->sftp_link ) { |
176 if ( ! $this->sftp_link ) { |
153 $this->errors->add( 'connect', |
177 $this->errors->add( |
|
178 'connect', |
154 /* translators: %s: hostname:port */ |
179 /* translators: %s: hostname:port */ |
155 sprintf( __( 'Failed to initialize a SFTP subsystem session with the SSH2 Server %s' ), |
180 sprintf( |
|
181 __( 'Failed to initialize a SFTP subsystem session with the SSH2 Server %s' ), |
156 $this->options['hostname'] . ':' . $this->options['port'] |
182 $this->options['hostname'] . ':' . $this->options['port'] |
157 ) |
183 ) |
158 ); |
184 ); |
159 return false; |
185 return false; |
160 } |
186 } |
182 } |
207 } |
183 return 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $path, '/' ); |
208 return 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $path, '/' ); |
184 } |
209 } |
185 |
210 |
186 /** |
211 /** |
|
212 * @since 2.7.0 |
187 * |
213 * |
188 * @param string $command |
214 * @param string $command |
189 * @param bool $returnbool |
215 * @param bool $returnbool |
190 * @return bool|string True on success, false on failure. String if the command was executed, `$returnbool` |
216 * @return bool|string True on success, false on failure. String if the command was executed, `$returnbool` |
191 * is false (default), and data from the resulting stream was retrieved. |
217 * is false (default), and data from the resulting stream was retrieved. |
192 */ |
218 */ |
193 public function run_command( $command, $returnbool = false ) { |
219 public function run_command( $command, $returnbool = false ) { |
194 if ( ! $this->link ) |
220 if ( ! $this->link ) { |
195 return false; |
221 return false; |
196 |
222 } |
197 if ( ! ($stream = ssh2_exec($this->link, $command)) ) { |
223 |
198 $this->errors->add( 'command', |
224 if ( ! ( $stream = ssh2_exec( $this->link, $command ) ) ) { |
|
225 $this->errors->add( |
|
226 'command', |
199 /* translators: %s: command */ |
227 /* translators: %s: command */ |
200 sprintf( __( 'Unable to perform command: %s'), |
228 sprintf( |
|
229 __( 'Unable to perform command: %s' ), |
201 $command |
230 $command |
202 ) |
231 ) |
203 ); |
232 ); |
204 } else { |
233 } else { |
205 stream_set_blocking( $stream, true ); |
234 stream_set_blocking( $stream, true ); |
206 stream_set_timeout( $stream, FS_TIMEOUT ); |
235 stream_set_timeout( $stream, FS_TIMEOUT ); |
207 $data = stream_get_contents( $stream ); |
236 $data = stream_get_contents( $stream ); |
208 fclose( $stream ); |
237 fclose( $stream ); |
209 |
238 |
210 if ( $returnbool ) |
239 if ( $returnbool ) { |
211 return ( $data === false ) ? false : '' != trim($data); |
240 return ( $data === false ) ? false : '' != trim( $data ); |
212 else |
241 } else { |
213 return $data; |
242 return $data; |
|
243 } |
214 } |
244 } |
215 return false; |
245 return false; |
216 } |
246 } |
217 |
247 |
218 /** |
248 /** |
219 * |
249 * Reads entire file into a string. |
220 * @param string $file |
250 * |
221 * @return string|false |
251 * @since 2.7.0 |
|
252 * |
|
253 * @param string $file Name of the file to read. |
|
254 * @return string|false Read data on success, false if no temporary file could be opened, |
|
255 * or if the file couldn't be retrieved. |
222 */ |
256 */ |
223 public function get_contents( $file ) { |
257 public function get_contents( $file ) { |
224 return file_get_contents( $this->sftp_path( $file ) ); |
258 return file_get_contents( $this->sftp_path( $file ) ); |
225 } |
259 } |
226 |
260 |
227 /** |
261 /** |
228 * |
262 * Reads entire file into an array. |
229 * @param string $file |
263 * |
230 * @return array |
264 * @since 2.7.0 |
231 */ |
265 * |
232 public function get_contents_array($file) { |
266 * @param string $file Path to the file. |
|
267 * @return array|false File contents in an array on success, false on failure. |
|
268 */ |
|
269 public function get_contents_array( $file ) { |
233 return file( $this->sftp_path( $file ) ); |
270 return file( $this->sftp_path( $file ) ); |
234 } |
271 } |
235 |
272 |
236 /** |
273 /** |
237 * |
274 * Writes a string to a file. |
238 * @param string $file |
275 * |
239 * @param string $contents |
276 * @since 2.7.0 |
240 * @param bool|int $mode |
277 * |
241 * @return bool |
278 * @param string $file Remote path to the file where to write the data. |
242 */ |
279 * @param string $contents The data to write. |
243 public function put_contents($file, $contents, $mode = false ) { |
280 * @param int|false $mode Optional. The file permissions as octal number, usually 0644. |
|
281 * Default false. |
|
282 * @return bool True on success, false on failure. |
|
283 */ |
|
284 public function put_contents( $file, $contents, $mode = false ) { |
244 $ret = file_put_contents( $this->sftp_path( $file ), $contents ); |
285 $ret = file_put_contents( $this->sftp_path( $file ), $contents ); |
245 |
286 |
246 if ( $ret !== strlen( $contents ) ) |
287 if ( $ret !== strlen( $contents ) ) { |
247 return false; |
288 return false; |
248 |
289 } |
249 $this->chmod($file, $mode); |
290 |
|
291 $this->chmod( $file, $mode ); |
250 |
292 |
251 return true; |
293 return true; |
252 } |
294 } |
253 |
295 |
254 /** |
296 /** |
255 * |
297 * Gets the current working directory. |
256 * @return bool |
298 * |
|
299 * @since 2.7.0 |
|
300 * |
|
301 * @return string|false The current working directory on success, false on failure. |
257 */ |
302 */ |
258 public function cwd() { |
303 public function cwd() { |
259 $cwd = ssh2_sftp_realpath( $this->sftp_link, '.' ); |
304 $cwd = ssh2_sftp_realpath( $this->sftp_link, '.' ); |
260 if ( $cwd ) { |
305 if ( $cwd ) { |
261 $cwd = trailingslashit( trim( $cwd ) ); |
306 $cwd = trailingslashit( trim( $cwd ) ); |
262 } |
307 } |
263 return $cwd; |
308 return $cwd; |
264 } |
309 } |
265 |
310 |
266 /** |
311 /** |
267 * |
312 * Changes current directory. |
268 * @param string $dir |
313 * |
269 * @return bool|string |
314 * @since 2.7.0 |
270 */ |
315 * |
271 public function chdir($dir) { |
316 * @param string $dir The new current directory. |
272 return $this->run_command('cd ' . $dir, true); |
317 * @return bool True on success, false on failure. |
273 } |
318 */ |
274 |
319 public function chdir( $dir ) { |
275 /** |
320 return $this->run_command( 'cd ' . $dir, true ); |
276 * |
321 } |
277 * @param string $file |
322 |
278 * @param string $group |
323 /** |
279 * @param bool $recursive |
324 * Changes the file group. |
280 * |
325 * |
281 * @return bool |
326 * @since 2.7.0 |
282 */ |
327 * |
283 public function chgrp($file, $group, $recursive = false ) { |
328 * @param string $file Path to the file. |
284 if ( ! $this->exists($file) ) |
329 * @param string|int $group A group name or number. |
285 return false; |
330 * @param bool $recursive Optional. If set to true, changes file group recursively. |
286 if ( ! $recursive || ! $this->is_dir($file) ) |
331 * Default false. |
287 return $this->run_command(sprintf('chgrp %s %s', escapeshellarg($group), escapeshellarg($file)), true); |
332 * @return bool True on success, false on failure. |
288 return $this->run_command(sprintf('chgrp -R %s %s', escapeshellarg($group), escapeshellarg($file)), true); |
333 */ |
289 } |
334 public function chgrp( $file, $group, $recursive = false ) { |
290 |
335 if ( ! $this->exists( $file ) ) { |
291 /** |
336 return false; |
292 * |
337 } |
293 * @param string $file |
338 if ( ! $recursive || ! $this->is_dir( $file ) ) { |
294 * @param int $mode |
339 return $this->run_command( sprintf( 'chgrp %s %s', escapeshellarg( $group ), escapeshellarg( $file ) ), true ); |
295 * @param bool $recursive |
340 } |
296 * @return bool|string |
341 return $this->run_command( sprintf( 'chgrp -R %s %s', escapeshellarg( $group ), escapeshellarg( $file ) ), true ); |
297 */ |
342 } |
298 public function chmod($file, $mode = false, $recursive = false) { |
343 |
299 if ( ! $this->exists($file) ) |
344 /** |
300 return false; |
345 * Changes filesystem permissions. |
|
346 * |
|
347 * @since 2.7.0 |
|
348 * |
|
349 * @param string $file Path to the file. |
|
350 * @param int|false $mode Optional. The permissions as octal number, usually 0644 for files, |
|
351 * 0755 for directories. Default false. |
|
352 * @param bool $recursive Optional. If set to true, changes file group recursively. |
|
353 * Default false. |
|
354 * @return bool True on success, false on failure. |
|
355 */ |
|
356 public function chmod( $file, $mode = false, $recursive = false ) { |
|
357 if ( ! $this->exists( $file ) ) { |
|
358 return false; |
|
359 } |
301 |
360 |
302 if ( ! $mode ) { |
361 if ( ! $mode ) { |
303 if ( $this->is_file($file) ) |
362 if ( $this->is_file( $file ) ) { |
304 $mode = FS_CHMOD_FILE; |
363 $mode = FS_CHMOD_FILE; |
305 elseif ( $this->is_dir($file) ) |
364 } elseif ( $this->is_dir( $file ) ) { |
306 $mode = FS_CHMOD_DIR; |
365 $mode = FS_CHMOD_DIR; |
307 else |
366 } else { |
308 return false; |
367 return false; |
309 } |
368 } |
310 |
369 } |
311 if ( ! $recursive || ! $this->is_dir($file) ) |
370 |
312 return $this->run_command(sprintf('chmod %o %s', $mode, escapeshellarg($file)), true); |
371 if ( ! $recursive || ! $this->is_dir( $file ) ) { |
313 return $this->run_command(sprintf('chmod -R %o %s', $mode, escapeshellarg($file)), true); |
372 return $this->run_command( sprintf( 'chmod %o %s', $mode, escapeshellarg( $file ) ), true ); |
314 } |
373 } |
315 |
374 return $this->run_command( sprintf( 'chmod -R %o %s', $mode, escapeshellarg( $file ) ), true ); |
316 /** |
375 } |
317 * Change the ownership of a file / folder. |
376 |
318 * |
377 /** |
319 * |
378 * Changes the owner of a file or directory. |
320 * @param string $file Path to the file. |
379 * |
|
380 * @since 2.7.0 |
|
381 * |
|
382 * @param string $file Path to the file or directory. |
321 * @param string|int $owner A user name or number. |
383 * @param string|int $owner A user name or number. |
322 * @param bool $recursive Optional. If set True changes file owner recursivly. Default False. |
384 * @param bool $recursive Optional. If set to true, changes file owner recursively. |
323 * @return bool True on success or false on failure. |
385 * Default false. |
|
386 * @return bool True on success, false on failure. |
324 */ |
387 */ |
325 public function chown( $file, $owner, $recursive = false ) { |
388 public function chown( $file, $owner, $recursive = false ) { |
326 if ( ! $this->exists($file) ) |
389 if ( ! $this->exists( $file ) ) { |
327 return false; |
390 return false; |
328 if ( ! $recursive || ! $this->is_dir($file) ) |
391 } |
329 return $this->run_command(sprintf('chown %s %s', escapeshellarg($owner), escapeshellarg($file)), true); |
392 if ( ! $recursive || ! $this->is_dir( $file ) ) { |
330 return $this->run_command(sprintf('chown -R %s %s', escapeshellarg($owner), escapeshellarg($file)), true); |
393 return $this->run_command( sprintf( 'chown %s %s', escapeshellarg( $owner ), escapeshellarg( $file ) ), true ); |
331 } |
394 } |
332 |
395 return $this->run_command( sprintf( 'chown -R %s %s', escapeshellarg( $owner ), escapeshellarg( $file ) ), true ); |
333 /** |
396 } |
334 * |
397 |
335 * @param string $file |
398 /** |
336 * @return string|false |
399 * Gets the file owner. |
337 */ |
400 * |
338 public function owner($file) { |
401 * @since 2.7.0 |
|
402 * |
|
403 * @param string $file Path to the file. |
|
404 * @return string|false Username of the owner on success, false on failure. |
|
405 */ |
|
406 public function owner( $file ) { |
339 $owneruid = @fileowner( $this->sftp_path( $file ) ); |
407 $owneruid = @fileowner( $this->sftp_path( $file ) ); |
340 if ( ! $owneruid ) |
408 if ( ! $owneruid ) { |
341 return false; |
409 return false; |
342 if ( ! function_exists('posix_getpwuid') ) |
410 } |
|
411 if ( ! function_exists( 'posix_getpwuid' ) ) { |
343 return $owneruid; |
412 return $owneruid; |
344 $ownerarray = posix_getpwuid($owneruid); |
413 } |
|
414 $ownerarray = posix_getpwuid( $owneruid ); |
345 return $ownerarray['name']; |
415 return $ownerarray['name']; |
346 } |
416 } |
347 |
417 |
348 /** |
418 /** |
349 * |
419 * Gets the permissions of the specified file or filepath in their octal format. |
350 * @param string $file |
420 * |
351 * @return string |
421 * @since 2.7.0 |
352 */ |
422 * |
353 public function getchmod($file) { |
423 * @param string $file Path to the file. |
|
424 * @return string Mode of the file (the last 3 digits). |
|
425 */ |
|
426 public function getchmod( $file ) { |
354 return substr( decoct( @fileperms( $this->sftp_path( $file ) ) ), -3 ); |
427 return substr( decoct( @fileperms( $this->sftp_path( $file ) ) ), -3 ); |
355 } |
428 } |
356 |
429 |
357 /** |
430 /** |
358 * |
431 * Gets the file's group. |
359 * @param string $file |
432 * |
360 * @return string|false |
433 * @since 2.7.0 |
361 */ |
434 * |
362 public function group($file) { |
435 * @param string $file Path to the file. |
|
436 * @return string|false The group on success, false on failure. |
|
437 */ |
|
438 public function group( $file ) { |
363 $gid = @filegroup( $this->sftp_path( $file ) ); |
439 $gid = @filegroup( $this->sftp_path( $file ) ); |
364 if ( ! $gid ) |
440 if ( ! $gid ) { |
365 return false; |
441 return false; |
366 if ( ! function_exists('posix_getgrgid') ) |
442 } |
|
443 if ( ! function_exists( 'posix_getgrgid' ) ) { |
367 return $gid; |
444 return $gid; |
368 $grouparray = posix_getgrgid($gid); |
445 } |
|
446 $grouparray = posix_getgrgid( $gid ); |
369 return $grouparray['name']; |
447 return $grouparray['name']; |
370 } |
448 } |
371 |
449 |
372 /** |
450 /** |
373 * |
451 * Copies a file. |
374 * @param string $source |
452 * |
375 * @param string $destination |
453 * @since 2.7.0 |
376 * @param bool $overwrite |
454 * |
377 * @param int|bool $mode |
455 * @param string $source Path to the source file. |
378 * @return bool |
456 * @param string $destination Path to the destination file. |
379 */ |
457 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. |
380 public function copy($source, $destination, $overwrite = false, $mode = false) { |
458 * Default false. |
381 if ( ! $overwrite && $this->exists($destination) ) |
459 * @param int|false $mode Optional. The permissions as octal number, usually 0644 for files, |
382 return false; |
460 * 0755 for dirs. Default false. |
383 $content = $this->get_contents($source); |
461 * @return bool True on success, false on failure. |
384 if ( false === $content) |
462 */ |
385 return false; |
463 public function copy( $source, $destination, $overwrite = false, $mode = false ) { |
386 return $this->put_contents($destination, $content, $mode); |
464 if ( ! $overwrite && $this->exists( $destination ) ) { |
387 } |
465 return false; |
388 |
466 } |
389 /** |
467 $content = $this->get_contents( $source ); |
390 * |
468 if ( false === $content ) { |
391 * @param string $source |
469 return false; |
392 * @param string $destination |
470 } |
393 * @param bool $overwrite |
471 return $this->put_contents( $destination, $content, $mode ); |
394 * @return bool |
472 } |
395 */ |
473 |
396 public function move($source, $destination, $overwrite = false) { |
474 /** |
|
475 * Moves a file. |
|
476 * |
|
477 * @since 2.7.0 |
|
478 * |
|
479 * @param string $source Path to the source file. |
|
480 * @param string $destination Path to the destination file. |
|
481 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. |
|
482 * Default false. |
|
483 * @return bool True on success, false on failure. |
|
484 */ |
|
485 public function move( $source, $destination, $overwrite = false ) { |
397 return @ssh2_sftp_rename( $this->sftp_link, $source, $destination ); |
486 return @ssh2_sftp_rename( $this->sftp_link, $source, $destination ); |
398 } |
487 } |
399 |
488 |
400 /** |
489 /** |
401 * |
490 * Deletes a file or directory. |
402 * @param string $file |
491 * |
403 * @param bool $recursive |
492 * @since 2.7.0 |
404 * @param string|bool $type |
493 * |
405 * @return bool |
494 * @param string $file Path to the file or directory. |
406 */ |
495 * @param bool $recursive Optional. If set to true, changes file group recursively. |
407 public function delete($file, $recursive = false, $type = false) { |
496 * Default false. |
408 if ( 'f' == $type || $this->is_file($file) ) |
497 * @param string|false $type Type of resource. 'f' for file, 'd' for directory. |
409 return ssh2_sftp_unlink($this->sftp_link, $file); |
498 * Default false. |
410 if ( ! $recursive ) |
499 * @return bool True on success, false on failure. |
411 return ssh2_sftp_rmdir($this->sftp_link, $file); |
500 */ |
412 $filelist = $this->dirlist($file); |
501 public function delete( $file, $recursive = false, $type = false ) { |
413 if ( is_array($filelist) ) { |
502 if ( 'f' == $type || $this->is_file( $file ) ) { |
414 foreach ( $filelist as $filename => $fileinfo) { |
503 return ssh2_sftp_unlink( $this->sftp_link, $file ); |
415 $this->delete($file . '/' . $filename, $recursive, $fileinfo['type']); |
504 } |
416 } |
505 if ( ! $recursive ) { |
417 } |
506 return ssh2_sftp_rmdir( $this->sftp_link, $file ); |
418 return ssh2_sftp_rmdir($this->sftp_link, $file); |
507 } |
419 } |
508 $filelist = $this->dirlist( $file ); |
420 |
509 if ( is_array( $filelist ) ) { |
421 /** |
510 foreach ( $filelist as $filename => $fileinfo ) { |
422 * |
511 $this->delete( $file . '/' . $filename, $recursive, $fileinfo['type'] ); |
423 * @param string $file |
512 } |
424 * @return bool |
513 } |
425 */ |
514 return ssh2_sftp_rmdir( $this->sftp_link, $file ); |
426 public function exists($file) { |
515 } |
|
516 |
|
517 /** |
|
518 * Checks if a file or directory exists. |
|
519 * |
|
520 * @since 2.7.0 |
|
521 * |
|
522 * @param string $file Path to file or directory. |
|
523 * @return bool Whether $file exists or not. |
|
524 */ |
|
525 public function exists( $file ) { |
427 return file_exists( $this->sftp_path( $file ) ); |
526 return file_exists( $this->sftp_path( $file ) ); |
428 } |
527 } |
429 |
528 |
430 /** |
529 /** |
431 * |
530 * Checks if resource is a file. |
432 * @param string $file |
531 * |
433 * @return bool |
532 * @since 2.7.0 |
434 */ |
533 * |
435 public function is_file($file) { |
534 * @param string $file File path. |
|
535 * @return bool Whether $file is a file. |
|
536 */ |
|
537 public function is_file( $file ) { |
436 return is_file( $this->sftp_path( $file ) ); |
538 return is_file( $this->sftp_path( $file ) ); |
437 } |
539 } |
438 |
540 |
439 /** |
541 /** |
440 * |
542 * Checks if resource is a directory. |
441 * @param string $path |
543 * |
442 * @return bool |
544 * @since 2.7.0 |
443 */ |
545 * |
444 public function is_dir($path) { |
546 * @param string $path Directory path. |
|
547 * @return bool Whether $path is a directory. |
|
548 */ |
|
549 public function is_dir( $path ) { |
445 return is_dir( $this->sftp_path( $path ) ); |
550 return is_dir( $this->sftp_path( $path ) ); |
446 } |
551 } |
447 |
552 |
448 /** |
553 /** |
449 * |
554 * Checks if a file is readable. |
450 * @param string $file |
555 * |
451 * @return bool |
556 * @since 2.7.0 |
452 */ |
557 * |
453 public function is_readable($file) { |
558 * @param string $file Path to file. |
|
559 * @return bool Whether $file is readable. |
|
560 */ |
|
561 public function is_readable( $file ) { |
454 return is_readable( $this->sftp_path( $file ) ); |
562 return is_readable( $this->sftp_path( $file ) ); |
455 } |
563 } |
456 |
564 |
457 /** |
565 /** |
458 * |
566 * Checks if a file or directory is writable. |
459 * @param string $file |
567 * |
460 * @return bool |
568 * @since 2.7.0 |
461 */ |
569 * |
462 public function is_writable($file) { |
570 * @param string $file Path to file or directory. |
|
571 * @return bool Whether $file is writable. |
|
572 */ |
|
573 public function is_writable( $file ) { |
463 // PHP will base it's writable checks on system_user === file_owner, not ssh_user === file_owner |
574 // PHP will base it's writable checks on system_user === file_owner, not ssh_user === file_owner |
464 return true; |
575 return true; |
465 } |
576 } |
466 |
577 |
467 /** |
578 /** |
468 * |
579 * Gets the file's last access time. |
469 * @param string $file |
580 * |
470 * @return int |
581 * @since 2.7.0 |
471 */ |
582 * |
472 public function atime($file) { |
583 * @param string $file Path to file. |
|
584 * @return int|false Unix timestamp representing last access time, false on failure. |
|
585 */ |
|
586 public function atime( $file ) { |
473 return fileatime( $this->sftp_path( $file ) ); |
587 return fileatime( $this->sftp_path( $file ) ); |
474 } |
588 } |
475 |
589 |
476 /** |
590 /** |
477 * |
591 * Gets the file modification time. |
478 * @param string $file |
592 * |
479 * @return int |
593 * @since 2.7.0 |
480 */ |
594 * |
481 public function mtime($file) { |
595 * @param string $file Path to file. |
|
596 * @return int|false Unix timestamp representing modification time, false on failure. |
|
597 */ |
|
598 public function mtime( $file ) { |
482 return filemtime( $this->sftp_path( $file ) ); |
599 return filemtime( $this->sftp_path( $file ) ); |
483 } |
600 } |
484 |
601 |
485 /** |
602 /** |
486 * |
603 * Gets the file size (in bytes). |
487 * @param string $file |
604 * |
488 * @return int |
605 * @since 2.7.0 |
489 */ |
606 * |
490 public function size($file) { |
607 * @param string $file Path to file. |
|
608 * @return int|false Size of the file in bytes on success, false on failure. |
|
609 */ |
|
610 public function size( $file ) { |
491 return filesize( $this->sftp_path( $file ) ); |
611 return filesize( $this->sftp_path( $file ) ); |
492 } |
612 } |
493 |
613 |
494 /** |
614 /** |
495 * |
615 * Sets the access and modification times of a file. |
496 * @param string $file |
616 * |
497 * @param int $time |
617 * Note: Not implemented. |
498 * @param int $atime |
618 * |
499 */ |
619 * @since 2.7.0 |
500 public function touch($file, $time = 0, $atime = 0) { |
620 * |
501 //Not implemented. |
621 * @param string $file Path to file. |
502 } |
622 * @param int $time Optional. Modified time to set for file. |
503 |
623 * Default 0. |
504 /** |
624 * @param int $atime Optional. Access time to set for file. |
505 * |
625 * Default 0. |
506 * @param string $path |
626 */ |
507 * @param mixed $chmod |
627 public function touch( $file, $time = 0, $atime = 0 ) { |
508 * @param mixed $chown |
628 // Not implemented. |
509 * @param mixed $chgrp |
629 } |
510 * @return bool |
630 |
511 */ |
631 /** |
512 public function mkdir($path, $chmod = false, $chown = false, $chgrp = false) { |
632 * Creates a directory. |
513 $path = untrailingslashit($path); |
633 * |
514 if ( empty($path) ) |
634 * @since 2.7.0 |
515 return false; |
635 * |
516 |
636 * @param string $path Path for new directory. |
517 if ( ! $chmod ) |
637 * @param int|false $chmod Optional. The permissions as octal number (or false to skip chmod). |
|
638 * Default false. |
|
639 * @param string|int $chown Optional. A user name or number (or false to skip chown). |
|
640 * Default false. |
|
641 * @param string|int $chgrp Optional. A group name or number (or false to skip chgrp). |
|
642 * Default false. |
|
643 * @return bool True on success, false on failure. |
|
644 */ |
|
645 public function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) { |
|
646 $path = untrailingslashit( $path ); |
|
647 if ( empty( $path ) ) { |
|
648 return false; |
|
649 } |
|
650 |
|
651 if ( ! $chmod ) { |
518 $chmod = FS_CHMOD_DIR; |
652 $chmod = FS_CHMOD_DIR; |
519 if ( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) ) |
653 } |
520 return false; |
654 if ( ! ssh2_sftp_mkdir( $this->sftp_link, $path, $chmod, true ) ) { |
521 if ( $chown ) |
655 return false; |
522 $this->chown($path, $chown); |
656 } |
523 if ( $chgrp ) |
657 if ( $chown ) { |
524 $this->chgrp($path, $chgrp); |
658 $this->chown( $path, $chown ); |
|
659 } |
|
660 if ( $chgrp ) { |
|
661 $this->chgrp( $path, $chgrp ); |
|
662 } |
525 return true; |
663 return true; |
526 } |
664 } |
527 |
665 |
528 /** |
666 /** |
529 * |
667 * Deletes a directory. |
530 * @param string $path |
668 * |
531 * @param bool $recursive |
669 * @since 2.7.0 |
532 * @return bool |
670 * |
533 */ |
671 * @param string $path Path to directory. |
534 public function rmdir($path, $recursive = false) { |
672 * @param bool $recursive Optional. Whether to recursively remove files/directories. |
535 return $this->delete($path, $recursive); |
673 * Default false. |
536 } |
674 * @return bool True on success, false on failure. |
537 |
675 */ |
538 /** |
676 public function rmdir( $path, $recursive = false ) { |
539 * |
677 return $this->delete( $path, $recursive ); |
540 * @param string $path |
678 } |
541 * @param bool $include_hidden |
679 |
542 * @param bool $recursive |
680 /** |
543 * @return bool|array |
681 * Gets details for files in a directory or a specific file. |
544 */ |
682 * |
545 public function dirlist($path, $include_hidden = true, $recursive = false) { |
683 * @since 2.7.0 |
546 if ( $this->is_file($path) ) { |
684 * |
547 $limit_file = basename($path); |
685 * @param string $path Path to directory or file. |
548 $path = dirname($path); |
686 * @param bool $include_hidden Optional. Whether to include details of hidden ("." prefixed) files. |
|
687 * Default true. |
|
688 * @param bool $recursive Optional. Whether to recursively include file details in nested directories. |
|
689 * Default false. |
|
690 * @return array|false { |
|
691 * Array of files. False if unable to list directory contents. |
|
692 * |
|
693 * @type string $name Name of the file or directory. |
|
694 * @type string $perms *nix representation of permissions. |
|
695 * @type int $permsn Octal representation of permissions. |
|
696 * @type string $owner Owner name or ID. |
|
697 * @type int $size Size of file in bytes. |
|
698 * @type int $lastmodunix Last modified unix timestamp. |
|
699 * @type mixed $lastmod Last modified month (3 letter) and day (without leading 0). |
|
700 * @type int $time Last modified time. |
|
701 * @type string $type Type of resource. 'f' for file, 'd' for directory. |
|
702 * @type mixed $files If a directory and $recursive is true, contains another array of files. |
|
703 * } |
|
704 */ |
|
705 public function dirlist( $path, $include_hidden = true, $recursive = false ) { |
|
706 if ( $this->is_file( $path ) ) { |
|
707 $limit_file = basename( $path ); |
|
708 $path = dirname( $path ); |
549 } else { |
709 } else { |
550 $limit_file = false; |
710 $limit_file = false; |
551 } |
711 } |
552 |
712 |
553 if ( ! $this->is_dir($path) ) |
713 if ( ! $this->is_dir( $path ) ) { |
554 return false; |
714 return false; |
|
715 } |
555 |
716 |
556 $ret = array(); |
717 $ret = array(); |
557 $dir = @dir( $this->sftp_path( $path ) ); |
718 $dir = @dir( $this->sftp_path( $path ) ); |
558 |
719 |
559 if ( ! $dir ) |
720 if ( ! $dir ) { |
560 return false; |
721 return false; |
561 |
722 } |
562 while (false !== ($entry = $dir->read()) ) { |
723 |
563 $struc = array(); |
724 while ( false !== ( $entry = $dir->read() ) ) { |
|
725 $struc = array(); |
564 $struc['name'] = $entry; |
726 $struc['name'] = $entry; |
565 |
727 |
566 if ( '.' == $struc['name'] || '..' == $struc['name'] ) |
728 if ( '.' == $struc['name'] || '..' == $struc['name'] ) { |
567 continue; //Do not care about these folders. |
729 continue; //Do not care about these folders. |
568 |
730 } |
569 if ( ! $include_hidden && '.' == $struc['name'][0] ) |
731 |
|
732 if ( ! $include_hidden && '.' == $struc['name'][0] ) { |
570 continue; |
733 continue; |
571 |
734 } |
572 if ( $limit_file && $struc['name'] != $limit_file ) |
735 |
|
736 if ( $limit_file && $struc['name'] != $limit_file ) { |
573 continue; |
737 continue; |
574 |
738 } |
575 $struc['perms'] = $this->gethchmod($path.'/'.$entry); |
739 |
576 $struc['permsn'] = $this->getnumchmodfromh($struc['perms']); |
740 $struc['perms'] = $this->gethchmod( $path . '/' . $entry ); |
577 $struc['number'] = false; |
741 $struc['permsn'] = $this->getnumchmodfromh( $struc['perms'] ); |
578 $struc['owner'] = $this->owner($path.'/'.$entry); |
742 $struc['number'] = false; |
579 $struc['group'] = $this->group($path.'/'.$entry); |
743 $struc['owner'] = $this->owner( $path . '/' . $entry ); |
580 $struc['size'] = $this->size($path.'/'.$entry); |
744 $struc['group'] = $this->group( $path . '/' . $entry ); |
581 $struc['lastmodunix']= $this->mtime($path.'/'.$entry); |
745 $struc['size'] = $this->size( $path . '/' . $entry ); |
582 $struc['lastmod'] = date('M j',$struc['lastmodunix']); |
746 $struc['lastmodunix'] = $this->mtime( $path . '/' . $entry ); |
583 $struc['time'] = date('h:i:s',$struc['lastmodunix']); |
747 $struc['lastmod'] = date( 'M j', $struc['lastmodunix'] ); |
584 $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd' : 'f'; |
748 $struc['time'] = date( 'h:i:s', $struc['lastmodunix'] ); |
|
749 $struc['type'] = $this->is_dir( $path . '/' . $entry ) ? 'd' : 'f'; |
585 |
750 |
586 if ( 'd' == $struc['type'] ) { |
751 if ( 'd' == $struc['type'] ) { |
587 if ( $recursive ) |
752 if ( $recursive ) { |
588 $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive); |
753 $struc['files'] = $this->dirlist( $path . '/' . $struc['name'], $include_hidden, $recursive ); |
589 else |
754 } else { |
590 $struc['files'] = array(); |
755 $struc['files'] = array(); |
|
756 } |
591 } |
757 } |
592 |
758 |
593 $ret[ $struc['name'] ] = $struc; |
759 $ret[ $struc['name'] ] = $struc; |
594 } |
760 } |
595 $dir->close(); |
761 $dir->close(); |
596 unset($dir); |
762 unset( $dir ); |
597 return $ret; |
763 return $ret; |
598 } |
764 } |
599 } |
765 } |