'uid' => $ownerOld,\r
'path' => $pathOld,\r
'type' => $type,\r
+ 'operation' => 'rename',\r
);\r
+\r
}\r
}\r
\r
/**\r
- * after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing\r
- * @param array $params array with oldpath and newpath\r
+ * mark file as renamed so that we know the original source after the file was renamed\r
+ * @param array $params with the old path and the new path\r
+ */\r
+ public static function preCopy($params) {\r
+ $user = \OCP\User::getUser();\r
+ $view = new \OC\Files\View('/');\r
+ $util = new Util($view, $user);\r
+ list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']);\r
+\r
+ // we only need to rename the keys if the rename happens on the same mountpoint\r
+ // otherwise we perform a stream copy, so we get a new set of keys\r
+ $mp1 = $view->getMountPoint('/' . $user . '/files/' . $params['oldpath']);\r
+ $mp2 = $view->getMountPoint('/' . $user . '/files/' . $params['newpath']);\r
+\r
+ $type = $view->is_dir('/' . $user . '/files/' . $params['oldpath']) ? 'folder' : 'file';\r
+\r
+ if ($mp1 === $mp2) {\r
+ self::$renamedFiles[$params['oldpath']] = array(\r
+ 'uid' => $ownerOld,\r
+ 'path' => $pathOld,\r
+ 'type' => $type,\r
+ 'operation' => 'copy');\r
+ }\r
+ }\r
+\r
+ /**\r
+ * after a file is renamed/copied, rename/copy its keyfile and share-keys also fix the file size and fix also the sharing\r
*\r
- * This function is connected to the rename signal of OC_Filesystem and adjust the name and location\r
- * of the stored versions along the actual file\r
+ * @param array $params array with oldpath and newpath\r
*/\r
- public static function postRename($params) {\r
+ public static function postRenameOrCopy($params) {\r
\r
if (\OCP\App::isEnabled('files_encryption') === false) {\r
return true;\r
$ownerOld = self::$renamedFiles[$params['oldpath']]['uid'];\r
$pathOld = self::$renamedFiles[$params['oldpath']]['path'];\r
$type = self::$renamedFiles[$params['oldpath']]['type'];\r
+ $operation = self::$renamedFiles[$params['oldpath']]['operation'];\r
unset(self::$renamedFiles[$params['oldpath']]);\r
} else {\r
\OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::DEBUG);\r
$matches = Helper::findShareKeys($oldShareKeyPath, $view);\r
foreach ($matches as $src) {\r
$dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src));\r
- $view->rename($src, $dst);\r
+ $view->$operation($src, $dst);\r
}\r
\r
} else {\r
// handle share-keys folders\r
- $view->rename($oldShareKeyPath, $newShareKeyPath);\r
+ $view->$operation($oldShareKeyPath, $newShareKeyPath);\r
}\r
\r
// Rename keyfile so it isn't orphaned\r
if ($view->file_exists($oldKeyfilePath)) {\r
- $view->rename($oldKeyfilePath, $newKeyfilePath);\r
+ $view->$operation($oldKeyfilePath, $newKeyfilePath);\r
}\r
\r
\r
public static function registerFilesystemHooks() {
\OCP\Util::connectHook('OC_Filesystem', 'rename', 'OCA\Encryption\Hooks', 'preRename');
- \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRename');
+ \OCP\Util::connectHook('OC_Filesystem', 'post_rename', 'OCA\Encryption\Hooks', 'postRenameOrCopy');
+ \OCP\Util::connectHook('OC_Filesystem', 'copy', 'OCA\Encryption\Hooks', 'preCopy');
+ \OCP\Util::connectHook('OC_Filesystem', 'post_copy', 'OCA\Encryption\Hooks', 'postRenameOrCopy');
\OCP\Util::connectHook('OC_Filesystem', 'post_delete', 'OCA\Encryption\Hooks', 'postDelete');
\OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete');
\OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUmount');
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");
$oldpath = $params['oldpath'];
$newpath = $params['newpath'];
if($oldpath<>'' && $newpath<>'') {
- Storage::rename( $oldpath, $newpath );
+ Storage::renameOrCopy($oldpath, $newpath, 'rename');
+ }
+ }
+ }
+
+ /**
+ * copy versions of copied files
+ * @param array $params array with oldpath and newpath
+ *
+ * This function is connected to the copy signal of OC_Filesystem and copies the
+ * the stored versions to the new location
+ */
+ public static function copy_hook($params) {
+
+ if (\OCP\App::isEnabled('files_versions')) {
+ $oldpath = $params['oldpath'];
+ $newpath = $params['newpath'];
+ if($oldpath<>'' && $newpath<>'') {
+ Storage::renameOrCopy($oldpath, $newpath, 'copy');
}
}
}
}
/**
- * rename versions of a file
+ * rename or copy versions of a file
+ * @param string $old_path
+ * @param string $new_path
+ * @param string $operation can be 'copy' or 'rename'
*/
- public static function rename($old_path, $new_path) {
+ public static function renameOrCopy($old_path, $new_path, $operation) {
list($uid, $oldpath) = self::getUidAndFilename($old_path);
list($uidn, $newpath) = self::getUidAndFilename($new_path);
$versions_view = new \OC\Files\View('/'.$uid .'/files_versions');
self::expire($newpath);
if ( $files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath) ) {
- $versions_view->rename($oldpath, $newpath);
+ $versions_view->$operation($oldpath, $newpath);
} else if ( ($versions = Storage::getVersions($uid, $oldpath)) ) {
// create missing dirs if necessary
self::createMissingDirectories($newpath, new \OC\Files\View('/'. $uidn));
foreach ($versions as $v) {
- $versions_view->rename($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']);
+ $versions_view->$operation($oldpath.'.v'.$v['version'], $newpath.'.v'.$v['version']);
}
}
}