diff options
-rw-r--r-- | appinfo/info.xml | 4 | ||||
-rw-r--r-- | lib/AppInfo/Application.php | 10 | ||||
-rw-r--r-- | lib/Mount/GroupMountPoint.php | 12 | ||||
-rw-r--r-- | lib/Mount/MountProvider.php | 1 | ||||
-rw-r--r-- | lib/Trash/GroupTrashItem.php | 3 | ||||
-rw-r--r-- | lib/Versions/GroupVersion.php | 60 | ||||
-rw-r--r-- | lib/Versions/VersionsBackend.php | 161 |
7 files changed, 248 insertions, 3 deletions
diff --git a/appinfo/info.xml b/appinfo/info.xml index 0800bbaf..3f4c755d 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -40,4 +40,8 @@ Note: encrypting the contents of group folders is currently not supported.]]></d <trash> <backend for="OCA\GroupFolders\Mount\GroupFolderStorage">OCA\GroupFolders\Trash\TrashBackend</backend> </trash> + + <versions> + <backend for="OCA\GroupFolders\Mount\GroupFolderStorage">OCA\GroupFolders\Versions\VersionsBackend</backend> + </versions> </info> diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 7b41a950..7452160d 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -26,8 +26,10 @@ use OCA\GroupFolders\Folder\FolderManager; use OCA\GroupFolders\Mount\MountProvider; use OCA\GroupFolders\Trash\TrashBackend; use OCA\GroupFolders\Trash\TrashManager; +use OCA\GroupFolders\Versions\VersionsBackend; use OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; +use OCP\AppFramework\Utility\ITimeFactory; use OCP\Files\NotFoundException; use OCP\IGroup; use OCP\IGroupManager; @@ -67,6 +69,14 @@ class Application extends App { $c->query(MountProvider::class) ); }); + + $container->registerService(VersionsBackend::class, function(IAppContainer $c) { + return new VersionsBackend( + $c->query('GroupAppFolder'), + $c->query(MountProvider::class), + $c->query(ITimeFactory::class) + ); + }); } public function register() { diff --git a/lib/Mount/GroupMountPoint.php b/lib/Mount/GroupMountPoint.php index f9d1b355..cdf1ba51 100644 --- a/lib/Mount/GroupMountPoint.php +++ b/lib/Mount/GroupMountPoint.php @@ -24,6 +24,14 @@ namespace OCA\GroupFolders\Mount; use OC\Files\Mount\MountPoint; class GroupMountPoint extends MountPoint { + /** @var int */ + private $folderId; + + public function __construct($folderId, $storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null, $mountId = null) { + $this->folderId = $folderId; + parent::__construct($storage, $mountpoint, $arguments, $loader, $mountOptions, $mountId); + } + public function getMountType() { return 'group'; } @@ -38,4 +46,8 @@ class GroupMountPoint extends MountPoint { $options['encrypt'] = false; return $options; } + + public function getFolderId(): int { + return $this->folderId; + } } diff --git a/lib/Mount/MountProvider.php b/lib/Mount/MountProvider.php index e3719888..2dc5397e 100644 --- a/lib/Mount/MountProvider.php +++ b/lib/Mount/MountProvider.php @@ -96,6 +96,7 @@ class MountProvider implements IMountProvider { ]); return new GroupMountPoint( + $id, $quotaStorage, $mountPoint, null, diff --git a/lib/Trash/GroupTrashItem.php b/lib/Trash/GroupTrashItem.php index 8bb7568f..47535462 100644 --- a/lib/Trash/GroupTrashItem.php +++ b/lib/Trash/GroupTrashItem.php @@ -24,9 +24,6 @@ namespace OCA\GroupFolders\Trash; use OCA\Files_Trashbin\Trash\TrashItem; class GroupTrashItem extends TrashItem { - /** @var Fold */ - private $groupFolder; - public function isRootItem(): bool { return substr_count($this->getTrashPath(), '/') === 2; } diff --git a/lib/Versions/GroupVersion.php b/lib/Versions/GroupVersion.php new file mode 100644 index 00000000..2dd16406 --- /dev/null +++ b/lib/Versions/GroupVersion.php @@ -0,0 +1,60 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\GroupFolders\Versions; + +use OCA\Files_Versions\Versions\IVersionBackend; +use OCA\Files_Versions\Versions\Version; +use OCP\Files\File; +use OCP\Files\FileInfo; +use OCP\IUser; + +class GroupVersion extends Version { + private $versionFile; + + private $folderId; + + public function __construct( + int $timestamp, + int $revisionId, + string $name, + int $size, + string $mimetype, + string $path, + FileInfo $sourceFileInfo, + IVersionBackend $backend, + IUser $user, + File $versionFile, + int $folderId + ) { + parent::__construct($timestamp, $revisionId, $name, $size, $mimetype, $path, $sourceFileInfo, $backend, $user); + $this->versionFile = $versionFile; + $this->folderId = $folderId; + } + + public function getVersionFile(): File { + return $this->versionFile; + } + + public function getFolderId(): int { + return $this->folderId; + } +} diff --git a/lib/Versions/VersionsBackend.php b/lib/Versions/VersionsBackend.php new file mode 100644 index 00000000..e96043c8 --- /dev/null +++ b/lib/Versions/VersionsBackend.php @@ -0,0 +1,161 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\GroupFolders\Versions; + +use OCA\Files_Versions\Versions\IVersion; +use OCA\Files_Versions\Versions\IVersionBackend; +use OCA\GroupFolders\Folder\FolderManager; +use OCA\GroupFolders\Mount\GroupMountPoint; +use OCA\GroupFolders\Mount\MountProvider; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\Files\File; +use OCP\Files\FileInfo; +use OCP\Files\Folder; +use OCP\Files\NotFoundException; +use OCP\IUser; + +class VersionsBackend implements IVersionBackend { + /** @var Folder */ + private $appFolder; + + /** @var MountProvider */ + private $mountProvider; + + /** @var ITimeFactory */ + private $timeFactory; + + public function __construct(Folder $appFolder, MountProvider $mountProvider, ITimeFactory $timeFactory) { + $this->appFolder = $appFolder; + $this->mountProvider = $mountProvider; + $this->timeFactory = $timeFactory; + } + + public function getVersionsForFile(IUser $user, FileInfo $file): array { + $mount = $file->getMountPoint(); + if ($mount instanceof GroupMountPoint) { + try { + $folderId = $mount->getFolderId(); + /** @var Folder $versionsFolder */ + $versionsFolder = $this->getVersionsFolder($mount->getFolderId())->get($file->getId()); + return array_map(function (File $versionFile) use ($file, $user, $folderId) { + return new GroupVersion( + (int)$versionFile->getName(), + (int)$versionFile->getName(), + $file->getName(), + $versionFile->getSize(), + $versionFile->getMimetype(), + $versionFile->getPath(), + $file, + $this, + $user, + $versionFile, + $folderId + ); + }, $versionsFolder->getDirectoryListing()); + } catch (NotFoundException $e) { + return []; + } + } else { + return []; + } + } + + public function createVersion(IUser $user, FileInfo $file) { + $mount = $file->getMountPoint(); + if ($mount instanceof GroupMountPoint) { + $folderId = $mount->getFolderId(); + $versionsFolder = $this->getVersionsFolder($folderId); + + try { + /** @var Folder $versionFolder */ + $versionFolder = $versionsFolder->get($file->getId()); + } catch (NotFoundException $e) { + $versionFolder = $versionsFolder->newFolder($file->getId()); + } + + $versionMount = $versionFolder->getMountPoint(); + $sourceMount = $file->getMountPoint(); + $sourceCache = $sourceMount->getStorage()->getCache(); + $revision = $this->timeFactory->getTime(); + + $versionInternalPath = $versionFolder->getInternalPath() . '/' . $revision; + $sourceInternalPath = $file->getInternalPath(); + + $versionMount->getStorage()->copyFromStorage($sourceMount->getStorage(), $sourceInternalPath, $versionInternalPath); + $versionMount->getStorage()->getCache()->copyFromCache($sourceCache, $sourceCache->get($sourceInternalPath), $versionInternalPath); + } + } + + public function rollback(IVersion $version) { + if ($version instanceof GroupVersion) { + $this->createVersion($version->getUser(), $version->getSourceFile()); + + $targetMount = $version->getSourceFile()->getMountPoint(); + $targetCache = $targetMount->getStorage()->getCache(); + $versionMount = $version->getVersionFile()->getMountPoint(); + $versionCache = $versionMount->getStorage()->getCache(); + + $targetInternalPath = $version->getSourceFile()->getInternalPath(); + $versionInternalPath = $version->getVersionFile()->getInternalPath(); + + $targetMount->getStorage()->copyFromStorage($versionMount->getStorage(), $versionInternalPath, $targetInternalPath); + $versionMount->getStorage()->getCache()->copyFromCache($targetCache, $versionCache->get($versionInternalPath), $versionInternalPath); + } + } + + public function read(IVersion $version) { + if ($version instanceof GroupVersion) { + return $version->getVersionFile()->fopen('r'); + } else { + return false; + } + } + + public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File { + $mount = $sourceFile->getMountPoint(); + if ($mount instanceof GroupMountPoint) { + try { + /** @var Folder $versionsFolder */ + $versionsFolder = $this->getVersionsFolder($mount->getFolderId())->get($sourceFile->getId()); + return $versionsFolder->get((string)$revision); + } catch (NotFoundException $e) { + return null; + } + } else { + return null; + } + } + + /** + * @param $folderId + * @return Folder + */ + private function getVersionsFolder(int $folderId) { + try { + return $this->appFolder->get('versions/' . $folderId); + } catch (NotFoundException $e) { + /** @var Folder $trashRoot */ + $trashRoot = $this->appFolder->nodeExists('versions') ? $this->appFolder->get('versions') : $this->appFolder->newFolder('versions'); + return $trashRoot->newFolder($folderId); + } + } +} |