Make permalinks work for trashed files (#24537)

Opening a permalink that points to a trashed file will now display the
file within the "Deleted Files" section in the files web UI.
This commit is contained in:
Vincent Petry 2016-05-11 19:41:36 +02:00 committed by Thomas Müller
parent bc1d70f08c
commit ceaac03bb5
3 changed files with 139 additions and 30 deletions

View File

@ -59,7 +59,8 @@ class Application extends App {
$server->getConfig(), $server->getConfig(),
$server->getEventDispatcher(), $server->getEventDispatcher(),
$server->getUserSession(), $server->getUserSession(),
$server->getUserFolder() $server->getAppManager(),
$server->getRootFolder()
); );
}); });

View File

@ -39,6 +39,7 @@ use OCP\IUserSession;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Http\NotFoundResponse;
use OCP\Files\Folder; use OCP\Files\Folder;
use OCP\App\IAppManager;
/** /**
* Class ViewController * Class ViewController
@ -62,8 +63,10 @@ class ViewController extends Controller {
protected $eventDispatcher; protected $eventDispatcher;
/** @var IUserSession */ /** @var IUserSession */
protected $userSession; protected $userSession;
/** @var IAppManager */
protected $appManager;
/** @var \OCP\Files\Folder */ /** @var \OCP\Files\Folder */
protected $userFolder; protected $rootFolder;
/** /**
* @param string $appName * @param string $appName
@ -74,7 +77,8 @@ class ViewController extends Controller {
* @param IConfig $config * @param IConfig $config
* @param EventDispatcherInterface $eventDispatcherInterface * @param EventDispatcherInterface $eventDispatcherInterface
* @param IUserSession $userSession * @param IUserSession $userSession
* @param Folder $userFolder * @param IAppManager $appManager
* @param Folder $rootFolder
*/ */
public function __construct($appName, public function __construct($appName,
IRequest $request, IRequest $request,
@ -84,7 +88,8 @@ class ViewController extends Controller {
IConfig $config, IConfig $config,
EventDispatcherInterface $eventDispatcherInterface, EventDispatcherInterface $eventDispatcherInterface,
IUserSession $userSession, IUserSession $userSession,
Folder $userFolder IAppManager $appManager,
Folder $rootFolder
) { ) {
parent::__construct($appName, $request); parent::__construct($appName, $request);
$this->appName = $appName; $this->appName = $appName;
@ -95,7 +100,8 @@ class ViewController extends Controller {
$this->config = $config; $this->config = $config;
$this->eventDispatcher = $eventDispatcherInterface; $this->eventDispatcher = $eventDispatcherInterface;
$this->userSession = $userSession; $this->userSession = $userSession;
$this->userFolder = $userFolder; $this->appManager = $appManager;
$this->rootFolder = $rootFolder;
} }
/** /**
@ -265,22 +271,34 @@ class ViewController extends Controller {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function showFile($fileId) { public function showFile($fileId) {
$files = $this->userFolder->getById($fileId); try {
$uid = $this->userSession->getUser()->getUID();
$baseFolder = $this->rootFolder->get($uid . '/files/');
$files = $baseFolder->getById($fileId);
$params = []; $params = [];
if (empty($files) && $this->appManager->isEnabledForUser('files_trashbin')) {
$baseFolder = $this->rootFolder->get($uid . '/files_trashbin/files/');
$files = $baseFolder->getById($fileId);
$params['view'] = 'trashbin';
}
if (!empty($files)) { if (!empty($files)) {
$file = current($files); $file = current($files);
if ($file instanceof Folder) { if ($file instanceof Folder) {
// set the full path to enter the folder // set the full path to enter the folder
$params['dir'] = $this->userFolder->getRelativePath($file->getPath()); $params['dir'] = $baseFolder->getRelativePath($file->getPath());
} else { } else {
// set parent path as dir // set parent path as dir
$params['dir'] = $this->userFolder->getRelativePath($file->getParent()->getPath()); $params['dir'] = $baseFolder->getRelativePath($file->getParent()->getPath());
// and scroll to the entry // and scroll to the entry
$params['scrollto'] = $file->getName(); $params['scrollto'] = $file->getName();
} }
return new RedirectResponse($this->urlGenerator->linkToRoute('files.view.index', $params)); return new RedirectResponse($this->urlGenerator->linkToRoute('files.view.index', $params));
} }
} catch (\OCP\Files\NotFoundException $e) {
return new NotFoundResponse();
}
return new NotFoundResponse(); return new NotFoundResponse();
} }
} }

View File

@ -37,6 +37,7 @@ use OCP\IConfig;
use OCP\IUserSession; use OCP\IUserSession;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use OCP\Files\Folder; use OCP\Files\Folder;
use OCP\App\IAppManager;
/** /**
* Class ViewControllerTest * Class ViewControllerTest
@ -62,8 +63,10 @@ class ViewControllerTest extends TestCase {
private $user; private $user;
/** @var IUserSession */ /** @var IUserSession */
private $userSession; private $userSession;
/** @var IAppManager */
private $appManager;
/** @var Folder */ /** @var Folder */
private $userFolder; private $rootFolder;
public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();
@ -74,11 +77,15 @@ class ViewControllerTest extends TestCase {
$this->config = $this->getMock('\OCP\IConfig'); $this->config = $this->getMock('\OCP\IConfig');
$this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface'); $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface');
$this->userSession = $this->getMock('\OCP\IUserSession'); $this->userSession = $this->getMock('\OCP\IUserSession');
$this->appManager = $this->getMock('\OCP\App\IAppManager');
$this->user = $this->getMock('\OCP\IUser'); $this->user = $this->getMock('\OCP\IUser');
$this->user->expects($this->any())
->method('getUID')
->will($this->returnValue('testuser1'));
$this->userSession->expects($this->any()) $this->userSession->expects($this->any())
->method('getUser') ->method('getUser')
->will($this->returnValue($this->user)); ->will($this->returnValue($this->user));
$this->userFolder = $this->getMock('\OCP\Files\Folder'); $this->rootFolder = $this->getMock('\OCP\Files\Folder');
$this->viewController = $this->getMockBuilder('\OCA\Files\Controller\ViewController') $this->viewController = $this->getMockBuilder('\OCA\Files\Controller\ViewController')
->setConstructorArgs([ ->setConstructorArgs([
'files', 'files',
@ -89,7 +96,8 @@ class ViewControllerTest extends TestCase {
$this->config, $this->config,
$this->eventDispatcher, $this->eventDispatcher,
$this->userSession, $this->userSession,
$this->userFolder $this->appManager,
$this->rootFolder
]) ])
->setMethods([ ->setMethods([
'getStorageInfo', 'getStorageInfo',
@ -307,15 +315,22 @@ class ViewControllerTest extends TestCase {
$node = $this->getMock('\OCP\Files\Folder'); $node = $this->getMock('\OCP\Files\Folder');
$node->expects($this->once()) $node->expects($this->once())
->method('getPath') ->method('getPath')
->will($this->returnValue('/user/files/test/sub')); ->will($this->returnValue('/testuser1/files/test/sub'));
$this->userFolder->expects($this->at(0)) $baseFolder = $this->getMock('\OCP\Files\Folder');
$this->rootFolder->expects($this->once())
->method('get')
->with('testuser1/files/')
->will($this->returnValue($baseFolder));
$baseFolder->expects($this->at(0))
->method('getById') ->method('getById')
->with(123) ->with(123)
->will($this->returnValue([$node])); ->will($this->returnValue([$node]));
$this->userFolder->expects($this->at(1)) $baseFolder->expects($this->at(1))
->method('getRelativePath') ->method('getRelativePath')
->with('/user/files/test/sub') ->with('/testuser1/files/test/sub')
->will($this->returnValue('/test/sub')); ->will($this->returnValue('/test/sub'));
$this->urlGenerator $this->urlGenerator
@ -339,7 +354,14 @@ class ViewControllerTest extends TestCase {
$parentNode = $this->getMock('\OCP\Files\Folder'); $parentNode = $this->getMock('\OCP\Files\Folder');
$parentNode->expects($this->once()) $parentNode->expects($this->once())
->method('getPath') ->method('getPath')
->will($this->returnValue('/user/files/test')); ->will($this->returnValue('testuser1/files/test'));
$baseFolder = $this->getMock('\OCP\Files\Folder');
$this->rootFolder->expects($this->once())
->method('get')
->with('testuser1/files/')
->will($this->returnValue($baseFolder));
$node = $this->getMock('\OCP\Files\File'); $node = $this->getMock('\OCP\Files\File');
$node->expects($this->once()) $node->expects($this->once())
@ -349,13 +371,13 @@ class ViewControllerTest extends TestCase {
->method('getName') ->method('getName')
->will($this->returnValue('somefile.txt')); ->will($this->returnValue('somefile.txt'));
$this->userFolder->expects($this->at(0)) $baseFolder->expects($this->at(0))
->method('getById') ->method('getById')
->with(123) ->with(123)
->will($this->returnValue([$node])); ->will($this->returnValue([$node]));
$this->userFolder->expects($this->at(1)) $baseFolder->expects($this->at(1))
->method('getRelativePath') ->method('getRelativePath')
->with('/user/files/test') ->with('testuser1/files/test')
->will($this->returnValue('/test')); ->will($this->returnValue('/test'));
$this->urlGenerator $this->urlGenerator
@ -376,7 +398,13 @@ class ViewControllerTest extends TestCase {
* @dataProvider showFileMethodProvider * @dataProvider showFileMethodProvider
*/ */
public function testShowFileRouteWithInvalidFileId($useShowFile) { public function testShowFileRouteWithInvalidFileId($useShowFile) {
$this->userFolder->expects($this->at(0)) $baseFolder = $this->getMock('\OCP\Files\Folder');
$this->rootFolder->expects($this->once())
->method('get')
->with('testuser1/files/')
->will($this->returnValue($baseFolder));
$baseFolder->expects($this->at(0))
->method('getById') ->method('getById')
->with(123) ->with(123)
->will($this->returnValue([])); ->will($this->returnValue([]));
@ -388,4 +416,66 @@ class ViewControllerTest extends TestCase {
$this->assertEquals($expected, $this->viewController->index('/whatever', '', '123')); $this->assertEquals($expected, $this->viewController->index('/whatever', '', '123'));
} }
} }
/**
* @dataProvider showFileMethodProvider
*/
public function testShowFileRouteWithTrashedFile($useShowFile) {
$this->appManager->expects($this->once())
->method('isEnabledForUser')
->with('files_trashbin')
->will($this->returnValue(true));
$parentNode = $this->getMock('\OCP\Files\Folder');
$parentNode->expects($this->once())
->method('getPath')
->will($this->returnValue('testuser1/files_trashbin/files/test.d1462861890/sub'));
$baseFolderFiles = $this->getMock('\OCP\Files\Folder');
$baseFolderTrash = $this->getMock('\OCP\Files\Folder');
$this->rootFolder->expects($this->at(0))
->method('get')
->with('testuser1/files/')
->will($this->returnValue($baseFolderFiles));
$this->rootFolder->expects($this->at(1))
->method('get')
->with('testuser1/files_trashbin/files/')
->will($this->returnValue($baseFolderTrash));
$baseFolderFiles->expects($this->once())
->method('getById')
->with(123)
->will($this->returnValue([]));
$node = $this->getMock('\OCP\Files\File');
$node->expects($this->once())
->method('getParent')
->will($this->returnValue($parentNode));
$node->expects($this->once())
->method('getName')
->will($this->returnValue('somefile.txt'));
$baseFolderTrash->expects($this->at(0))
->method('getById')
->with(123)
->will($this->returnValue([$node]));
$baseFolderTrash->expects($this->at(1))
->method('getRelativePath')
->with('testuser1/files_trashbin/files/test.d1462861890/sub')
->will($this->returnValue('/test.d1462861890/sub'));
$this->urlGenerator
->expects($this->once())
->method('linkToRoute')
->with('files.view.index', ['view' => 'trashbin', 'dir' => '/test.d1462861890/sub', 'scrollto' => 'somefile.txt'])
->will($this->returnValue('/apps/files/?view=trashbin&dir=/test.d1462861890/sub&scrollto=somefile.txt'));
$expected = new Http\RedirectResponse('/apps/files/?view=trashbin&dir=/test.d1462861890/sub&scrollto=somefile.txt');
if ($useShowFile) {
$this->assertEquals($expected, $this->viewController->showFile(123));
} else {
$this->assertEquals($expected, $this->viewController->index('/whatever', '', '123'));
}
}
} }