diff --git a/apps/settings/appinfo/info.xml b/apps/settings/appinfo/info.xml index aa5fdfdcf81..69489e8ef2a 100644 --- a/apps/settings/appinfo/info.xml +++ b/apps/settings/appinfo/info.xml @@ -35,7 +35,6 @@ OCA\Settings\Settings\Admin\Sharing OCA\Settings\Settings\Admin\Security OCA\Settings\Settings\Admin\Delegation - OCA\Settings\Settings\Admin\Users OCA\Settings\Sections\Admin\Additional OCA\Settings\Sections\Admin\Delegation OCA\Settings\Sections\Admin\Groupware @@ -45,6 +44,8 @@ OCA\Settings\Sections\Admin\Security OCA\Settings\Sections\Admin\Server OCA\Settings\Sections\Admin\Sharing + OCA\Settings\Settings\Admin\Users + OCA\Settings\Sections\Admin\Users OCA\Settings\Settings\Personal\Additional OCA\Settings\Settings\Personal\PersonalInfo OCA\Settings\Settings\Personal\ServerDevNotice diff --git a/apps/settings/composer/composer/autoload_classmap.php b/apps/settings/composer/composer/autoload_classmap.php index b12f345e05b..8c90376d79c 100644 --- a/apps/settings/composer/composer/autoload_classmap.php +++ b/apps/settings/composer/composer/autoload_classmap.php @@ -60,6 +60,7 @@ return array( 'OCA\\Settings\\Sections\\Admin\\Security' => $baseDir . '/../lib/Sections/Admin/Security.php', 'OCA\\Settings\\Sections\\Admin\\Server' => $baseDir . '/../lib/Sections/Admin/Server.php', 'OCA\\Settings\\Sections\\Admin\\Sharing' => $baseDir . '/../lib/Sections/Admin/Sharing.php', + 'OCA\\Settings\\Sections\\Admin\\Users' => $baseDir . '/../lib/Sections/Admin/Users.php', 'OCA\\Settings\\Sections\\Personal\\Availability' => $baseDir . '/../lib/Sections/Personal/Availability.php', 'OCA\\Settings\\Sections\\Personal\\Calendar' => $baseDir . '/../lib/Sections/Personal/Calendar.php', 'OCA\\Settings\\Sections\\Personal\\PersonalInfo' => $baseDir . '/../lib/Sections/Personal/PersonalInfo.php', diff --git a/apps/settings/composer/composer/autoload_static.php b/apps/settings/composer/composer/autoload_static.php index e6e2ed9f45c..cf6ebfacba8 100644 --- a/apps/settings/composer/composer/autoload_static.php +++ b/apps/settings/composer/composer/autoload_static.php @@ -75,6 +75,7 @@ class ComposerStaticInitSettings 'OCA\\Settings\\Sections\\Admin\\Security' => __DIR__ . '/..' . '/../lib/Sections/Admin/Security.php', 'OCA\\Settings\\Sections\\Admin\\Server' => __DIR__ . '/..' . '/../lib/Sections/Admin/Server.php', 'OCA\\Settings\\Sections\\Admin\\Sharing' => __DIR__ . '/..' . '/../lib/Sections/Admin/Sharing.php', + 'OCA\\Settings\\Sections\\Admin\\Users' => __DIR__ . '/..' . '/../lib/Sections/Admin/Users.php', 'OCA\\Settings\\Sections\\Personal\\Availability' => __DIR__ . '/..' . '/../lib/Sections/Personal/Availability.php', 'OCA\\Settings\\Sections\\Personal\\Calendar' => __DIR__ . '/..' . '/../lib/Sections/Personal/Calendar.php', 'OCA\\Settings\\Sections\\Personal\\PersonalInfo' => __DIR__ . '/..' . '/../lib/Sections/Personal/PersonalInfo.php', diff --git a/apps/settings/lib/Sections/Admin/Users.php b/apps/settings/lib/Sections/Admin/Users.php new file mode 100644 index 00000000000..d5e080331e8 --- /dev/null +++ b/apps/settings/lib/Sections/Admin/Users.php @@ -0,0 +1,36 @@ +l->t('Users'); + } + + public function getPriority(): int { + return 55; + } + + public function getIcon(): string { + return ''; + } +} diff --git a/apps/settings/lib/Settings/Admin/Delegation.php b/apps/settings/lib/Settings/Admin/Delegation.php index 59a26d1ac04..06ff2af9447 100644 --- a/apps/settings/lib/Settings/Admin/Delegation.php +++ b/apps/settings/lib/Settings/Admin/Delegation.php @@ -45,32 +45,19 @@ class Delegation implements ISettings { private function initSettingState(): void { // Available settings page initialization - $sections = $this->settingManager->getAdminSections(); + $delegatedSettings = $this->settingManager->getAdminDelegatedSettings(); $settings = []; - foreach ($sections as $sectionPriority) { - foreach ($sectionPriority as $section) { - $sectionSettings = $this->settingManager->getAdminSettings($section->getId()); - $sectionSettings = array_reduce($sectionSettings, [$this, 'getDelegatedSettings'], []); - $settings = array_merge( - $settings, - array_map(function (IDelegatedSettings $setting) use ($section) { - $sectionName = $section->getName() . ($setting->getName() !== null ? ' - ' . $setting->getName() : ''); - return [ - 'class' => get_class($setting), - 'sectionName' => $sectionName, - 'id' => mb_strtolower(str_replace(' ', '-', $sectionName)), - 'priority' => $section->getPriority(), - ]; - }, $sectionSettings) - ); + foreach ($delegatedSettings as ['section' => $section, 'settings' => $sectionSettings]) { + foreach ($sectionSettings as $setting) { + $sectionName = $section->getName() . ($setting->getName() !== null ? ' - ' . $setting->getName() : ''); + $settings[] = [ + 'class' => get_class($setting), + 'sectionName' => $sectionName, + 'id' => mb_strtolower(str_replace(' ', '-', $sectionName)), + 'priority' => $section->getPriority(), + ]; } } - usort($settings, function (array $a, array $b) { - if ($a['priority'] == $b['priority']) { - return 0; - } - return ($a['priority'] < $b['priority']) ? -1 : 1; - }); $this->initialStateService->provideInitialState('available-settings', $settings); } diff --git a/apps/settings/lib/Settings/Admin/Users.php b/apps/settings/lib/Settings/Admin/Users.php index c569890a0dc..8e45216b9c4 100644 --- a/apps/settings/lib/Settings/Admin/Users.php +++ b/apps/settings/lib/Settings/Admin/Users.php @@ -10,49 +10,27 @@ declare(strict_types=1); namespace OCA\Settings\Settings\Admin; use OCP\AppFramework\Http\TemplateResponse; -use OCP\IL10N; use OCP\Settings\IDelegatedSettings; /** * Empty settings class, used only for admin delegation. */ class Users implements IDelegatedSettings { - - public function __construct( - protected string $appName, - private IL10N $l10n, - ) { - } - - /** - * Empty template response - */ public function getForm(): TemplateResponse { - - return new /** @template-extends TemplateResponse<\OCP\AppFramework\Http::STATUS_OK, array{}> */ class($this->appName, '') extends TemplateResponse { - public function render(): string { - return ''; - } - }; + throw new \Exception('Admin delegation settings should never be rendered'); } public function getSection(): ?string { - return 'admindelegation'; + return 'usersdelegation'; } - /** - * @return int whether the form should be rather on the top or bottom of - * the admin section. The forms are arranged in ascending order of the - * priority values. It is required to return a value between 0 and 100. - * - * E.g.: 70 - */ public function getPriority(): int { return 0; } - public function getName(): string { - return $this->l10n->t('Users'); + public function getName(): ?string { + /* Use section name alone */ + return null; } public function getAuthorizedAppConfig(): array { diff --git a/apps/webhook_listeners/appinfo/info.xml b/apps/webhook_listeners/appinfo/info.xml index 859bd010186..260f176bd5d 100644 --- a/apps/webhook_listeners/appinfo/info.xml +++ b/apps/webhook_listeners/appinfo/info.xml @@ -32,6 +32,7 @@ - OCA\WebhookListeners\Settings\Admin + OCA\WebhookListeners\Settings\Admin + OCA\WebhookListeners\Settings\AdminSection diff --git a/apps/webhook_listeners/composer/composer/autoload_classmap.php b/apps/webhook_listeners/composer/composer/autoload_classmap.php index 3a8e2fe16ae..959b4c1d2ae 100644 --- a/apps/webhook_listeners/composer/composer/autoload_classmap.php +++ b/apps/webhook_listeners/composer/composer/autoload_classmap.php @@ -20,4 +20,5 @@ return array( 'OCA\\WebhookListeners\\ResponseDefinitions' => $baseDir . '/../lib/ResponseDefinitions.php', 'OCA\\WebhookListeners\\Service\\PHPMongoQuery' => $baseDir . '/../lib/Service/PHPMongoQuery.php', 'OCA\\WebhookListeners\\Settings\\Admin' => $baseDir . '/../lib/Settings/Admin.php', + 'OCA\\WebhookListeners\\Settings\\AdminSection' => $baseDir . '/../lib/Settings/AdminSection.php', ); diff --git a/apps/webhook_listeners/composer/composer/autoload_static.php b/apps/webhook_listeners/composer/composer/autoload_static.php index d63fe31af47..b9b367315f6 100644 --- a/apps/webhook_listeners/composer/composer/autoload_static.php +++ b/apps/webhook_listeners/composer/composer/autoload_static.php @@ -35,6 +35,7 @@ class ComposerStaticInitWebhookListeners 'OCA\\WebhookListeners\\ResponseDefinitions' => __DIR__ . '/..' . '/../lib/ResponseDefinitions.php', 'OCA\\WebhookListeners\\Service\\PHPMongoQuery' => __DIR__ . '/..' . '/../lib/Service/PHPMongoQuery.php', 'OCA\\WebhookListeners\\Settings\\Admin' => __DIR__ . '/..' . '/../lib/Settings/Admin.php', + 'OCA\\WebhookListeners\\Settings\\AdminSection' => __DIR__ . '/..' . '/../lib/Settings/AdminSection.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/apps/webhook_listeners/lib/Settings/Admin.php b/apps/webhook_listeners/lib/Settings/Admin.php index 64ed53426f9..f076f348c0d 100644 --- a/apps/webhook_listeners/lib/Settings/Admin.php +++ b/apps/webhook_listeners/lib/Settings/Admin.php @@ -9,51 +9,32 @@ declare(strict_types=1); namespace OCA\WebhookListeners\Settings; -use OCP\AppFramework\Http; +use OCA\WebhookListeners\AppInfo\Application; use OCP\AppFramework\Http\TemplateResponse; -use OCP\IL10N; use OCP\Settings\IDelegatedSettings; /** * Empty settings class, used only for admin delegation for now as there is no UI */ class Admin implements IDelegatedSettings { - - public function __construct( - protected string $appName, - private IL10N $l10n, - ) { - } - /** * Empty template response */ public function getForm(): TemplateResponse { - - return new /** @template-extends TemplateResponse */ class($this->appName, '') extends TemplateResponse { - public function render(): string { - return ''; - } - }; + throw new \Exception('Admin delegation settings should never be rendered'); } - public function getSection(): ?string { - return 'admindelegation'; + public function getSection(): string { + return Application::APP_ID . '-admin'; } - /** - * @return int whether the form should be rather on the top or bottom of - * the admin section. The forms are arranged in ascending order of the - * priority values. It is required to return a value between 0 and 100. - * - * E.g.: 70 - */ public function getPriority(): int { return 0; } - public function getName(): string { - return $this->l10n->t('Webhooks'); + public function getName(): ?string { + /* Use section name alone */ + return null; } public function getAuthorizedAppConfig(): array { diff --git a/apps/webhook_listeners/lib/Settings/AdminSection.php b/apps/webhook_listeners/lib/Settings/AdminSection.php new file mode 100644 index 00000000000..84670ebb2d8 --- /dev/null +++ b/apps/webhook_listeners/lib/Settings/AdminSection.php @@ -0,0 +1,37 @@ +l->t('Webhooks'); + } + + public function getPriority(): int { + return 56; + } + + public function getIcon(): string { + return ''; + } +} diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php index 8e5f4935f05..4702aec37c1 100644 --- a/lib/private/App/AppManager.php +++ b/lib/private/App/AppManager.php @@ -502,7 +502,7 @@ class AppManager implements IAppManager { } if (!empty($info['settings'])) { - $settingsManager = \OC::$server->get(ISettingsManager::class); + $settingsManager = \OCP\Server::get(ISettingsManager::class); if (!empty($info['settings']['admin'])) { foreach ($info['settings']['admin'] as $setting) { $settingsManager->registerSetting('admin', $setting); @@ -523,6 +523,16 @@ class AppManager implements IAppManager { $settingsManager->registerSection('personal', $section); } } + if (!empty($info['settings']['admin-delegation'])) { + foreach ($info['settings']['admin-delegation'] as $setting) { + $settingsManager->registerSetting(ISettingsManager::SETTINGS_DELEGATION, $setting); + } + } + if (!empty($info['settings']['admin-delegation-section'])) { + foreach ($info['settings']['admin-delegation-section'] as $section) { + $settingsManager->registerSection(ISettingsManager::SETTINGS_DELEGATION, $section); + } + } } if (!empty($info['collaboration']['plugins'])) { diff --git a/lib/private/App/InfoParser.php b/lib/private/App/InfoParser.php index 634dc1fbdd5..677f45d7ae0 100644 --- a/lib/private/App/InfoParser.php +++ b/lib/private/App/InfoParser.php @@ -184,6 +184,12 @@ class InfoParser { if (isset($array['settings']['personal-section']) && !is_array($array['settings']['personal-section'])) { $array['settings']['personal-section'] = [$array['settings']['personal-section']]; } + if (isset($array['settings']['admin-delegation']) && !is_array($array['settings']['admin-delegation'])) { + $array['settings']['admin-delegation'] = [$array['settings']['admin-delegation']]; + } + if (isset($array['settings']['admin-delegation-section']) && !is_array($array['settings']['admin-delegation-section'])) { + $array['settings']['admin-delegation-section'] = [$array['settings']['admin-delegation-section']]; + } if (isset($array['navigations']['navigation']) && $this->isNavigationItem($array['navigations']['navigation'])) { $array['navigations']['navigation'] = [$array['navigations']['navigation']]; } diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 78dc64c3c3f..7b4dd9fcc9b 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -16,6 +16,7 @@ use OCP\IServerContainer; use OCP\IURLGenerator; use OCP\IUser; use OCP\L10N\IFactory; +use OCP\Settings\IDelegatedSettings; use OCP\Settings\IIconSection; use OCP\Settings\IManager; use OCP\Settings\ISettings; @@ -23,54 +24,31 @@ use OCP\Settings\ISubAdminSettings; use Psr\Log\LoggerInterface; class Manager implements IManager { - /** @var LoggerInterface */ - private $log; + private ?IL10N $l = null; - /** @var IL10N */ - private $l; - - /** @var IFactory */ - private $l10nFactory; - - /** @var IURLGenerator */ - private $url; - - /** @var IServerContainer */ - private $container; + /** @var array>> */ + protected array $sectionClasses = []; - /** @var AuthorizedGroupMapper $mapper */ - private $mapper; + /** @var array> */ + protected array $sections = []; - /** @var IGroupManager $groupManager */ - private $groupManager; + /** @var array, self::SETTINGS_*> */ + protected array $settingClasses = []; - /** @var ISubAdmin $subAdmin */ - private $subAdmin; + /** @var array>> */ + protected array $settings = []; public function __construct( - LoggerInterface $log, - IFactory $l10nFactory, - IURLGenerator $url, - IServerContainer $container, - AuthorizedGroupMapper $mapper, - IGroupManager $groupManager, - ISubAdmin $subAdmin, + private LoggerInterface $log, + private IFactory $l10nFactory, + private IURLGenerator $url, + private IServerContainer $container, + private AuthorizedGroupMapper $mapper, + private IGroupManager $groupManager, + private ISubAdmin $subAdmin, ) { - $this->log = $log; - $this->l10nFactory = $l10nFactory; - $this->url = $url; - $this->container = $container; - $this->mapper = $mapper; - $this->groupManager = $groupManager; - $this->subAdmin = $subAdmin; } - /** @var array>> */ - protected $sectionClasses = []; - - /** @var array> */ - protected $sections = []; - /** * @inheritdoc */ @@ -138,12 +116,6 @@ class Manager implements IManager { ], true); } - /** @var array, self::SETTINGS_*> */ - protected $settingClasses = []; - - /** @var array>> */ - protected $settings = []; - /** * @inheritdoc */ @@ -164,40 +136,41 @@ class Manager implements IManager { } if (!isset($this->settings[$type][$section])) { $this->settings[$type][$section] = []; - } - foreach ($this->settingClasses as $class => $settingsType) { - if ($type !== $settingsType) { - continue; - } + foreach ($this->settingClasses as $class => $settingsType) { + if ($type !== $settingsType) { + continue; + } - try { - /** @var ISettings $setting */ - $setting = $this->container->get($class); - } catch (QueryException $e) { - $this->log->info($e->getMessage(), ['exception' => $e]); - continue; - } + try { + /** @var ISettings $setting */ + $setting = $this->container->get($class); + } catch (QueryException $e) { + $this->log->info($e->getMessage(), ['exception' => $e]); + continue; + } - if (!$setting instanceof ISettings) { - $e = new \InvalidArgumentException('Invalid settings setting registered (' . $class . ')'); - $this->log->info($e->getMessage(), ['exception' => $e]); - continue; - } + if (!$setting instanceof ISettings) { + $e = new \InvalidArgumentException('Invalid settings setting registered (' . $class . ')'); + $this->log->info($e->getMessage(), ['exception' => $e]); + continue; + } + $settingSection = $setting->getSection(); + if ($settingSection === null) { + continue; + } - if ($filter !== null && !$filter($setting)) { - continue; - } - if ($setting->getSection() === null) { - continue; - } + if (!isset($this->settings[$settingsType][$settingSection])) { + $this->settings[$settingsType][$settingSection] = []; + } + $this->settings[$settingsType][$settingSection][] = $setting; - if (!isset($this->settings[$settingsType][$setting->getSection()])) { - $this->settings[$settingsType][$setting->getSection()] = []; + unset($this->settingClasses[$class]); } - $this->settings[$settingsType][$setting->getSection()][] = $setting; + } - unset($this->settingClasses[$class]); + if ($filter !== null) { + return array_values(array_filter($this->settings[$type][$section], $filter)); } return $this->settings[$type][$section]; @@ -349,4 +322,31 @@ class Manager implements IManager { } return $settings; } + + /** + * @return array}> + */ + public function getAdminDelegatedSettings(): array { + $sections = $this->getAdminSections(); + $settings = []; + foreach ($sections as $sectionPriority) { + foreach ($sectionPriority as $section) { + /** @var IDelegatedSettings[] */ + $sectionSettings = array_merge( + $this->getSettings(self::SETTINGS_ADMIN, $section->getID(), fn (ISettings $settings): bool => $settings instanceof IDelegatedSettings), + $this->getSettings(self::SETTINGS_DELEGATION, $section->getID(), fn (ISettings $settings): bool => $settings instanceof IDelegatedSettings), + ); + usort( + $sectionSettings, + fn (ISettings $s1, ISettings $s2) => $s1->getPriority() <=> $s2->getPriority() + ); + $settings[$section->getID()] = [ + 'section' => $section, + 'settings' => $sectionSettings, + ]; + } + } + uasort($settings, fn (array $a, array $b) => $a['section']->getPriority() <=> $b['section']->getPriority()); + return $settings; + } } diff --git a/lib/public/Settings/IManager.php b/lib/public/Settings/IManager.php index 954fd3fdb56..1a22705d3e7 100644 --- a/lib/public/Settings/IManager.php +++ b/lib/public/Settings/IManager.php @@ -47,6 +47,12 @@ interface IManager { */ public const SETTINGS_PERSONAL = 'personal'; + /** + * @since 33.0.0 + * For settings only used for delegation but not appearing in settings menu + */ + public const SETTINGS_DELEGATION = 'delegation'; + /** * @psalm-param self::SETTINGS_* $type * @param class-string $section @@ -118,4 +124,11 @@ interface IManager { * @since 25.0.0 */ public function getSection(string $type, string $sectionId): ?IIconSection; + + /** + * Return admin delegated settings, sorted by priority and grouped by section + * @return array}> + * @since 33.0.0 + */ + public function getAdminDelegatedSettings(): array; } diff --git a/resources/app-info-shipped.xsd b/resources/app-info-shipped.xsd index 7a139e50bc5..db51ec15c78 100644 --- a/resources/app-info-shipped.xsd +++ b/resources/app-info-shipped.xsd @@ -415,6 +415,10 @@ maxOccurs="unbounded"/> + + diff --git a/resources/app-info.xsd b/resources/app-info.xsd index 9b491fd6a05..cee16b0cedc 100644 --- a/resources/app-info.xsd +++ b/resources/app-info.xsd @@ -411,6 +411,10 @@ maxOccurs="unbounded"/> + +