diff options
author | jld3103 <jld3103yt@gmail.com> | 2023-12-07 16:39:16 +0100 |
---|---|---|
committer | Andrey Borysenko <andrey18106x@gmail.com> | 2024-03-12 13:56:54 +0200 |
commit | 4ac2375ca2082750432ccc9cff46bf5888b4db30 (patch) | |
tree | bca24a21f4dfa0184f8e400e9508fc5600ade8d4 /lib/public | |
parent | c42397358f05aa60ae91ed11e7754fddba182cce (diff) | |
download | nextcloud-server-4ac2375ca2082750432ccc9cff46bf5888b4db30.tar.gz nextcloud-server-4ac2375ca2082750432ccc9cff46bf5888b4db30.zip |
feat: Add declarative settings
Signed-off-by: jld3103 <jld3103yt@gmail.com>
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
Signed-off-by: Andrey Borysenko <andrey18106x@gmail.com>
Diffstat (limited to 'lib/public')
7 files changed, 496 insertions, 0 deletions
diff --git a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php index f515180cef5..09bc703e0a4 100644 --- a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php +++ b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php @@ -399,4 +399,15 @@ interface IRegistrationContext { * @since 28.0.0 */ public function registerSetupCheck(string $setupCheckClass): void; + + /** + * Register an implementation of \OCP\Settings\IDeclarativeSettings that + * will handle the implementation of declarative settings + * + * @param string $declarativeSettingsClass + * @psalm-param class-string<\OCP\Settings\IDeclarativeSettingsForm> $declarativeSettingsClass + * @return void + * @since 29.0.0 + */ + public function registerDeclarativeSettings(string $declarativeSettingsClass): void; } diff --git a/lib/public/Settings/DeclarativeSettingsTypes.php b/lib/public/Settings/DeclarativeSettingsTypes.php new file mode 100644 index 00000000000..01e20ee7cc9 --- /dev/null +++ b/lib/public/Settings/DeclarativeSettingsTypes.php @@ -0,0 +1,145 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Andrey Borysenko <andrey.borysenko@nextcloud.com> + * + * @author Andrey Borysenko <andrey.borysenko@nextcloud.com> + * + * @license GNU AGPL version 3 or any later version + * + * 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 OCP\Settings; + +/** + * Declarative settings types supported in the IDeclarativeSettingsForm forms + * + * @since 29.0.0 + */ +final class DeclarativeSettingsTypes { + /** + * IDeclarativeSettingsForm section_type which is determines where the form is displayed + * + * @since 29.0.0 + */ + public const SECTION_TYPE_ADMIN = 'admin'; + + /** + * IDeclarativeSettingsForm section_type which is determines where the form is displayed + * + * @since 29.0.0 + */ + public const SECTION_TYPE_PERSONAL = 'personal'; + + /** + * 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. + * + * @since 29.0.0 + */ + public const STORAGE_TYPE_EXTERNAL = 'external'; + + /** + * 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 + */ + public const STORAGE_TYPE_INTERNAL = 'internal'; + + /** + * NcInputField type text + * + * @since 29.0.0 + */ + public const TEXT = 'text'; + + /** + * NcInputField type password + * + * @since 29.0.0 + */ + public const PASSWORD = 'password'; + + /** + * NcInputField type email + * + * @since 29.0.0 + */ + public const EMAIL = 'email'; + + /** + * NcInputField type tel + * + * @since 29.0.0 + */ + public const TEL = 'tel'; + + /** + * NcInputField type url + * + * @since 29.0.0 + */ + public const URL = 'url'; + + /** + * NcInputField type number + * + * @since 29.0.0 + */ + public const NUMBER = 'number'; + + /** + * NcCheckboxRadioSwitch type checkbox + * + * @since 29.0.0 + */ + public const CHECKBOX = 'checkbox'; + + /** + * Multiple NcCheckboxRadioSwitch type checkbox representing a one config value (saved as JSON object) + * + * @since 29.0.0 + */ + public const MULTI_CHECKBOX = 'multi-checkbox'; + + /** + * NcCheckboxRadioSwitch type radio + * + * @since 29.0.0 + */ + public const RADIO = 'radio'; + + /** + * NcSelect + * + * @since 29.0.0 + */ + public const SELECT = 'select'; + + /** + * Multiple NcSelect representing a one config value (saved as JSON array) + * + * @since 29.0.0 + */ + public const MULTI_SELECT = 'multi-select'; +} diff --git a/lib/public/Settings/Events/DeclarativeSettingsGetValueEvent.php b/lib/public/Settings/Events/DeclarativeSettingsGetValueEvent.php new file mode 100644 index 00000000000..c7224f761fd --- /dev/null +++ b/lib/public/Settings/Events/DeclarativeSettingsGetValueEvent.php @@ -0,0 +1,81 @@ +<?php + +namespace OCP\Settings\Events; + +use Exception; +use OCP\EventDispatcher\Event; +use OCP\IUser; +use OCP\Settings\IDeclarativeSettingsForm; + +/** + * @psalm-import-type DeclarativeSettingsValueTypes from IDeclarativeSettingsForm + * + * @since 29.0.0 + */ +class DeclarativeSettingsGetValueEvent extends Event { + /** + * @var ?DeclarativeSettingsValueTypes + */ + private mixed $value = null; + + /** + * @since 29.0.0 + */ + public function __construct( + private IUser $user, + private string $app, + private string $formId, + private string $fieldId, + ) { + parent::__construct(); + } + + /** + * @since 29.0.0 + */ + public function getUser(): IUser { + return $this->user; + } + + /** + * @since 29.0.0 + */ + public function getApp(): string { + return $this->app; + } + + /** + * @since 29.0.0 + */ + public function getFormId(): string { + return $this->formId; + } + + /** + * @since 29.0.0 + */ + public function getFieldId(): string { + return $this->fieldId; + } + + /** + * @since 29.0.0 + */ + public function setValue(mixed $value): void { + $this->value = $value; + } + + /** + * @return DeclarativeSettingsValueTypes + * @throws Exception + * + * @since 29.0.0 + */ + public function getValue(): mixed { + if ($this->value === null) { + throw new Exception('Value not set'); + } + + return $this->value; + } +} diff --git a/lib/public/Settings/Events/DeclarativeSettingsRegisterFormEvent.php b/lib/public/Settings/Events/DeclarativeSettingsRegisterFormEvent.php new file mode 100644 index 00000000000..d017596e545 --- /dev/null +++ b/lib/public/Settings/Events/DeclarativeSettingsRegisterFormEvent.php @@ -0,0 +1,29 @@ +<?php + +namespace OCP\Settings\Events; + +use OCP\EventDispatcher\Event; +use OCP\Settings\IDeclarativeManager; +use OCP\Settings\IDeclarativeSettingsForm; + +/** + * @psalm-import-type DeclarativeSettingsFormSchemaWithoutValues from IDeclarativeSettingsForm + * + * @since 29.0.0 + */ +class DeclarativeSettingsRegisterFormEvent extends Event { + /** + * @since 29.0.0 + */ + public function __construct(private IDeclarativeManager $manager) { + parent::__construct(); + } + + /** + * @param DeclarativeSettingsFormSchemaWithoutValues $schema + * @since 29.0.0 + */ + public function registerSchema(string $app, array $schema): void { + $this->manager->registerSchema($app, $schema); + } +} diff --git a/lib/public/Settings/Events/DeclarativeSettingsSetValueEvent.php b/lib/public/Settings/Events/DeclarativeSettingsSetValueEvent.php new file mode 100644 index 00000000000..d298c1ec9b4 --- /dev/null +++ b/lib/public/Settings/Events/DeclarativeSettingsSetValueEvent.php @@ -0,0 +1,63 @@ +<?php + +namespace OCP\Settings\Events; + +use OCP\EventDispatcher\Event; +use OCP\IUser; +use OCP\Settings\IDeclarativeSettingsForm; + +/** + * @psalm-import-type DeclarativeSettingsValueTypes from IDeclarativeSettingsForm + * + * @since 29.0.0 + */ +class DeclarativeSettingsSetValueEvent extends Event { + /** + * @param DeclarativeSettingsValueTypes $value + * @since 29.0.0 + */ + public function __construct( + private IUser $user, + private string $app, + private string $formId, + private string $fieldId, + private mixed $value, + ) { + parent::__construct(); + } + + /** + * @since 29.0.0 + */ + public function getUser(): IUser { + return $this->user; + } + + /** + * @since 29.0.0 + */ + public function getApp(): string { + return $this->app; + } + + /** + * @since 29.0.0 + */ + public function getFormId(): string { + return $this->formId; + } + + /** + * @since 29.0.0 + */ + public function getFieldId(): string { + return $this->fieldId; + } + + /** + * @since 29.0.0 + */ + public function getValue(): mixed { + return $this->value; + } +} diff --git a/lib/public/Settings/IDeclarativeManager.php b/lib/public/Settings/IDeclarativeManager.php new file mode 100644 index 00000000000..586296bac13 --- /dev/null +++ b/lib/public/Settings/IDeclarativeManager.php @@ -0,0 +1,89 @@ +<?php +/** + * @copyright Copyright (c) 2023 Kate Döen <kate.doeen@nextcloud.com> + * + * @author Kate Döen <kate.doeen@nextcloud.com> + * + * @license GNU AGPL version 3 or any later version + * + * 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 OCP\Settings; + +use Exception; +use OC\AppFramework\Middleware\Security\Exceptions\NotAdminException; +use OCP\IUser; + +/** + * @since 29.0.0 + * + * @psalm-import-type DeclarativeSettingsValueTypes from IDeclarativeSettingsForm + * @psalm-import-type DeclarativeSettingsSectionType from IDeclarativeSettingsForm + * @psalm-import-type DeclarativeSettingsFormSchemaWithValues from IDeclarativeSettingsForm + * @psalm-import-type DeclarativeSettingsFormSchemaWithoutValues from IDeclarativeSettingsForm + */ +interface IDeclarativeManager { + /** + * Registers a new declarative settings schema. + * + * @param DeclarativeSettingsFormSchemaWithoutValues $schema + * @since 29.0.0 + */ + public function registerSchema(string $app, array $schema): void; + + /** + * Load all schemas from the registration context and events. + * + * @since 29.0.0 + */ + public function loadSchemas(): void; + + /** + * Gets the IDs of the forms for the given type and section. + * + * @param DeclarativeSettingsSectionType $type + * @param string $section + * @return array<string, list<string>> + * + * @since 29.0.0 + */ + public function getFormIDs(IUser $user, string $type, string $section): array; + + /** + * Gets the forms including the field values for the given type and section. + * + * @param IUser $user Used for reading values from the personal section or for authorization for the admin section. + * @param ?DeclarativeSettingsSectionType $type If it is null the forms will not be filtered by type. + * @param ?string $section If it is null the forms will not be filtered by section. + * @return list<DeclarativeSettingsFormSchemaWithValues> + * + * @since 29.0.0 + */ + public function getFormsWithValues(IUser $user, ?string $type, ?string $section): array; + + /** + * Sets a value for the given field ID. + * + * @param IUser $user Used for storing values in the personal section or for authorization for the admin section. + * @param DeclarativeSettingsValueTypes $value + * + * @throws Exception + * @throws NotAdminException + * + * @since 29.0.0 + */ + public function setValue(IUser $user, string $app, string $formId, string $fieldId, mixed $value): void; +} diff --git a/lib/public/Settings/IDeclarativeSettingsForm.php b/lib/public/Settings/IDeclarativeSettingsForm.php new file mode 100644 index 00000000000..fd9fe120f6f --- /dev/null +++ b/lib/public/Settings/IDeclarativeSettingsForm.php @@ -0,0 +1,78 @@ +<?php +/** + * @copyright Copyright (c) 2023 Kate Döen <kate.doeen@nextcloud.com> + * + * @author Kate Döen <kate.doeen@nextcloud.com> + * + * @license GNU AGPL version 3 or any later version + * + * 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 OCP\Settings; + +/** + * @since 29.0.0 + * + * @psalm-type DeclarativeSettingsSectionType = 'admin'|'personal' + * + * @psalm-type DeclarativeSettingsStorageType = 'internal'|'external' + * + * @psalm-type DeclarativeSettingsValueTypes = string|int|float|bool|list<string> + * + * @psalm-type DeclarativeSettingsFormField = array{ + * id: string, + * title: string, + * description?: string, + * type: 'text'|'password'|'email'|'tel'|'url'|'number'|'checkbox'|'multi-checkbox'|'radio'|'select'|'multi-select', + * placeholder?: string, + * label?: string, + * default: mixed, + * options?: list<string|array{name: string, value: mixed}>, + * } + * + * @psalm-type DeclarativeSettingsFormFieldWithValue = DeclarativeSettingsFormField&array{ + * value: DeclarativeSettingsValueTypes, + * } + * + * @psalm-type DeclarativeSettingsFormSchema = array{ + * id: string, + * priority: int, + * section_type: DeclarativeSettingsSectionType, + * section_id: string, + * storage_type: DeclarativeSettingsStorageType, + * title: string, + * description?: string, + * doc_url?: string, + * } + * + * @psalm-type DeclarativeSettingsFormSchemaWithValues = DeclarativeSettingsFormSchema&array{ + * app: string, + * fields: list<DeclarativeSettingsFormFieldWithValue>, + * } + * + * @psalm-type DeclarativeSettingsFormSchemaWithoutValues = DeclarativeSettingsFormSchema&array{ + * fields: list<DeclarativeSettingsFormField>, + * } + */ +interface IDeclarativeSettingsForm { + /** + * Gets the schema that defines the declarative settings form + * + * @return DeclarativeSettingsFormSchemaWithoutValues + * @since 29.0.0 + */ + public function getSchema(): array; +} |