feat(settings): Add support for delegated settings not appearing in menu

Adds a new type of settings, delegation, which is only used for admin
 delegation but does not appear in admin menu.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
pull/55261/head
Côme Chilliet 2 weeks ago
parent 50684fa3b0
commit 09acd7e308
No known key found for this signature in database
GPG Key ID: A3E2F658B28C760A
  1. 33
      apps/settings/lib/Settings/Admin/Delegation.php
  2. 7
      lib/private/App/AppManager.php
  3. 3
      lib/private/App/InfoParser.php
  4. 84
      lib/private/Settings/Manager.php
  5. 13
      lib/public/Settings/IManager.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);
}

@ -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,11 @@ class AppManager implements IAppManager {
$settingsManager->registerSection('personal', $section);
}
}
if (!empty($info['settings']['delegation'])) {
foreach ($info['settings']['delegation'] as $setting) {
$settingsManager->registerSetting(ISettingsManager::SETTINGS_DELEGATION, $setting);
}
}
}
if (!empty($info['collaboration']['plugins'])) {

@ -184,6 +184,9 @@ 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']['delegation']) && !is_array($array['settings']['delegation'])) {
$array['settings']['delegation'] = [$array['settings']['delegation']];
}
if (isset($array['navigations']['navigation']) && $this->isNavigationItem($array['navigations']['navigation'])) {
$array['navigations']['navigation'] = [$array['navigations']['navigation']];
}

@ -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;
@ -135,41 +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;
}
$settingSection = $setting->getSection();
if ($settingSection === null) {
continue;
}
if (!isset($this->settings[$settingsType][$settingSection])) {
$this->settings[$settingsType][$settingSection] = [];
}
$this->settings[$settingsType][$settingSection][] = $setting;
if (!isset($this->settings[$settingsType][$settingSection])) {
$this->settings[$settingsType][$settingSection] = [];
unset($this->settingClasses[$class]);
}
$this->settings[$settingsType][$settingSection][] = $setting;
}
unset($this->settingClasses[$class]);
if ($filter !== null) {
return array_values(array_filter($this->settings[$type][$section], $filter));
}
return $this->settings[$type][$section];
@ -321,4 +322,31 @@ class Manager implements IManager {
}
return $settings;
}
/**
* @return array<string, array{section:IIconSection,settings:list<IDelegatedSettings>}>
*/
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;
}
}

@ -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<IIconSection> $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<string, array{section:IIconSection,settings:list<IDelegatedSettings>}>
* @since 33.0.0
*/
public function getAdminDelegatedSettings(): array;
}

Loading…
Cancel
Save