Fixed FTP and SMB to use rmdir() when deleting folders

Some storages need to use different calls for deleting files or folders,
usually unlink() and rmdir().

Fixes #4532 (SMB dir deletion)
Fixes #5941 (FTP dir deletion)

Note that the extra is_dir() should be fast because it's read from the
stat cache.
This commit is contained in:
Vincent Petry 2013-11-29 12:58:57 +01:00
parent 41a1a32e5a
commit d69243ee51
4 changed files with 46 additions and 8 deletions

View File

@ -61,6 +61,22 @@ class FTP extends \OC\Files\Storage\StreamWrapper{
$url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path; $url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path;
return $url; return $url;
} }
/**
* Unlinks file or directory
* @param string @path
*/
public function unlink($path) {
if ($this->is_dir($path)) {
return $this->rmdir($path);
}
else {
$url = $this->constructUrl($path);
$result = unlink($url);
clearstatcache(true, $url);
return $result;
}
}
public function fopen($path,$mode) { public function fopen($path,$mode) {
switch($mode) { switch($mode) {
case 'r': case 'r':

View File

@ -82,12 +82,18 @@ class SMB extends \OC\Files\Storage\StreamWrapper{
} }
/** /**
* Unlinks file * Unlinks file or directory
* @param string @path * @param string @path
*/ */
public function unlink($path) { public function unlink($path) {
unlink($this->constructUrl($path)); if ($this->is_dir($path)) {
clearstatcache(); $this->rmdir($path);
}
else {
$url = $this->constructUrl($path);
unlink($url);
clearstatcache(false, $url);
}
// smb4php still returns false even on success so // smb4php still returns false even on success so
// check here whether file was really deleted // check here whether file was really deleted
return !file_exists($path); return !file_exists($path);

View File

@ -25,8 +25,9 @@ abstract class StreamWrapper extends Common {
$this->unlink($path . '/' . $file); $this->unlink($path . '/' . $file);
} }
} }
$success = rmdir($this->constructUrl($path)); $url = $this->constructUrl($path);
clearstatcache(); $success = rmdir($url);
clearstatcache(false, $url);
return $success; return $success;
} else { } else {
return false; return false;
@ -46,8 +47,11 @@ abstract class StreamWrapper extends Common {
} }
public function unlink($path) { public function unlink($path) {
$success = unlink($this->constructUrl($path)); $url = $this->constructUrl($path);
clearstatcache(); $success = unlink($url);
// normally unlink() is supposed to do this implicitly,
// but doing it anyway just to be sure
clearstatcache(false, $url);
return $success; return $success;
} }

View File

@ -254,7 +254,19 @@ abstract class Storage extends \PHPUnit_Framework_TestCase {
$this->instance->mkdir('folder/bar'); $this->instance->mkdir('folder/bar');
$this->instance->file_put_contents('folder/asd.txt', 'foobar'); $this->instance->file_put_contents('folder/asd.txt', 'foobar');
$this->instance->file_put_contents('folder/bar/foo.txt', 'asd'); $this->instance->file_put_contents('folder/bar/foo.txt', 'asd');
$this->instance->rmdir('folder'); $this->assertTrue($this->instance->rmdir('folder'));
$this->assertFalse($this->instance->file_exists('folder/asd.txt'));
$this->assertFalse($this->instance->file_exists('folder/bar/foo.txt'));
$this->assertFalse($this->instance->file_exists('folder/bar'));
$this->assertFalse($this->instance->file_exists('folder'));
}
public function testRecursiveUnlink() {
$this->instance->mkdir('folder');
$this->instance->mkdir('folder/bar');
$this->instance->file_put_contents('folder/asd.txt', 'foobar');
$this->instance->file_put_contents('folder/bar/foo.txt', 'asd');
$this->assertTrue($this->instance->unlink('folder'));
$this->assertFalse($this->instance->file_exists('folder/asd.txt')); $this->assertFalse($this->instance->file_exists('folder/asd.txt'));
$this->assertFalse($this->instance->file_exists('folder/bar/foo.txt')); $this->assertFalse($this->instance->file_exists('folder/bar/foo.txt'));
$this->assertFalse($this->instance->file_exists('folder/bar')); $this->assertFalse($this->instance->file_exists('folder/bar'));