aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2024-10-15 20:22:33 +0200
committerFerdinand Thiessen <opensource@fthiessen.de>2024-10-15 20:33:45 +0200
commit9a7e1bb2276f4a4635cd330fbc2a385ebaeed5ee (patch)
treee33bb863c02fc890f596a64354fc440278e67b30 /lib
parentcd3dc1719b8e84526f2c99634f0dc8bf16380579 (diff)
downloadnextcloud-server-9a7e1bb2276f4a4635cd330fbc2a385ebaeed5ee.tar.gz
nextcloud-server-9a7e1bb2276f4a4635cd330fbc2a385ebaeed5ee.zip
feat(DeclarativeSettings): Allow to implement value getter and setter directly in Form
Instead of implementing the form class, a setter event listener and a getter event listener, this allows to simply write a basic class that provides `getSchema`, `setValue` and `getValue` functions. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Settings/DeclarativeManager.php53
-rw-r--r--lib/public/Settings/DeclarativeSettingsTypes.php6
-rw-r--r--lib/public/Settings/IDeclarativeSettingsFormWithHandlers.php31
5 files changed, 79 insertions, 13 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 1219c0f5aa4..545c33f2572 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -698,6 +698,7 @@ return array(
'OCP\\Settings\\Events\\DeclarativeSettingsSetValueEvent' => $baseDir . '/lib/public/Settings/Events/DeclarativeSettingsSetValueEvent.php',
'OCP\\Settings\\IDeclarativeManager' => $baseDir . '/lib/public/Settings/IDeclarativeManager.php',
'OCP\\Settings\\IDeclarativeSettingsForm' => $baseDir . '/lib/public/Settings/IDeclarativeSettingsForm.php',
+ 'OCP\\Settings\\IDeclarativeSettingsFormWithHandlers' => $baseDir . '/lib/public/Settings/IDeclarativeSettingsFormWithHandlers.php',
'OCP\\Settings\\IDelegatedSettings' => $baseDir . '/lib/public/Settings/IDelegatedSettings.php',
'OCP\\Settings\\IIconSection' => $baseDir . '/lib/public/Settings/IIconSection.php',
'OCP\\Settings\\IManager' => $baseDir . '/lib/public/Settings/IManager.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 0e93ee8addd..fcb2a0cd8c9 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -731,6 +731,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Settings\\Events\\DeclarativeSettingsSetValueEvent' => __DIR__ . '/../../..' . '/lib/public/Settings/Events/DeclarativeSettingsSetValueEvent.php',
'OCP\\Settings\\IDeclarativeManager' => __DIR__ . '/../../..' . '/lib/public/Settings/IDeclarativeManager.php',
'OCP\\Settings\\IDeclarativeSettingsForm' => __DIR__ . '/../../..' . '/lib/public/Settings/IDeclarativeSettingsForm.php',
+ 'OCP\\Settings\\IDeclarativeSettingsFormWithHandlers' => __DIR__ . '/../../..' . '/lib/public/Settings/IDeclarativeSettingsFormWithHandlers.php',
'OCP\\Settings\\IDelegatedSettings' => __DIR__ . '/../../..' . '/lib/public/Settings/IDelegatedSettings.php',
'OCP\\Settings\\IIconSection' => __DIR__ . '/../../..' . '/lib/public/Settings/IIconSection.php',
'OCP\\Settings\\IManager' => __DIR__ . '/../../..' . '/lib/public/Settings/IManager.php',
diff --git a/lib/private/Settings/DeclarativeManager.php b/lib/private/Settings/DeclarativeManager.php
index 5c2b868f417..ee253b86449 100644
--- a/lib/private/Settings/DeclarativeManager.php
+++ b/lib/private/Settings/DeclarativeManager.php
@@ -22,6 +22,7 @@ use OCP\Settings\Events\DeclarativeSettingsRegisterFormEvent;
use OCP\Settings\Events\DeclarativeSettingsSetValueEvent;
use OCP\Settings\IDeclarativeManager;
use OCP\Settings\IDeclarativeSettingsForm;
+use OCP\Settings\IDeclarativeSettingsFormWithHandlers;
use Psr\Log\LoggerInterface;
/**
@@ -32,6 +33,15 @@ use Psr\Log\LoggerInterface;
* @psalm-import-type DeclarativeSettingsFormSchemaWithoutValues from IDeclarativeSettingsForm
*/
class DeclarativeManager implements IDeclarativeManager {
+
+ /** @var array<string, list<IDeclarativeSettingsForm>> */
+ private array $declarativeForms = [];
+
+ /**
+ * @var array<string, list<DeclarativeSettingsFormSchemaWithoutValues>>
+ */
+ private array $appSchemas = [];
+
public function __construct(
private IEventDispatcher $eventDispatcher,
private IGroupManager $groupManager,
@@ -43,11 +53,6 @@ class DeclarativeManager implements IDeclarativeManager {
}
/**
- * @var array<string, list<DeclarativeSettingsFormSchemaWithoutValues>>
- */
- private array $appSchemas = [];
-
- /**
* @inheritdoc
*/
public function registerSchema(string $app, array $schema): void {
@@ -77,11 +82,15 @@ class DeclarativeManager implements IDeclarativeManager {
* @inheritdoc
*/
public function loadSchemas(): void {
- $declarativeSettings = $this->coordinator->getRegistrationContext()->getDeclarativeSettings();
- foreach ($declarativeSettings as $declarativeSetting) {
- /** @var IDeclarativeSettingsForm $declarativeSettingObject */
- $declarativeSettingObject = Server::get($declarativeSetting->getService());
- $this->registerSchema($declarativeSetting->getAppId(), $declarativeSettingObject->getSchema());
+ if (empty($this->declarativeForms)) {
+ $declarativeSettings = $this->coordinator->getRegistrationContext()->getDeclarativeSettings();
+ foreach ($declarativeSettings as $declarativeSetting) {
+ $app = $declarativeSetting->getAppId();
+ /** @var IDeclarativeSettingsForm $declarativeForm */
+ $declarativeForm = Server::get($declarativeSetting->getService());
+ $this->registerSchema($app, $declarativeForm->getSchema());
+ $this->declarativeForms[$app][] = $declarativeForm;
+ }
}
$this->eventDispatcher->dispatchTyped(new DeclarativeSettingsRegisterFormEvent($this));
@@ -224,6 +233,10 @@ class DeclarativeManager implements IDeclarativeManager {
$storageType = $this->getStorageType($app, $fieldId);
switch ($storageType) {
case DeclarativeSettingsTypes::STORAGE_TYPE_EXTERNAL:
+ $form = $this->getForm($app, $formId);
+ if ($form !== null && $form instanceof IDeclarativeSettingsFormWithHandlers) {
+ return $form->getValue($fieldId, $user);
+ }
$event = new DeclarativeSettingsGetValueEvent($user, $app, $formId, $fieldId);
$this->eventDispatcher->dispatchTyped($event);
return $event->getValue();
@@ -244,6 +257,12 @@ class DeclarativeManager implements IDeclarativeManager {
$storageType = $this->getStorageType($app, $fieldId);
switch ($storageType) {
case DeclarativeSettingsTypes::STORAGE_TYPE_EXTERNAL:
+ $form = $this->getForm($app, $formId);
+ if ($form !== null && $form instanceof IDeclarativeSettingsFormWithHandlers) {
+ $form->setValue($fieldId, $value, $user);
+ break;
+ }
+ // fall back to event handling
$this->eventDispatcher->dispatchTyped(new DeclarativeSettingsSetValueEvent($user, $app, $formId, $fieldId, $value));
break;
case DeclarativeSettingsTypes::STORAGE_TYPE_INTERNAL:
@@ -254,6 +273,20 @@ class DeclarativeManager implements IDeclarativeManager {
}
}
+ /**
+ * If a declarative setting was registered as a form and not just a schema
+ * then this will yield the registering form.
+ */
+ private function getForm(string $app, string $formId): ?IDeclarativeSettingsForm {
+ $allForms = $this->declarativeForms[$app] ?? [];
+ foreach ($allForms as $form) {
+ if ($form->getSchema()['id'] === $formId) {
+ return $form;
+ }
+ }
+ return null;
+ }
+
private function getInternalValue(IUser $user, string $app, string $formId, string $fieldId): mixed {
$sectionType = $this->getSectionType($app, $fieldId);
$defaultValue = $this->getDefaultValue($app, $formId, $fieldId);
diff --git a/lib/public/Settings/DeclarativeSettingsTypes.php b/lib/public/Settings/DeclarativeSettingsTypes.php
index 82444af9b82..7edf0cbdd6e 100644
--- a/lib/public/Settings/DeclarativeSettingsTypes.php
+++ b/lib/public/Settings/DeclarativeSettingsTypes.php
@@ -32,8 +32,9 @@ final class DeclarativeSettingsTypes {
/**
* IDeclarativeSettingsForm storage_type which is determines where and how the config value is stored
*
- *
- * For `external` storage_type the app implementing \OCP\Settings\SetDeclarativeSettingsValueEvent and \OCP\Settings\GetDeclarativeSettingsValueEvent events is responsible for storing and retrieving the config value.
+ * For `external` storage_type the app needs to either implement event listeners for \OCP\Settings\SetDeclarativeSettingsValueEvent
+ * and \OCP\Settings\GetDeclarativeSettingsValueEvent or the IDeclarativeSettingsForm also needs to implement
+ * IDeclarativeSettingsFormWithHandlers for storing and retrieving the config value.
*
* @since 29.0.0
*/
@@ -43,7 +44,6 @@ final class DeclarativeSettingsTypes {
* IDeclarativeSettingsForm storage_type which is determines where and how the config value is stored
*
* For `internal` storage_type the config value is stored in default `appconfig` and `preferences` tables.
- * For `external` storage_type the app implementing \OCP\Settings\SetDeclarativeSettingsValueEvent and \OCP\Settings\GetDeclarativeSettingsValueEvent events is responsible for storing and retrieving the config value.
*
* @since 29.0.0
*/
diff --git a/lib/public/Settings/IDeclarativeSettingsFormWithHandlers.php b/lib/public/Settings/IDeclarativeSettingsFormWithHandlers.php
new file mode 100644
index 00000000000..180df73d995
--- /dev/null
+++ b/lib/public/Settings/IDeclarativeSettingsFormWithHandlers.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\Settings;
+
+use OCP\IUser;
+
+/**
+ * @since 31.0.0
+ */
+interface IDeclarativeSettingsFormWithHandlers extends IDeclarativeSettingsForm {
+
+ /**
+ * This function is called to get the current value of a specific forms field.
+ * @since 31.0.0
+ */
+ public function getValue(string $fieldId, IUser $user): mixed;
+
+ /**
+ * This function is called when a user updated a form field to persist the setting.
+ * @since 31.0.0
+ */
+ public function setValue(string $fieldId, mixed $value, IUser $user): void;
+
+}