]> source.dussan.org Git - nextcloud-server.git/commitdiff
get the source path and owner in a pre hook and the target path and owner in a
authorBjoern Schiessle <schiessle@owncloud.com>
Tue, 28 Oct 2014 14:57:08 +0000 (15:57 +0100)
committerBjoern Schiessle <schiessle@owncloud.com>
Wed, 29 Oct 2014 09:11:01 +0000 (10:11 +0100)
post hook

apps/files_versions/lib/hooks.php
apps/files_versions/lib/versions.php
apps/files_versions/tests/versions.php

index 1a584232ba74e72296849ffba02fa6fb766d1c1c..024cb6a3c39bb8020d6c520643d112f83c187b67 100644 (file)
@@ -16,12 +16,14 @@ class Hooks {
 
        public static function connectHooks() {
                // Listen to write signals
-               \OCP\Util::connectHook('OC_Filesystem', 'write', "OCA\Files_Versions\Hooks", "write_hook");
+               \OCP\Util::connectHook('OC_Filesystem', 'write', 'OCA\Files_Versions\Hooks', 'write_hook');
                // Listen to delete and rename signals
-               \OCP\Util::connectHook('OC_Filesystem', 'post_delete', "OCA\Files_Versions\Hooks", "remove_hook");
-               \OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA\Files_Versions\Hooks", "pre_remove_hook");
-               \OCP\Util::connectHook('OC_Filesystem', 'rename', "OCA\Files_Versions\Hooks", "rename_hook");
-               \OCP\Util::connectHook('OC_Filesystem', 'copy', "OCA\Files_Versions\Hooks", "copy_hook");
+               \OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Files_Versions\Hooks', 'remove_hook');
+               \OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Files_Versions\Hooks', 'pre_remove_hook');
+               \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Files_Versions\Hooks', 'rename_hook');
+               \OCP\Util::connectHook('OC_Filesystem', 'post_copy', 'OCA\Files_Versions\Hooks', 'copy_hook');
+               \OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Files_Versions\Hooks', 'pre_renameOrCopy_hook');
+               \OCP\Util::connectHook('OC_Filesystem', 'copy', 'OCA\Files_Versions\Hooks', 'pre_renameOrCopy_hook');
        }
 
        /**
@@ -102,4 +104,25 @@ class Hooks {
                }
        }
 
+       /**
+        * Remember owner and the owner path of the source file.
+        * If the file already exists, then it was a upload of a existing file
+        * over the web interface and we call Storage::store() directly
+        *
+        * @param array $params array with oldpath and newpath
+        *
+        */
+       public static function pre_renameOrCopy_hook($params) {
+               if (\OCP\App::isEnabled('files_versions')) {
+
+                       $view = new \OC\Files\View(\OCP\User::getUser() . '/files');
+                       if ($view->file_exists($params['newpath'])) {
+                               Storage::store($params['newpath']);
+                       } else {
+                               Storage::setSourcePathAndUser($params['oldpath']);
+                       }
+
+               }
+       }
+
 }
index bdb26896948341a5fb0dccdb196f638a32dbf743..35e79569cda23fb01109df40a77ea45a0eb80746 100644 (file)
@@ -24,6 +24,8 @@ class Storage {
        // files for which we can remove the versions after the delete operation was successful
        private static $deletedFiles = array();
 
+       private static $sourcePathAndUser = array();
+
        private static $max_versions_per_interval = array(
                //first 10sec, one version every 2sec
                1 => array('intervalEndsAfter' => 10,      'step' => 2),
@@ -50,6 +52,34 @@ class Storage {
                return array($uid, $filename);
        }
 
+       /**
+        * remeber the owner and the owner path of the source file
+        *
+        * @param string $source source path
+        */
+       public static function setSourcePathAndUser($source) {
+               list($uid, $path) = self::getUidAndFilename($source);
+               self::$sourcePathAndUser[$source] = array('uid' => $uid, 'path' => $path);
+       }
+
+       /**
+        * gets the owner and the owner path from the source path
+        *
+        * @param string $source source path
+        * @return array with user id and path
+        */
+       public static function getSourcePathAndUser($source) {
+
+               if (isset(self::$sourcePathAndUser[$source])) {
+                       $uid = self::$sourcePathAndUser[$source]['uid'];
+                       $path = self::$sourcePathAndUser[$source]['path'];
+                       unset(self::$sourcePathAndUser[$source]);
+               } else {
+                       $uid = $path = false;
+               }
+               return array($uid, $path);
+       }
+
        /**
         * get current size of all versions from a given user
         *
@@ -180,16 +210,20 @@ class Storage {
         * @param string $operation can be 'copy' or 'rename'
         */
        public static function renameOrCopy($old_path, $new_path, $operation) {
-               list($uid, $oldpath) = self::getUidAndFilename($old_path);
+               list($uid, $oldpath) = self::getSourcePathAndUser($old_path);
+
+               // it was a upload of a existing file if no old path exists
+               // in this case the pre-hook already called the store method and we can
+               // stop here
+               if ($oldpath === false) {
+                       return true;
+               }
+
                list($uidn, $newpath) = self::getUidAndFilename($new_path);
                $versions_view = new \OC\Files\View('/'.$uid .'/files_versions');
                $files_view = new \OC\Files\View('/'.$uid .'/files');
 
-               // if the file already exists than it was a upload of a existing file
-               // over the web interface -> store() is the right function we need here
-               if ($files_view->file_exists($newpath)) {
-                       return self::store($new_path);
-               }
+
 
                if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) {
                        $versions_view->$operation($oldpath, $newpath);
index 558c8dfcb8abc9c61b82792c13c898310526851b..6dfba6bcf233191f78523fc959d44ace0684276d 100644 (file)
@@ -30,18 +30,28 @@ require_once __DIR__ . '/../lib/versions.php';
 class Test_Files_Versioning extends \PHPUnit_Framework_TestCase {
 
        const TEST_VERSIONS_USER = 'test-versions-user';
+       const TEST_VERSIONS_USER2 = 'test-versions-user2';
        const USERS_VERSIONS_ROOT = '/test-versions-user/files_versions';
 
        private $rootView;
 
        public static function setUpBeforeClass() {
+
+               // clear share hooks
+               \OC_Hook::clear('OCP\\Share');
+               \OC::registerShareHooks();
+               \OCA\Files_Versions\Hooks::connectHooks();
+               \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
+
                // create test user
+               self::loginHelper(self::TEST_VERSIONS_USER2, true);
                self::loginHelper(self::TEST_VERSIONS_USER, true);
        }
 
        public static function tearDownAfterClass() {
                // cleanup test user
                \OC_User::deleteUser(self::TEST_VERSIONS_USER);
+               \OC_User::deleteUser(self::TEST_VERSIONS_USER2);
        }
 
        function setUp() {
@@ -222,7 +232,7 @@ class Test_Files_Versioning extends \PHPUnit_Framework_TestCase {
                $this->rootView->file_put_contents($v2, 'version2');
 
                // execute rename hook of versions app
-               \OCA\Files_Versions\Storage::renameOrCopy("test.txt", "test2.txt", 'rename');
+               \OC\Files\Filesystem::rename("test.txt", "test2.txt");
 
                $this->assertFalse($this->rootView->file_exists($v1));
                $this->assertFalse($this->rootView->file_exists($v2));
@@ -234,6 +244,50 @@ class Test_Files_Versioning extends \PHPUnit_Framework_TestCase {
                \OC\Files\Filesystem::unlink('test2.txt');
        }
 
+       function testRenameInSharedFolder() {
+
+               \OC\Files\Filesystem::mkdir('folder1');
+               \OC\Files\Filesystem::mkdir('folder1/folder2');
+               \OC\Files\Filesystem::file_put_contents("folder1/test.txt", "test file");
+
+               $fileInfo = \OC\Files\Filesystem::getFileInfo('folder1');
+
+               $t1 = time();
+               // second version is two weeks older, this way we make sure that no
+               // version will be expired
+               $t2 = $t1 - 60 * 60 * 24 * 14;
+
+               $this->rootView->mkdir(self::USERS_VERSIONS_ROOT . '/folder1');
+               // create some versions
+               $v1 = self::USERS_VERSIONS_ROOT . '/folder1/test.txt.v' . $t1;
+               $v2 = self::USERS_VERSIONS_ROOT . '/folder1/test.txt.v' . $t2;
+               $v1Renamed = self::USERS_VERSIONS_ROOT . '/folder1/folder2/test.txt.v' . $t1;
+               $v2Renamed = self::USERS_VERSIONS_ROOT . '/folder1/folder2/test.txt.v' . $t2;
+
+               $this->rootView->file_put_contents($v1, 'version1');
+               $this->rootView->file_put_contents($v2, 'version2');
+
+               \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_VERSIONS_USER2, OCP\PERMISSION_ALL);
+
+               self::loginHelper(self::TEST_VERSIONS_USER2);
+
+               $this->assertTrue(\OC\Files\Filesystem::file_exists('folder1/test.txt'));
+
+               // execute rename hook of versions app
+               \OC\Files\Filesystem::rename('/folder1/test.txt', '/folder1/folder2/test.txt');
+
+               self::loginHelper(self::TEST_VERSIONS_USER2);
+
+               $this->assertFalse($this->rootView->file_exists($v1));
+               $this->assertFalse($this->rootView->file_exists($v2));
+
+               $this->assertTrue($this->rootView->file_exists($v1Renamed));
+               $this->assertTrue($this->rootView->file_exists($v2Renamed));
+
+               //cleanup
+               \OC\Files\Filesystem::unlink('/folder1/folder2/test.txt');
+       }
+
        function testCopy() {
 
                \OC\Files\Filesystem::file_put_contents("test.txt", "test file");
@@ -253,7 +307,7 @@ class Test_Files_Versioning extends \PHPUnit_Framework_TestCase {
                $this->rootView->file_put_contents($v2, 'version2');
 
                // execute copy hook of versions app
-               \OCA\Files_Versions\Storage::renameOrCopy("test.txt", "test2.txt", 'copy');
+               \OC\Files\Filesystem::copy("test.txt", "test2.txt");
 
                $this->assertTrue($this->rootView->file_exists($v1));
                $this->assertTrue($this->rootView->file_exists($v2));