From c99e254178c52a568e4070fadab894d321efa6bf Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 1 Jul 2013 17:40:19 +0200 Subject: [PATCH 01/12] aditional test cases for copy and rename --- tests/lib/files/storage/storage.php | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 38cd17ac8c..92afd47673 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -345,4 +345,44 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertEquals(array('test.txt'), $content); } + + public function testCopyOverWriteFile() { + $this->instance->file_put_contents('target.txt', 'foo'); + $this->instance->file_put_contents('source.txt', 'bar'); + $this->instance->copy('source.txt', 'target.txt'); + $this->assertEquals('bar', $this->instance->file_get_contents('target.txt')); + } + + public function testRenameOverWriteFile() { + $this->instance->file_put_contents('target.txt', 'foo'); + $this->instance->file_put_contents('source.txt', 'bar'); + $this->instance->rename('source.txt', 'target.txt'); + $this->assertEquals('bar', $this->instance->file_get_contents('target.txt')); + $this->assertFalse($this->instance->file_exists('source.txt')); + } + + public function testRenameDirectory() { + $this->instance->mkdir('source'); + $this->instance->file_put_contents('source/test1.txt', 'foo'); + $this->instance->file_put_contents('source/test2.txt', 'qwerty'); + $this->instance->mkdir('source/subfolder'); + $this->instance->file_put_contents('source/subfolder/test.txt', 'bar'); + $this->instance->rename('source', 'target'); + + $this->assertFalse($this->instance->file_exists('source')); + $this->assertFalse($this->instance->file_exists('source/test1.txt')); + $this->assertFalse($this->instance->file_exists('source/test2.txt')); + $this->assertFalse($this->instance->file_exists('source/subfolder')); + $this->assertFalse($this->instance->file_exists('source/test.txt')); + + $this->assertTrue($this->instance->file_exists('target')); + $this->assertTrue($this->instance->file_exists('target/test1.txt')); + $this->assertTrue($this->instance->file_exists('target/test2.txt')); + $this->assertTrue($this->instance->file_exists('target/subfolder')); + $this->assertTrue($this->instance->file_exists('target/subfolder/test.txt')); + + $this->assertEquals('foo', $this->instance->file_get_contents('target/test1.txt')); + $this->assertEquals('qwerty', $this->instance->file_get_contents('target/test2.txt')); + $this->assertEquals('bar', $this->instance->file_get_contents('target/subfolder/test.txt')); + } } From e83b41493fe28eca612f3993a5a1cc3e44e9c145 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 1 Jul 2013 17:41:49 +0200 Subject: [PATCH 02/12] remove unneeded delTree --- lib/private/files/storage/local.php | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index de940fc7cd..aaa9f3c858 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -164,7 +164,7 @@ if (\OC_Util::runningOnWindows()) { } public function unlink($path) { - return $this->delTree($path); + return unlink($this->datadir . $path); } public function rename($path1, $path2) { @@ -212,30 +212,6 @@ if (\OC_Util::runningOnWindows()) { return $return; } - /** - * @param string $dir - */ - private function delTree($dir) { - $dirRelative = $dir; - $dir = $this->datadir . $dir; - if (!file_exists($dir)) return true; - if (!is_dir($dir) || is_link($dir)) return unlink($dir); - foreach (scandir($dir) as $item) { - if ($item == '.' || $item == '..') continue; - if (is_file($dir . '/' . $item)) { - if (unlink($dir . '/' . $item)) { - } - } elseif (is_dir($dir . '/' . $item)) { - if (!$this->delTree($dirRelative . "/" . $item)) { - return false; - }; - } - } - if ($return = rmdir($dir)) { - } - return $return; - } - /** * @param string $fullPath */ From 38c1da09768d034ee788f0c6a4284591e914fe4a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 1 Jul 2013 17:45:01 +0200 Subject: [PATCH 03/12] fix recursive rename for local storage backend --- lib/private/files/storage/local.php | 6 ++++-- tests/lib/files/storage/storage.php | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index aaa9f3c858..ec28ebac6e 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -177,9 +177,11 @@ if (\OC_Util::runningOnWindows()) { return false; } - if ($return = rename($this->datadir . $path1, $this->datadir . $path2)) { + if ($this->is_dir($path2)) { + $this->rmdir($path2); } - return $return; + + return rename($this->datadir . $path1, $this->datadir . $path2); } public function copy($path1, $path2) { diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 92afd47673..4a4626fc5c 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -385,4 +385,20 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertEquals('qwerty', $this->instance->file_get_contents('target/test2.txt')); $this->assertEquals('bar', $this->instance->file_get_contents('target/subfolder/test.txt')); } + + public function testRenameOverWriteDirectory() { + $this->instance->mkdir('source'); + $this->instance->file_put_contents('source/test1.txt', 'foo'); + + $this->instance->mkdir('target'); + $this->instance->file_put_contents('target/test1.txt', 'bar'); + $this->instance->file_put_contents('target/test2.txt', 'bar'); + + $this->instance->rename('source', 'target'); + + $this->assertFalse($this->instance->file_exists('source')); + $this->assertFalse($this->instance->file_exists('source/test1.txt')); + $this->assertFalse($this->instance->file_exists('target/test2.txt')); + $this->assertEquals('foo', $this->instance->file_get_contents('target/test1.txt')); + } } From 03ba497a8c1e149857d6c3a4d4cab49dea5903c1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 1 Jul 2013 17:57:40 +0200 Subject: [PATCH 04/12] add recursive copy to local storage backend --- lib/private/files/storage/local.php | 26 +++++++++--- tests/lib/files/storage/storage.php | 65 ++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index ec28ebac6e..dc6e7a12c6 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -179,20 +179,34 @@ if (\OC_Util::runningOnWindows()) { if ($this->is_dir($path2)) { $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); } return rename($this->datadir . $path1, $this->datadir . $path2); } public function copy($path1, $path2) { - if ($this->is_dir($path2)) { - if (!$this->file_exists($path2)) { - $this->mkdir($path2); + if ($this->is_dir($path1)) { + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); } - $source = substr($path1, strrpos($path1, '/') + 1); - $path2 .= $source; + $dir = $this->opendir($path1); + $this->mkdir($path2); + while ($file = readdir($dir)) { + if (($file != '.') && ($file != '..')) { + if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { + return false; + } + } + } + closedir($dir); + return true; + } else { + return copy($this->datadir . $path1, $this->datadir . $path2); } - return copy($this->datadir . $path1, $this->datadir . $path2); } public function fopen($path, $mode) { diff --git a/tests/lib/files/storage/storage.php b/tests/lib/files/storage/storage.php index 4a4626fc5c..24390f0536 100644 --- a/tests/lib/files/storage/storage.php +++ b/tests/lib/files/storage/storage.php @@ -373,7 +373,7 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->instance->file_exists('source/test1.txt')); $this->assertFalse($this->instance->file_exists('source/test2.txt')); $this->assertFalse($this->instance->file_exists('source/subfolder')); - $this->assertFalse($this->instance->file_exists('source/test.txt')); + $this->assertFalse($this->instance->file_exists('source/subfolder/test.txt')); $this->assertTrue($this->instance->file_exists('target')); $this->assertTrue($this->instance->file_exists('target/test1.txt')); @@ -401,4 +401,67 @@ abstract class Storage extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->instance->file_exists('target/test2.txt')); $this->assertEquals('foo', $this->instance->file_get_contents('target/test1.txt')); } + + public function testRenameOverWriteDirectoryOverFile() { + $this->instance->mkdir('source'); + $this->instance->file_put_contents('source/test1.txt', 'foo'); + + $this->instance->file_put_contents('target', 'bar'); + + $this->instance->rename('source', 'target'); + + $this->assertFalse($this->instance->file_exists('source')); + $this->assertFalse($this->instance->file_exists('source/test1.txt')); + $this->assertEquals('foo', $this->instance->file_get_contents('target/test1.txt')); + } + + public function testCopyDirectory() { + $this->instance->mkdir('source'); + $this->instance->file_put_contents('source/test1.txt', 'foo'); + $this->instance->file_put_contents('source/test2.txt', 'qwerty'); + $this->instance->mkdir('source/subfolder'); + $this->instance->file_put_contents('source/subfolder/test.txt', 'bar'); + $this->instance->copy('source', 'target'); + + $this->assertTrue($this->instance->file_exists('source')); + $this->assertTrue($this->instance->file_exists('source/test1.txt')); + $this->assertTrue($this->instance->file_exists('source/test2.txt')); + $this->assertTrue($this->instance->file_exists('source/subfolder')); + $this->assertTrue($this->instance->file_exists('source/subfolder/test.txt')); + + $this->assertTrue($this->instance->file_exists('target')); + $this->assertTrue($this->instance->file_exists('target/test1.txt')); + $this->assertTrue($this->instance->file_exists('target/test2.txt')); + $this->assertTrue($this->instance->file_exists('target/subfolder')); + $this->assertTrue($this->instance->file_exists('target/subfolder/test.txt')); + + $this->assertEquals('foo', $this->instance->file_get_contents('target/test1.txt')); + $this->assertEquals('qwerty', $this->instance->file_get_contents('target/test2.txt')); + $this->assertEquals('bar', $this->instance->file_get_contents('target/subfolder/test.txt')); + } + + public function testCopyOverWriteDirectory() { + $this->instance->mkdir('source'); + $this->instance->file_put_contents('source/test1.txt', 'foo'); + + $this->instance->mkdir('target'); + $this->instance->file_put_contents('target/test1.txt', 'bar'); + $this->instance->file_put_contents('target/test2.txt', 'bar'); + + $this->instance->copy('source', 'target'); + + $this->assertFalse($this->instance->file_exists('target/test2.txt')); + $this->assertEquals('foo', $this->instance->file_get_contents('target/test1.txt')); + } + + public function testCopyOverWriteDirectoryOverFile() { + $this->instance->mkdir('source'); + $this->instance->file_put_contents('source/test1.txt', 'foo'); + + $this->instance->file_put_contents('target', 'bar'); + + $this->instance->copy('source', 'target'); + + $this->assertEquals('foo', $this->instance->file_get_contents('target/test1.txt')); + } } From c3c9612c99c0bd8b2da9cac262045c43775f2988 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 1 Jul 2013 18:02:56 +0200 Subject: [PATCH 05/12] fix recursive copy and rename for mapped local storage backend --- lib/private/files/storage/mappedlocal.php | 37 +++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php index 0769166164..9d3fa01d88 100644 --- a/lib/private/files/storage/mappedlocal.php +++ b/lib/private/files/storage/mappedlocal.php @@ -177,6 +177,12 @@ class MappedLocal extends \OC\Files\Storage\Common{ return false; } + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); + } + $physicPath1 = $this->buildPath($path1); $physicPath2 = $this->buildPath($path2); if($return=rename($physicPath1, $physicPath2)) { @@ -187,18 +193,29 @@ class MappedLocal extends \OC\Files\Storage\Common{ return $return; } public function copy($path1, $path2) { - if($this->is_dir($path2)) { - if(!$this->file_exists($path2)) { - $this->mkdir($path2); + if ($this->is_dir($path1)) { + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); } - $source=substr($path1, strrpos($path1, '/')+1); - $path2.=$source; + $dir = $this->opendir($path1); + $this->mkdir($path2); + while ($file = readdir($dir)) { + if (($file != '.') && ($file != '..')) { + if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { + return false; + } + } + } + closedir($dir); + return true; + } else { + if ($return = copy($this->buildPath($path1), $this->buildPath($path2))) { + $this->copyMapping($path1, $path2); + } + return $return; } - if($return=copy($this->buildPath($path1), $this->buildPath($path2))) { - // mapper needs to create copies or all children - $this->copyMapping($path1, $path2); - } - return $return; } public function fopen($path, $mode) { if($return=fopen($this->buildPath($path), $mode)) { From ea44f0e20f9685e5d8396380a5fcb383d9efee90 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 1 Jul 2013 18:11:05 +0200 Subject: [PATCH 06/12] fix recursive copy and rename for common storage backend --- lib/private/files/storage/common.php | 47 ++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index cfca8ca008..5fae43d8bf 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -137,20 +137,49 @@ abstract class Common implements \OC\Files\Storage\Storage { } public function rename($path1, $path2) { - if ($this->copy($path1, $path2)) { - $this->removeCachedFile($path1); - return $this->unlink($path1); + if ($this->file_exists($path2)) { + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); + } + } + + $this->removeCachedFile($path1); + if ($this->is_dir($path1)) { + return $this->copy($path1, $path2) and $this->rmdir($path1); } else { - return false; + return $this->copy($path1, $path2) and $this->unlink($path1); } } public function copy($path1, $path2) { - $source = $this->fopen($path1, 'r'); - $target = $this->fopen($path2, 'w'); - list($count, $result) = \OC_Helper::streamCopy($source, $target); - $this->removeCachedFile($path2); - return $result; + if ($this->is_dir($path1)) { + if ($this->file_exists($path2)) { + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); + } + } + $dir = $this->opendir($path1); + $this->mkdir($path2); + while ($file = readdir($dir)) { + if (($file != '.') && ($file != '..')) { + if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { + return false; + } + } + } + closedir($dir); + return true; + } else { + $source = $this->fopen($path1, 'r'); + $target = $this->fopen($path2, 'w'); + list(, $result) = \OC_Helper::streamCopy($source, $target); + $this->removeCachedFile($path2); + return $result; + } } public function getMimeType($path) { From 1302602173f1cdd2def9702362227b003d17303f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 1 Jul 2013 18:11:33 +0200 Subject: [PATCH 07/12] fix illegal usage of unlink in test case --- tests/lib/files/cache/scanner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 5182fac8b1..fb06f2dff3 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -195,7 +195,7 @@ class Scanner extends \PHPUnit_Framework_TestCase { $this->scanner->scan(''); $this->assertTrue($this->cache->inCache('folder/bar.txt')); - $this->storage->unlink('/folder'); + $this->storage->rmdir('/folder'); $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $this->assertFalse($this->cache->inCache('folder')); $this->assertFalse($this->cache->inCache('folder/bar.txt')); From d15ed9b4d39c290a9643be69ad9fbb9478570321 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 1 Jul 2013 19:12:48 +0200 Subject: [PATCH 08/12] use \OC\Files\Filesystem::isIgnoredDir --- lib/private/files/storage/common.php | 2 +- lib/private/files/storage/local.php | 2 +- lib/private/files/storage/mappedlocal.php | 144 +++++++++++++--------- 3 files changed, 86 insertions(+), 62 deletions(-) diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index 5fae43d8bf..ed51bbf647 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -165,7 +165,7 @@ abstract class Common implements \OC\Files\Storage\Storage { $dir = $this->opendir($path1); $this->mkdir($path2); while ($file = readdir($dir)) { - if (($file != '.') && ($file != '..')) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { return false; } diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index dc6e7a12c6..bbb4ae77e4 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -196,7 +196,7 @@ if (\OC_Util::runningOnWindows()) { $dir = $this->opendir($path1); $this->mkdir($path2); while ($file = readdir($dir)) { - if (($file != '.') && ($file != '..')) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { return false; } diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php index 9d3fa01d88..3ebdcf9538 100644 --- a/lib/private/files/storage/mappedlocal.php +++ b/lib/private/files/storage/mappedlocal.php @@ -10,29 +10,33 @@ namespace OC\Files\Storage; /** * for local filestore, we only have to map the paths */ -class MappedLocal extends \OC\Files\Storage\Common{ +class MappedLocal extends \OC\Files\Storage\Common { protected $datadir; private $mapper; public function __construct($arguments) { - $this->datadir=$arguments['datadir']; - if(substr($this->datadir, -1)!=='/') { - $this->datadir.='/'; + $this->datadir = $arguments['datadir']; + if (substr($this->datadir, -1) !== '/') { + $this->datadir .= '/'; } - $this->mapper= new \OC\Files\Mapper($this->datadir); + $this->mapper = new \OC\Files\Mapper($this->datadir); } + public function __destruct() { if (defined('PHPUNIT_RUN')) { $this->mapper->removePath($this->datadir, true, true); } } - public function getId(){ - return 'local::'.$this->datadir; + + public function getId() { + return 'local::' . $this->datadir; } + public function mkdir($path) { return @mkdir($this->buildPath($path), 0777, true); } + public function rmdir($path) { try { $it = new \RecursiveIteratorIterator( @@ -68,9 +72,10 @@ class MappedLocal extends \OC\Files\Storage\Common{ return false; } } + public function opendir($path) { $files = array('.', '..'); - $physicalPath= $this->buildPath($path); + $physicalPath = $this->buildPath($path); $logicalPath = $this->mapper->physicalToLogic($physicalPath); $dh = opendir($physicalPath); @@ -80,7 +85,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ continue; } - $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file); + $logicalFilePath = $this->mapper->physicalToLogic($physicalPath . '/' . $file); $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); $file = $this->stripLeading($file); @@ -88,18 +93,21 @@ class MappedLocal extends \OC\Files\Storage\Common{ } } - \OC\Files\Stream\Dir::register('local-win32'.$path, $files); - return opendir('fakedir://local-win32'.$path); + \OC\Files\Stream\Dir::register('local-win32' . $path, $files); + return opendir('fakedir://local-win32' . $path); } + public function is_dir($path) { - if(substr($path, -1)=='/') { - $path=substr($path, 0, -1); + if (substr($path, -1) == '/') { + $path = substr($path, 0, -1); } return is_dir($this->buildPath($path)); } + public function is_file($path) { return is_file($this->buildPath($path)); } + public function stat($path) { $fullPath = $this->buildPath($path); $statResult = stat($fullPath); @@ -111,17 +119,19 @@ class MappedLocal extends \OC\Files\Storage\Common{ } return $statResult; } + public function filetype($path) { - $filetype=filetype($this->buildPath($path)); - if($filetype=='link') { - $filetype=filetype(realpath($this->buildPath($path))); + $filetype = filetype($this->buildPath($path)); + if ($filetype == 'link') { + $filetype = filetype(realpath($this->buildPath($path))); } return $filetype; } + public function filesize($path) { - if($this->is_dir($path)) { + if ($this->is_dir($path)) { return 0; - }else{ + } else { $fullPath = $this->buildPath($path); $fileSize = filesize($fullPath); if ($fileSize < 0) { @@ -131,49 +141,58 @@ class MappedLocal extends \OC\Files\Storage\Common{ return $fileSize; } } + public function isReadable($path) { return is_readable($this->buildPath($path)); } + public function isUpdatable($path) { return is_writable($this->buildPath($path)); } + public function file_exists($path) { return file_exists($this->buildPath($path)); } + public function filemtime($path) { return filemtime($this->buildPath($path)); } - public function touch($path, $mtime=null) { + + public function touch($path, $mtime = null) { // sets the modification time of the file to the given value. // If mtime is nil the current time is set. // note that the access time of the file always changes to the current time. - if(!is_null($mtime)) { - $result=touch( $this->buildPath($path), $mtime ); - }else{ - $result=touch( $this->buildPath($path)); + if (!is_null($mtime)) { + $result = touch($this->buildPath($path), $mtime); + } else { + $result = touch($this->buildPath($path)); } - if( $result ) { - clearstatcache( true, $this->buildPath($path) ); + if ($result) { + clearstatcache(true, $this->buildPath($path)); } return $result; } + public function file_get_contents($path) { return file_get_contents($this->buildPath($path)); } + public function file_put_contents($path, $data) { return file_put_contents($this->buildPath($path), $data); } + public function unlink($path) { return $this->delTree($path); } + public function rename($path1, $path2) { if (!$this->isUpdatable($path1)) { - \OC_Log::write('core', 'unable to rename, file is not writable : '.$path1, \OC_Log::ERROR); + \OC_Log::write('core', 'unable to rename, file is not writable : ' . $path1, \OC_Log::ERROR); return false; } - if(! $this->file_exists($path1)) { - \OC_Log::write('core', 'unable to rename, file does not exists : '.$path1, \OC_Log::ERROR); + if (!$this->file_exists($path1)) { + \OC_Log::write('core', 'unable to rename, file does not exists : ' . $path1, \OC_Log::ERROR); return false; } @@ -185,13 +204,14 @@ class MappedLocal extends \OC\Files\Storage\Common{ $physicPath1 = $this->buildPath($path1); $physicPath2 = $this->buildPath($path2); - if($return=rename($physicPath1, $physicPath2)) { + if ($return = rename($physicPath1, $physicPath2)) { // mapper needs to create copies or all children $this->copyMapping($path1, $path2); $this->cleanMapper($physicPath1, false, true); } return $return; } + public function copy($path1, $path2) { if ($this->is_dir($path1)) { if ($this->is_dir($path2)) { @@ -202,7 +222,7 @@ class MappedLocal extends \OC\Files\Storage\Common{ $dir = $this->opendir($path1); $this->mkdir($path2); while ($file = readdir($dir)) { - if (($file != '.') && ($file != '..')) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { return false; } @@ -217,9 +237,10 @@ class MappedLocal extends \OC\Files\Storage\Common{ return $return; } } + public function fopen($path, $mode) { - if($return=fopen($this->buildPath($path), $mode)) { - switch($mode) { + if ($return = fopen($this->buildPath($path), $mode)) { + switch ($mode) { case 'r': break; case 'r+': @@ -240,15 +261,15 @@ class MappedLocal extends \OC\Files\Storage\Common{ * @param string $dir */ private function delTree($dir, $isLogicPath=true) { - $dirRelative=$dir; + $dirRelative = $dir; if ($isLogicPath) { - $dir=$this->buildPath($dir); + $dir = $this->buildPath($dir); } if (!file_exists($dir)) { return true; } if (!is_dir($dir) || is_link($dir)) { - if($return=unlink($dir)) { + if ($return = unlink($dir)) { $this->cleanMapper($dir, false); return $return; } @@ -257,17 +278,17 @@ class MappedLocal extends \OC\Files\Storage\Common{ if ($item == '.' || $item == '..') { continue; } - if(is_file($dir.'/'.$item)) { - if(unlink($dir.'/'.$item)) { - $this->cleanMapper($dir.'/'.$item, false); + if (is_file($dir . '/' . $item)) { + if (unlink($dir . '/' . $item)) { + $this->cleanMapper($dir . '/' . $item, false); } - }elseif(is_dir($dir.'/'.$item)) { - if (!$this->delTree($dir. "/" . $item, false)) { + } elseif (is_dir($dir . '/' . $item)) { + if (!$this->delTree($dir . "/" . $item, false)) { return false; }; } } - if($return=rmdir($dir)) { + if ($return = rmdir($dir)) { $this->cleanMapper($dir, false); } return $return; @@ -295,14 +316,14 @@ class MappedLocal extends \OC\Files\Storage\Common{ } } else { \OC_Log::write('core', - 'Unable to determine file size of "'.$fullPath.'". Unknown OS: '.$name, + 'Unable to determine file size of "' . $fullPath . '". Unknown OS: ' . $name, \OC_Log::ERROR); } return 0; } - public function hash($type, $path, $raw=false) { + public function hash($type, $path, $raw = false) { return hash_file($type, $this->buildPath($path), $raw); } @@ -313,9 +334,11 @@ class MappedLocal extends \OC\Files\Storage\Common{ public function search($query) { return $this->searchInDir($query); } + public function getLocalFile($path) { return $this->buildPath($path); } + public function getLocalFolder($path) { return $this->buildPath($path); } @@ -323,20 +346,20 @@ class MappedLocal extends \OC\Files\Storage\Common{ /** * @param string $query */ - protected function searchInDir($query, $dir='') { - $files=array(); + protected function searchInDir($query, $dir = '') { + $files = array(); $physicalDir = $this->buildPath($dir); foreach (scandir($physicalDir) as $item) { if ($item == '.' || $item == '..') continue; - $physicalItem = $this->mapper->physicalToLogic($physicalDir.'/'.$item); - $item = substr($physicalItem, strlen($physicalDir)+1); + $physicalItem = $this->mapper->physicalToLogic($physicalDir . '/' . $item); + $item = substr($physicalItem, strlen($physicalDir) + 1); - if(strstr(strtolower($item), strtolower($query)) !== false) { - $files[]=$dir.'/'.$item; + if (strstr(strtolower($item), strtolower($query)) !== false) { + $files[] = $dir . '/' . $item; } - if(is_dir($physicalItem)) { - $files=array_merge($files, $this->searchInDir($query, $dir.'/'.$item)); + if (is_dir($physicalItem)) { + $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item)); } } return $files; @@ -344,30 +367,31 @@ class MappedLocal extends \OC\Files\Storage\Common{ /** * check if a file or folder has been updated since $time + * * @param string $path * @param int $time * @return bool */ public function hasUpdated($path, $time) { - return $this->filemtime($path)>$time; + return $this->filemtime($path) > $time; } /** * @param string $path */ - private function buildPath($path, $create=true) { + private function buildPath($path, $create = true) { $path = $this->stripLeading($path); - $fullPath = $this->datadir.$path; + $fullPath = $this->datadir . $path; return $this->mapper->logicToPhysical($fullPath, $create); } /** * @param string $path */ - private function cleanMapper($path, $isLogicPath=true, $recursive=true) { + private function cleanMapper($path, $isLogicPath = true, $recursive=true) { $fullPath = $path; if ($isLogicPath) { - $fullPath = $this->datadir.$path; + $fullPath = $this->datadir . $path; } $this->mapper->removePath($fullPath, $isLogicPath, $recursive); } @@ -380,8 +404,8 @@ class MappedLocal extends \OC\Files\Storage\Common{ $path1 = $this->stripLeading($path1); $path2 = $this->stripLeading($path2); - $fullPath1 = $this->datadir.$path1; - $fullPath2 = $this->datadir.$path2; + $fullPath1 = $this->datadir . $path1; + $fullPath2 = $this->datadir . $path2; $this->mapper->copy($fullPath1, $fullPath2); } @@ -390,10 +414,10 @@ class MappedLocal extends \OC\Files\Storage\Common{ * @param string $path */ private function stripLeading($path) { - if(strpos($path, '/') === 0) { + if (strpos($path, '/') === 0) { $path = substr($path, 1); } - if(strpos($path, '\\') === 0) { + if (strpos($path, '\\') === 0) { $path = substr($path, 1); } if ($path === false) { From 488fc402e4c144692a1a4c84d5cfacaae9bea2b8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 4 Jul 2013 21:17:52 +0200 Subject: [PATCH 09/12] remove unneeded check --- lib/private/files/storage/common.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index ed51bbf647..8ebc0bcddb 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -140,7 +140,7 @@ abstract class Common implements \OC\Files\Storage\Storage { if ($this->file_exists($path2)) { if ($this->is_dir($path2)) { $this->rmdir($path2); - } else if ($this->is_file($path2)) { + } else { $this->unlink($path2); } } @@ -158,7 +158,7 @@ abstract class Common implements \OC\Files\Storage\Storage { if ($this->file_exists($path2)) { if ($this->is_dir($path2)) { $this->rmdir($path2); - } else if ($this->is_file($path2)) { + } else { $this->unlink($path2); } } From 8187164fe1c125c478f1c9f64700626d329aa0d1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Jul 2013 21:39:58 +0200 Subject: [PATCH 10/12] re-use rescursive copy from common storage --- lib/private/files/storage/local.php | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index bbb4ae77e4..43ffeaf80c 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -188,22 +188,7 @@ if (\OC_Util::runningOnWindows()) { public function copy($path1, $path2) { if ($this->is_dir($path1)) { - if ($this->is_dir($path2)) { - $this->rmdir($path2); - } else if ($this->is_file($path2)) { - $this->unlink($path2); - } - $dir = $this->opendir($path1); - $this->mkdir($path2); - while ($file = readdir($dir)) { - if (!\OC\Files\Filesystem::isIgnoredDir($file)) { - if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { - return false; - } - } - } - closedir($dir); - return true; + return parent::copy($path1, $path2); } else { return copy($this->datadir . $path1, $this->datadir . $path2); } From af35b6ad9db6490f5bfd25143d214f5b1d8dfd34 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 6 May 2014 15:54:48 +0200 Subject: [PATCH 11/12] Fix LocalStorage->unlink to work on folder as expected --- lib/private/files/storage/local.php | 9 ++++++++- lib/private/files/view.php | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index 43ffeaf80c..943c416308 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -164,7 +164,14 @@ if (\OC_Util::runningOnWindows()) { } public function unlink($path) { - return unlink($this->datadir . $path); + if ($this->is_dir($path)) { + return $this->rmdir($path); + } else if ($this->is_file($path)) { + return unlink($this->datadir . $path); + } else { + return false; + } + } public function rename($path1, $path2) { diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 940f31fe42..0743d5c6d9 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -432,7 +432,7 @@ class View { if ($this->is_dir($path1)) { $result = $this->copy($path1, $path2); if ($result === true) { - $result = $storage1->unlink($internalPath1); + $result = $storage1->rmdir($internalPath1); } } else { $source = $this->fopen($path1 . $postFix1, 'r'); From 467e9c2bb0dadb58e6cdb03830318b725123c7aa Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 May 2014 12:46:12 +0200 Subject: [PATCH 12/12] Remove code duplication --- lib/private/files/storage/common.php | 41 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php index 8ebc0bcddb..1ed0d79817 100644 --- a/lib/private/files/storage/common.php +++ b/lib/private/files/storage/common.php @@ -7,6 +7,7 @@ */ namespace OC\Files\Storage; +use OC\Files\Filesystem; use OC\Files\Cache\Watcher; /** @@ -36,6 +37,22 @@ abstract class Common implements \OC\Files\Storage\Storage { public function __construct($parameters) { } + /** + * Remove a file of folder + * + * @param string $path + * @return bool + */ + protected function remove($path) { + if ($this->is_dir($path)) { + return $this->rmdir($path); + } else if($this->is_file($path)) { + return $this->unlink($path); + } else { + return false; + } + } + public function is_dir($path) { return $this->filetype($path) == 'dir'; } @@ -137,35 +154,19 @@ abstract class Common implements \OC\Files\Storage\Storage { } public function rename($path1, $path2) { - if ($this->file_exists($path2)) { - if ($this->is_dir($path2)) { - $this->rmdir($path2); - } else { - $this->unlink($path2); - } - } + $this->remove($path2); $this->removeCachedFile($path1); - if ($this->is_dir($path1)) { - return $this->copy($path1, $path2) and $this->rmdir($path1); - } else { - return $this->copy($path1, $path2) and $this->unlink($path1); - } + return $this->copy($path1, $path2) and $this->remove($path1); } public function copy($path1, $path2) { if ($this->is_dir($path1)) { - if ($this->file_exists($path2)) { - if ($this->is_dir($path2)) { - $this->rmdir($path2); - } else { - $this->unlink($path2); - } - } + $this->remove($path2); $dir = $this->opendir($path1); $this->mkdir($path2); while ($file = readdir($dir)) { - if (!\OC\Files\Filesystem::isIgnoredDir($file)) { + if (!Filesystem::isIgnoredDir($file)) { if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { return false; }