Files
Ferdinand Thiessen 2f73fb2696 chore(files_versions): drop the deprecated \OCP\Versions rollback hook
The listener only bridged VersionRestoredEvent to the legacy hook, was
deprecated in 32.0.0 as "removed in the next version", and has no
listeners left. The typed event keeps its consumers.

Assisted-by: ClaudeCode:claude-opus-5
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2026-09-16 11:52:28 +02:00

135 lines
5.7 KiB
PHP

<?php
/**
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Files_Versions\AppInfo;
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\CreateVersionEvent;
use OCA\Files_Versions\Listener\CreateVersionListenerForWorkflow;
use OCA\Files_Versions\Listener\FileEventsListener;
use OCA\Files_Versions\Listener\LoadAdditionalListener;
use OCA\Files_Versions\Listener\LoadSidebarListener;
use OCA\Files_Versions\Listener\RegisterWorkflowIntegrationListener;
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\App\IAppManager;
use OCP\AppFramework\App;
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\BeforeNodeWrittenEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\Node\NodeCreatedEvent;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\NodeTouchedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\WorkflowEngine\Events\LoadSettingsScriptsEvent;
use OCP\WorkflowEngine\Events\RegisterOperationsEvent;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
class Application extends App implements IBootstrap {
public const APP_ID = 'files_versions';
public function __construct(array $urlParams = []) {
parent::__construct(self::APP_ID, $urlParams);
}
#[\Override]
public function register(IRegistrationContext $context): void {
/**
* Register capabilities
*/
$context->registerCapability(Capabilities::class);
/**
* Register $principalBackend for the DAV collection
*/
$context->registerServiceAlias('principalBackend', Principal::class);
$context->registerServiceAlias(IVersionManager::class, VersionManager::class);
/**
* Register Events
*/
$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);
$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);
// we add the version author listener with lower priority to make sure new versions already are created by FileEventsListener
$context->registerEventListener(NodeWrittenEvent::class, VersionAuthorListener::class, -1);
// WFE integration
$context->registerEventListener(RegisterOperationsEvent::class, RegisterWorkflowIntegrationListener::class);
$context->registerEventListener(LoadSettingsScriptsEvent::class, RegisterWorkflowIntegrationListener::class);
$context->registerEventListener(CreateVersionEvent::class, CreateVersionListenerForWorkflow::class);
}
#[\Override]
public function boot(IBootContext $context): void {
$context->injectFn(\Closure::fromCallable([$this, 'registerVersionBackends']));
}
public function registerVersionBackends(ContainerInterface $container, IAppManager $appManager, LoggerInterface $logger): void {
foreach ($appManager->getEnabledApps() as $app) {
$appInfo = $appManager->getAppInfo($app);
if (isset($appInfo['versions'])) {
$backends = $appInfo['versions'];
foreach ($backends as $backend) {
if (isset($backend['@value'])) {
$this->loadBackend($backend, $container, $logger);
} else {
foreach ($backend as $singleBackend) {
$this->loadBackend($singleBackend, $container, $logger);
}
}
}
}
}
}
private function loadBackend(array $backend, ContainerInterface $container, LoggerInterface $logger): void {
/** @var IVersionManager $versionManager */
$versionManager = $container->get(IVersionManager::class);
$class = $backend['@value'];
$for = $backend['@attributes']['for'];
try {
$backendObject = $container->get($class);
$versionManager->registerBackend($for, $backendObject);
} catch (\Exception $e) {
$logger->error($e->getMessage(), ['exception' => $e]);
}
}
}