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.tags/v6.0.0RC2
@@ -61,6 +61,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': |
@@ -82,12 +82,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); |
@@ -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; | |||
@@ -46,8 +47,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; | |||
} | |||
@@ -254,7 +254,19 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { | |||
$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->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/bar/foo.txt')); | |||
$this->assertFalse($this->instance->file_exists('folder/bar')); |