Merge pull request #2802 from nextcloud/trash-improvements
let the owner restore files if they where moved out of a shared folder
This commit is contained in:
commit
1588dd0ee0
|
@ -44,10 +44,24 @@ class Storage extends Wrapper {
|
||||||
*/
|
*/
|
||||||
private static $disableTrash = false;
|
private static $disableTrash = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remember which file/folder was moved out of s shared folder
|
||||||
|
* in this case we want to add a copy to the owners trash bin
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $moveOutOfSharedFolder = [];
|
||||||
|
|
||||||
/** @var IUserManager */
|
/** @var IUserManager */
|
||||||
private $userManager;
|
private $userManager;
|
||||||
|
|
||||||
function __construct($parameters, IUserManager $userManager = null) {
|
/**
|
||||||
|
* Storage constructor.
|
||||||
|
*
|
||||||
|
* @param array $parameters
|
||||||
|
* @param IUserManager|null $userManager
|
||||||
|
*/
|
||||||
|
public function __construct($parameters, IUserManager $userManager = null) {
|
||||||
$this->mountPoint = $parameters['mountPoint'];
|
$this->mountPoint = $parameters['mountPoint'];
|
||||||
$this->userManager = $userManager;
|
$this->userManager = $userManager;
|
||||||
parent::__construct($parameters);
|
parent::__construct($parameters);
|
||||||
|
@ -58,8 +72,47 @@ class Storage extends Wrapper {
|
||||||
*/
|
*/
|
||||||
public static function preRenameHook($params) {
|
public static function preRenameHook($params) {
|
||||||
// in cross-storage cases, a rename is a copy + unlink,
|
// in cross-storage cases, a rename is a copy + unlink,
|
||||||
// that last unlink must not go to trash
|
// that last unlink must not go to trash, only exception:
|
||||||
self::$disableTrash = true;
|
// if the file was moved from a shared storage to a local folder,
|
||||||
|
// in this case the owner should get a copy in his trash bin so that
|
||||||
|
// they can restore the files again
|
||||||
|
|
||||||
|
$oldPath = $params['oldpath'];
|
||||||
|
$newPath = dirname($params['newpath']);
|
||||||
|
$currentUser = \OC::$server->getUserSession()->getUser();
|
||||||
|
|
||||||
|
$fileMovedOutOfSharedFolder = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($currentUser) {
|
||||||
|
$currentUserId = $currentUser->getUID();
|
||||||
|
|
||||||
|
$view = new View($currentUserId . '/files');
|
||||||
|
$fileInfo = $view->getFileInfo($oldPath);
|
||||||
|
if ($fileInfo) {
|
||||||
|
$sourceStorage = $fileInfo->getStorage();
|
||||||
|
$sourceOwner = $view->getOwner($oldPath);
|
||||||
|
$targetOwner = $view->getOwner($newPath);
|
||||||
|
|
||||||
|
if ($sourceOwner !== $targetOwner
|
||||||
|
&& $sourceStorage->instanceOfStorage('OCA\Files_Sharing\SharedStorage')
|
||||||
|
) {
|
||||||
|
$fileMovedOutOfSharedFolder = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// do nothing, in this case we just disable the trashbin and continue
|
||||||
|
$logger = \OC::$server->getLogger();
|
||||||
|
$logger->debug('Trashbin storage could not check if a file was moved out of a shared folder: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if($fileMovedOutOfSharedFolder) {
|
||||||
|
self::$moveOutOfSharedFolder['/' . $currentUserId . '/files' . $oldPath] = true;
|
||||||
|
} else {
|
||||||
|
self::$disableTrash = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,6 +127,7 @@ class Storage extends Wrapper {
|
||||||
*
|
*
|
||||||
* @param string $path1 first path
|
* @param string $path1 first path
|
||||||
* @param string $path2 second path
|
* @param string $path2 second path
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function rename($path1, $path2) {
|
public function rename($path1, $path2) {
|
||||||
$result = $this->storage->rename($path1, $path2);
|
$result = $this->storage->rename($path1, $path2);
|
||||||
|
@ -93,7 +147,14 @@ class Storage extends Wrapper {
|
||||||
* @return bool true if the operation succeeded, false otherwise
|
* @return bool true if the operation succeeded, false otherwise
|
||||||
*/
|
*/
|
||||||
public function unlink($path) {
|
public function unlink($path) {
|
||||||
return $this->doDelete($path, 'unlink');
|
if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
|
||||||
|
$result = $this->doDelete($path, 'unlink', true);
|
||||||
|
unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
|
||||||
|
} else {
|
||||||
|
$result = $this->doDelete($path, 'unlink');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +165,14 @@ class Storage extends Wrapper {
|
||||||
* @return bool true if the operation succeeded, false otherwise
|
* @return bool true if the operation succeeded, false otherwise
|
||||||
*/
|
*/
|
||||||
public function rmdir($path) {
|
public function rmdir($path) {
|
||||||
return $this->doDelete($path, 'rmdir');
|
if (isset(self::$moveOutOfSharedFolder[$this->mountPoint . $path])) {
|
||||||
|
$result = $this->doDelete($path, 'rmdir', true);
|
||||||
|
unset(self::$moveOutOfSharedFolder[$this->mountPoint . $path]);
|
||||||
|
} else {
|
||||||
|
$result = $this->doDelete($path, 'rmdir');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,10 +201,11 @@ class Storage extends Wrapper {
|
||||||
*
|
*
|
||||||
* @param string $path path of file or folder to delete
|
* @param string $path path of file or folder to delete
|
||||||
* @param string $method either "unlink" or "rmdir"
|
* @param string $method either "unlink" or "rmdir"
|
||||||
|
* @param bool $ownerOnly delete for owner only (if file gets moved out of a shared folder)
|
||||||
*
|
*
|
||||||
* @return bool true if the operation succeeded, false otherwise
|
* @return bool true if the operation succeeded, false otherwise
|
||||||
*/
|
*/
|
||||||
private function doDelete($path, $method) {
|
private function doDelete($path, $method, $ownerOnly = false) {
|
||||||
if (self::$disableTrash
|
if (self::$disableTrash
|
||||||
|| !\OC_App::isEnabled('files_trashbin')
|
|| !\OC_App::isEnabled('files_trashbin')
|
||||||
|| (pathinfo($path, PATHINFO_EXTENSION) === 'part')
|
|| (pathinfo($path, PATHINFO_EXTENSION) === 'part')
|
||||||
|
@ -158,7 +227,7 @@ class Storage extends Wrapper {
|
||||||
$this->deletedFiles[$normalized] = $normalized;
|
$this->deletedFiles[$normalized] = $normalized;
|
||||||
if ($filesPath = $view->getRelativePath($normalized)) {
|
if ($filesPath = $view->getRelativePath($normalized)) {
|
||||||
$filesPath = trim($filesPath, '/');
|
$filesPath = trim($filesPath, '/');
|
||||||
$result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath);
|
$result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath, $ownerOnly);
|
||||||
// in cross-storage cases the file will be copied
|
// in cross-storage cases the file will be copied
|
||||||
// but not deleted, so we delete it here
|
// but not deleted, so we delete it here
|
||||||
if ($result) {
|
if ($result) {
|
||||||
|
|
|
@ -196,9 +196,11 @@ class Trashbin {
|
||||||
* move file to the trash bin
|
* move file to the trash bin
|
||||||
*
|
*
|
||||||
* @param string $file_path path to the deleted file/directory relative to the files root directory
|
* @param string $file_path path to the deleted file/directory relative to the files root directory
|
||||||
|
* @param bool $ownerOnly delete for owner only (if file gets moved out of a shared folder)
|
||||||
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public static function move2trash($file_path) {
|
public static function move2trash($file_path, $ownerOnly = false) {
|
||||||
// get the user for which the filesystem is setup
|
// get the user for which the filesystem is setup
|
||||||
$root = Filesystem::getRoot();
|
$root = Filesystem::getRoot();
|
||||||
list(, $user) = explode('/', $root);
|
list(, $user) = explode('/', $root);
|
||||||
|
@ -261,8 +263,8 @@ class Trashbin {
|
||||||
|
|
||||||
self::retainVersions($filename, $owner, $ownerPath, $timestamp);
|
self::retainVersions($filename, $owner, $ownerPath, $timestamp);
|
||||||
|
|
||||||
// if owner !== user we need to also add a copy to the owners trash
|
// if owner !== user we need to also add a copy to the users trash
|
||||||
if ($user !== $owner) {
|
if ($user !== $owner && $ownerOnly === false) {
|
||||||
self::copyFilesToUser($ownerPath, $owner, $file_path, $user, $timestamp);
|
self::copyFilesToUser($ownerPath, $owner, $file_path, $user, $timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue