diff options
author | Morris Jobke <hey@morrisjobke.de> | 2015-04-14 14:35:08 +0200 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2015-04-14 14:35:08 +0200 |
commit | 82cab257622759d1b64582f27de33a982c79c158 (patch) | |
tree | bcacfc55a044830e1a5529b9bece572bb6f180e8 /lib/private/files/view.php | |
parent | ffa115b51725c4774b49c2419f88cb91d726386b (diff) | |
parent | 0f21303b751291188733e24b5f213053ea96a368 (diff) | |
download | nextcloud-server-82cab257622759d1b64582f27de33a982c79c158.tar.gz nextcloud-server-82cab257622759d1b64582f27de33a982c79c158.zip |
Merge pull request #13360 from owncloud/cross-storage-move
Proper copy/move between multiple local storages
Diffstat (limited to 'lib/private/files/view.php')
-rw-r--r-- | lib/private/files/view.php | 109 |
1 files changed, 24 insertions, 85 deletions
diff --git a/lib/private/files/view.php b/lib/private/files/view.php index be14521990a..3300998da35 100644 --- a/lib/private/files/view.php +++ b/lib/private/files/view.php @@ -584,8 +584,6 @@ class View { * @return bool|mixed */ public function rename($path1, $path2) { - $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; - $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); if ( @@ -617,58 +615,33 @@ class View { if ($run) { $this->verifyPath(dirname($path2), basename($path2)); - $mp1 = $this->getMountPoint($path1 . $postFix1); - $mp2 = $this->getMountPoint($path2 . $postFix2); $manager = Filesystem::getMountManager(); - $mount = $manager->find($absolutePath1 . $postFix1); - $storage1 = $mount->getStorage(); - $internalPath1 = $mount->getInternalPath($absolutePath1 . $postFix1); - list($storage2, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - if ($internalPath1 === '' and $mount instanceof MoveableMount) { + $mount1 = $this->getMount($path1); + $mount2 = $this->getMount($path2); + $storage1 = $mount1->getStorage(); + $storage2 = $mount2->getStorage(); + $internalPath1 = $mount1->getInternalPath($absolutePath1); + $internalPath2 = $mount2->getInternalPath($absolutePath2); + + if ($internalPath1 === '' and $mount1 instanceof MoveableMount) { if ($this->isTargetAllowed($absolutePath2)) { /** - * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount + * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1 */ - $sourceMountPoint = $mount->getMountPoint(); - $result = $mount->moveMount($absolutePath2); - $manager->moveMount($sourceMountPoint, $mount->getMountPoint()); + $sourceMountPoint = $mount1->getMountPoint(); + $result = $mount1->moveMount($absolutePath2); + $manager->moveMount($sourceMountPoint, $mount1->getMountPoint()); } else { $result = false; } - } elseif ($mp1 == $mp2) { + } elseif ($storage1 == $storage2) { if ($storage1) { $result = $storage1->rename($internalPath1, $internalPath2); } else { $result = false; } } else { - if ($this->is_dir($path1)) { - $result = $this->copy($path1, $path2, true); - if ($result === true) { - $result = $storage1->rmdir($internalPath1); - } - } else { - $source = $this->fopen($path1 . $postFix1, 'r'); - $target = $this->fopen($path2 . $postFix2, 'w'); - list(, $result) = \OC_Helper::streamCopy($source, $target); - if ($result !== false) { - $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 - fclose($source); - fclose($target); - - if ($result !== false) { - $result &= $storage1->unlink($internalPath1); - } else { - // delete partially written target file - $storage2->unlink($internalPath2); - // delete cache entry that was created by fopen - $storage2->getCache()->remove($internalPath2); - } - } + $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); } if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) { // if it was a rename from a part file to a regular file it was a write and not a rename operation @@ -710,8 +683,6 @@ class View { * @return bool|mixed */ public function copy($path1, $path2, $preserveMtime = false) { - $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; - $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); if ( @@ -740,52 +711,20 @@ class View { $this->emit_file_hooks_pre($exists, $path2, $run); } if ($run) { - $mp1 = $this->getMountPoint($path1 . $postFix1); - $mp2 = $this->getMountPoint($path2 . $postFix2); - if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - if ($storage) { - $result = $storage->copy($internalPath1, $internalPath2); - if (!$result) { - // delete partially written target file - $storage->unlink($internalPath2); - $storage->getCache()->remove($internalPath2); - } + $mount1 = $this->getMount($path1); + $mount2 = $this->getMount($path2); + $storage1 = $mount1->getStorage(); + $internalPath1 = $mount1->getInternalPath($absolutePath1); + $storage2 = $mount2->getStorage(); + $internalPath2 = $mount2->getInternalPath($absolutePath2); + if ($mount1->getMountPoint() == $mount2->getMountPoint()) { + if ($storage1) { + $result = $storage1->copy($internalPath1, $internalPath2); } else { $result = false; } } 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)) { - if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file, $preserveMtime)) { - $result = false; - } - } - } - } - } else { - list($storage2, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); - $source = $this->fopen($path1 . $postFix1, 'r'); - $target = $this->fopen($path2 . $postFix2, 'w'); - list(, $result) = \OC_Helper::streamCopy($source, $target); - if($result && $preserveMtime) { - $this->touch($path2, $this->filemtime($path1)); - } - fclose($source); - fclose($target); - if (!$result) { - // delete partially written target file - $storage2->unlink($internalPath2); - $storage2->getCache()->remove($internalPath2); - } - } + $result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2); } $this->updater->update($path2); if ($this->shouldEmitHooks() && $result !== false) { |