Merge pull request #3425 from owncloud/move-storages

Support for moving/copying folders between storages
This commit is contained in:
Michael Gapczynski 2013-05-23 17:35:11 -07:00
commit a98d6c4be6
6 changed files with 83 additions and 34 deletions

View File

@ -1,5 +1,5 @@
<?php if(count($_["breadcrumb"])):?>
<div class="crumb">
<div class="crumb" data-dir=''>
<a href="<?php print_unescaped($_['baseURL']); ?>">
<img src="<?php print_unescaped(OCP\image_path('core', 'places/home.svg'));?>" class="svg" />
</a>

View File

@ -116,7 +116,7 @@ class Scanner {
\OC_DB::beginTransaction();
while ($file = readdir($dh)) {
$child = ($path) ? $path . '/' . $file : $file;
if (!$this->isIgnoredDir($file)) {
if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
$data = $this->scanFile($child, $recursive === self::SCAN_SHALLOW);
if ($data) {
if ($data['size'] === -1) {
@ -150,18 +150,6 @@ class Scanner {
return $size;
}
/**
* @brief check if the directory should be ignored when scanning
* NOTE: the special directories . and .. would cause never ending recursion
* @param String $dir
* @return boolean
*/
private function isIgnoredDir($dir) {
if ($dir === '.' || $dir === '..') {
return true;
}
return false;
}
/**
* @brief check if the file should be ignored when scanning
* NOTE: files with a '.part' extension are ignored as well!

View File

@ -453,6 +453,19 @@ class Filesystem {
return (in_array($filename, $blacklist));
}
/**
* @brief check if the directory should be ignored when scanning
* NOTE: the special directories . and .. would cause never ending recursion
* @param String $dir
* @return boolean
*/
static public function isIgnoredDir($dir) {
if ($dir === '.' || $dir === '..') {
return true;
}
return false;
}
/**
* following functions are equivalent to their php builtin equivalents for arguments/return values.
*/

View File

@ -138,27 +138,21 @@ abstract class Common implements \OC\Files\Storage\Storage {
*/
public function deleteAll($directory, $empty = false) {
$directory = trim($directory, '/');
if (!$this->file_exists(\OCP\USER::getUser() . '/' . $directory)
|| !$this->is_dir(\OCP\USER::getUser() . '/' . $directory)
) {
return false;
} elseif (!$this->isReadable(\OCP\USER::getUser() . '/' . $directory)) {
if (!$this->is_dir($directory) || !$this->isReadable($directory)) {
return false;
} else {
$directoryHandle = $this->opendir(\OCP\USER::getUser() . '/' . $directory);
$directoryHandle = $this->opendir($directory);
while ($contents = readdir($directoryHandle)) {
if ($contents != '.' && $contents != '..') {
$path = $directory . "/" . $contents;
if (!\OC\Files\Filesystem::isIgnoredDir($contents)) {
$path = $directory . '/' . $contents;
if ($this->is_dir($path)) {
$this->deleteAll($path);
} else {
$this->unlink(\OCP\USER::getUser() . '/' . $path); // TODO: make unlink use same system path as is_dir
$this->unlink($path);
}
}
}
//$this->closedir( $directoryHandle ); // TODO: implement closedir in OC_FSV
if ($empty == false) {
if ($empty === false) {
if (!$this->rmdir($directory)) {
return false;
}

View File

@ -375,11 +375,19 @@ class View {
$result = false;
}
} else {
$source = $this->fopen($path1 . $postFix1, 'r');
$target = $this->fopen($path2 . $postFix2, 'w');
list($count, $result) = \OC_Helper::streamCopy($source, $target);
list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
$storage1->unlink($internalPath1);
if ($this->is_dir($path1)) {
$result = $this->copy($path1, $path2);
if ($result === true) {
list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
$result = $storage1->deleteAll($internalPath1);
}
} else {
$source = $this->fopen($path1 . $postFix1, 'r');
$target = $this->fopen($path2 . $postFix2, 'w');
list($count, $result) = \OC_Helper::streamCopy($source, $target);
list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
$storage1->unlink($internalPath1);
}
}
if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path1)) {
\OC_Hook::emit(
@ -462,9 +470,18 @@ class View {
$result = false;
}
} else {
$source = $this->fopen($path1 . $postFix1, 'r');
$target = $this->fopen($path2 . $postFix2, 'w');
list($count, $result) = \OC_Helper::streamCopy($source, $target);
if ($this->is_dir($path1) && ($dh = $this->opendir($path1))) {
$result = $this->mkdir($path2);
while ($file = readdir($dh)) {
if (!Filesystem::isIgnoredDir($file)) {
$result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file);
}
}
} else {
$source = $this->fopen($path1 . $postFix1, 'r');
$target = $this->fopen($path2 . $postFix2, 'w');
list($count, $result) = \OC_Helper::streamCopy($source, $target);
}
}
if ($this->fakeRoot == Filesystem::getRoot()) {
\OC_Hook::emit(

View File

@ -234,6 +234,43 @@ class View extends \PHPUnit_Framework_TestCase {
$this->assertEquals(3, $cachedData['size']);
}
function testCopyBetweenStorages() {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
\OC\Files\Filesystem::mount($storage1, array(), '/');
\OC\Files\Filesystem::mount($storage2, array(), '/substorage');
$rootView = new \OC\Files\View('');
$rootView->mkdir('substorage/emptyfolder');
$rootView->copy('substorage', 'anotherfolder');
$this->assertTrue($rootView->is_dir('/anotherfolder'));
$this->assertTrue($rootView->is_dir('/substorage'));
$this->assertTrue($rootView->is_dir('/anotherfolder/emptyfolder'));
$this->assertTrue($rootView->is_dir('/substorage/emptyfolder'));
$this->assertTrue($rootView->file_exists('/anotherfolder/foo.txt'));
$this->assertTrue($rootView->file_exists('/anotherfolder/foo.png'));
$this->assertTrue($rootView->file_exists('/anotherfolder/folder/bar.txt'));
$this->assertTrue($rootView->file_exists('/substorage/foo.txt'));
$this->assertTrue($rootView->file_exists('/substorage/foo.png'));
$this->assertTrue($rootView->file_exists('/substorage/folder/bar.txt'));
}
function testMoveBetweenStorages() {
$storage1 = $this->getTestStorage();
$storage2 = $this->getTestStorage();
\OC\Files\Filesystem::mount($storage1, array(), '/');
\OC\Files\Filesystem::mount($storage2, array(), '/substorage');
$rootView = new \OC\Files\View('');
$rootView->rename('foo.txt', 'substorage/folder/foo.txt');
$this->assertFalse($rootView->file_exists('foo.txt'));
$this->assertTrue($rootView->file_exists('substorage/folder/foo.txt'));
$rootView->rename('substorage/folder', 'anotherfolder');
$this->assertFalse($rootView->is_dir('substorage/folder'));
$this->assertTrue($rootView->file_exists('anotherfolder/foo.txt'));
$this->assertTrue($rootView->file_exists('anotherfolder/bar.txt'));
}
function testTouch() {
$storage = $this->getTestStorage(true, '\Test\Files\TemporaryNoTouch');