Skip to content

Commit

Permalink
Merge pull request #44049 from nextcloud/feat/show-name-of-user-in-ve…
Browse files Browse the repository at this point in the history
…rsions

feat: show the id of last author in versions metadata
  • Loading branch information
emoral435 authored Mar 11, 2024
2 parents b32c0f7 + bfacc6d commit f99b820
Show file tree
Hide file tree
Showing 20 changed files with 274 additions and 12 deletions.
3 changes: 3 additions & 0 deletions apps/files_versions/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
'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\\Listener\\MetadataFileEvents' => $baseDir . '/../lib/Listener/MetadataFileEvents.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',
Expand All @@ -32,6 +33,8 @@
'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\\IMetadataVersion' => $baseDir . '/../lib/Versions/IMetadataVersion.php',
'OCA\\Files_Versions\\Versions\\IMetadataVersionBackend' => $baseDir . '/../lib/Versions/IMetadataVersionBackend.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\\INeedSyncVersionBackend' => $baseDir . '/../lib/Versions/INeedSyncVersionBackend.php',
Expand Down
3 changes: 3 additions & 0 deletions apps/files_versions/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class ComposerStaticInitFiles_Versions
'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\\Listener\\MetadataFileEvents' => __DIR__ . '/..' . '/../lib/Listener/MetadataFileEvents.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',
Expand All @@ -47,6 +48,8 @@ class ComposerStaticInitFiles_Versions
'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\\IMetadataVersion' => __DIR__ . '/..' . '/../lib/Versions/IMetadataVersion.php',
'OCA\\Files_Versions\\Versions\\IMetadataVersionBackend' => __DIR__ . '/..' . '/../lib/Versions/IMetadataVersionBackend.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\\INeedSyncVersionBackend' => __DIR__ . '/..' . '/../lib/Versions/INeedSyncVersionBackend.php',
Expand Down
4 changes: 2 additions & 2 deletions apps/files_versions/composer/composer/installed.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
'name' => '__root__',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'a820e3d036741ad1194361eca11bc1cbcdda0a47',
'reference' => '84930a207a8d5f0ef32320796fe188892b63fa19',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
Expand All @@ -13,7 +13,7 @@
'__root__' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'a820e3d036741ad1194361eca11bc1cbcdda0a47',
'reference' => '84930a207a8d5f0ef32320796fe188892b63fa19',
'type' => 'library',
'install_path' => __DIR__ . '/../',
'aliases' => array(),
Expand Down
3 changes: 3 additions & 0 deletions apps/files_versions/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use OCA\Files_Versions\Listener\FileEventsListener;
use OCA\Files_Versions\Listener\LoadAdditionalListener;
use OCA\Files_Versions\Listener\LoadSidebarListener;
use OCA\Files_Versions\Listener\MetadataFileEvents;
use OCA\Files_Versions\Versions\IVersionManager;
use OCA\Files_Versions\Versions\VersionManager;
use OCP\Accounts\IAccountManager;
Expand Down Expand Up @@ -119,6 +120,8 @@ public function register(IRegistrationContext $context): void {
$context->registerEventListener(NodeCopiedEvent::class, FileEventsListener::class);
$context->registerEventListener(BeforeNodeRenamedEvent::class, FileEventsListener::class);
$context->registerEventListener(BeforeNodeCopiedEvent::class, FileEventsListener::class);

$context->registerEventListener(NodeWrittenEvent::class, MetadataFileEvents::class);
}

public function boot(IBootContext $context): void {
Expand Down
19 changes: 19 additions & 0 deletions apps/files_versions/lib/Db/VersionEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,23 @@ public function setLabel(string $label): void {
$this->metadata['label'] = $label;
$this->markFieldUpdated('metadata');
}

/**
* @abstract given a key, return the value associated with the key in the metadata column
* if nothing is found, we return an empty string
* @param string $key key associated with the value
*/
public function getMetadataValue(string $key): ?string {
return $this->metadata[$key] ?? null;
}

/**
* @abstract sets a key value pair in the metadata column
* @param string $key key associated with the value
* @param string $value value associated with the key
*/
public function setMetadataValue(string $key, string $value): void {
$this->metadata[$key] = $value;
$this->markFieldUpdated('metadata');
}
}
2 changes: 1 addition & 1 deletion apps/files_versions/lib/Db/VersionsMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function deleteAllVersionsForFileId(int $fileId): int {
->executeStatement();
}

public function deleteAllVersionsForUser(int $storageId, string $path = null): void {
public function deleteAllVersionsForUser(int $storageId, ?string $path = null): void {
$fileIdsGenerator = $this->getFileIdsGenerator($storageId, $path);

$versionEntitiesDeleteQuery = $this->db->getQueryBuilder();
Expand Down
68 changes: 68 additions & 0 deletions apps/files_versions/lib/Listener/MetadataFileEvents.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

/**
* @author Eduardo Morales [email protected]>
*
* @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 OC\Files\Node\Folder;
use OCA\Files_Versions\Versions\IMetadataVersionBackend;
use OCA\Files_Versions\Versions\IVersionManager;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\Files\Node;
use OCP\IUserSession;

/** @template-implements IEventListener<NodeWrittenEvent> */
class MetadataFileEvents implements IEventListener {
public function __construct(
private IVersionManager $versionManager,
private IUserSession $userSession,
) {
}

/**
* @abstract handles events from a nodes version being changed
* @param Event $event the event that triggered this listener to activate
*/
public function handle(Event $event): void {
if ($event instanceof NodeWrittenEvent) {
$this->post_write_hook($event->getNode());
}
}

/**
* @abstract handles the NodeWrittenEvent, and sets the metadata for the associated node
* @param Node $node the node that is currently being written
*/
public function post_write_hook(Node $node): void {
$user = $this->userSession->getUser();
// Do not handle folders or users that we cannot get metadata from
if ($node instanceof Folder || is_null($user)) {
return;
}
// check if our version manager supports setting the metadata
if ($this->versionManager instanceof IMetadataVersionBackend) {
$author = $user->getUID();
$this->versionManager->setMetadataValue($node, 'author', $author);
}
}
}
3 changes: 3 additions & 0 deletions apps/files_versions/lib/Sabre/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class Plugin extends ServerPlugin {

public const VERSION_LABEL = '{http://nextcloud.org/ns}version-label';

public const VERSION_AUTHOR = '{http://nextcloud.org/ns}version-author'; // dav property for author

public function __construct(
private IRequest $request,
private IPreview $previewManager,
Expand Down Expand Up @@ -93,6 +95,7 @@ public function afterGet(RequestInterface $request, ResponseInterface $response)
public function propFind(PropFind $propFind, INode $node): void {
if ($node instanceof VersionFile) {
$propFind->handle(self::VERSION_LABEL, fn () => $node->getLabel());
$propFind->handle(self::VERSION_AUTHOR, fn () => $node->getMetadataValue("author"));
$propFind->handle(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, fn () => $this->previewManager->isMimeSupported($node->getContentType()));
}
}
Expand Down
8 changes: 8 additions & 0 deletions apps/files_versions/lib/Sabre/VersionFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
namespace OCA\Files_Versions\Sabre;

use OCA\Files_Versions\Versions\IDeletableVersionBackend;
use OCA\Files_Versions\Versions\IMetadataVersion;
use OCA\Files_Versions\Versions\INameableVersion;
use OCA\Files_Versions\Versions\INameableVersionBackend;
use OCA\Files_Versions\Versions\IVersion;
Expand Down Expand Up @@ -109,6 +110,13 @@ public function setLabel($label): bool {
}
}

public function getMetadataValue(string $key): ?string {
if ($this->version instanceof IMetadataVersion) {
return $this->version->getMetadataValue($key);
}
return null;
}

public function getLastModified(): int {
return $this->version->getTimestamp();
}
Expand Down
38 changes: 38 additions & 0 deletions apps/files_versions/lib/Versions/IMetadataVersion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2024 Eduardo Morales <[email protected]>
*
* @license GNU AGPL-3.0-or-later
*
* 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;

/**
* This interface allows for just direct accessing of the metadata column JSON
* @since 29.0.0
*/
interface IMetadataVersion {
/**
* retrieves the metadata value from our $key param
*
* @param string $key the key for the json value of the metadata column
* @since 29.0.0
*/
public function getMetadataValue(string $key): ?string;
}
52 changes: 52 additions & 0 deletions apps/files_versions/lib/Versions/IMetadataVersionBackend.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2024 Eduardo Morales <[email protected]>
*
* @license GNU AGPL-3.0-or-later
*
* 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;

/**
* This interface edits the metadata column of a node.
* Each column of the metadata has a key => value mapping.
* @since 29.0.0
*/
interface IMetadataVersionBackend {
/**
* Sets a key value pair in the metadata column corresponding to the node's version.
*
* @param Node $node the node that triggered the Metadata event listener, aka, the file version
* @param string $key the key for the json value of the metadata column
* @param string $value the value that corresponds to the key in the metadata column
* @since 29.0.0
*/
public function setMetadataValue(Node $node, string $key, string $value): void;

/**
* Retrieves a corresponding value from the metadata column using the key.
*
* @param Node $node the node that triggered the Metadata event listener, aka, the file version
* @param string $key the key for the json value of the metadata column
* @since 29.0.0
*/
public function getMetadataValue(Node $node, string $key): ?string;
}
3 changes: 2 additions & 1 deletion apps/files_versions/lib/Versions/INameableVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
namespace OCA\Files_Versions\Versions;

/**
* @deprecated 29.0.0
* @since 26.0.0
*/
interface INameableVersion {
/**
* Get the user created label
*
* @deprecated 29.0.0
* @return string
* @since 26.0.0
*/
Expand Down
3 changes: 2 additions & 1 deletion apps/files_versions/lib/Versions/INameableVersionBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
namespace OCA\Files_Versions\Versions;

/**
* @deprecated 29.0.0
* @since 26.0.0
*/
interface INameableVersionBackend {
/**
* Set the label for a version.
*
* @deprecated 29.0.0
* @since 26.0.0
*/
public function setVersionLabel(IVersion $version, string $label): void;
Expand Down
32 changes: 31 additions & 1 deletion apps/files_versions/lib/Versions/LegacyVersionsBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@
use OCP\Files\Folder;
use OCP\Files\IMimeTypeLoader;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\Files\Storage\IStorage;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;

class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend {
class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend, IMetadataVersionBackend {
private IRootFolder $rootFolder;
private IUserManager $userManager;
private VersionsMapper $versionsMapper;
Expand Down Expand Up @@ -312,4 +313,33 @@ private function currentUserHasPermissions(IVersion $version, int $permissions):

return ($sourceFile->getPermissions() & $permissions) === $permissions;
}

public function setMetadataValue(Node $node, string $key, string $value): void {
// Do not handle folders.
if ($node instanceof File) {

try {
$versionEntity = $this->versionsMapper->findVersionForFileId($node->getId(), $node->getMTime());
} catch (\Exception $e) {
throw $e; // the version does not exist or too many versions exist
}

$currentMetadata = $versionEntity->getMetadata() ?? [];

$currentMetadata[$key] = $value;
$versionEntity->setMetadata($currentMetadata);
$this->versionsMapper->update($versionEntity);
}

}

public function getMetadataValue(Node $node, string $key): ?string {
try {
$versionEntity = $this->versionsMapper->findVersionForFileId($node->getId(), $node->getMTime());
return $versionEntity->getMetadataValue($key);
} catch (\InvalidArgumentException $e) {
// we tried to find a version or key that doesn't exist
return null;
}
}
}
Loading

0 comments on commit f99b820

Please sign in to comment.