aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_versions
diff options
context:
space:
mode:
authorLouis Chemineau <louis@chmn.me>2024-03-26 12:21:56 +0100
committerLouis Chemineau <louis@chmn.me>2024-03-26 17:40:31 +0100
commit369274c9ee82eed6010a1a3b9cc5bac1a9926e2c (patch)
tree1a480e3b6ce1ae1536f284bc51ee53f269e6fdcc /apps/files_versions
parent1a55084930cbdd89e349cc0c9f4a2c2aeedb1e3c (diff)
downloadnextcloud-server-369274c9ee82eed6010a1a3b9cc5bac1a9926e2c.tar.gz
nextcloud-server-369274c9ee82eed6010a1a3b9cc5bac1a9926e2c.zip
feat(files_versions): Add listener and interfaces to allow versions migration across storages
Signed-off-by: Louis Chemineau <louis@chmn.me>
Diffstat (limited to 'apps/files_versions')
-rw-r--r--apps/files_versions/composer/composer/autoload_classmap.php2
-rw-r--r--apps/files_versions/composer/composer/autoload_static.php2
-rw-r--r--apps/files_versions/lib/AppInfo/Application.php6
-rw-r--r--apps/files_versions/lib/Listener/FileEventsListener.php21
-rw-r--r--apps/files_versions/lib/Listener/VersionStorageMoveListener.php154
-rw-r--r--apps/files_versions/lib/Versions/IMetadataVersion.php8
-rw-r--r--apps/files_versions/lib/Versions/IVersionManager.php8
-rw-r--r--apps/files_versions/lib/Versions/IVersionsImporterBackend.php50
-rw-r--r--apps/files_versions/lib/Versions/LegacyVersionsBackend.php75
-rw-r--r--apps/files_versions/lib/Versions/Version.php4
-rw-r--r--apps/files_versions/lib/Versions/VersionManager.php1
11 files changed, 329 insertions, 2 deletions
diff --git a/apps/files_versions/composer/composer/autoload_classmap.php b/apps/files_versions/composer/composer/autoload_classmap.php
index c7fa952de27..94256f79da1 100644
--- a/apps/files_versions/composer/composer/autoload_classmap.php
+++ b/apps/files_versions/composer/composer/autoload_classmap.php
@@ -22,6 +22,7 @@ return array(
'OCA\\Files_Versions\\Listener\\LoadAdditionalListener' => $baseDir . '/../lib/Listener/LoadAdditionalListener.php',
'OCA\\Files_Versions\\Listener\\LoadSidebarListener' => $baseDir . '/../lib/Listener/LoadSidebarListener.php',
'OCA\\Files_Versions\\Listener\\VersionAuthorListener' => $baseDir . '/../lib/Listener/VersionAuthorListener.php',
+ 'OCA\\Files_Versions\\Listener\\VersionStorageMoveListener' => $baseDir . '/../lib/Listener/VersionStorageMoveListener.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',
@@ -41,6 +42,7 @@ return array(
'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\\IVersionsImporterBackend' => $baseDir . '/../lib/Versions/IVersionsImporterBackend.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',
diff --git a/apps/files_versions/composer/composer/autoload_static.php b/apps/files_versions/composer/composer/autoload_static.php
index 988b8e27cbe..1ac235d936d 100644
--- a/apps/files_versions/composer/composer/autoload_static.php
+++ b/apps/files_versions/composer/composer/autoload_static.php
@@ -37,6 +37,7 @@ class ComposerStaticInitFiles_Versions
'OCA\\Files_Versions\\Listener\\LoadAdditionalListener' => __DIR__ . '/..' . '/../lib/Listener/LoadAdditionalListener.php',
'OCA\\Files_Versions\\Listener\\LoadSidebarListener' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarListener.php',
'OCA\\Files_Versions\\Listener\\VersionAuthorListener' => __DIR__ . '/..' . '/../lib/Listener/VersionAuthorListener.php',
+ 'OCA\\Files_Versions\\Listener\\VersionStorageMoveListener' => __DIR__ . '/..' . '/../lib/Listener/VersionStorageMoveListener.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',
@@ -56,6 +57,7 @@ class ComposerStaticInitFiles_Versions
'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\\IVersionsImporterBackend' => __DIR__ . '/..' . '/../lib/Versions/IVersionsImporterBackend.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',
diff --git a/apps/files_versions/lib/AppInfo/Application.php b/apps/files_versions/lib/AppInfo/Application.php
index e6870139ee2..f9ab1883a6e 100644
--- a/apps/files_versions/lib/AppInfo/Application.php
+++ b/apps/files_versions/lib/AppInfo/Application.php
@@ -37,6 +37,7 @@ use OCA\Files_Versions\Listener\FileEventsListener;
use OCA\Files_Versions\Listener\LoadAdditionalListener;
use OCA\Files_Versions\Listener\LoadSidebarListener;
use OCA\Files_Versions\Listener\VersionAuthorListener;
+use OCA\Files_Versions\Listener\VersionStorageMoveListener;
use OCA\Files_Versions\Versions\IVersionManager;
use OCA\Files_Versions\Versions\VersionManager;
use OCP\Accounts\IAccountManager;
@@ -109,6 +110,11 @@ class Application extends App implements IBootstrap {
$context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class);
$context->registerEventListener(LoadSidebar::class, LoadSidebarListener::class);
+ $context->registerEventListener(BeforeNodeRenamedEvent::class, VersionStorageMoveListener::class);
+ $context->registerEventListener(NodeRenamedEvent::class, VersionStorageMoveListener::class);
+ $context->registerEventListener(BeforeNodeCopiedEvent::class, VersionStorageMoveListener::class);
+ $context->registerEventListener(NodeCopiedEvent::class, VersionStorageMoveListener::class);
+
$context->registerEventListener(NodeCreatedEvent::class, FileEventsListener::class);
$context->registerEventListener(BeforeNodeTouchedEvent::class, FileEventsListener::class);
$context->registerEventListener(NodeTouchedEvent::class, FileEventsListener::class);
diff --git a/apps/files_versions/lib/Listener/FileEventsListener.php b/apps/files_versions/lib/Listener/FileEventsListener.php
index 24a21b22549..3273f1f9c40 100644
--- a/apps/files_versions/lib/Listener/FileEventsListener.php
+++ b/apps/files_versions/lib/Listener/FileEventsListener.php
@@ -300,6 +300,13 @@ class FileEventsListener implements IEventListener {
* of the stored versions along the actual file
*/
public function rename_hook(Node $source, Node $target): void {
+ $sourceBackend = $this->versionManager->getBackendForStorage($source->getParent()->getStorage());
+ $targetBackend = $this->versionManager->getBackendForStorage($target->getStorage());
+ // If different backends, do nothing.
+ if ($sourceBackend !== $targetBackend) {
+ return;
+ }
+
$oldPath = $this->getPathForNode($source);
$newPath = $this->getPathForNode($target);
Storage::renameOrCopy($oldPath, $newPath, 'rename');
@@ -312,6 +319,13 @@ class FileEventsListener implements IEventListener {
* the stored versions to the new location
*/
public function copy_hook(Node $source, Node $target): void {
+ $sourceBackend = $this->versionManager->getBackendForStorage($source->getParent()->getStorage());
+ $targetBackend = $this->versionManager->getBackendForStorage($target->getStorage());
+ // If different backends, do nothing.
+ if ($sourceBackend !== $targetBackend) {
+ return;
+ }
+
$oldPath = $this->getPathForNode($source);
$newPath = $this->getPathForNode($target);
Storage::renameOrCopy($oldPath, $newPath, 'copy');
@@ -325,6 +339,13 @@ class FileEventsListener implements IEventListener {
*
*/
public function pre_renameOrCopy_hook(Node $source, Node $target): void {
+ $sourceBackend = $this->versionManager->getBackendForStorage($source->getStorage());
+ $targetBackend = $this->versionManager->getBackendForStorage($target->getParent()->getStorage());
+ // If different backends, do nothing.
+ if ($sourceBackend !== $targetBackend) {
+ return;
+ }
+
// if we rename a movable mount point, then the versions don't have
// to be renamed
$oldPath = $this->getPathForNode($source);
diff --git a/apps/files_versions/lib/Listener/VersionStorageMoveListener.php b/apps/files_versions/lib/Listener/VersionStorageMoveListener.php
new file mode 100644
index 00000000000..1648bd403d2
--- /dev/null
+++ b/apps/files_versions/lib/Listener/VersionStorageMoveListener.php
@@ -0,0 +1,154 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2024 Louis Chmn <louis@chmn.me>
+ *
+ * @author Louis Chmn <louis@chmn.me>
+ *
+ * @license GNU AGPL-3.0-or-later
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OCA\Files_Versions\Listener;
+
+use Exception;
+use OC\Files\Node\NonExistingFile;
+use OCA\Files_Versions\Versions\IVersionBackend;
+use OCA\Files_Versions\Versions\IVersionManager;
+use OCA\Files_Versions\Versions\IVersionsImporterBackend;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Files\Events\Node\AbstractNodesEvent;
+use OCP\Files\Events\Node\BeforeNodeRenamedEvent;
+use OCP\Files\Events\Node\NodeCopiedEvent;
+use OCP\Files\Events\Node\NodeRenamedEvent;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\Node;
+use OCP\Files\Storage\IStorage;
+use OCP\IUser;
+use OCP\IUserSession;
+
+/** @template-implements IEventListener<Event> */
+class VersionStorageMoveListener implements IEventListener {
+ /** @var File[] */
+ private array $movedNodes = [];
+
+ public function __construct(
+ private IVersionManager $versionManager,
+ private IUserSession $userSession,
+ ) {
+ }
+
+ /**
+ * @abstract Moves version across storages if necessary.
+ * @throws Exception No user in session
+ */
+ public function handle(Event $event): void {
+ if (!($event instanceof AbstractNodesEvent)) {
+ return;
+ }
+
+ $source = $event->getSource();
+ $target = $event->getTarget();
+
+ $sourceStorage = $this->getNodeStorage($source);
+ $targetStorage = $this->getNodeStorage($target);
+
+ $sourceBackend = $this->versionManager->getBackendForStorage($sourceStorage);
+ $targetBackend = $this->versionManager->getBackendForStorage($targetStorage);
+
+ // If same backend, nothing to do.
+ if ($sourceBackend === $targetBackend) {
+ return;
+ }
+
+ $user = $this->userSession->getUser() ?? $source->getOwner();
+
+ if ($user === null) {
+ throw new Exception("Cannot move versions across storages without a user.");
+ }
+
+ if ($event instanceof BeforeNodeRenamedEvent) {
+ $this->recursivelyPrepareMove($source);
+ } elseif ($event instanceof NodeRenamedEvent || $event instanceof NodeCopiedEvent) {
+ $this->recursivelyHandleMoveOrCopy($event, $user, $source, $target, $sourceBackend, $targetBackend);
+ }
+ }
+
+ /**
+ * Store all sub files in this->movedNodes so their info can be used after the operation.
+ */
+ private function recursivelyPrepareMove(Node $source): void {
+ if ($source instanceof File) {
+ $this->movedNodes[$source->getId()] = $source;
+ } elseif ($source instanceof Folder) {
+ foreach ($source->getDirectoryListing() as $child) {
+ $this->recursivelyPrepareMove($child);
+ }
+ }
+ }
+
+ /**
+ * Call handleMoveOrCopy on each sub files
+ * @param NodeRenamedEvent|NodeCopiedEvent $event
+ */
+ private function recursivelyHandleMoveOrCopy(Event $event, IUser $user, ?Node $source, Node $target, IVersionBackend $sourceBackend, IVersionBackend $targetBackend): void {
+ if ($target instanceof File) {
+ if ($event instanceof NodeRenamedEvent) {
+ $source = $this->movedNodes[$target->getId()];
+ }
+
+ /** @var File $source */
+ $this->handleMoveOrCopy($event, $user, $source, $target, $sourceBackend, $targetBackend);
+ } elseif ($target instanceof Folder) {
+ /** @var Folder $source */
+ foreach ($target->getDirectoryListing() as $targetChild) {
+ if ($event instanceof NodeCopiedEvent) {
+ $sourceChild = $source->get($targetChild->getName());
+ } else {
+ $sourceChild = null;
+ }
+
+ $this->recursivelyHandleMoveOrCopy($event, $user, $sourceChild, $targetChild, $sourceBackend, $targetBackend);
+ }
+ }
+ }
+
+ /**
+ * Called only during NodeRenamedEvent or NodeCopiedEvent
+ * Will send the source node versions to the new backend, and then delete them from the old backend.
+ * @param NodeRenamedEvent|NodeCopiedEvent $event
+ */
+ private function handleMoveOrCopy(Event $event, IUser $user, File $source, File $target, IVersionBackend $sourceBackend, IVersionBackend $targetBackend): void {
+ if ($targetBackend instanceof IVersionsImporterBackend) {
+ $versions = $sourceBackend->getVersionsForFile($user, $source);
+ $targetBackend->importVersionsForFile($user, $source, $target, $versions);
+ }
+
+ if ($event instanceof NodeRenamedEvent && $sourceBackend instanceof IVersionsImporterBackend) {
+ $sourceBackend->clearVersionsForFile($user, $source, $target);
+ }
+ }
+
+ private function getNodeStorage(Node $node): IStorage {
+ if ($node instanceof NonExistingFile) {
+ return $node->getParent()->getStorage();
+ } else {
+ return $node->getStorage();
+ }
+ }
+}
diff --git a/apps/files_versions/lib/Versions/IMetadataVersion.php b/apps/files_versions/lib/Versions/IMetadataVersion.php
index 44f8d904147..40ee827012a 100644
--- a/apps/files_versions/lib/Versions/IMetadataVersion.php
+++ b/apps/files_versions/lib/Versions/IMetadataVersion.php
@@ -29,6 +29,14 @@ namespace OCA\Files_Versions\Versions;
*/
interface IMetadataVersion {
/**
+ * retrieves the all the metadata
+ *
+ * @return string[]
+ * @since 29.0.0
+ */
+ public function getMetadata(): array;
+
+ /**
* retrieves the metadata value from our $key param
*
* @param string $key the key for the json value of the metadata column
diff --git a/apps/files_versions/lib/Versions/IVersionManager.php b/apps/files_versions/lib/Versions/IVersionManager.php
index afc3046fa48..ee5d7abeb0c 100644
--- a/apps/files_versions/lib/Versions/IVersionManager.php
+++ b/apps/files_versions/lib/Versions/IVersionManager.php
@@ -25,6 +25,8 @@ declare(strict_types=1);
*/
namespace OCA\Files_Versions\Versions;
+use OCP\Files\Storage\IStorage;
+
/**
* @since 15.0.0
*/
@@ -37,4 +39,10 @@ interface IVersionManager extends IVersionBackend {
* @since 15.0.0
*/
public function registerBackend(string $storageType, IVersionBackend $backend);
+
+ /**
+ * @throws BackendNotFoundException
+ * @since 29.0.0
+ */
+ public function getBackendForStorage(IStorage $storage): IVersionBackend;
}
diff --git a/apps/files_versions/lib/Versions/IVersionsImporterBackend.php b/apps/files_versions/lib/Versions/IVersionsImporterBackend.php
new file mode 100644
index 00000000000..45649268107
--- /dev/null
+++ b/apps/files_versions/lib/Versions/IVersionsImporterBackend.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2024 Louis Chmn <louis@chmn.me>
+ *
+ * @author Louis Chmn <louis@chmn.me>
+ *
+ * @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\Node;
+use OCP\IUser;
+
+/**
+ * @since 29.0.0
+ */
+interface IVersionsImporterBackend {
+ /**
+ * Import the given versions for the target file.
+ *
+ * @param Node $source - The source might not exist anymore.
+ * @param IVersion[] $versions
+ * @since 29.0.0
+ */
+ public function importVersionsForFile(IUser $user, Node $source, Node $target, array $versions): void;
+
+ /**
+ * Clear all versions for a file
+ *
+ * @since 29.0.0
+ */
+ public function clearVersionsForFile(IUser $user, Node $source, Node $target): void;
+}
diff --git a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php
index dcc56225c73..deb8833c87b 100644
--- a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php
+++ b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php
@@ -27,6 +27,7 @@ declare(strict_types=1);
namespace OCA\Files_Versions\Versions;
+use Exception;
use OC\Files\View;
use OCA\DAV\Connector\Sabre\Exception\Forbidden;
use OCA\Files_Sharing\ISharedStorage;
@@ -45,14 +46,16 @@ use OCP\Files\Storage\IStorage;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
+use Psr\Log\LoggerInterface;
-class LegacyVersionsBackend implements IVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend, IMetadataVersionBackend {
+class LegacyVersionsBackend implements IVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend, IMetadataVersionBackend, IVersionsImporterBackend {
public function __construct(
private IRootFolder $rootFolder,
private IUserManager $userManager,
private VersionsMapper $versionsMapper,
private IMimeTypeLoader $mimeTypeLoader,
private IUserSession $userSession,
+ private LoggerInterface $logger,
) {
}
@@ -304,4 +307,74 @@ class LegacyVersionsBackend implements IVersionBackend, IDeletableVersionBackend
$versionEntity->setMetadataValue($key, $value);
$this->versionsMapper->update($versionEntity);
}
+
+
+ /**
+ * @inheritdoc
+ */
+ public function importVersionsForFile(IUser $user, Node $source, Node $target, array $versions): void {
+ $userFolder = $this->rootFolder->getUserFolder($user->getUID());
+ $relativePath = $userFolder->getRelativePath($target->getPath());
+
+ if ($relativePath === null) {
+ throw new \Exception('Target does not have a relative path' . $target->getPath());
+ }
+
+ $userView = new View('/' . $user->getUID());
+ // create all parent folders
+ Storage::createMissingDirectories($relativePath, $userView);
+ Storage::scheduleExpire($user->getUID(), $relativePath);
+
+ foreach ($versions as $version) {
+ // 1. Import the file in its new location.
+ // Nothing to do for the current version.
+ if ($version->getTimestamp() !== $source->getMTime()) {
+ $backend = $version->getBackend();
+ $versionFile = $backend->getVersionFile($user, $source, $version->getRevisionId());
+ $newVersionPath = 'files_versions/' . $relativePath . '.v' . $version->getTimestamp();
+
+ $versionContent = $versionFile->fopen('r');
+ if ($versionContent === false) {
+ $this->logger->warning('Fail to open version file.', ['source' => $source, 'version' => $version, 'versionFile' => $versionFile]);
+ continue;
+ }
+
+ $userView->file_put_contents($newVersionPath, $versionContent);
+ // ensure the file is scanned
+ $userView->getFileInfo($newVersionPath);
+ }
+
+ // 2. Create the entity in the database
+ $versionEntity = new VersionEntity();
+ $versionEntity->setFileId($target->getId());
+ $versionEntity->setTimestamp($version->getTimestamp());
+ $versionEntity->setSize($version->getSize());
+ $versionEntity->setMimetype($this->mimeTypeLoader->getId($version->getMimetype()));
+ if ($version instanceof IMetadataVersion) {
+ $versionEntity->setMetadata($version->getMetadata());
+ }
+ $this->versionsMapper->insert($versionEntity);
+ }
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function clearVersionsForFile(IUser $user, Node $source, Node $target): void {
+ $userFolder = $this->rootFolder->getUserFolder($user->getUID());
+
+ $relativePath = $userFolder->getRelativePath($source->getPath());
+ if ($relativePath === null) {
+ throw new Exception("Relative path not found for node with path: " . $source->getPath());
+ }
+
+ $versions = Storage::getVersions($user->getUID(), $relativePath);
+ /** @var Folder versionFolder */
+ $versionFolder = $this->rootFolder->get('admin/files_versions');
+ foreach ($versions as $version) {
+ $versionFolder->get($version['path'] . '.v' . (int)$version['version'])->delete();
+ }
+
+ $this->versionsMapper->deleteAllVersionsForFileId($target->getId());
+ }
}
diff --git a/apps/files_versions/lib/Versions/Version.php b/apps/files_versions/lib/Versions/Version.php
index 40f2507433d..83d27db2f7e 100644
--- a/apps/files_versions/lib/Versions/Version.php
+++ b/apps/files_versions/lib/Versions/Version.php
@@ -79,6 +79,10 @@ class Version implements IVersion, IMetadataVersion {
return $this->user;
}
+ public function getMetadata(): array {
+ return $this->metadata;
+ }
+
public function getMetadataValue(string $key): ?string {
return $this->metadata[$key] ?? null;
}
diff --git a/apps/files_versions/lib/Versions/VersionManager.php b/apps/files_versions/lib/Versions/VersionManager.php
index f12b5679fbc..754dd8523c9 100644
--- a/apps/files_versions/lib/Versions/VersionManager.php
+++ b/apps/files_versions/lib/Versions/VersionManager.php
@@ -203,5 +203,4 @@ class VersionManager implements IVersionManager, IDeletableVersionBackend, INeed
return $result;
}
}
-
}