modular versions api
Allows apps to register version backends for storage types The existing versions backend is wrapped in a "legacy" backend. Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
parent
4a642fc004
commit
4403d771ad
21 changed files with 798 additions and 120 deletions
|
@ -41,4 +41,8 @@
|
|||
<collection>OCA\Files_Versions\Sabre\RootCollection</collection>
|
||||
</collections>
|
||||
</sabre>
|
||||
|
||||
<versions>
|
||||
<backend for="OCP\Files\Storage\IStorage">OCA\Files_Versions\Versions\LegacyVersionsBackend</backend>
|
||||
</versions>
|
||||
</info>
|
||||
|
|
|
@ -23,4 +23,11 @@ return array(
|
|||
'OCA\\Files_Versions\\Sabre\\VersionHome' => $baseDir . '/../lib/Sabre/VersionHome.php',
|
||||
'OCA\\Files_Versions\\Sabre\\VersionRoot' => $baseDir . '/../lib/Sabre/VersionRoot.php',
|
||||
'OCA\\Files_Versions\\Storage' => $baseDir . '/../lib/Storage.php',
|
||||
'OCA\\Files_Versions\\Versions\\BackendNotFoundException' => $baseDir . '/../lib/Versions/BackendNotFoundException.php',
|
||||
'OCA\\Files_Versions\\Versions\\IVersion' => $baseDir . '/../lib/Versions/IVersion.php',
|
||||
'OCA\\Files_Versions\\Versions\\IVersionBackend' => $baseDir . '/../lib/Versions/IVersionBackend.php',
|
||||
'OCA\\Files_Versions\\Versions\\IVersionManager' => $baseDir . '/../lib/Versions/IVersionManager.php',
|
||||
'OCA\\Files_Versions\\Versions\\LegacyVersionsBackend' => $baseDir . '/../lib/Versions/LegacyVersionsBackend.php',
|
||||
'OCA\\Files_Versions\\Versions\\Version' => $baseDir . '/../lib/Versions/Version.php',
|
||||
'OCA\\Files_Versions\\Versions\\VersionManager' => $baseDir . '/../lib/Versions/VersionManager.php',
|
||||
);
|
||||
|
|
|
@ -38,6 +38,13 @@ class ComposerStaticInitFiles_Versions
|
|||
'OCA\\Files_Versions\\Sabre\\VersionHome' => __DIR__ . '/..' . '/../lib/Sabre/VersionHome.php',
|
||||
'OCA\\Files_Versions\\Sabre\\VersionRoot' => __DIR__ . '/..' . '/../lib/Sabre/VersionRoot.php',
|
||||
'OCA\\Files_Versions\\Storage' => __DIR__ . '/..' . '/../lib/Storage.php',
|
||||
'OCA\\Files_Versions\\Versions\\BackendNotFoundException' => __DIR__ . '/..' . '/../lib/Versions/BackendNotFoundException.php',
|
||||
'OCA\\Files_Versions\\Versions\\IVersion' => __DIR__ . '/..' . '/../lib/Versions/IVersion.php',
|
||||
'OCA\\Files_Versions\\Versions\\IVersionBackend' => __DIR__ . '/..' . '/../lib/Versions/IVersionBackend.php',
|
||||
'OCA\\Files_Versions\\Versions\\IVersionManager' => __DIR__ . '/..' . '/../lib/Versions/IVersionManager.php',
|
||||
'OCA\\Files_Versions\\Versions\\LegacyVersionsBackend' => __DIR__ . '/..' . '/../lib/Versions/LegacyVersionsBackend.php',
|
||||
'OCA\\Files_Versions\\Versions\\Version' => __DIR__ . '/..' . '/../lib/Versions/Version.php',
|
||||
'OCA\\Files_Versions\\Versions\\VersionManager' => __DIR__ . '/..' . '/../lib/Versions/VersionManager.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
namespace OCA\Files_Versions\AppInfo;
|
||||
|
||||
use OCA\DAV\Connector\Sabre\Principal;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCA\Files_Versions\Versions\VersionManager;
|
||||
use OCP\AppFramework\App;
|
||||
use OCA\Files_Versions\Expiration;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\AppFramework\IAppContainer;
|
||||
use OCA\Files_Versions\Capabilities;
|
||||
|
||||
class Application extends App {
|
||||
|
@ -43,14 +44,45 @@ class Application extends App {
|
|||
/*
|
||||
* Register $principalBackend for the DAV collection
|
||||
*/
|
||||
$container->registerService('principalBackend', function () {
|
||||
$container->registerService('principalBackend', function (IAppContainer $c) {
|
||||
$server = $c->getServer();
|
||||
return new Principal(
|
||||
\OC::$server->getUserManager(),
|
||||
\OC::$server->getGroupManager(),
|
||||
\OC::$server->getShareManager(),
|
||||
\OC::$server->getUserSession(),
|
||||
\OC::$server->getConfig()
|
||||
$server->getUserManager(),
|
||||
$server->getGroupManager(),
|
||||
$server->getShareManager(),
|
||||
$server->getUserSession(),
|
||||
$server->getConfig()
|
||||
);
|
||||
});
|
||||
|
||||
$container->registerService(IVersionManager::class, function(IAppContainer $c) {
|
||||
return new VersionManager();
|
||||
});
|
||||
|
||||
$this->registerVersionBackends();
|
||||
}
|
||||
|
||||
public function registerVersionBackends() {
|
||||
$server = $this->getContainer()->getServer();
|
||||
$logger = $server->getLogger();
|
||||
$appManager = $server->getAppManager();
|
||||
/** @var IVersionManager $versionManager */
|
||||
$versionManager = $this->getContainer()->getServer()->query(IVersionManager::class);
|
||||
foreach($appManager->getInstalledApps() as $app) {
|
||||
$appInfo = $appManager->getAppInfo($app);
|
||||
if (isset($appInfo['versions'])) {
|
||||
$backends = $appInfo['versions'];
|
||||
foreach($backends as $backend) {
|
||||
$class = $backend['@value'];
|
||||
$for = $backend['@attributes']['for'];
|
||||
try {
|
||||
$backendObject = $server->query($class);
|
||||
$versionManager->registerBackend($for, $backendObject);
|
||||
} catch (\Exception $e) {
|
||||
$logger->logException($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,45 +21,53 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Versions\Controller;
|
||||
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IMimeTypeDetector;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IPreview;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserSession;
|
||||
|
||||
class PreviewController extends Controller {
|
||||
|
||||
/** @var IRootFolder */
|
||||
private $rootFolder;
|
||||
|
||||
/** @var string */
|
||||
private $userId;
|
||||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
|
||||
/** @var IMimeTypeDetector */
|
||||
private $mimeTypeDetector;
|
||||
|
||||
/** @var IVersionManager */
|
||||
private $versionManager;
|
||||
|
||||
/** @var IPreview */
|
||||
private $previewManager;
|
||||
|
||||
public function __construct($appName,
|
||||
IRequest $request,
|
||||
IRootFolder $rootFolder,
|
||||
$userId,
|
||||
IMimeTypeDetector $mimeTypeDetector,
|
||||
IPreview $previewManager) {
|
||||
public function __construct(
|
||||
$appName,
|
||||
IRequest $request,
|
||||
IRootFolder $rootFolder,
|
||||
IUserSession $userSession,
|
||||
IMimeTypeDetector $mimeTypeDetector,
|
||||
IVersionManager $versionManager,
|
||||
IPreview $previewManager
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->userId = $userId;
|
||||
$this->userSession = $userSession;
|
||||
$this->mimeTypeDetector = $mimeTypeDetector;
|
||||
$this->versionManager = $versionManager;
|
||||
$this->previewManager = $previewManager;
|
||||
}
|
||||
|
||||
|
@ -79,20 +87,17 @@ class PreviewController extends Controller {
|
|||
$y = 44,
|
||||
$version = ''
|
||||
) {
|
||||
if($file === '' || $version === '' || $x === 0 || $y === 0) {
|
||||
if ($file === '' || $version === '' || $x === 0 || $y === 0) {
|
||||
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
try {
|
||||
$userFolder = $this->rootFolder->getUserFolder($this->userId);
|
||||
/** @var Folder $versionFolder */
|
||||
$versionFolder = $userFolder->getParent()->get('files_versions');
|
||||
$mimeType = $this->mimeTypeDetector->detectPath($file);
|
||||
$file = $versionFolder->get($file.'.v'.$version);
|
||||
|
||||
/** @var File $file */
|
||||
$f = $this->previewManager->getPreview($file, $x, $y, true, IPreview::MODE_FILL, $mimeType);
|
||||
return new FileDisplayResponse($f, Http::STATUS_OK, ['Content-Type' => $f->getMimeType()]);
|
||||
$user = $this->userSession->getUser();
|
||||
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
|
||||
$file = $userFolder->get($file);
|
||||
$versionFile = $this->versionManager->getVersionFile($user, $file, (int)$version);
|
||||
$preview = $this->previewManager->getPreview($versionFile, $x, $y, true, IPreview::MODE_FILL, $versionFile->getMimetype());
|
||||
return new FileDisplayResponse($preview, Http::STATUS_OK, ['Content-Type' => $preview->getMimeType()]);
|
||||
} catch (NotFoundException $e) {
|
||||
return new DataResponse([], Http::STATUS_NOT_FOUND);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
|
|
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Files_Versions\Sabre;
|
||||
|
||||
use OCP\IUser;
|
||||
use Sabre\DAV\Exception\Forbidden;
|
||||
use Sabre\DAV\ICollection;
|
||||
use Sabre\DAV\IMoveTarget;
|
||||
|
@ -31,14 +32,6 @@ use Sabre\DAV\INode;
|
|||
|
||||
|
||||
class RestoreFolder implements ICollection, IMoveTarget {
|
||||
|
||||
/** @var string */
|
||||
protected $userId;
|
||||
|
||||
public function __construct(string $userId) {
|
||||
$this->userId = $userId;
|
||||
}
|
||||
|
||||
public function createFile($name, $data = null) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
|
@ -80,7 +73,8 @@ class RestoreFolder implements ICollection, IMoveTarget {
|
|||
return false;
|
||||
}
|
||||
|
||||
return $sourceNode->rollBack();
|
||||
$sourceNode->rollBack();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,10 +20,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Versions\Sabre;
|
||||
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUserManager;
|
||||
use Sabre\DAV\INode;
|
||||
use Sabre\DAVACL\AbstractPrincipalCollection;
|
||||
use Sabre\DAVACL\PrincipalBackend;
|
||||
|
@ -33,12 +36,24 @@ class RootCollection extends AbstractPrincipalCollection {
|
|||
/** @var IRootFolder */
|
||||
private $rootFolder;
|
||||
|
||||
public function __construct(PrincipalBackend\BackendInterface $principalBackend,
|
||||
IRootFolder $rootFolder,
|
||||
IConfig $config) {
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var IVersionManager */
|
||||
private $versionManager;
|
||||
|
||||
public function __construct(
|
||||
PrincipalBackend\BackendInterface $principalBackend,
|
||||
IRootFolder $rootFolder,
|
||||
IConfig $config,
|
||||
IUserManager $userManager,
|
||||
IVersionManager $versionManager
|
||||
) {
|
||||
parent::__construct($principalBackend, 'principals/users');
|
||||
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->userManager = $userManager;
|
||||
$this->versionManager = $versionManager;
|
||||
|
||||
$this->disableListing = !$config->getSystemValue('debug', false);
|
||||
}
|
||||
|
@ -54,12 +69,12 @@ class RootCollection extends AbstractPrincipalCollection {
|
|||
* @return INode
|
||||
*/
|
||||
public function getChildForPrincipal(array $principalInfo) {
|
||||
list(,$name) = \Sabre\Uri\split($principalInfo['uri']);
|
||||
list(, $name) = \Sabre\Uri\split($principalInfo['uri']);
|
||||
$user = \OC::$server->getUserSession()->getUser();
|
||||
if (is_null($user) || $name !== $user->getUID()) {
|
||||
throw new \Sabre\DAV\Exception\Forbidden();
|
||||
}
|
||||
return new VersionHome($principalInfo, $this->rootFolder);
|
||||
return new VersionHome($principalInfo, $this->rootFolder, $this->userManager, $this->versionManager);
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
|
|
|
@ -21,11 +21,15 @@ declare(strict_types=1);
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Versions\Sabre;
|
||||
|
||||
use OCA\Files_Versions\Storage;
|
||||
use OCA\Files_Versions\Versions\IVersion;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\IUser;
|
||||
use Sabre\DAV\Exception\Forbidden;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
use Sabre\DAV\ICollection;
|
||||
|
@ -37,13 +41,17 @@ class VersionCollection implements ICollection {
|
|||
/** @var File */
|
||||
private $file;
|
||||
|
||||
/** @var string */
|
||||
private $userId;
|
||||
/** @var IUser */
|
||||
private $user;
|
||||
|
||||
public function __construct(Folder $userFolder, File $file, string $userId) {
|
||||
/** @var IVersionManager */
|
||||
private $versionManager;
|
||||
|
||||
public function __construct(Folder $userFolder, File $file, IUser $user, IVersionManager $versionManager) {
|
||||
$this->userFolder = $userFolder;
|
||||
$this->file = $file;
|
||||
$this->userId = $userId;
|
||||
$this->user = $user;
|
||||
$this->versionManager = $versionManager;
|
||||
}
|
||||
|
||||
public function createFile($name, $data = null) {
|
||||
|
@ -68,10 +76,10 @@ class VersionCollection implements ICollection {
|
|||
}
|
||||
|
||||
public function getChildren(): array {
|
||||
$versions = Storage::getVersions($this->userId, $this->userFolder->getRelativePath($this->file->getPath()));
|
||||
$versions = $this->versionManager->getVersionsForFile($this->user, $this->file);
|
||||
|
||||
return array_map(function (array $data) {
|
||||
return new VersionFile($data, $this->userFolder->getParent());
|
||||
return array_map(function (IVersion $version) {
|
||||
return new VersionFile($version, $this->versionManager);
|
||||
}, $versions);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,26 +21,26 @@ declare(strict_types=1);
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Versions\Sabre;
|
||||
|
||||
use OCA\Files_Versions\Storage;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCA\Files_Versions\Versions\IVersion;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\Files\NotFoundException;
|
||||
use Sabre\DAV\Exception\Forbidden;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
use Sabre\DAV\IFile;
|
||||
|
||||
class VersionFile implements IFile {
|
||||
/** @var array */
|
||||
private $data;
|
||||
/** @var IVersion */
|
||||
private $version;
|
||||
|
||||
/** @var Folder */
|
||||
private $userRoot;
|
||||
/** @var IVersionManager */
|
||||
private $versionManager;
|
||||
|
||||
public function __construct(array $data, Folder $userRoot) {
|
||||
$this->data = $data;
|
||||
$this->userRoot = $userRoot;
|
||||
public function __construct(IVersion $version, IVersionManager $versionManager) {
|
||||
$this->version = $version;
|
||||
$this->versionManager = $versionManager;
|
||||
}
|
||||
|
||||
public function put($data) {
|
||||
|
@ -49,27 +49,22 @@ class VersionFile implements IFile {
|
|||
|
||||
public function get() {
|
||||
try {
|
||||
/** @var Folder $versions */
|
||||
$versions = $this->userRoot->get('files_versions');
|
||||
/** @var File $version */
|
||||
$version = $versions->get($this->data['path'].'.v'.$this->data['version']);
|
||||
return $this->versionManager->read($this->version);
|
||||
} catch (NotFoundException $e) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
||||
return $version->fopen('rb');
|
||||
}
|
||||
|
||||
public function getContentType(): string {
|
||||
return $this->data['mimetype'];
|
||||
return $this->version->getMimeType();
|
||||
}
|
||||
|
||||
public function getETag(): string {
|
||||
return $this->data['version'];
|
||||
return (string)$this->version->getRevisionId();
|
||||
}
|
||||
|
||||
public function getSize(): int {
|
||||
return $this->data['size'];
|
||||
return $this->version->getSize();
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
|
@ -77,7 +72,7 @@ class VersionFile implements IFile {
|
|||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->data['version'];
|
||||
return (string)$this->version->getRevisionId();
|
||||
}
|
||||
|
||||
public function setName($name) {
|
||||
|
@ -85,10 +80,10 @@ class VersionFile implements IFile {
|
|||
}
|
||||
|
||||
public function getLastModified(): int {
|
||||
return (int)$this->data['version'];
|
||||
return $this->version->getTimestamp();
|
||||
}
|
||||
|
||||
public function rollBack(): bool {
|
||||
return Storage::rollback($this->data['path'], $this->data['version']);
|
||||
public function rollBack() {
|
||||
$this->versionManager->rollback($this->version);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Versions\Sabre;
|
||||
|
||||
use OC\User\NoUserException;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IUserManager;
|
||||
use Sabre\DAV\Exception\Forbidden;
|
||||
use Sabre\DAV\ICollection;
|
||||
|
||||
|
@ -34,9 +38,25 @@ class VersionHome implements ICollection {
|
|||
/** @var IRootFolder */
|
||||
private $rootFolder;
|
||||
|
||||
public function __construct(array $principalInfo, IRootFolder $rootFolder) {
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
|
||||
/** @var IVersionManager */
|
||||
private $versionManager;
|
||||
|
||||
public function __construct(array $principalInfo, IRootFolder $rootFolder, IUserManager $userManager, IVersionManager $versionManager) {
|
||||
$this->principalInfo = $principalInfo;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->userManager = $userManager;
|
||||
$this->versionManager = $versionManager;
|
||||
}
|
||||
|
||||
private function getUser() {
|
||||
list(, $name) = \Sabre\Uri\split($this->principalInfo['uri']);
|
||||
$user = $this->userManager->get($name);
|
||||
if (!$user) {
|
||||
throw new NoUserException();
|
||||
}
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
|
@ -44,8 +64,7 @@ class VersionHome implements ICollection {
|
|||
}
|
||||
|
||||
public function getName(): string {
|
||||
list(,$name) = \Sabre\Uri\split($this->principalInfo['uri']);
|
||||
return $name;
|
||||
return $this->getUser()->getUID();
|
||||
}
|
||||
|
||||
public function setName($name) {
|
||||
|
@ -61,22 +80,22 @@ class VersionHome implements ICollection {
|
|||
}
|
||||
|
||||
public function getChild($name) {
|
||||
list(,$userId) = \Sabre\Uri\split($this->principalInfo['uri']);
|
||||
$user = $this->getUser();
|
||||
|
||||
if ($name === 'versions') {
|
||||
return new VersionRoot($userId, $this->rootFolder);
|
||||
return new VersionRoot($user, $this->rootFolder, $this->versionManager);
|
||||
}
|
||||
if ($name === 'restore') {
|
||||
return new RestoreFolder($userId);
|
||||
return new RestoreFolder();
|
||||
}
|
||||
}
|
||||
|
||||
public function getChildren() {
|
||||
list(,$userId) = \Sabre\Uri\split($this->principalInfo['uri']);
|
||||
$user = $this->getUser();
|
||||
|
||||
return [
|
||||
new VersionRoot($userId, $this->rootFolder),
|
||||
new RestoreFolder($userId),
|
||||
new VersionRoot($user, $this->rootFolder, $this->versionManager),
|
||||
new RestoreFolder(),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -23,23 +23,29 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Files_Versions\Sabre;
|
||||
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IUser;
|
||||
use Sabre\DAV\Exception\Forbidden;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
use Sabre\DAV\ICollection;
|
||||
|
||||
class VersionRoot implements ICollection {
|
||||
|
||||
/** @var string */
|
||||
private $userId;
|
||||
/** @var IUser */
|
||||
private $user;
|
||||
|
||||
/** @var IRootFolder */
|
||||
private $rootFolder;
|
||||
|
||||
public function __construct(string $userId, IRootFolder $rootFolder) {
|
||||
$this->userId = $userId;
|
||||
/** @var IVersionManager */
|
||||
private $versionManager;
|
||||
|
||||
public function __construct(IUser $user, IRootFolder $rootFolder, IVersionManager $versionManager) {
|
||||
$this->user = $user;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->versionManager = $versionManager;
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
|
@ -63,7 +69,7 @@ class VersionRoot implements ICollection {
|
|||
}
|
||||
|
||||
public function getChild($name) {
|
||||
$userFolder = $this->rootFolder->getUserFolder($this->userId);
|
||||
$userFolder = $this->rootFolder->getUserFolder($this->user->getUID());
|
||||
|
||||
$fileId = (int)$name;
|
||||
$nodes = $userFolder->getById($fileId);
|
||||
|
@ -78,7 +84,7 @@ class VersionRoot implements ICollection {
|
|||
throw new NotFound();
|
||||
}
|
||||
|
||||
return new VersionCollection($userFolder, $node, $this->userId);
|
||||
return new VersionCollection($userFolder, $node, $this->user, $this->versionManager);
|
||||
}
|
||||
|
||||
public function getChildren(): array {
|
||||
|
|
|
@ -48,6 +48,7 @@ use OC\Files\View;
|
|||
use OCA\Files_Versions\AppInfo\Application;
|
||||
use OCA\Files_Versions\Command\Expire;
|
||||
use OCA\Files_Versions\Events\CreateVersionEvent;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Lock\ILockingProvider;
|
||||
use OCP\User;
|
||||
|
@ -178,10 +179,10 @@ class Storage {
|
|||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
|
||||
$files_view = new View('/'.$uid .'/files');
|
||||
$users_view = new View('/'.$uid);
|
||||
|
||||
$eventDispatcher = \OC::$server->getEventDispatcher();
|
||||
$id = $files_view->getFileInfo($filename)->getId();
|
||||
$fileInfo = $files_view->getFileInfo($filename);
|
||||
$id = $fileInfo->getId();
|
||||
$nodes = \OC::$server->getRootFolder()->getById($id);
|
||||
foreach ($nodes as $node) {
|
||||
$event = new CreateVersionEvent($node);
|
||||
|
@ -192,20 +193,16 @@ class Storage {
|
|||
}
|
||||
|
||||
// no use making versions for empty files
|
||||
if ($files_view->filesize($filename) === 0) {
|
||||
if ($fileInfo->getSize() === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create all parent folders
|
||||
self::createMissingDirectories($filename, $users_view);
|
||||
/** @var IVersionManager $versionManager */
|
||||
$versionManager = \OC::$server->query(IVersionManager::class);
|
||||
$userManager = \OC::$server->getUserManager();
|
||||
$user = $userManager->get($uid);
|
||||
|
||||
self::scheduleExpire($uid, $filename);
|
||||
|
||||
// store a new version of a file
|
||||
$mtime = $users_view->filemtime('files/' . $filename);
|
||||
$users_view->copy('files/' . $filename, 'files_versions/' . $filename . '.v' . $mtime);
|
||||
// call getFileInfo to enforce a file cache entry for the new version
|
||||
$users_view->getFileInfo('files_versions/' . $filename . '.v' . $mtime);
|
||||
$versionManager->createVersion($user, $fileInfo);
|
||||
}
|
||||
|
||||
|
||||
|
@ -695,7 +692,7 @@ class Storage {
|
|||
* @param string $uid owner of the file
|
||||
* @param string $fileName file/folder for which to schedule expiration
|
||||
*/
|
||||
private static function scheduleExpire($uid, $fileName) {
|
||||
public static function scheduleExpire($uid, $fileName) {
|
||||
// let the admin disable auto expire
|
||||
$expiration = self::getExpiration();
|
||||
if ($expiration->isEnabled()) {
|
||||
|
@ -833,7 +830,7 @@ class Storage {
|
|||
* "files" folder
|
||||
* @param View $view view on data/user/
|
||||
*/
|
||||
private static function createMissingDirectories($filename, $view) {
|
||||
public static function createMissingDirectories($filename, $view) {
|
||||
$dirname = Filesystem::normalizePath(dirname($filename));
|
||||
$dirParts = explode('/', $dirname);
|
||||
$dir = "/files_versions";
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* @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\Files_Versions\Versions;
|
||||
|
||||
class BackendNotFoundException extends \Exception {
|
||||
|
||||
}
|
99
apps/files_versions/lib/Versions/IVersion.php
Normal file
99
apps/files_versions/lib/Versions/IVersion.php
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?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\Files_Versions\Versions;
|
||||
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\IUser;
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
interface IVersion {
|
||||
/**
|
||||
* @return IVersionBackend
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getBackend(): IVersionBackend;
|
||||
|
||||
/**
|
||||
* Get the file info of the source file
|
||||
*
|
||||
* @return FileInfo
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getSourceFile(): FileInfo;
|
||||
|
||||
/**
|
||||
* Get the id of the revision for the file
|
||||
*
|
||||
* @return int
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getRevisionId(): int;
|
||||
|
||||
/**
|
||||
* Get the timestamp this version was created
|
||||
*
|
||||
* @return int
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getTimestamp(): int;
|
||||
|
||||
/**
|
||||
* Get the size of this version
|
||||
*
|
||||
* @return int
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getSize(): int;
|
||||
|
||||
/**
|
||||
* Get the name of the source file at the time of making this version
|
||||
*
|
||||
* @return string
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getSourceFileName(): string;
|
||||
|
||||
/**
|
||||
* Get the mimetype of this version
|
||||
*
|
||||
* @return string
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getMimeType(): string;
|
||||
|
||||
/**
|
||||
* Get the path of this version
|
||||
*
|
||||
* @return string
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getVersionPath(): string;
|
||||
|
||||
/**
|
||||
* @return IUser
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getUser(): IUser;
|
||||
}
|
81
apps/files_versions/lib/Versions/IVersionBackend.php
Normal file
81
apps/files_versions/lib/Versions/IVersionBackend.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?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\Files_Versions\Versions;
|
||||
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\IUser;
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
interface IVersionBackend {
|
||||
/**
|
||||
* Get all versions for a file
|
||||
*
|
||||
* @param IUser $user
|
||||
* @param FileInfo $file
|
||||
* @return IVersion[]
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getVersionsForFile(IUser $user, FileInfo $file): array;
|
||||
|
||||
/**
|
||||
* Create a new version for a file
|
||||
*
|
||||
* @param IUser $user
|
||||
* @param FileInfo $file
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function createVersion(IUser $user, FileInfo $file);
|
||||
|
||||
/**
|
||||
* Restore this version
|
||||
*
|
||||
* @param IVersion $version
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function rollback(IVersion $version);
|
||||
|
||||
/**
|
||||
* Open the file for reading
|
||||
*
|
||||
* @param IVersion $version
|
||||
* @return resource
|
||||
* @throws NotFoundException
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function read(IVersion $version);
|
||||
|
||||
/**
|
||||
* Get the preview for a specific version of a file
|
||||
*
|
||||
* @param IUser $user
|
||||
* @param FileInfo $sourceFile
|
||||
* @param int $revision
|
||||
* @return ISimpleFile
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File;
|
||||
}
|
36
apps/files_versions/lib/Versions/IVersionManager.php
Normal file
36
apps/files_versions/lib/Versions/IVersionManager.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?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\Files_Versions\Versions;
|
||||
|
||||
/**
|
||||
* @since 15.0.0
|
||||
*/
|
||||
interface IVersionManager extends IVersionBackend {
|
||||
/**
|
||||
* Register a new backend
|
||||
*
|
||||
* @param string $storageType
|
||||
* @param IVersionBackend $backend
|
||||
* @since 15.0.0
|
||||
*/
|
||||
public function registerBackend(string $storageType, IVersionBackend $backend);
|
||||
}
|
105
apps/files_versions/lib/Versions/LegacyVersionsBackend.php
Normal file
105
apps/files_versions/lib/Versions/LegacyVersionsBackend.php
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?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\Files_Versions\Versions;
|
||||
|
||||
use OC\Files\View;
|
||||
use OCA\Files_Versions\Storage;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IUser;
|
||||
|
||||
class LegacyVersionsBackend implements IVersionBackend {
|
||||
/** @var IRootFolder */
|
||||
private $rootFolder;
|
||||
|
||||
public function __construct(IRootFolder $rootFolder) {
|
||||
$this->rootFolder = $rootFolder;
|
||||
}
|
||||
|
||||
public function getVersionsForFile(IUser $user, FileInfo $file): array {
|
||||
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
|
||||
$versions = Storage::getVersions($user->getUID(), $userFolder->getRelativePath($file->getPath()));
|
||||
|
||||
return array_map(function (array $data) use ($file, $user) {
|
||||
return new Version(
|
||||
(int)$data['version'],
|
||||
(int)$data['version'],
|
||||
$data['name'],
|
||||
(int)$data['size'],
|
||||
$data['mimetype'],
|
||||
$data['path'],
|
||||
$file,
|
||||
$this,
|
||||
$user
|
||||
);
|
||||
}, $versions);
|
||||
}
|
||||
|
||||
public function createVersion(IUser $user, FileInfo $file) {
|
||||
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
|
||||
$relativePath = $userFolder->getRelativePath($file->getPath());
|
||||
$userView = new View('/' . $user->getUID());
|
||||
// create all parent folders
|
||||
Storage::createMissingDirectories($relativePath, $userView);
|
||||
|
||||
Storage::scheduleExpire($user->getUID(), $relativePath);
|
||||
|
||||
// store a new version of a file
|
||||
$userView->copy('files/' . $relativePath, 'files_versions/' . $relativePath . '.v' . $file->getMtime());
|
||||
// ensure the file is scanned
|
||||
$userView->getFileInfo('files_versions/' . $relativePath . '.v' . $file->getMtime());
|
||||
}
|
||||
|
||||
public function rollback(IVersion $version) {
|
||||
return Storage::rollback($version->getVersionPath(), $version->getRevisionId());
|
||||
}
|
||||
|
||||
private function getVersionFolder(IUser $user): Folder {
|
||||
$userRoot = $this->rootFolder->getUserFolder($user->getUID())
|
||||
->getParent();
|
||||
try {
|
||||
/** @var Folder $folder */
|
||||
$folder = $userRoot->get('files_versions');
|
||||
return $folder;
|
||||
} catch (NotFoundException $e) {
|
||||
return $userRoot->newFolder('files_versions');
|
||||
}
|
||||
}
|
||||
|
||||
public function read(IVersion $version) {
|
||||
$versions = $this->getVersionFolder($version->getUser());
|
||||
/** @var File $file */
|
||||
$file = $versions->get($version->getVersionPath() . '.v' . $version->getRevisionId());
|
||||
return $file->fopen('r');
|
||||
}
|
||||
|
||||
public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
|
||||
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
|
||||
$versionFolder = $this->getVersionFolder($user);
|
||||
/** @var File $file */
|
||||
$file = $versionFolder->get($userFolder->getRelativePath($sourceFile->getPath()) . '.v' . $revision);
|
||||
return $file;
|
||||
}
|
||||
}
|
113
apps/files_versions/lib/Versions/Version.php
Normal file
113
apps/files_versions/lib/Versions/Version.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?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\Files_Versions\Versions;
|
||||
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\IUser;
|
||||
|
||||
class Version implements IVersion {
|
||||
/** @var int */
|
||||
private $timestamp;
|
||||
|
||||
/** @var int */
|
||||
private $revisionId;
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
|
||||
/** @var int */
|
||||
private $size;
|
||||
|
||||
/** @var string */
|
||||
private $mimetype;
|
||||
|
||||
/** @var string */
|
||||
private $path;
|
||||
|
||||
/** @var FileInfo */
|
||||
private $sourceFileInfo;
|
||||
|
||||
/** @var IVersionBackend */
|
||||
private $backend;
|
||||
|
||||
/** @var IUser */
|
||||
private $user;
|
||||
|
||||
public function __construct(
|
||||
int $timestamp,
|
||||
int $revisionId,
|
||||
string $name,
|
||||
int $size,
|
||||
string $mimetype,
|
||||
string $path,
|
||||
FileInfo $sourceFileInfo,
|
||||
IVersionBackend $backend,
|
||||
IUser $user
|
||||
) {
|
||||
$this->timestamp = $timestamp;
|
||||
$this->revisionId = $revisionId;
|
||||
$this->name = $name;
|
||||
$this->size = $size;
|
||||
$this->mimetype = $mimetype;
|
||||
$this->path = $path;
|
||||
$this->sourceFileInfo = $sourceFileInfo;
|
||||
$this->backend = $backend;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function getBackend(): IVersionBackend {
|
||||
return $this->backend;
|
||||
}
|
||||
|
||||
public function getSourceFile(): FileInfo {
|
||||
return $this->sourceFileInfo;
|
||||
}
|
||||
|
||||
public function getRevisionId(): int {
|
||||
return $this->revisionId;
|
||||
}
|
||||
|
||||
public function getTimestamp(): int {
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
public function getSize(): int {
|
||||
return $this->size;
|
||||
}
|
||||
|
||||
public function getSourceFileName(): string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getMimeType(): string {
|
||||
return $this->mimetype;
|
||||
}
|
||||
|
||||
public function getVersionPath(): string {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getUser(): IUser {
|
||||
return $this->user;
|
||||
}
|
||||
}
|
93
apps/files_versions/lib/Versions/VersionManager.php
Normal file
93
apps/files_versions/lib/Versions/VersionManager.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?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\Files_Versions\Versions;
|
||||
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use OCP\IUser;
|
||||
|
||||
class VersionManager implements IVersionManager {
|
||||
/** @var IVersionBackend[] */
|
||||
private $backends = [];
|
||||
|
||||
public function registerBackend(string $storageType, IVersionBackend $backend) {
|
||||
$this->backends[$storageType] = $backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IVersionBackend[]
|
||||
*/
|
||||
private function getBackends(): array {
|
||||
return $this->backends;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IStorage $storage
|
||||
* @return IVersionBackend
|
||||
* @throws BackendNotFoundException
|
||||
*/
|
||||
public function getBackendForStorage(IStorage $storage): IVersionBackend {
|
||||
$fullType = get_class($storage);
|
||||
$backends = $this->getBackends();
|
||||
$foundType = array_reduce(array_keys($backends), function ($type, $registeredType) use ($storage) {
|
||||
if (
|
||||
$storage->instanceOfStorage($registeredType) &&
|
||||
($type === '' || is_subclass_of($registeredType, $type))
|
||||
) {
|
||||
return $registeredType;
|
||||
} else {
|
||||
return $type;
|
||||
}
|
||||
}, '');
|
||||
if ($foundType === '') {
|
||||
throw new BackendNotFoundException("Version backend for $fullType not found");
|
||||
} else {
|
||||
return $backends[$foundType];
|
||||
}
|
||||
}
|
||||
|
||||
public function getVersionsForFile(IUser $user, FileInfo $file): array {
|
||||
$backend = $this->getBackendForStorage($file->getStorage());
|
||||
return $backend->getVersionsForFile($user, $file);
|
||||
}
|
||||
|
||||
public function createVersion(IUser $user, FileInfo $file) {
|
||||
$backend = $this->getBackendForStorage($file->getStorage());
|
||||
$backend->createVersion($user, $file);
|
||||
}
|
||||
|
||||
public function rollback(IVersion $version) {
|
||||
$backend = $version->getBackend();
|
||||
return $backend->rollback($version);
|
||||
}
|
||||
|
||||
public function read(IVersion $version) {
|
||||
$backend = $version->getBackend();
|
||||
return $backend->read($version);
|
||||
}
|
||||
|
||||
public function getVersionFile(IUser $user, FileInfo $sourceFile, int $revision): File {
|
||||
$backend = $this->getBackendForStorage($sourceFile->getStorage());
|
||||
return $backend->getVersionFile($user, $sourceFile, $revision);
|
||||
}
|
||||
}
|
|
@ -20,9 +20,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Files_Versions\Tests\Controller;
|
||||
|
||||
use OC\User\User;
|
||||
use OCA\Files_Versions\Controller\PreviewController;
|
||||
use OCA\Files_Versions\Versions\IVersionManager;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
|
@ -34,6 +37,8 @@ use OCP\Files\NotFoundException;
|
|||
use OCP\Files\SimpleFS\ISimpleFile;
|
||||
use OCP\IPreview;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
use Test\TestCase;
|
||||
|
||||
class PreviewControllerTest extends TestCase {
|
||||
|
@ -50,23 +55,39 @@ class PreviewControllerTest extends TestCase {
|
|||
/** @var IPreview|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $previewManager;
|
||||
|
||||
/** @var PreviewController */
|
||||
/** @var PreviewController|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $controller;
|
||||
|
||||
/** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $userSession;
|
||||
|
||||
/** @var IVersionManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
private $versionManager;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->rootFolder = $this->createMock(IRootFolder::class);
|
||||
$this->userId = 'user';
|
||||
$user = $this->createMock(IUser::class);
|
||||
$user->expects($this->any())
|
||||
->method('getUID')
|
||||
->willReturn($this->userId);
|
||||
$this->mimeTypeDetector = $this->createMock(IMimeTypeDetector::class);
|
||||
$this->previewManager = $this->createMock(IPreview::class);
|
||||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
$this->userSession->expects($this->any())
|
||||
->method('getUser')
|
||||
->willReturn($user);
|
||||
$this->versionManager = $this->createMock(IVersionManager::class);
|
||||
|
||||
$this->controller = new PreviewController(
|
||||
'files_versions',
|
||||
$this->createMock(IRequest::class),
|
||||
$this->rootFolder,
|
||||
$this->userId,
|
||||
$this->userSession,
|
||||
$this->mimeTypeDetector,
|
||||
$this->versionManager,
|
||||
$this->previewManager
|
||||
);
|
||||
}
|
||||
|
@ -102,24 +123,23 @@ class PreviewControllerTest extends TestCase {
|
|||
public function testValidPreview() {
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userRoot = $this->createMock(Folder::class);
|
||||
$versions = $this->createMock(Folder::class);
|
||||
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->userId)
|
||||
->willReturn($userFolder);
|
||||
$userFolder->method('getParent')
|
||||
->willReturn($userRoot);
|
||||
$userRoot->method('get')
|
||||
->with('files_versions')
|
||||
->willReturn($versions);
|
||||
|
||||
$this->mimeTypeDetector->method('detectPath')
|
||||
->with($this->equalTo('file'))
|
||||
->willReturn('myMime');
|
||||
$sourceFile = $this->createMock(File::class);
|
||||
$userFolder->method('get')
|
||||
->with('file')
|
||||
->willReturn($sourceFile);
|
||||
|
||||
$file = $this->createMock(File::class);
|
||||
$versions->method('get')
|
||||
->with($this->equalTo('file.v42'))
|
||||
$file->method('getMimetype')
|
||||
->willReturn('myMime');
|
||||
|
||||
$this->versionManager->method('getVersionFile')
|
||||
->willReturn($file);
|
||||
|
||||
$preview = $this->createMock(ISimpleFile::class);
|
||||
|
@ -138,24 +158,23 @@ class PreviewControllerTest extends TestCase {
|
|||
public function testVersionNotFound() {
|
||||
$userFolder = $this->createMock(Folder::class);
|
||||
$userRoot = $this->createMock(Folder::class);
|
||||
$versions = $this->createMock(Folder::class);
|
||||
|
||||
$this->rootFolder->method('getUserFolder')
|
||||
->with($this->userId)
|
||||
->willReturn($userFolder);
|
||||
$userFolder->method('getParent')
|
||||
->willReturn($userRoot);
|
||||
$userRoot->method('get')
|
||||
->with('files_versions')
|
||||
->willReturn($versions);
|
||||
|
||||
$sourceFile = $this->createMock(File::class);
|
||||
$userFolder->method('get')
|
||||
->with('file')
|
||||
->willReturn($sourceFile);
|
||||
|
||||
$this->mimeTypeDetector->method('detectPath')
|
||||
->with($this->equalTo('file'))
|
||||
->willReturn('myMime');
|
||||
|
||||
$file = $this->createMock(File::class);
|
||||
$versions->method('get')
|
||||
->with($this->equalTo('file.v42'))
|
||||
$this->versionManager->method('getVersionFile')
|
||||
->willThrowException(new NotFoundException());
|
||||
|
||||
$res = $this->controller->getPreview('file', 10, 10, '42');
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
maxOccurs="1" />
|
||||
<xs:element name="trash" type="trash" minOccurs="0"
|
||||
maxOccurs="1" />
|
||||
<xs:element name="versions" type="versions" minOccurs="0"
|
||||
maxOccurs="1" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:unique name="uniqueNameL10n">
|
||||
|
@ -670,6 +672,21 @@
|
|||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="versions">
|
||||
<xs:sequence>
|
||||
<xs:element name="backend" type="versions-backend" minOccurs="1"
|
||||
maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="versions-backend">
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="php-class">
|
||||
<xs:attribute name="for" type="php-class" use="required"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:simpleType name="php-class">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:pattern
|
||||
|
|
Loading…
Reference in a new issue