mirror of
https://github.com/nextcloud/server.git
synced 2026-06-10 09:13:19 -04:00
Merge pull request #50990 from AIlkiv/refactor/version-rollback-to-event
refactor: move version rollback hook to event
This commit is contained in:
commit
ef099806a4
7 changed files with 158 additions and 12 deletions
|
|
@ -17,8 +17,10 @@ return array(
|
|||
'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\\Events\\VersionRestoredEvent' => $baseDir . '/../lib/Events/VersionRestoredEvent.php',
|
||||
'OCA\\Files_Versions\\Expiration' => $baseDir . '/../lib/Expiration.php',
|
||||
'OCA\\Files_Versions\\Listener\\FileEventsListener' => $baseDir . '/../lib/Listener/FileEventsListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\LegacyRollbackListener' => $baseDir . '/../lib/Listener/LegacyRollbackListener.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\\VersionAuthorListener' => $baseDir . '/../lib/Listener/VersionAuthorListener.php',
|
||||
|
|
|
|||
|
|
@ -32,8 +32,10 @@ class ComposerStaticInitFiles_Versions
|
|||
'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\\Events\\VersionRestoredEvent' => __DIR__ . '/..' . '/../lib/Events/VersionRestoredEvent.php',
|
||||
'OCA\\Files_Versions\\Expiration' => __DIR__ . '/..' . '/../lib/Expiration.php',
|
||||
'OCA\\Files_Versions\\Listener\\FileEventsListener' => __DIR__ . '/..' . '/../lib/Listener/FileEventsListener.php',
|
||||
'OCA\\Files_Versions\\Listener\\LegacyRollbackListener' => __DIR__ . '/..' . '/../lib/Listener/LegacyRollbackListener.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\\VersionAuthorListener' => __DIR__ . '/..' . '/../lib/Listener/VersionAuthorListener.php',
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ use OCA\DAV\Connector\Sabre\Principal;
|
|||
use OCA\Files\Event\LoadAdditionalScriptsEvent;
|
||||
use OCA\Files\Event\LoadSidebar;
|
||||
use OCA\Files_Versions\Capabilities;
|
||||
use OCA\Files_Versions\Events\VersionRestoredEvent;
|
||||
use OCA\Files_Versions\Listener\FileEventsListener;
|
||||
use OCA\Files_Versions\Listener\LegacyRollbackListener;
|
||||
use OCA\Files_Versions\Listener\LoadAdditionalListener;
|
||||
use OCA\Files_Versions\Listener\LoadSidebarListener;
|
||||
use OCA\Files_Versions\Listener\VersionAuthorListener;
|
||||
|
|
@ -80,9 +82,7 @@ class Application extends App implements IBootstrap {
|
|||
);
|
||||
});
|
||||
|
||||
$context->registerService(IVersionManager::class, function () {
|
||||
return new VersionManager();
|
||||
});
|
||||
$context->registerServiceAlias(IVersionManager::class, VersionManager::class);
|
||||
|
||||
/**
|
||||
* Register Events
|
||||
|
|
@ -108,6 +108,8 @@ class Application extends App implements IBootstrap {
|
|||
$context->registerEventListener(BeforeNodeCopiedEvent::class, FileEventsListener::class);
|
||||
|
||||
$context->registerEventListener(NodeWrittenEvent::class, VersionAuthorListener::class);
|
||||
|
||||
$context->registerEventListener(VersionRestoredEvent::class, LegacyRollbackListener::class);
|
||||
}
|
||||
|
||||
public function boot(IBootContext $context): void {
|
||||
|
|
|
|||
33
apps/files_versions/lib/Events/VersionRestoredEvent.php
Normal file
33
apps/files_versions/lib/Events/VersionRestoredEvent.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Files_Versions\Events;
|
||||
|
||||
use OCA\Files_Versions\Versions\IVersion;
|
||||
use OCP\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* Class VersionRestoredEvent
|
||||
*
|
||||
* Event that is called after a successful restore of a previous version
|
||||
*
|
||||
* @package OCA\Files_Versions
|
||||
*/
|
||||
class VersionRestoredEvent extends Event {
|
||||
public function __construct(
|
||||
private IVersion $version,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Version that was restored
|
||||
*/
|
||||
public function getVersion(): IVersion {
|
||||
return $this->version;
|
||||
}
|
||||
}
|
||||
35
apps/files_versions/lib/Listener/LegacyRollbackListener.php
Normal file
35
apps/files_versions/lib/Listener/LegacyRollbackListener.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCA\Files_Versions\Listener;
|
||||
|
||||
use OCA\Files_Versions\Events\VersionRestoredEvent;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
|
||||
/**
|
||||
* This listener is designed to be compatible with third-party code
|
||||
* that can still use a hook. This listener will be removed in
|
||||
* the next version and the rollback hook will stop working.
|
||||
*
|
||||
* @deprecated 32.0.0
|
||||
* @template-implements IEventListener<VersionRestoredEvent>
|
||||
*/
|
||||
class LegacyRollbackListener implements IEventListener {
|
||||
public function handle(Event $event): void {
|
||||
if (!($event instanceof VersionRestoredEvent)) {
|
||||
return;
|
||||
}
|
||||
$version = $event->getVersion();
|
||||
\OC_Hook::emit('\OCP\Versions', 'rollback', [
|
||||
'path' => $version->getVersionPath(),
|
||||
'revision' => $version->getRevisionId(),
|
||||
'node' => $version->getSourceFile(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Files_Versions\Versions;
|
||||
|
||||
use OCA\Files_Versions\Events\VersionRestoredEvent;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\Files\IRootFolder;
|
||||
|
|
@ -21,9 +23,15 @@ use OCP\Lock\ManuallyLockedException;
|
|||
use OCP\Server;
|
||||
|
||||
class VersionManager implements IVersionManager, IDeletableVersionBackend, INeedSyncVersionBackend, IMetadataVersionBackend {
|
||||
|
||||
/** @var (IVersionBackend[])[] */
|
||||
private $backends = [];
|
||||
|
||||
public function __construct(
|
||||
private IEventDispatcher $dispatcher,
|
||||
) {
|
||||
}
|
||||
|
||||
public function registerBackend(string $storageType, IVersionBackend $backend) {
|
||||
if (!isset($this->backends[$storageType])) {
|
||||
$this->backends[$storageType] = [];
|
||||
|
|
@ -87,11 +95,7 @@ class VersionManager implements IVersionManager, IDeletableVersionBackend, INeed
|
|||
$result = self::handleAppLocks(fn (): ?bool => $backend->rollback($version));
|
||||
// rollback doesn't have a return type yet and some implementations don't return anything
|
||||
if ($result === null || $result === true) {
|
||||
\OC_Hook::emit('\OCP\Versions', 'rollback', [
|
||||
'path' => $version->getVersionPath(),
|
||||
'revision' => $version->getRevisionId(),
|
||||
'node' => $version->getSourceFile(),
|
||||
]);
|
||||
$this->dispatcher->dispatchTyped(new VersionRestoredEvent($version));
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,11 @@ declare(strict_types=1);
|
|||
namespace OCA\files_versions\tests\Versions;
|
||||
|
||||
use OC\Files\Storage\Local;
|
||||
use OCA\Files_Versions\Events\VersionRestoredEvent;
|
||||
use OCA\Files_Versions\Versions\IVersion;
|
||||
use OCA\Files_Versions\Versions\IVersionBackend;
|
||||
use OCA\Files_Versions\Versions\VersionManager;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Files\Storage\IStorage;
|
||||
use Test\TestCase;
|
||||
|
||||
|
|
@ -30,7 +33,8 @@ class VersionManagerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetBackendSingle(): void {
|
||||
$manager = new VersionManager();
|
||||
$dispatcher = $this->createMock(IEventDispatcher::class);
|
||||
$manager = new VersionManager($dispatcher);
|
||||
$backend = $this->getBackend();
|
||||
$manager->registerBackend(IStorage::class, $backend);
|
||||
|
||||
|
|
@ -38,7 +42,8 @@ class VersionManagerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetBackendMoreSpecific(): void {
|
||||
$manager = new VersionManager();
|
||||
$dispatcher = $this->createMock(IEventDispatcher::class);
|
||||
$manager = new VersionManager($dispatcher);
|
||||
$backend1 = $this->getBackend();
|
||||
$backend2 = $this->getBackend();
|
||||
$manager->registerBackend(IStorage::class, $backend1);
|
||||
|
|
@ -48,7 +53,8 @@ class VersionManagerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetBackendNoUse(): void {
|
||||
$manager = new VersionManager();
|
||||
$dispatcher = $this->createMock(IEventDispatcher::class);
|
||||
$manager = new VersionManager($dispatcher);
|
||||
$backend1 = $this->getBackend();
|
||||
$backend2 = $this->getBackend(false);
|
||||
$manager->registerBackend(IStorage::class, $backend1);
|
||||
|
|
@ -58,7 +64,8 @@ class VersionManagerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetBackendMultiple(): void {
|
||||
$manager = new VersionManager();
|
||||
$dispatcher = $this->createMock(IEventDispatcher::class);
|
||||
$manager = new VersionManager($dispatcher);
|
||||
$backend1 = $this->getBackend();
|
||||
$backend2 = $this->getBackend(false);
|
||||
$backend3 = $this->getBackend();
|
||||
|
|
@ -68,4 +75,65 @@ class VersionManagerTest extends TestCase {
|
|||
|
||||
$this->assertEquals($backend3, $manager->getBackendForStorage($this->getStorage(Local::class)));
|
||||
}
|
||||
|
||||
public function testRollbackSuccess(): void {
|
||||
$versionMock = $this->createMock(IVersion::class);
|
||||
$backendMock = $this->createMock(IVersionBackend::class);
|
||||
|
||||
$backendMock->expects($this->once())
|
||||
->method('rollback')
|
||||
->with($versionMock)
|
||||
->willReturn(true);
|
||||
|
||||
$versionMock->method('getBackend')->willReturn($backendMock);
|
||||
|
||||
$dispatcherMock = $this->createMock(IEventDispatcher::class);
|
||||
$dispatcherMock->expects($this->once())
|
||||
->method('dispatchTyped')
|
||||
->with($this->isInstanceOf(VersionRestoredEvent::class));
|
||||
|
||||
$manager = new VersionManager($dispatcherMock);
|
||||
|
||||
$this->assertTrue($manager->rollback($versionMock));
|
||||
}
|
||||
|
||||
public function testRollbackNull(): void {
|
||||
$versionMock = $this->createMock(IVersion::class);
|
||||
$backendMock = $this->createMock(IVersionBackend::class);
|
||||
|
||||
$backendMock->expects($this->once())
|
||||
->method('rollback')
|
||||
->with($versionMock)
|
||||
->willReturn(null);
|
||||
|
||||
$versionMock->method('getBackend')->willReturn($backendMock);
|
||||
|
||||
$dispatcherMock = $this->createMock(IEventDispatcher::class);
|
||||
$dispatcherMock->expects($this->once())
|
||||
->method('dispatchTyped')
|
||||
->with($this->isInstanceOf(VersionRestoredEvent::class));
|
||||
|
||||
$manager = new VersionManager($dispatcherMock);
|
||||
|
||||
$this->assertNull($manager->rollback($versionMock));
|
||||
}
|
||||
|
||||
public function testRollbackFailure(): void {
|
||||
$versionMock = $this->createMock(IVersion::class);
|
||||
$backendMock = $this->createMock(IVersionBackend::class);
|
||||
|
||||
$backendMock->expects($this->once())
|
||||
->method('rollback')
|
||||
->with($versionMock)
|
||||
->willReturn(false);
|
||||
|
||||
$versionMock->method('getBackend')->willReturn($backendMock);
|
||||
|
||||
$dispatcherMock = $this->createMock(IEventDispatcher::class);
|
||||
$dispatcherMock->expects($this->never())->method('dispatchTyped');
|
||||
|
||||
$manager = new VersionManager($dispatcherMock);
|
||||
|
||||
$this->assertFalse($manager->rollback($versionMock));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue