Example #1
0
	public function testMoveCrossStorage() {
		$storage2 = new Temporary(array());
		$cache2 = $storage2->getCache();
		Filesystem::mount($storage2, array(), '/bar');
		$this->storage->file_put_contents('foo.txt', 'qwerty');

		$this->updater->update('foo.txt');

		$this->assertTrue($this->cache->inCache('foo.txt'));
		$this->assertFalse($cache2->inCache('bar.txt'));
		$cached = $this->cache->get('foo.txt');

		// "rename"
		$storage2->file_put_contents('bar.txt', 'qwerty');
		$this->storage->unlink('foo.txt');

		$this->assertTrue($this->cache->inCache('foo.txt'));
		$this->assertFalse($cache2->inCache('bar.txt'));

		$this->updater->rename('foo.txt', 'bar/bar.txt');

		$this->assertFalse($this->cache->inCache('foo.txt'));
		$this->assertTrue($cache2->inCache('bar.txt'));

		$cachedTarget = $cache2->get('bar.txt');
		$this->assertEquals($cached['mtime'], $cachedTarget['mtime']);
		$this->assertEquals($cached['size'], $cachedTarget['size']);
		$this->assertEquals($cached['etag'], $cachedTarget['etag']);
		$this->assertEquals($cached['fileid'], $cachedTarget['fileid']);
	}
Example #2
0
 public function testMoveDisabled()
 {
     $this->storage->file_put_contents('foo.txt', 'qwerty');
     $this->updater->update('foo.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
     $cached = $this->cache->get('foo.txt');
     $this->storage->rename('foo.txt', 'bar.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
     $this->updater->disable();
     $this->updater->rename('foo.txt', 'bar.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
 }
Example #3
0
 public function testMove()
 {
     $this->storage->file_put_contents('foo.txt', 'qwerty');
     $this->updater->update('foo.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
     $cached = $this->cache->get('foo.txt');
     $this->storage->rename('foo.txt', 'bar.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
     $this->updater->rename('foo.txt', 'bar.txt');
     $this->assertFalse($this->cache->inCache('foo.txt'));
     $this->assertTrue($this->cache->inCache('bar.txt'));
     $cachedTarget = $this->cache->get('bar.txt');
     $this->assertEquals($cached['etag'], $cachedTarget['etag']);
     $this->assertEquals($cached['mtime'], $cachedTarget['mtime']);
     $this->assertEquals($cached['size'], $cachedTarget['size']);
     $this->assertEquals($cached['fileid'], $cachedTarget['fileid']);
 }
Example #4
0
 /**
  * Rename/move a file or folder from the source path to target path.
  *
  * @param string $path1 source path
  * @param string $path2 target path
  *
  * @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 (Filesystem::isValidPath($path2) and Filesystem::isValidPath($path1) and !Filesystem::isFileBlacklisted($path2)) {
         $path1 = $this->getRelativePath($absolutePath1);
         $path2 = $this->getRelativePath($absolutePath2);
         $exists = $this->file_exists($path2);
         if ($path1 == null or $path2 == null) {
             return false;
         }
         $run = true;
         if ($this->shouldEmitHooks() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
             // if it was a rename from a part file to a regular file it was a write and not a rename operation
             $this->emit_file_hooks_pre($exists, $path2, $run);
         } elseif ($this->shouldEmitHooks()) {
             \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_rename, array(Filesystem::signal_param_oldpath => $this->getHookPath($path1), Filesystem::signal_param_newpath => $this->getHookPath($path2), Filesystem::signal_param_run => &$run));
         }
         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) {
                 if ($this->isTargetAllowed($absolutePath2)) {
                     /**
                      * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount
                      */
                     $sourceMountPoint = $mount->getMountPoint();
                     $result = $mount->moveMount($absolutePath2);
                     $manager->moveMount($sourceMountPoint, $mount->getMountPoint());
                 } else {
                     $result = false;
                 }
             } elseif ($mp1 == $mp2) {
                 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);
                     }
                 }
             }
             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
                 $this->updater->update($path2);
                 if ($this->shouldEmitHooks()) {
                     $this->emit_file_hooks_post($exists, $path2);
                 }
             } elseif ($result) {
                 $this->updater->rename($path1, $path2);
                 if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
                     \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_rename, array(Filesystem::signal_param_oldpath => $this->getHookPath($path1), Filesystem::signal_param_newpath => $this->getHookPath($path2)));
                 }
             }
             return $result;
         } else {
             return false;
         }
     } else {
         return false;
     }
 }
Example #5
0
 /**
  * Rename/move a file or folder from the source path to target path.
  *
  * @param string $path1 source path
  * @param string $path2 target path
  *
  * @return bool|mixed
  */
 public function rename($path1, $path2)
 {
     $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
     $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
     $result = false;
     if (Filesystem::isValidPath($path2) and Filesystem::isValidPath($path1) and !Filesystem::isFileBlacklisted($path2)) {
         $path1 = $this->getRelativePath($absolutePath1);
         $path2 = $this->getRelativePath($absolutePath2);
         $exists = $this->file_exists($path2);
         if ($path1 == null or $path2 == null) {
             return false;
         }
         $this->lockFile($path1, ILockingProvider::LOCK_SHARED, true);
         try {
             $this->lockFile($path2, ILockingProvider::LOCK_SHARED, true);
         } catch (LockedException $e) {
             $this->unlockFile($path1, ILockingProvider::LOCK_SHARED);
             throw $e;
         }
         $run = true;
         if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
             // if it was a rename from a part file to a regular file it was a write and not a rename operation
             $this->emit_file_hooks_pre($exists, $path2, $run);
         } elseif ($this->shouldEmitHooks($path1)) {
             \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_rename, array(Filesystem::signal_param_oldpath => $this->getHookPath($path1), Filesystem::signal_param_newpath => $this->getHookPath($path2), Filesystem::signal_param_run => &$run));
         }
         if ($run) {
             $this->verifyPath(dirname($path2), basename($path2));
             $manager = Filesystem::getMountManager();
             $mount1 = $this->getMount($path1);
             $mount2 = $this->getMount($path2);
             $storage1 = $mount1->getStorage();
             $storage2 = $mount2->getStorage();
             $internalPath1 = $mount1->getInternalPath($absolutePath1);
             $internalPath2 = $mount2->getInternalPath($absolutePath2);
             $this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE, true);
             $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE, true);
             if ($internalPath1 === '' and $mount1 instanceof MoveableMount) {
                 if ($this->isTargetAllowed($absolutePath2)) {
                     /**
                      * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1
                      */
                     $sourceMountPoint = $mount1->getMountPoint();
                     $result = $mount1->moveMount($absolutePath2);
                     $manager->moveMount($sourceMountPoint, $mount1->getMountPoint());
                 } else {
                     $result = false;
                 }
                 // moving a file/folder within the same mount point
             } elseif ($storage1 == $storage2) {
                 if ($storage1) {
                     $result = $storage1->rename($internalPath1, $internalPath2);
                 } else {
                     $result = false;
                 }
                 // moving a file/folder between storages (from $storage1 to $storage2)
             } else {
                 $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
                 $this->updater->update($path2);
             } else {
                 if ($result) {
                     if ($internalPath1 !== '') {
                         // dont do a cache update for moved mounts
                         $this->updater->rename($path1, $path2);
                     } else {
                         // only do etag propagation
                         $this->getUpdater()->getPropagator()->addChange($path1);
                         $this->getUpdater()->getPropagator()->addChange($path2);
                         $this->getUpdater()->getPropagator()->propagateChanges();
                     }
                 }
             }
             $this->changeLock($path1, ILockingProvider::LOCK_SHARED, true);
             $this->changeLock($path2, ILockingProvider::LOCK_SHARED, true);
             if (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2) && $result !== false) {
                 if ($this->shouldEmitHooks()) {
                     $this->emit_file_hooks_post($exists, $path2);
                 }
             } elseif ($result) {
                 if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
                     \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_rename, array(Filesystem::signal_param_oldpath => $this->getHookPath($path1), Filesystem::signal_param_newpath => $this->getHookPath($path2)));
                 }
             }
         }
         $this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true);
         $this->unlockFile($path2, ILockingProvider::LOCK_SHARED, true);
     }
     return $result;
 }