Skip to content

Commit d813657

Browse files
authored
Merge pull request nextcloud#43980 from nextcloud/backport/43898/stable27
[stable27] Improve files version listing
2 parents 96b88d3 + 2957d8a commit d813657

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

apps/files_versions/lib/Versions/LegacyVersionsBackend.php

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* along with this program. If not, see <http://www.gnu.org/licenses/>.
2525
*
2626
*/
27+
2728
namespace OCA\Files_Versions\Versions;
2829

2930
use OC\Files\View;
@@ -103,64 +104,70 @@ public function getVersionsForFile(IUser $user, FileInfo $file): array {
103104
throw new NotFoundException("File not found ($fileId)");
104105
}
105106

106-
$versions = $this->getVersionsForFileFromDB($file, $user);
107-
108-
// Early exit if we find any version in the database.
109-
// Else we continue to populate the DB from what's on disk.
110-
if (count($versions) > 0) {
111-
return $versions;
112-
}
113-
114-
// Insert the entry in the DB for the current version.
115-
$versionEntity = new VersionEntity();
116-
$versionEntity->setFileId($fileId);
117-
$versionEntity->setTimestamp($file->getMTime());
118-
$versionEntity->setSize($file->getSize());
119-
$versionEntity->setMimetype($this->mimeTypeLoader->getId($file->getMimetype()));
120-
$versionEntity->setMetadata([]);
121-
$this->versionsMapper->insert($versionEntity);
122-
123107
// Insert entries in the DB for existing versions.
124108
$relativePath = $userFolder->getRelativePath($file->getPath());
125109
if ($relativePath === null) {
126110
throw new NotFoundException("Relative path not found for file $fileId (" . $file->getPath() . ')');
127111
}
128112

129-
$versionsOnFS = Storage::getVersions($user->getUID(), $relativePath);
130-
foreach ($versionsOnFS as $version) {
131-
$versionEntity = new VersionEntity();
132-
$versionEntity->setFileId($fileId);
133-
$versionEntity->setTimestamp((int)$version['version']);
134-
$versionEntity->setSize((int)$version['size']);
135-
$versionEntity->setMimetype($this->mimeTypeLoader->getId($version['mimetype']));
136-
$versionEntity->setMetadata([]);
137-
$this->versionsMapper->insert($versionEntity);
113+
$currentVersion = [
114+
'version' => (string)$file->getMtime(),
115+
'size' => $file->getSize(),
116+
'mimetype' => $file->getMimetype(),
117+
];
118+
119+
$versionsInDB = $this->versionsMapper->findAllVersionsForFileId($file->getId());
120+
/** @var array<int, array> */
121+
$versionsInFS = array_values(Storage::getVersions($user->getUID(), $relativePath));
122+
123+
/** @var array<int, array{db: ?VersionEntity, fs: ?mixed}> */
124+
$groupedVersions = [];
125+
$davVersions = [];
126+
127+
foreach ($versionsInDB as $version) {
128+
$revisionId = $version->getTimestamp();
129+
$groupedVersions[$revisionId] = $groupedVersions[$revisionId] ?? [];
130+
$groupedVersions[$revisionId]['db'] = $version;
138131
}
139132

140-
return $this->getVersionsForFileFromDB($file, $user);
141-
}
133+
foreach ([$currentVersion, ...$versionsInFS] as $version) {
134+
$revisionId = $version['version'];
135+
$groupedVersions[$revisionId] = $groupedVersions[$revisionId] ?? [];
136+
$groupedVersions[$revisionId]['fs'] = $version;
137+
}
142138

143-
/**
144-
* @return IVersion[]
145-
*/
146-
private function getVersionsForFileFromDB(FileInfo $file, IUser $user): array {
147-
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
139+
/** @var array<string, array{db: ?VersionEntity, fs: ?mixed}> $groupedVersions */
140+
foreach ($groupedVersions as $versions) {
141+
if (empty($versions['db']) && !empty($versions['fs'])) {
142+
$versions['db'] = new VersionEntity();
143+
$versions['db']->setFileId($fileId);
144+
$versions['db']->setTimestamp((int)$versions['fs']['version']);
145+
$versions['db']->setSize((int)$versions['fs']['size']);
146+
$versions['db']->setMimetype($this->mimeTypeLoader->getId($versions['fs']['mimetype']));
147+
$versions['db']->setMetadata([]);
148+
$this->versionsMapper->insert($versions['db']);
149+
} elseif (!empty($versions['db']) && empty($versions['fs'])) {
150+
$this->versionsMapper->delete($versions['db']);
151+
continue;
152+
}
148153

149-
return array_map(
150-
fn (VersionEntity $versionEntity) => new Version(
151-
$versionEntity->getTimestamp(),
152-
$versionEntity->getTimestamp(),
154+
$version = new Version(
155+
$versions['db']->getTimestamp(),
156+
$versions['db']->getTimestamp(),
153157
$file->getName(),
154-
$versionEntity->getSize(),
155-
$this->mimeTypeLoader->getMimetypeById($versionEntity->getMimetype()),
158+
$versions['db']->getSize(),
159+
$this->mimeTypeLoader->getMimetypeById($versions['db']->getMimetype()),
156160
$userFolder->getRelativePath($file->getPath()),
157161
$file,
158162
$this,
159163
$user,
160-
$versionEntity->getLabel(),
161-
),
162-
$this->versionsMapper->findAllVersionsForFileId($file->getId())
163-
);
164+
$versions['db']->getLabel(),
165+
);
166+
167+
array_push($davVersions, $version);
168+
}
169+
170+
return $davVersions;
164171
}
165172

166173
public function createVersion(IUser $user, FileInfo $file) {

0 commit comments

Comments
 (0)