diff options
author | Vincent Petry <pvince81@owncloud.com> | 2013-11-29 12:58:57 +0100 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2013-12-02 11:12:09 +0100 |
commit | 3b18c1bae4fd038c378010e76d4946313f23f2ef (patch) | |
tree | 494fe145fe218f901ae290b3fe1e2a11e894b34c | |
parent | e079d34f5af344e432f0d4aa7f128d02e69336f2 (diff) | |
download | nextcloud-server-3b18c1bae4fd038c378010e76d4946313f23f2ef.tar.gz nextcloud-server-3b18c1bae4fd038c378010e76d4946313f23f2ef.zip |
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.
Backport of d69243e
-rw-r--r-- | apps/files_external/lib/ftp.php | 16 | ||||
-rw-r--r-- | apps/files_external/lib/smb.php | 12 | ||||
-rw-r--r-- | apps/files_external/lib/streamwrapper.php | 12 | ||||
-rw-r--r-- | tests/lib/files/storage/storage.php | 24 |
4 files changed, 57 insertions, 7 deletions
diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index ca6c635eb2b..85d7a5a32ae 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -58,6 +58,22 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ $url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path; 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) { switch($mode) { case 'r': diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index fb6259930ba..0ca58f0daa7 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -72,12 +72,18 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ } /** - * Unlinks file + * Unlinks file or directory * @param string @path */ public function unlink($path) { - unlink($this->constructUrl($path)); - clearstatcache(); + if ($this->is_dir($path)) { + $this->rmdir($path); + } + else { + $url = $this->constructUrl($path); + unlink($url); + clearstatcache(false, $url); + } // smb4php still returns false even on success so // check here whether file was really deleted return !file_exists($path); diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index a086f411f57..a01204d45fb 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -25,8 +25,9 @@ abstract class StreamWrapper extends Common { $this->unlink($path . '/' . $file); } } - $success = rmdir($this->constructUrl($path)); - clearstatcache(); + $url = $this->constructUrl($path); + $success = rmdir($url); + clearstatcache(false, $url); return $success; } else { return false; @@ -59,8 +60,11 @@ abstract class StreamWrapper extends Common { } public function unlink($path) { - $success = unlink($this->constructUrl($path)); - clearstatcache(); + $url = $this->constructUrl($path); + $success = unlink($url); + // normally unlink() is supposed to do this implicitly, + // but doing it anyway just to be sure + clearstatcache(false, $url); return $success; } diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 4587a3b2d06..ea3ca7d19e0 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -286,4 +286,28 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->instance->touch('foo'); $this->assertTrue($this->instance->file_exists('foo')); } + + public function testRecursiveRmdir() { + $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->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/bar/foo.txt')); + $this->assertFalse($this->instance->file_exists('folder/bar')); + $this->assertFalse($this->instance->file_exists('folder')); + } } |