aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2025-07-22 11:43:49 -0100
committerMaxence Lange <maxence@artificial-owl.com>2025-07-23 15:20:30 -0100
commitab5c2145662e505763197a7c30bc24bf47ca1fbd (patch)
treef2e4b3a7d3620e6802b8be970818a387ee4c4638
parent7268525a8a13807441280376f7ec70b6fcad2845 (diff)
downloadnextcloud-server-feat/preset/load-apps-on-preset.tar.gz
nextcloud-server-feat/preset/load-apps-on-preset.zip
feat(preset): load apps on preset changefeat/preset/load-apps-on-preset
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
-rw-r--r--core/Command/Config/Preset.php10
-rw-r--r--lib/private/AppConfig.php19
-rw-r--r--lib/private/Config/ConfigManager.php30
-rw-r--r--lib/private/Config/PresetManager.php124
-rw-r--r--lib/private/Config/UserConfig.php18
5 files changed, 147 insertions, 54 deletions
diff --git a/core/Command/Config/Preset.php b/core/Command/Config/Preset.php
index 9f1424dcc54..e1edfdd4a5f 100644
--- a/core/Command/Config/Preset.php
+++ b/core/Command/Config/Preset.php
@@ -9,9 +9,8 @@ declare(strict_types=1);
namespace OC\Core\Command\Config;
use NCU\Config\Lexicon\Preset as ConfigLexiconPreset;
-use OC\Config\ConfigManager;
+use OC\Config\PresetManager;
use OC\Core\Command\Base;
-use OCP\IConfig;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -19,8 +18,7 @@ use Symfony\Component\Console\Output\OutputInterface;
class Preset extends Base {
public function __construct(
- private readonly IConfig $config,
- private readonly ConfigManager $configManager,
+ private readonly PresetManager $presetManager,
) {
parent::__construct();
}
@@ -49,10 +47,10 @@ class Preset extends Base {
return self::INVALID;
}
- $this->configManager->setLexiconPreset($preset);
+ $this->presetManager->setLexiconPreset($preset);
}
- $current = ConfigLexiconPreset::tryFrom($this->config->getSystemValueInt(ConfigManager::PRESET_CONFIGKEY, 0)) ?? ConfigLexiconPreset::NONE;
+ $current = $this->presetManager->getLexiconPreset();
$this->writeArrayInOutputFormat($input, $output, [$current->name], 'current preset: ');
return self::SUCCESS;
}
diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php
index f050deba1ca..0ef061abed3 100644
--- a/lib/private/AppConfig.php
+++ b/lib/private/AppConfig.php
@@ -14,9 +14,9 @@ use JsonException;
use NCU\Config\Lexicon\ConfigLexiconEntry;
use NCU\Config\Lexicon\ConfigLexiconStrictness;
use NCU\Config\Lexicon\IConfigLexicon;
-use NCU\Config\Lexicon\Preset;
use OC\AppFramework\Bootstrap\Coordinator;
use OC\Config\ConfigManager;
+use OC\Config\PresetManager;
use OCP\DB\Exception as DBException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Exceptions\AppConfigIncorrectTypeException;
@@ -65,13 +65,14 @@ class AppConfig implements IAppConfig {
/** @var array<string, array{entries: array<string, ConfigLexiconEntry>, aliases: array<string, string>, strictness: ConfigLexiconStrictness}> ['app_id' => ['strictness' => ConfigLexiconStrictness, 'entries' => ['config_key' => ConfigLexiconEntry[]]] */
private array $configLexiconDetails = [];
private bool $ignoreLexiconAliases = false;
- private ?Preset $configLexiconPreset = null;
/** @var ?array<string, string> */
private ?array $appVersionsCache = null;
public function __construct(
protected IDBConnection $connection,
protected IConfig $config,
+ private readonly ConfigManager $configManager,
+ private readonly PresetManager $presetManager,
protected LoggerInterface $logger,
protected ICrypto $crypto,
) {
@@ -519,8 +520,7 @@ class AppConfig implements IAppConfig {
// interested to check options in case a modification of the value is needed
// ie inverting value from previous key when using lexicon option RENAME_INVERT_BOOLEAN
if ($origKey !== $key && $type === self::VALUE_BOOL) {
- $configManager = Server::get(ConfigManager::class);
- $value = ($configManager->convertToBool($value, $this->getLexiconEntry($app, $key))) ? '1' : '0';
+ $value = ($this->configManager->convertToBool($value, $this->getLexiconEntry($app, $key))) ? '1' : '0';
}
return $value;
@@ -1184,7 +1184,6 @@ class AppConfig implements IAppConfig {
public function clearCache(bool $reload = false): void {
$this->lazyLoaded = $this->fastLoaded = false;
$this->lazyCache = $this->fastCache = $this->valueTypes = $this->configLexiconDetails = [];
- $this->configLexiconPreset = null;
if (!$reload) {
return;
@@ -1669,7 +1668,7 @@ class AppConfig implements IAppConfig {
$lazy = $configValue->isLazy();
// only look for default if needed, default from Lexicon got priority
if ($default !== null) {
- $default = $configValue->getDefault($this->getLexiconPreset()) ?? $default;
+ $default = $configValue->getDefault($this->presetManager->getLexiconPreset()) ?? $default;
}
if ($configValue->isFlagged(self::FLAG_SENSITIVE)) {
@@ -1757,14 +1756,6 @@ class AppConfig implements IAppConfig {
$this->ignoreLexiconAliases = $ignore;
}
- private function getLexiconPreset(): Preset {
- if ($this->configLexiconPreset === null) {
- $this->configLexiconPreset = Preset::tryFrom($this->config->getSystemValueInt(ConfigManager::PRESET_CONFIGKEY, 0)) ?? Preset::NONE;
- }
-
- return $this->configLexiconPreset;
- }
-
/**
* Returns the installed versions of all apps
*
diff --git a/lib/private/Config/ConfigManager.php b/lib/private/Config/ConfigManager.php
index 67466617941..9b1e1afae32 100644
--- a/lib/private/Config/ConfigManager.php
+++ b/lib/private/Config/ConfigManager.php
@@ -9,15 +9,13 @@ declare(strict_types=1);
namespace OC\Config;
use JsonException;
-use NCU\Config\Exceptions\TypeConflictException;
-use NCU\Config\IUserConfig;
-use NCU\Config\Lexicon\ConfigLexiconEntry;
-use NCU\Config\Lexicon\Preset;
use NCU\Config\ValueType;
use OC\AppConfig;
use OCP\App\IAppManager;
+use NCU\Config\Exceptions\TypeConflictException;
+use NCU\Config\IUserConfig;
+use NCU\Config\Lexicon\ConfigLexiconEntry;
use OCP\IAppConfig;
-use OCP\IConfig;
use OCP\Server;
use Psr\Log\LoggerInterface;
@@ -27,20 +25,23 @@ use Psr\Log\LoggerInterface;
* @since 32.0.0
*/
class ConfigManager {
- /** @since 32.0.0 */
- public const PRESET_CONFIGKEY = 'config_preset';
-
/** @var AppConfig|null $appConfig */
private ?IAppConfig $appConfig = null;
/** @var UserConfig|null $userConfig */
private ?IUserConfig $userConfig = null;
public function __construct(
- private readonly IConfig $config,
private readonly LoggerInterface $logger,
) {
}
+ public function clearConfigCaches(): void {
+ $this->loadConfigServices();
+ $this->appConfig->clearCache();
+ $this->userConfig->clearCacheAll();
+ }
+
+
/**
* Use the rename values from the list of ConfigLexiconEntry defined in each app ConfigLexicon
* to migrate config value to a new config key.
@@ -81,17 +82,6 @@ class ConfigManager {
}
/**
- * store in config.php the new preset
- * refresh cached preset
- */
- public function setLexiconPreset(Preset $preset): void {
- $this->config->setSystemValue(self::PRESET_CONFIGKEY, $preset->value);
- $this->loadConfigServices();
- $this->appConfig->clearCache();
- $this->userConfig->clearCacheAll();
- }
-
- /**
* config services cannot be load at __construct() or install will fail
*/
private function loadConfigServices(): void {
diff --git a/lib/private/Config/PresetManager.php b/lib/private/Config/PresetManager.php
new file mode 100644
index 00000000000..88eb2314e6a
--- /dev/null
+++ b/lib/private/Config/PresetManager.php
@@ -0,0 +1,124 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OC\Config;
+
+use NCU\Config\Lexicon\Preset;
+use OC\App\AppManager;
+use OC\Core\Command\App\Install;
+use OC\Installer;
+use OCP\App\AppPathNotFoundException;
+use OCP\App\IAppManager;
+use OCP\IConfig;
+use Psr\Log\LoggerInterface;
+
+/**
+ * tools to maintains configurations
+ *
+ * @since 32.0.0
+ */
+class PresetManager {
+ private const PRESET_CONFIGKEY = 'config_preset';
+
+ private ?AppManager $appManager = null;
+ private ?Installer $installer = null;
+
+ private ?Preset $configLexiconPreset = null;
+
+ public function __construct(
+ private readonly IConfig $config,
+ private readonly ConfigManager $configManager,
+ private readonly LoggerInterface $logger,
+ ) {
+ }
+
+ /**
+ * store in config.php the new preset
+ * refresh cached preset
+ */
+ public function setLexiconPreset(Preset $preset): void {
+ $this->config->setSystemValue(self::PRESET_CONFIGKEY, $preset->value);
+ $this->configLexiconPreset = $preset;
+ $this->configManager->clearConfigCaches();
+ $this->refreshPresetApps();
+ }
+
+ public function getLexiconPreset(): Preset {
+ if ($this->configLexiconPreset === null) {
+ $this->configLexiconPreset = Preset::tryFrom($this->config->getSystemValueInt(self::PRESET_CONFIGKEY, 0)) ?? Preset::NONE;
+ }
+
+ return $this->configLexiconPreset;
+ }
+
+ public function refreshPresetApps(): void {
+ $this->loadAppManager();
+
+ $apps = $this->getPresetApps($this->getLexiconPreset());
+ foreach ($apps['disabled'] ?? [] as $app) {
+ try {
+ $this->appManager->disableApp($app);
+ } catch (\Exception $e) {
+ $this->logger->warning('could not disable app', ['exception' => $e]);
+ }
+ }
+
+ foreach ($apps['enabled'] ?? [] as $app) {
+ $this->installApp($app);
+ }
+ }
+
+ private function loadAppManager(): void {
+ if ($this->appManager === null) {
+ $this->appManager = \OCP\Server::get(IAppManager::class);
+ }
+ if ($this->installer === null) {
+ $this->installer = \OCP\Server::get(Installer::class);
+ }
+ }
+
+ private function installApp(string $appId): void {
+ $this->loadAppManager();
+ if (!$this->installer->isDownloaded($appId)) {
+ try {
+ $this->installer->downloadApp($appId);
+ } catch (\Exception $e) {
+ $this->logger->warning('could not download app', ['appId' => $appId, 'exception' => $e]);
+ return;
+ }
+ }
+
+ try {
+ $this->installer->installApp($appId, true);
+ } catch (\Exception $e) {
+ $this->logger->warning('could not install app', ['appId' => $appId, 'exception' => $e]);
+ return;
+ }
+
+ try {
+ $this->appManager->enableApp($appId);
+ } catch (AppPathNotFoundException $e) {
+ $this->logger->warning('could not enable app', ['appId' => $appId, 'exception' => $e]);
+ return;
+ }
+ }
+
+ /**
+ * get listing of enabled/disabled app from Preset
+ *
+ * @return array{enabled: list<string>, disabled: list<string>}
+ */
+ private function getPresetApps(Preset $preset): array {
+ return match ($preset) {
+ Preset::LARGE => ['enabled' => ['globalsiteselector', 'intros'], 'disabled' => []],
+ Preset::CLUB, Preset::FAMILY, Preset::EDUCATION, Preset::SMALL, Preset::MEDIUM => ['enabled' => ['intros'], 'disabled' => []],
+ Preset::SHARED => ['enabled' => ['intros', 'external'], 'disabled' => []],
+ default => ['enabled' => [], 'disabled' => ['intros']],
+ };
+ }
+}
diff --git a/lib/private/Config/UserConfig.php b/lib/private/Config/UserConfig.php
index fb0bf954f57..35fdded7fd1 100644
--- a/lib/private/Config/UserConfig.php
+++ b/lib/private/Config/UserConfig.php
@@ -17,7 +17,6 @@ use NCU\Config\Exceptions\UnknownKeyException;
use NCU\Config\IUserConfig;
use NCU\Config\Lexicon\ConfigLexiconEntry;
use NCU\Config\Lexicon\ConfigLexiconStrictness;
-use NCU\Config\Lexicon\Preset;
use NCU\Config\ValueType;
use OC\AppFramework\Bootstrap\Coordinator;
use OCP\DB\Exception as DBException;
@@ -67,11 +66,12 @@ class UserConfig implements IUserConfig {
/** @var array<string, array{entries: array<string, ConfigLexiconEntry>, aliases: array<string, string>, strictness: ConfigLexiconStrictness}> ['app_id' => ['strictness' => ConfigLexiconStrictness, 'entries' => ['config_key' => ConfigLexiconEntry[]]] */
private array $configLexiconDetails = [];
private bool $ignoreLexiconAliases = false;
- private ?Preset $configLexiconPreset = null;
public function __construct(
protected IDBConnection $connection,
protected IConfig $config,
+ private readonly ConfigManager $configManager,
+ private readonly ConfigManager $presetManager,
protected LoggerInterface $logger,
protected ICrypto $crypto,
) {
@@ -771,8 +771,7 @@ class UserConfig implements IUserConfig {
// interested to check options in case a modification of the value is needed
// ie inverting value from previous key when using lexicon option RENAME_INVERT_BOOLEAN
if ($origKey !== $key && $type === ValueType::BOOL) {
- $configManager = Server::get(ConfigManager::class);
- $value = ($configManager->convertToBool($value, $this->getLexiconEntry($app, $key))) ? '1' : '0';
+ $value = ($this->configManager->convertToBool($value, $this->getLexiconEntry($app, $key))) ? '1' : '0';
}
return $value;
@@ -1635,7 +1634,6 @@ class UserConfig implements IUserConfig {
public function clearCacheAll(): void {
$this->lazyLoaded = $this->fastLoaded = [];
$this->lazyCache = $this->fastCache = $this->valueDetails = $this->configLexiconDetails = [];
- $this->configLexiconPreset = null;
}
/**
@@ -1936,7 +1934,7 @@ class UserConfig implements IUserConfig {
// only look for default if needed, default from Lexicon got priority if not overwritten by admin
if ($default !== null) {
- $default = $this->getSystemDefault($app, $configValue) ?? $configValue->getDefault($this->getLexiconPreset()) ?? $default;
+ $default = $this->getSystemDefault($app, $configValue) ?? $configValue->getDefault($this->presetManager->getLexiconPreset()) ?? $default;
}
// returning false will make get() returning $default and set() not changing value in database
@@ -2037,12 +2035,4 @@ class UserConfig implements IUserConfig {
public function ignoreLexiconAliases(bool $ignore): void {
$this->ignoreLexiconAliases = $ignore;
}
-
- private function getLexiconPreset(): Preset {
- if ($this->configLexiconPreset === null) {
- $this->configLexiconPreset = Preset::tryFrom($this->config->getSystemValueInt(ConfigManager::PRESET_CONFIGKEY, 0)) ?? Preset::NONE;
- }
-
- return $this->configLexiconPreset;
- }
}