Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions apps/files_trashbin/tests/StorageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ protected function setUp(): void {
parent::setUp();

\OC_Hook::clear();
\OC::$server->boot();

// register trashbin hooks
$trashbinApp = new Application();
$trashbinApp->boot($this->createMock(IBootContext::class));
Expand Down Expand Up @@ -224,8 +226,6 @@ public function testCrossStorageDeleteFolder() {
* Test that deleted versions properly land in the trashbin.
*/
public function testDeleteVersionsOfFile() {
\OCA\Files_Versions\Hooks::connectHooks();

// trigger a version (multiple would not work because of the expire logic)
$this->userView->file_put_contents('test.txt', 'v1');

Expand Down Expand Up @@ -253,8 +253,6 @@ public function testDeleteVersionsOfFile() {
* Test that deleted versions properly land in the trashbin.
*/
public function testDeleteVersionsOfFolder() {
\OCA\Files_Versions\Hooks::connectHooks();

// trigger a version (multiple would not work because of the expire logic)
$this->userView->file_put_contents('folder/inside.txt', 'v1');

Expand Down Expand Up @@ -288,8 +286,6 @@ public function testDeleteVersionsOfFolder() {
* Test that deleted versions properly land in the trashbin when deleting as share recipient.
*/
public function testDeleteVersionsOfFileAsRecipient() {
\OCA\Files_Versions\Hooks::connectHooks();

$this->userView->mkdir('share');
// trigger a version (multiple would not work because of the expire logic)
$this->userView->file_put_contents('share/test.txt', 'v1');
Expand Down Expand Up @@ -341,8 +337,6 @@ public function testDeleteVersionsOfFileAsRecipient() {
* Test that deleted versions properly land in the trashbin when deleting as share recipient.
*/
public function testDeleteVersionsOfFolderAsRecipient() {
\OCA\Files_Versions\Hooks::connectHooks();

$this->userView->mkdir('share');
$this->userView->mkdir('share/folder');
// trigger a version (multiple would not work because of the expire logic)
Expand Down Expand Up @@ -410,8 +404,6 @@ public function testDeleteVersionsOfFolderAsRecipient() {
* unlink() which should NOT trigger the version deletion logic.
*/
public function testKeepFileAndVersionsWhenMovingFileBetweenStorages() {
\OCA\Files_Versions\Hooks::connectHooks();

$storage2 = new Temporary([]);
\OC\Files\Filesystem::mount($storage2, [], $this->user . '/files/substorage');

Expand Down Expand Up @@ -451,8 +443,6 @@ public function testKeepFileAndVersionsWhenMovingFileBetweenStorages() {
* unlink() which should NOT trigger the version deletion logic.
*/
public function testKeepFileAndVersionsWhenMovingFolderBetweenStorages() {
\OCA\Files_Versions\Hooks::connectHooks();

$storage2 = new Temporary([]);
\OC\Files\Filesystem::mount($storage2, [], $this->user . '/files/substorage');

Expand Down
2 changes: 1 addition & 1 deletion apps/files_versions/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
This application automatically maintains older versions of files that are changed. When enabled, a hidden versions folder is provisioned in every user's directory and is used to store old file versions. A user can revert to an older version through the web interface at any time, with the replaced file becoming a version. The app automatically manages the versions folder to ensure the user does not run out of Quota because of versions.
In addition to the expiry of versions, the versions app makes certain never to use more than 50% of the user's currently available free space. If stored versions exceed this limit, the app will delete the oldest versions first until it meets this limit. More information is available in the Versions documentation.
</description>
<version>1.19.0</version>
<version>1.19.1</version>
<licence>agpl</licence>
<author>Frank Karlitschek</author>
<author>Bjoern Schiessle</author>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@
'OCA\\Files_Versions\\Command\\Expire' => $baseDir . '/../lib/Command/Expire.php',
'OCA\\Files_Versions\\Command\\ExpireVersions' => $baseDir . '/../lib/Command/ExpireVersions.php',
'OCA\\Files_Versions\\Controller\\PreviewController' => $baseDir . '/../lib/Controller/PreviewController.php',
'OCA\\Files_Versions\\Db\\VersionEntity' => $baseDir . '/../lib/Db/VersionEntity.php',
'OCA\\Files_Versions\\Db\\VersionsMapper' => $baseDir . '/../lib/Db/VersionsMapper.php',
'OCA\\Files_Versions\\Events\\CreateVersionEvent' => $baseDir . '/../lib/Events/CreateVersionEvent.php',
'OCA\\Files_Versions\\Expiration' => $baseDir . '/../lib/Expiration.php',
'OCA\\Files_Versions\\Hooks' => $baseDir . '/../lib/Hooks.php',
'OCA\\Files_Versions\\Listener\\FileEventsListener' => $baseDir . '/../lib/Listener/FileEventsListener.php',
'OCA\\Files_Versions\\Listener\\LoadAdditionalListener' => $baseDir . '/../lib/Listener/LoadAdditionalListener.php',
'OCA\\Files_Versions\\Listener\\LoadSidebarListener' => $baseDir . '/../lib/Listener/LoadSidebarListener.php',
'OCA\\Files_Versions\\Migration\\Version1020Date20221114144058' => $baseDir . '/../lib/Migration/Version1020Date20221114144058.php',
'OCA\\Files_Versions\\Sabre\\Plugin' => $baseDir . '/../lib/Sabre/Plugin.php',
'OCA\\Files_Versions\\Sabre\\RestoreFolder' => $baseDir . '/../lib/Sabre/RestoreFolder.php',
'OCA\\Files_Versions\\Sabre\\RootCollection' => $baseDir . '/../lib/Sabre/RootCollection.php',
Expand All @@ -28,6 +31,9 @@
'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\\IDeletableVersionBackend' => $baseDir . '/../lib/Versions/IDeletableVersionBackend.php',
'OCA\\Files_Versions\\Versions\\INameableVersion' => $baseDir . '/../lib/Versions/INameableVersion.php',
'OCA\\Files_Versions\\Versions\\INameableVersionBackend' => $baseDir . '/../lib/Versions/INameableVersionBackend.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',
Expand Down
8 changes: 7 additions & 1 deletion apps/files_versions/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ class ComposerStaticInitFiles_Versions
'OCA\\Files_Versions\\Command\\Expire' => __DIR__ . '/..' . '/../lib/Command/Expire.php',
'OCA\\Files_Versions\\Command\\ExpireVersions' => __DIR__ . '/..' . '/../lib/Command/ExpireVersions.php',
'OCA\\Files_Versions\\Controller\\PreviewController' => __DIR__ . '/..' . '/../lib/Controller/PreviewController.php',
'OCA\\Files_Versions\\Db\\VersionEntity' => __DIR__ . '/..' . '/../lib/Db/VersionEntity.php',
'OCA\\Files_Versions\\Db\\VersionsMapper' => __DIR__ . '/..' . '/../lib/Db/VersionsMapper.php',
'OCA\\Files_Versions\\Events\\CreateVersionEvent' => __DIR__ . '/..' . '/../lib/Events/CreateVersionEvent.php',
'OCA\\Files_Versions\\Expiration' => __DIR__ . '/..' . '/../lib/Expiration.php',
'OCA\\Files_Versions\\Hooks' => __DIR__ . '/..' . '/../lib/Hooks.php',
'OCA\\Files_Versions\\Listener\\FileEventsListener' => __DIR__ . '/..' . '/../lib/Listener/FileEventsListener.php',
'OCA\\Files_Versions\\Listener\\LoadAdditionalListener' => __DIR__ . '/..' . '/../lib/Listener/LoadAdditionalListener.php',
'OCA\\Files_Versions\\Listener\\LoadSidebarListener' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarListener.php',
'OCA\\Files_Versions\\Migration\\Version1020Date20221114144058' => __DIR__ . '/..' . '/../lib/Migration/Version1020Date20221114144058.php',
'OCA\\Files_Versions\\Sabre\\Plugin' => __DIR__ . '/..' . '/../lib/Sabre/Plugin.php',
'OCA\\Files_Versions\\Sabre\\RestoreFolder' => __DIR__ . '/..' . '/../lib/Sabre/RestoreFolder.php',
'OCA\\Files_Versions\\Sabre\\RootCollection' => __DIR__ . '/..' . '/../lib/Sabre/RootCollection.php',
Expand All @@ -43,6 +46,9 @@ class ComposerStaticInitFiles_Versions
'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\\IDeletableVersionBackend' => __DIR__ . '/..' . '/../lib/Versions/IDeletableVersionBackend.php',
'OCA\\Files_Versions\\Versions\\INameableVersion' => __DIR__ . '/..' . '/../lib/Versions/INameableVersion.php',
'OCA\\Files_Versions\\Versions\\INameableVersionBackend' => __DIR__ . '/..' . '/../lib/Versions/INameableVersionBackend.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',
Expand Down
30 changes: 24 additions & 6 deletions apps/files_versions/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Files\Event\LoadSidebar;
use OCA\Files_Versions\Capabilities;
use OCA\Files_Versions\Hooks;
use OCA\Files_Versions\Listener\FileEventsListener;
use OCA\Files_Versions\Listener\LoadAdditionalListener;
use OCA\Files_Versions\Listener\LoadSidebarListener;
use OCA\Files_Versions\Versions\IVersionManager;
Expand All @@ -44,6 +44,17 @@
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Files\Events\Node\BeforeNodeCopiedEvent;
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\Events\Node\BeforeNodeRenamedEvent;
use OCP\Files\Events\Node\BeforeNodeTouchedEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\BeforeNodeWrittenEvent;
use OCP\Files\Events\Node\NodeCreatedEvent;
use OCP\Files\Events\Node\NodeTouchedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IServerContainer;
Expand Down Expand Up @@ -96,15 +107,22 @@ public function register(IRegistrationContext $context): void {
*/
$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class);
$context->registerEventListener(LoadSidebar::class, LoadSidebarListener::class);

$context->registerEventListener(NodeCreatedEvent::class, FileEventsListener::class);
$context->registerEventListener(BeforeNodeTouchedEvent::class, FileEventsListener::class);
$context->registerEventListener(NodeTouchedEvent::class, FileEventsListener::class);
$context->registerEventListener(BeforeNodeWrittenEvent::class, FileEventsListener::class);
$context->registerEventListener(NodeWrittenEvent::class, FileEventsListener::class);
$context->registerEventListener(BeforeNodeDeletedEvent::class, FileEventsListener::class);
$context->registerEventListener(NodeDeletedEvent::class, FileEventsListener::class);
$context->registerEventListener(NodeRenamedEvent::class, FileEventsListener::class);
$context->registerEventListener(NodeCopiedEvent::class, FileEventsListener::class);
$context->registerEventListener(BeforeNodeRenamedEvent::class, FileEventsListener::class);
$context->registerEventListener(BeforeNodeCopiedEvent::class, FileEventsListener::class);
}

public function boot(IBootContext $context): void {
$context->injectFn(\Closure::fromCallable([$this, 'registerVersionBackends']));

/**
* Register hooks
*/
Hooks::connectHooks();
}

public function registerVersionBackends(ContainerInterface $container, IAppManager $appManager, LoggerInterface $logger): void {
Expand Down
20 changes: 18 additions & 2 deletions apps/files_versions/lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,35 @@
*/
namespace OCA\Files_Versions;

use OCP\App\IAppManager;
use OCP\Capabilities\ICapability;
use OCP\IConfig;

class Capabilities implements ICapability {

private IConfig $config;
private IAppManager $appManager;

public function __construct(
IConfig $config,
IAppManager $appManager
) {
$this->config = $config;
$this->appManager = $appManager;
}

/**
* Return this classes capabilities
*
* @return array
*/
public function getCapabilities() {
$groupFolderOrS3VersioningInstalled = $this->appManager->isInstalled('groupfolders') || $this->appManager->isInstalled('groupfolders');

return [
'files' => [
'versioning' => true
'versioning' => true,
'version_labeling' => !$groupFolderOrS3VersioningInstalled && $this->config->getSystemValueBool('enable_version_labeling', true),
'version_deletion' => !$groupFolderOrS3VersioningInstalled && $this->config->getSystemValueBool('enable_version_deletion', true),
]
];
}
Expand Down
81 changes: 81 additions & 0 deletions apps/files_versions/lib/Db/VersionEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2022 Louis Chmn <[email protected]>
*
* @author Louis Chmn <[email protected]>
*
* @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\Db;

use JsonSerializable;

use OCP\AppFramework\Db\Entity;
use OCP\DB\Types;

/**
* @method int getFileId()
* @method void setFileId(int $fileId)
* @method int getTimestamp()
* @method void setTimestamp(int $timestamp)
* @method int getSize()
* @method void setSize(int $size)
* @method int getMimetype()
* @method void setMimetype(int $mimetype)
* @method array|null getMetadata()
* @method void setMetadata(array $metadata)
*/
class VersionEntity extends Entity implements JsonSerializable {
protected ?int $fileId = null;
protected ?int $timestamp = null;
protected ?int $size = null;
protected ?int $mimetype = null;
protected ?array $metadata = null;

public function __construct() {
$this->addType('id', Types::INTEGER);
$this->addType('file_id', Types::INTEGER);
$this->addType('timestamp', Types::INTEGER);
$this->addType('size', Types::INTEGER);
$this->addType('mimetype', Types::INTEGER);
$this->addType('metadata', Types::JSON);
}

public function jsonSerialize(): array {
return [
'id' => $this->id,
'file_id' => $this->fileId,
'timestamp' => $this->timestamp,
'size' => $this->size,
'mimetype' => $this->mimetype,
'metadata' => $this->metadata,
];
}

public function getLabel(): string {
return $this->metadata['label'] ?? '';
}

public function setLabel(string $label): void {
$this->metadata['label'] = $label;
$this->markFieldUpdated('metadata');
}
}
88 changes: 88 additions & 0 deletions apps/files_versions/lib/Db/VersionsMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2022 Louis Chmn <[email protected]>
*
* @author Louis Chmn <[email protected]>
*
* @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\Db;

use OCA\Files_Versions\Db\VersionEntity;
use OCP\IDBConnection;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\IResult;

/**
* @extends QBMapper<VersionEntity>
*/
class VersionsMapper extends QBMapper {
public function __construct(IDBConnection $db) {
parent::__construct($db, 'files_versions', VersionEntity::class);
}

/**
* @return VersionEntity[]
*/
public function findAllVersionsForFileId(int $fileId): array {
$qb = $this->db->getQueryBuilder();

$qb->select('*')
->from($this->getTableName())
->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId)));

return $this->findEntities($qb);
}

/**
* @return VersionEntity
*/
public function findCurrentVersionForFileId(int $fileId): VersionEntity {
$qb = $this->db->getQueryBuilder();

$qb->select('*')
->from($this->getTableName())
->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId)))
->orderBy('timestamp', 'DESC')
->setMaxResults(1);

return $this->findEntity($qb);
}

public function findVersionForFileId(int $fileId, int $timestamp): VersionEntity {
$qb = $this->db->getQueryBuilder();

$qb->select('*')
->from($this->getTableName())
->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId)))
->andWhere($qb->expr()->eq('timestamp', $qb->createNamedParameter($timestamp)));

return $this->findEntity($qb);
}

public function deleteAllVersionsForFileId(int $fileId): int {
$qb = $this->db->getQueryBuilder();

return $qb->delete($this->getTableName())
->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId)))
->executeStatement();
}
}
Loading