diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-04-17 17:11:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-17 17:11:36 +0200 |
commit | 3aa9c53a87cc1e69fb4285af265b2a3bba429614 (patch) | |
tree | 2666012026b470def0126305b5739ea397e27e44 | |
parent | f865f447673cb452278652992abcde17276569ee (diff) | |
parent | 97e59b12a13fcaf51280818c176a2631ebc1d3a4 (diff) | |
download | nextcloud-server-3aa9c53a87cc1e69fb4285af265b2a3bba429614.tar.gz nextcloud-server-3aa9c53a87cc1e69fb4285af265b2a3bba429614.zip |
Merge pull request #44644 from nextcloud/enh/noid/returns-formated-app-values
fix(appconfig): format app values
-rw-r--r-- | lib/private/AppConfig.php | 72 | ||||
-rw-r--r-- | lib/private/AppFramework/Services/AppConfig.php | 2 | ||||
-rw-r--r-- | lib/public/AppFramework/Services/IAppConfig.php | 2 | ||||
-rw-r--r-- | lib/public/IAppConfig.php | 9 | ||||
-rw-r--r-- | tests/lib/AppConfigTest.php | 15 |
5 files changed, 86 insertions, 14 deletions
diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php index 5d753a6ee9c..c72a4073832 100644 --- a/lib/private/AppConfig.php +++ b/lib/private/AppConfig.php @@ -211,7 +211,7 @@ class AppConfig implements IAppConfig { * @param string $prefix config keys prefix to search * @param bool $filtered TRUE to hide sensitive config values. Value are replaced by {@see IConfig::SENSITIVE_VALUE} * - * @return array<string, string> [configKey => configValue] + * @return array<string, string|int|float|bool|array> [configKey => configValue] * @since 29.0.0 */ public function getAllValues(string $app, string $prefix = '', bool $filtered = false): array { @@ -219,8 +219,9 @@ class AppConfig implements IAppConfig { // if we want to filter values, we need to get sensitivity $this->loadConfigAll(); // array_merge() will remove numeric keys (here config keys), so addition arrays instead + $values = $this->formatAppValues($app, ($this->fastCache[$app] ?? []) + ($this->lazyCache[$app] ?? [])); $values = array_filter( - (($this->fastCache[$app] ?? []) + ($this->lazyCache[$app] ?? [])), + $values, function (string $key) use ($prefix): bool { return str_starts_with($key, $prefix); // filter values based on $prefix }, ARRAY_FILTER_USE_KEY @@ -253,14 +254,14 @@ class AppConfig implements IAppConfig { * * @param string $key config key * @param bool $lazy search within lazy loaded config + * @param int|null $typedAs enforce type for the returned values ({@see self::VALUE_STRING} and others) * - * @return array<string, string> [appId => configValue] + * @return array<string, string|int|float|bool|array> [appId => configValue] * @since 29.0.0 */ - public function searchValues(string $key, bool $lazy = false): array { + public function searchValues(string $key, bool $lazy = false, ?int $typedAs = null): array { $this->assertParams('', $key, true); $this->loadConfig($lazy); - $values = []; /** @var array<array-key, array<array-key, mixed>> $cache */ if ($lazy) { @@ -269,9 +270,10 @@ class AppConfig implements IAppConfig { $cache = $this->fastCache; } + $values = []; foreach (array_keys($cache) as $app) { if (isset($cache[$app][$key])) { - $values[$app] = $cache[$app][$key]; + $values[$app] = $this->convertTypedValue($cache[$app][$key], $typedAs ?? $this->getValueType((string)$app, $key, $lazy)); } } @@ -510,9 +512,9 @@ class AppConfig implements IAppConfig { * @see VALUE_BOOL * @see VALUE_ARRAY */ - public function getValueType(string $app, string $key): int { + public function getValueType(string $app, string $key, ?bool $lazy = null): int { $this->assertParams($app, $key); - $this->loadConfigAll(); + $this->loadConfig($lazy); if (!isset($this->valueTypes[$app][$key])) { throw new AppConfigUnknownKeyException('unknown config key'); @@ -1369,7 +1371,7 @@ class AppConfig implements IAppConfig { $key = ($key === false) ? '' : $key; if (!$app) { - return $this->searchValues($key); + return $this->searchValues($key, false, self::VALUE_MIXED); } else { return $this->getAllValues($app, $key); } @@ -1387,6 +1389,58 @@ class AppConfig implements IAppConfig { return $this->getAllValues($app, filtered: true); } + + /** + * **Warning:** avoid default NULL value for $lazy as this will + * load all lazy values from the database + * + * @param string $app + * @param array<string, string> $values ['key' => 'value'] + * @param bool|null $lazy + * + * @return array<string, string|int|float|bool|array> + */ + private function formatAppValues(string $app, array $values, ?bool $lazy = null): array { + foreach($values as $key => $value) { + try { + $type = $this->getValueType($app, $key, $lazy); + } catch (AppConfigUnknownKeyException $e) { + continue; + } + + $values[$key] = $this->convertTypedValue($value, $type); + } + + return $values; + } + + /** + * convert string value to the expected type + * + * @param string $value + * @param int $type + * + * @return string|int|float|bool|array + */ + private function convertTypedValue(string $value, int $type): string|int|float|bool|array { + switch ($type) { + case self::VALUE_INT: + return (int)$value; + case self::VALUE_FLOAT: + return (float)$value; + case self::VALUE_BOOL: + return in_array(strtolower($value), ['1', 'true', 'yes', 'on']); + case self::VALUE_ARRAY: + try { + return json_decode($value, true, flags: JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + // ignoreable + } + break; + } + return $value; + } + /** * @param string $app * diff --git a/lib/private/AppFramework/Services/AppConfig.php b/lib/private/AppFramework/Services/AppConfig.php index 1d18baef9ed..d3dfd3d362b 100644 --- a/lib/private/AppFramework/Services/AppConfig.php +++ b/lib/private/AppFramework/Services/AppConfig.php @@ -97,7 +97,7 @@ class AppConfig implements IAppConfig { * @param string $key config keys prefix to search * @param bool $filtered TRUE to hide sensitive config values. Value are replaced by {@see IConfig::SENSITIVE_VALUE} * - * @return array<string, string> [configKey => configValue] + * @return array<string, string|int|float|bool|array> [configKey => configValue] * @since 29.0.0 */ public function getAllAppValues(string $key = '', bool $filtered = false): array { diff --git a/lib/public/AppFramework/Services/IAppConfig.php b/lib/public/AppFramework/Services/IAppConfig.php index 9340fdd3c32..74588ef2c99 100644 --- a/lib/public/AppFramework/Services/IAppConfig.php +++ b/lib/public/AppFramework/Services/IAppConfig.php @@ -88,7 +88,7 @@ interface IAppConfig { * @param string $key config keys prefix to search, can be empty. * @param bool $filtered filter sensitive config values * - * @return array<string, string> [configKey => configValue] + * @return array<string, string|int|float|bool|array> [configKey => configValue] * @since 29.0.0 */ public function getAllAppValues(string $key = '', bool $filtered = false): array; diff --git a/lib/public/IAppConfig.php b/lib/public/IAppConfig.php index afcdf67f92c..10fc7c90650 100644 --- a/lib/public/IAppConfig.php +++ b/lib/public/IAppConfig.php @@ -140,7 +140,7 @@ interface IAppConfig { * @param string $prefix config keys prefix to search, can be empty. * @param bool $filtered filter sensitive config values * - * @return array<string, string> [configKey => configValue] + * @return array<string, string|int|float|bool|array> [configKey => configValue] * @since 29.0.0 */ public function getAllValues(string $app, string $prefix = '', bool $filtered = false): array; @@ -151,11 +151,12 @@ interface IAppConfig { * * @param string $key config key * @param bool $lazy search within lazy loaded config + * @param int|null $typedAs enforce type for the returned values {@see self::VALUE_STRING} and others * * @return array<string, string|int|float|bool|array> [appId => configValue] * @since 29.0.0 */ - public function searchValues(string $key, bool $lazy = false): array; + public function searchValues(string $key, bool $lazy = false, ?int $typedAs = null): array; /** * Get config value assigned to a config key. @@ -261,9 +262,11 @@ interface IAppConfig { * returns the type of config value * * **WARNING:** ignore lazy filtering, all config values are loaded from database + * unless lazy is set to false * * @param string $app id of the app * @param string $key config key + * @param bool|null $lazy * * @return int * @throws AppConfigUnknownKeyException @@ -274,7 +277,7 @@ interface IAppConfig { * @see VALUE_BOOL * @see VALUE_ARRAY */ - public function getValueType(string $app, string $key): int; + public function getValueType(string $app, string $key, ?bool $lazy = null): int; /** * Store a config key and its value in database diff --git a/tests/lib/AppConfigTest.php b/tests/lib/AppConfigTest.php index 86bd339bc7e..5bbc3f56791 100644 --- a/tests/lib/AppConfigTest.php +++ b/tests/lib/AppConfigTest.php @@ -386,6 +386,21 @@ class AppConfigTest extends TestCase { $config->isLazy('unknown-app', 'inexistant-key'); } + public function testGetAllValues(): void { + $config = $this->generateAppConfig(); + $this->assertEquals( + [ + 'array' => ['test' => 1], + 'bool' => true, + 'float' => 3.14, + 'int' => 42, + 'mixed' => 'mix', + 'string' => 'value', + ], + $config->getAllValues('typed') + ); + } + public function testGetAllValuesWithEmptyApp(): void { $config = $this->generateAppConfig(); $this->expectException(InvalidArgumentException::class); |