diff options
-rw-r--r-- | apps/files_trashbin/lib/trashbin.php | 43 | ||||
-rw-r--r-- | lib/private/files/view.php | 13 | ||||
-rw-r--r-- | tests/lib/files/view.php | 29 |
3 files changed, 40 insertions, 45 deletions
diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index 1833936ea26..f5cebea6b78 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -166,7 +166,8 @@ class Trashbin { \OC_FileProxy::$enabled = false; $trashPath = '/files_trashbin/files/' . $filename . '.d' . $timestamp; try { - $sizeOfAddedFiles = self::renameRecursive('/files/'.$file_path, $trashPath, $view); + $sizeOfAddedFiles = $view->filesize('/files/' . $file_path); + $view->rename('/files/' . $file_path, $trashPath); } catch (\OCA\Files_Trashbin\Exceptions\CopyRecursiveException $e) { $sizeOfAddedFiles = false; if ($view->file_exists($trashPath)) { @@ -806,46 +807,6 @@ class Trashbin { } /** - * recursive rename a whole directory and preserve timestamps - * - * @param string $source source path, relative to the users files directory - * @param string $destination destination path relative to the users root directoy - * @param \OC\Files\View $view file view for the users root directory - * @return int - * @throws Exceptions\CopyRecursiveException - */ - private static function renameRecursive($source, $destination, \OC\Files\View $view) { - $size = 0; - if ($view->is_dir($source)) { - $view->mkdir($destination); - $view->touch($destination, $view->filemtime($source)); - foreach ($view->getDirectoryContent($source) as $i) { - $pathDir = $source . '/' . $i['name']; - if ($view->is_dir($pathDir)) { - $size += self::renameRecursive($pathDir, $destination . '/' . $i['name'], $view); - } else { - $size += $view->filesize($pathDir); - $mtime = $view->filemtime($pathDir); - $result = $view->rename($pathDir, $destination . '/' . $i['name']); - if (!$result) { - throw new \OCA\Files_Trashbin\Exceptions\CopyRecursiveException(); - } - $view->touch($destination . '/' . $i['name'], $mtime); - } - } - } else { - $size += $view->filesize($source); - $mtime = $view->filemtime($source); - $result = $view->rename($source, $destination); - if (!$result) { - throw new \OCA\Files_Trashbin\Exceptions\CopyRecursiveException(); - } - $view->touch($destination, $mtime); - } - return $size; - } - - /** * find all versions which belong to the file we want to restore * * @param string $filename name of the file which should be restored diff --git a/lib/private/files/view.php b/lib/private/files/view.php index 76b7d34e756..f466361bd02 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -511,7 +511,7 @@ class View { } } else { if ($this->is_dir($path1)) { - $result = $this->copy($path1, $path2); + $result = $this->copy($path1, $path2, true); if ($result === true) { $result = $storage1->rmdir($internalPath1); } @@ -519,6 +519,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); list($count, $result) = \OC_Helper::streamCopy($source, $target); + $this->touch($path2, $this->filemtime($path1)); // close open handle - especially $source is necessary because unlink below will // throw an exception on windows because the file is locked @@ -556,7 +557,7 @@ class View { } } - public function copy($path1, $path2) { + public function copy($path1, $path2, $preserveMtime = false) { $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); @@ -601,10 +602,13 @@ class View { } else { if ($this->is_dir($path1) && ($dh = $this->opendir($path1))) { $result = $this->mkdir($path2); + if ($preserveMtime) { + $this->touch($path2, $this->filemtime($path1)); + } if (is_resource($dh)) { while (($file = readdir($dh)) !== false) { if (!Filesystem::isIgnoredDir($file)) { - $result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file); + $result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file, $preserveMtime); } } } @@ -612,6 +616,9 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); list($count, $result) = \OC_Helper::streamCopy($source, $target); + if($preserveMtime) { + $this->touch($path2, $this->filemtime($path1)); + } fclose($source); fclose($target); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 3ff19d7385d..158c964fd0d 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -613,7 +613,7 @@ class View extends \Test\TestCase { if (\OC_Util::runningOnWindows()) { $this->markTestSkipped('[Windows] '); $depth = ((260 - $tmpdirLength) / 57); - }elseif(\OC_Util::runningOnMac()){ + } elseif (\OC_Util::runningOnMac()) { $depth = ((1024 - $tmpdirLength) / 57); } else { $depth = ((4000 - $tmpdirLength) / 57); @@ -806,4 +806,31 @@ class View extends \Test\TestCase { array('putFileInfo', array()), ); } + + public function testRenameCrossStoragePreserveMtime() { + $storage1 = new Temporary(array()); + $storage2 = new Temporary(array()); + $scanner1 = $storage1->getScanner(); + $scanner2 = $storage2->getScanner(); + $storage1->mkdir('sub'); + $storage1->mkdir('foo'); + $storage1->file_put_contents('foo.txt', 'asd'); + $storage1->file_put_contents('foo/bar.txt', 'asd'); + \OC\Files\Filesystem::mount($storage1, array(), '/test/'); + \OC\Files\Filesystem::mount($storage2, array(), '/test/sub/storage'); + + $view = new \OC\Files\View(''); + $time = time() - 200; + $view->touch('/test/foo.txt', $time); + $view->touch('/test/foo', $time); + $view->touch('/test/foo/bar.txt', $time); + + $view->rename('/test/foo.txt', '/test/sub/storage/foo.txt'); + + $this->assertEquals($time, $view->filemtime('/test/sub/storage/foo.txt')); + + $view->rename('/test/foo', '/test/sub/storage/foo'); + + $this->assertEquals($time, $view->filemtime('/test/sub/storage/foo/bar.txt')); + } } |