summaryrefslogtreecommitdiffstats
path: root/apps/files_trashbin/lib/Storage.php
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2018-09-10 14:40:35 +0200
committerRobin Appelman <robin@icewind.nl>2018-10-17 14:56:45 +0200
commit4adac445dc57d1ccc7f26e21018e1e731e5b1654 (patch)
treeb3da061a9332a1ebca2809a61ea3cf186d9fb259 /apps/files_trashbin/lib/Storage.php
parent2634ceb35b72eac94e6bf4c61640036392c5f97f (diff)
downloadnextcloud-server-4adac445dc57d1ccc7f26e21018e1e731e5b1654.tar.gz
nextcloud-server-4adac445dc57d1ccc7f26e21018e1e731e5b1654.zip
fix select statement
fix select statement Make trashbin api modules Apps can register trashbin backends for specific storages, allowing them to modify trashbin behavior for storages The old trashbin implementation has been wrapped in a "legacy" backend, for future work this can be replaced with a new backend that better handles shares while still keeping the legacy backend around to keep existing trash from being accessible Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'apps/files_trashbin/lib/Storage.php')
-rw-r--r--apps/files_trashbin/lib/Storage.php180
1 files changed, 35 insertions, 145 deletions
diff --git a/apps/files_trashbin/lib/Storage.php b/apps/files_trashbin/lib/Storage.php
index 54b47a6a19e..0db634eeb9e 100644
--- a/apps/files_trashbin/lib/Storage.php
+++ b/apps/files_trashbin/lib/Storage.php
@@ -31,34 +31,18 @@ use OC\Files\Filesystem;
use OC\Files\Storage\Wrapper\Wrapper;
use OC\Files\View;
use OCA\Files_Trashbin\Events\MoveToTrashEvent;
+use OCA\Files_Trashbin\Trash\ITrashManager;
use OCP\Encryption\Exceptions\GenericEncryptionException;
use OCP\Files\IRootFolder;
+use OCP\Files\Mount\IMountPoint;
use OCP\Files\Node;
use OCP\ILogger;
use OCP\IUserManager;
use Symfony\Component\EventDispatcher\EventDispatcher;
class Storage extends Wrapper {
-
+ /** @var IMountPoint */
private $mountPoint;
- // remember already deleted files to avoid infinite loops if the trash bin
- // move files across storages
- private $deletedFiles = array();
-
- /**
- * Disable trash logic
- *
- * @var bool
- */
- 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 */
private $userManager;
@@ -72,21 +56,29 @@ class Storage extends Wrapper {
/** @var IRootFolder */
private $rootFolder;
+ /** @var ITrashManager */
+ private $trashManager;
+
/**
* Storage constructor.
*
* @param array $parameters
+ * @param ITrashManager $trashManager
* @param IUserManager|null $userManager
* @param ILogger|null $logger
* @param EventDispatcher|null $eventDispatcher
* @param IRootFolder|null $rootFolder
*/
- public function __construct($parameters,
- IUserManager $userManager = null,
- ILogger $logger = null,
- EventDispatcher $eventDispatcher = null,
- IRootFolder $rootFolder = null) {
+ public function __construct(
+ $parameters,
+ ITrashManager $trashManager = null,
+ IUserManager $userManager = null,
+ ILogger $logger = null,
+ EventDispatcher $eventDispatcher = null,
+ IRootFolder $rootFolder = null
+ ) {
$this->mountPoint = $parameters['mountPoint'];
+ $this->trashManager = $trashManager;
$this->userManager = $userManager;
$this->logger = $logger;
$this->eventDispatcher = $eventDispatcher;
@@ -95,81 +87,6 @@ class Storage extends Wrapper {
}
/**
- * @internal
- */
- public static function preRenameHook($params) {
- // in cross-storage cases, a rename is a copy + unlink,
- // that last unlink must not go to trash, only exception:
- // 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
- \OC::$server->getLogger()->logException($e, [
- 'message' => 'Trashbin storage could not check if a file was moved out of a shared folder.',
- 'level' => ILogger::DEBUG,
- 'app' => 'files_trashbin',
- ]);
- }
-
- if($fileMovedOutOfSharedFolder) {
- self::$moveOutOfSharedFolder['/' . $currentUserId . '/files' . $oldPath] = true;
- } else {
- self::$disableTrash = true;
- }
-
- }
-
- /**
- * @internal
- */
- public static function postRenameHook($params) {
- self::$disableTrash = false;
- }
-
- /**
- * Rename path1 to path2 by calling the wrapped storage.
- *
- * @param string $path1 first path
- * @param string $path2 second path
- * @return bool
- */
- public function rename($path1, $path2) {
- $result = $this->storage->rename($path1, $path2);
- if ($result === false) {
- // when rename failed, the post_rename hook isn't triggered,
- // but we still want to reenable the trash logic
- self::$disableTrash = false;
- }
- return $result;
- }
-
- /**
* Deletes the given file by moving it into the trashbin.
*
* @param string $path path of file or folder to delete
@@ -178,22 +95,15 @@ class Storage extends Wrapper {
*/
public function unlink($path) {
try {
- 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 $this->doDelete($path, 'unlink');
} catch (GenericEncryptionException $e) {
// in case of a encryption exception we delete the file right away
$this->logger->info(
- "Can't move file" . $path .
+ "Can't move file" . $path .
"to the trash bin, therefore it was deleted right away");
- $result = $this->storage->unlink($path);
+ return $this->storage->unlink($path);
}
-
- return $result;
}
/**
@@ -204,14 +114,7 @@ class Storage extends Wrapper {
* @return bool true if the operation succeeded, false otherwise
*/
public function rmdir($path) {
- 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;
+ return $this->doDelete($path, 'rmdir');
}
/**
@@ -221,7 +124,7 @@ class Storage extends Wrapper {
* @param $path
* @return bool
*/
- protected function shouldMoveToTrash($path){
+ protected function shouldMoveToTrash($path) {
// check if there is a app which want to disable the trash bin for this file
$fileId = $this->storage->getCache()->getId($path);
@@ -262,17 +165,16 @@ class Storage extends Wrapper {
*
* @param string $path path of file or folder to delete
* @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
*/
- private function doDelete($path, $method, $ownerOnly = false) {
- if (self::$disableTrash
- || !\OC::$server->getAppManager()->isEnabledForUser('files_trashbin')
+ private function doDelete($path, $method) {
+ if (
+ !\OC::$server->getAppManager()->isEnabledForUser('files_trashbin')
|| (pathinfo($path, PATHINFO_EXTENSION) === 'part')
|| $this->shouldMoveToTrash($path) === false
) {
- return call_user_func_array([$this->storage, $method], [$path]);
+ return call_user_func([$this->storage, $method], $path);
}
// check permissions before we continue, this is especially important for
@@ -281,28 +183,12 @@ class Storage extends Wrapper {
return false;
}
- $normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path, true, false, true);
- $result = true;
- $view = Filesystem::getView();
- if (!isset($this->deletedFiles[$normalized]) && $view instanceof View) {
- $this->deletedFiles[$normalized] = $normalized;
- if ($filesPath = $view->getRelativePath($normalized)) {
- $filesPath = trim($filesPath, '/');
- $result = \OCA\Files_Trashbin\Trashbin::move2trash($filesPath, $ownerOnly);
- // in cross-storage cases the file will be copied
- // but not deleted, so we delete it here
- if ($result) {
- call_user_func_array([$this->storage, $method], [$path]);
- }
- } else {
- $result = call_user_func_array([$this->storage, $method], [$path]);
- }
- unset($this->deletedFiles[$normalized]);
- } else if ($this->storage->file_exists($path)) {
- $result = call_user_func_array([$this->storage, $method], [$path]);
+ $isMovedToTrash = $this->trashManager->moveToTrash($this, $path);
+ if (!$isMovedToTrash) {
+ return call_user_func([$this->storage, $method], $path);
+ } else {
+ return true;
}
-
- return $result;
}
/**
@@ -311,7 +197,8 @@ class Storage extends Wrapper {
public static function setupStorage() {
\OC\Files\Filesystem::addStorageWrapper('oc_trashbin', function ($mountPoint, $storage) {
return new \OCA\Files_Trashbin\Storage(
- array('storage' => $storage, 'mountPoint' => $mountPoint),
+ ['storage' => $storage, 'mountPoint' => $mountPoint],
+ \OC::$server->query(ITrashManager::class),
\OC::$server->getUserManager(),
\OC::$server->getLogger(),
\OC::$server->getEventDispatcher(),
@@ -320,4 +207,7 @@ class Storage extends Wrapper {
}, 1);
}
+ public function getMountPoint() {
+ return $this->mountPoint;
+ }
}