|
|
|
@ -14,8 +14,8 @@ use JsonException; |
|
|
|
|
use OC\AppFramework\Bootstrap\Coordinator; |
|
|
|
|
use OC\Config\ConfigManager; |
|
|
|
|
use OC\Config\PresetManager; |
|
|
|
|
use OC\Memcache\Factory as CacheFactory; |
|
|
|
|
use OCP\Config\Lexicon\Entry; |
|
|
|
|
use OCP\Config\Lexicon\ILexicon; |
|
|
|
|
use OCP\Config\Lexicon\Strictness; |
|
|
|
|
use OCP\Config\ValueType; |
|
|
|
|
use OCP\DB\Exception as DBException; |
|
|
|
@ -24,6 +24,8 @@ use OCP\Exceptions\AppConfigIncorrectTypeException; |
|
|
|
|
use OCP\Exceptions\AppConfigTypeConflictException; |
|
|
|
|
use OCP\Exceptions\AppConfigUnknownKeyException; |
|
|
|
|
use OCP\IAppConfig; |
|
|
|
|
use OCP\ICache; |
|
|
|
|
use OCP\ICacheFactory; |
|
|
|
|
use OCP\IConfig; |
|
|
|
|
use OCP\IDBConnection; |
|
|
|
|
use OCP\Security\ICrypto; |
|
|
|
@ -53,10 +55,12 @@ class AppConfig implements IAppConfig { |
|
|
|
|
private const KEY_MAX_LENGTH = 64; |
|
|
|
|
private const ENCRYPTION_PREFIX = '$AppConfigEncryption$'; |
|
|
|
|
private const ENCRYPTION_PREFIX_LENGTH = 21; // strlen(self::ENCRYPTION_PREFIX) |
|
|
|
|
private const LOCAL_CACHE_KEY = 'OC\\AppConfig'; |
|
|
|
|
private const LOCAL_CACHE_TTL = 3; |
|
|
|
|
|
|
|
|
|
/** @var array<string, array<string, mixed>> ['app_id' => ['config_key' => 'config_value']] */ |
|
|
|
|
/** @var array<string, array<string, string>> ['app_id' => ['config_key' => 'config_value']] */ |
|
|
|
|
private array $fastCache = []; // cache for normal config keys |
|
|
|
|
/** @var array<string, array<string, mixed>> ['app_id' => ['config_key' => 'config_value']] */ |
|
|
|
|
/** @var array<string, array<string, string>> ['app_id' => ['config_key' => 'config_value']] */ |
|
|
|
|
private array $lazyCache = []; // cache for lazy config keys |
|
|
|
|
/** @var array<string, array<string, int>> ['app_id' => ['config_key' => bitflag]] */ |
|
|
|
|
private array $valueTypes = []; // type for all config values |
|
|
|
@ -67,6 +71,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
private bool $ignoreLexiconAliases = false; |
|
|
|
|
/** @var ?array<string, string> */ |
|
|
|
|
private ?array $appVersionsCache = null; |
|
|
|
|
private ?ICache $localCache = null; |
|
|
|
|
|
|
|
|
|
public function __construct( |
|
|
|
|
protected IDBConnection $connection, |
|
|
|
@ -75,7 +80,13 @@ class AppConfig implements IAppConfig { |
|
|
|
|
private readonly PresetManager $presetManager, |
|
|
|
|
protected LoggerInterface $logger, |
|
|
|
|
protected ICrypto $crypto, |
|
|
|
|
readonly CacheFactory $cacheFactory, |
|
|
|
|
) { |
|
|
|
|
if ($config->getSystemValueBool('cache_app_config', true) && $cacheFactory->isLocalCacheAvailable()) { |
|
|
|
|
$cacheFactory->withServerVersionPrefix(function (ICacheFactory $factory) { |
|
|
|
|
$this->localCache = $factory->createLocal(); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -85,7 +96,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
* @since 7.0.0 |
|
|
|
|
*/ |
|
|
|
|
public function getApps(): array { |
|
|
|
|
$this->loadConfigAll(); |
|
|
|
|
$this->loadConfig(lazy: true); |
|
|
|
|
$apps = array_merge(array_keys($this->fastCache), array_keys($this->lazyCache)); |
|
|
|
|
sort($apps); |
|
|
|
|
|
|
|
|
@ -103,7 +114,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
*/ |
|
|
|
|
public function getKeys(string $app): array { |
|
|
|
|
$this->assertParams($app); |
|
|
|
|
$this->loadConfigAll($app); |
|
|
|
|
$this->loadConfig($app, true); |
|
|
|
|
$keys = array_merge(array_keys($this->fastCache[$app] ?? []), array_keys($this->lazyCache[$app] ?? [])); |
|
|
|
|
sort($keys); |
|
|
|
|
|
|
|
|
@ -149,19 +160,16 @@ class AppConfig implements IAppConfig { |
|
|
|
|
*/ |
|
|
|
|
public function hasKey(string $app, string $key, ?bool $lazy = false): bool { |
|
|
|
|
$this->assertParams($app, $key); |
|
|
|
|
$this->loadConfig($app, $lazy); |
|
|
|
|
$this->loadConfig($app, $lazy ?? true); |
|
|
|
|
$this->matchAndApplyLexiconDefinition($app, $key); |
|
|
|
|
|
|
|
|
|
$hasLazy = isset($this->lazyCache[$app][$key]); |
|
|
|
|
$hasFast = isset($this->fastCache[$app][$key]); |
|
|
|
|
if ($lazy === null) { |
|
|
|
|
$appCache = $this->getAllValues($app); |
|
|
|
|
return isset($appCache[$key]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($lazy) { |
|
|
|
|
return isset($this->lazyCache[$app][$key]); |
|
|
|
|
return $hasLazy || $hasFast; |
|
|
|
|
} else { |
|
|
|
|
return $lazy ? $hasLazy : $hasFast; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return isset($this->fastCache[$app][$key]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -175,7 +183,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
*/ |
|
|
|
|
public function isSensitive(string $app, string $key, ?bool $lazy = false): bool { |
|
|
|
|
$this->assertParams($app, $key); |
|
|
|
|
$this->loadConfig(null, $lazy); |
|
|
|
|
$this->loadConfig(null, $lazy ?? true); |
|
|
|
|
$this->matchAndApplyLexiconDefinition($app, $key); |
|
|
|
|
|
|
|
|
|
if (!isset($this->valueTypes[$app][$key])) { |
|
|
|
@ -227,7 +235,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
public function getAllValues(string $app, string $prefix = '', bool $filtered = false): array { |
|
|
|
|
$this->assertParams($app, $prefix); |
|
|
|
|
// if we want to filter values, we need to get sensitivity |
|
|
|
|
$this->loadConfigAll($app); |
|
|
|
|
$this->loadConfig($app, true); |
|
|
|
|
// 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( |
|
|
|
@ -479,7 +487,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
return $default; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$this->loadConfig($app, $lazy); |
|
|
|
|
$this->loadConfig($app, $lazy ?? true); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* We ignore check if mixed type is requested. |
|
|
|
@ -551,7 +559,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$this->assertParams($app, $key); |
|
|
|
|
$this->loadConfig($app, $lazy); |
|
|
|
|
$this->loadConfig($app, $lazy ?? true); |
|
|
|
|
|
|
|
|
|
if (!isset($this->valueTypes[$app][$key])) { |
|
|
|
|
throw new AppConfigUnknownKeyException('unknown config key'); |
|
|
|
@ -788,7 +796,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
if (!$this->matchAndApplyLexiconDefinition($app, $key, $lazy, $type)) { |
|
|
|
|
return false; // returns false as database is not updated |
|
|
|
|
} |
|
|
|
|
$this->loadConfig(null, $lazy); |
|
|
|
|
$this->loadConfig(null, $lazy ?? true); |
|
|
|
|
|
|
|
|
|
$sensitive = $this->isTyped(self::VALUE_SENSITIVE, $type); |
|
|
|
|
$inserted = $refreshCache = false; |
|
|
|
@ -803,7 +811,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
* no update if key is already known with set lazy status and value is |
|
|
|
|
* not different, unless sensitivity is switched from false to true. |
|
|
|
|
*/ |
|
|
|
|
if ($origValue === $this->getTypedValue($app, $key, $value, $lazy, $type) |
|
|
|
|
if ($origValue === $this->getTypedValue($app, $key, $value, $lazy ?? true, $type) |
|
|
|
|
&& (!$sensitive || $this->isSensitive($app, $key, $lazy))) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
@ -835,7 +843,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
if (!$inserted) { |
|
|
|
|
$currType = $this->valueTypes[$app][$key] ?? 0; |
|
|
|
|
if ($currType === 0) { // this might happen when switching lazy loading status |
|
|
|
|
$this->loadConfigAll(); |
|
|
|
|
$this->loadConfig(lazy: true); |
|
|
|
|
$currType = $this->valueTypes[$app][$key] ?? 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -856,7 +864,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
&& ($type | self::VALUE_SENSITIVE) !== ($currType | self::VALUE_SENSITIVE)) { |
|
|
|
|
try { |
|
|
|
|
$currType = $this->convertTypeToString($currType); |
|
|
|
|
$type = $this->convertTypeToString($type); |
|
|
|
|
$this->convertTypeToString($type); |
|
|
|
|
} catch (AppConfigIncorrectTypeException) { |
|
|
|
|
// can be ignored, this was just needed for a better exception message. |
|
|
|
|
} |
|
|
|
@ -895,6 +903,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
$this->fastCache[$app][$key] = $value; |
|
|
|
|
} |
|
|
|
|
$this->valueTypes[$app][$key] = $type; |
|
|
|
|
$this->clearLocalCache(); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
@ -916,7 +925,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
*/ |
|
|
|
|
public function updateType(string $app, string $key, int $type = self::VALUE_MIXED): bool { |
|
|
|
|
$this->assertParams($app, $key); |
|
|
|
|
$this->loadConfigAll(); |
|
|
|
|
$this->loadConfig(lazy: true); |
|
|
|
|
$this->matchAndApplyLexiconDefinition($app, $key); |
|
|
|
|
$this->isLazy($app, $key); // confirm key exists |
|
|
|
|
|
|
|
|
@ -959,7 +968,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
*/ |
|
|
|
|
public function updateSensitive(string $app, string $key, bool $sensitive): bool { |
|
|
|
|
$this->assertParams($app, $key); |
|
|
|
|
$this->loadConfigAll(); |
|
|
|
|
$this->loadConfig(lazy: true); |
|
|
|
|
$this->matchAndApplyLexiconDefinition($app, $key); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
@ -1019,7 +1028,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
*/ |
|
|
|
|
public function updateLazy(string $app, string $key, bool $lazy): bool { |
|
|
|
|
$this->assertParams($app, $key); |
|
|
|
|
$this->loadConfigAll(); |
|
|
|
|
$this->loadConfig(lazy: true); |
|
|
|
|
$this->matchAndApplyLexiconDefinition($app, $key); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
@ -1055,7 +1064,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
*/ |
|
|
|
|
public function getDetails(string $app, string $key): array { |
|
|
|
|
$this->assertParams($app, $key); |
|
|
|
|
$this->loadConfigAll(); |
|
|
|
|
$this->loadConfig(lazy: true); |
|
|
|
|
$this->matchAndApplyLexiconDefinition($app, $key); |
|
|
|
|
$lazy = $this->isLazy($app, $key); |
|
|
|
|
|
|
|
|
@ -1198,6 +1207,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
unset($this->lazyCache[$app][$key]); |
|
|
|
|
unset($this->fastCache[$app][$key]); |
|
|
|
|
unset($this->valueTypes[$app][$key]); |
|
|
|
|
$this->clearLocalCache(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -1227,12 +1237,13 @@ 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->localCache?->remove(self::LOCAL_CACHE_KEY); |
|
|
|
|
|
|
|
|
|
if (!$reload) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$this->loadConfigAll(); |
|
|
|
|
$this->loadConfig(lazy: true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1293,35 +1304,49 @@ class AppConfig implements IAppConfig { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function loadConfigAll(?string $app = null): void { |
|
|
|
|
$this->loadConfig($app, null); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Load normal config or config set as lazy loaded |
|
|
|
|
* |
|
|
|
|
* @param bool|null $lazy set to TRUE to load config set as lazy loaded, set to NULL to load all config |
|
|
|
|
* @param bool $lazy set to TRUE to also load config values set as lazy loaded |
|
|
|
|
*/ |
|
|
|
|
private function loadConfig(?string $app = null, ?bool $lazy = false): void { |
|
|
|
|
private function loadConfig(?string $app = null, bool $lazy = false): void { |
|
|
|
|
if ($this->isLoaded($lazy)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// if lazy is null or true, we debug log |
|
|
|
|
if (($lazy ?? true) !== false && $app !== null) { |
|
|
|
|
if ($lazy === true && $app !== null) { |
|
|
|
|
$exception = new \RuntimeException('The loading of lazy AppConfig values have been triggered by app "' . $app . '"'); |
|
|
|
|
$this->logger->debug($exception->getMessage(), ['exception' => $exception, 'app' => $app]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$qb = $this->connection->getQueryBuilder(); |
|
|
|
|
$qb->from('appconfig'); |
|
|
|
|
$loadLazyOnly = $lazy && $this->isLoaded(); |
|
|
|
|
|
|
|
|
|
// we only need value from lazy when loadConfig does not specify it |
|
|
|
|
$qb->select('appid', 'configkey', 'configvalue', 'type'); |
|
|
|
|
/** @var array<mixed> */ |
|
|
|
|
$cacheContent = $this->localCache?->get(self::LOCAL_CACHE_KEY) ?? []; |
|
|
|
|
$includesLazyValues = !empty($cacheContent) && !empty($cacheContent['lazyCache']); |
|
|
|
|
if (!empty($cacheContent) && (!$lazy || $includesLazyValues)) { |
|
|
|
|
$this->valueTypes = $cacheContent['valueTypes']; |
|
|
|
|
$this->fastCache = $cacheContent['fastCache']; |
|
|
|
|
$this->fastLoaded = !empty($this->fastCache); |
|
|
|
|
if ($includesLazyValues) { |
|
|
|
|
$this->lazyCache = $cacheContent['lazyCache']; |
|
|
|
|
$this->lazyLoaded = !empty($this->lazyCache); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($lazy !== null) { |
|
|
|
|
$qb->where($qb->expr()->eq('lazy', $qb->createNamedParameter($lazy ? 1 : 0, IQueryBuilder::PARAM_INT))); |
|
|
|
|
// Otherwise no cache available and we need to fetch from database |
|
|
|
|
$qb = $this->connection->getQueryBuilder(); |
|
|
|
|
$qb->from('appconfig') |
|
|
|
|
->select('appid', 'configkey', 'configvalue', 'type'); |
|
|
|
|
|
|
|
|
|
if ($lazy === false) { |
|
|
|
|
$qb->where($qb->expr()->eq('lazy', $qb->createNamedParameter(0, IQueryBuilder::PARAM_INT))); |
|
|
|
|
} else { |
|
|
|
|
if ($loadLazyOnly) { |
|
|
|
|
$qb->where($qb->expr()->eq('lazy', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT))); |
|
|
|
|
} |
|
|
|
|
$qb->addSelect('lazy'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1329,56 +1354,34 @@ class AppConfig implements IAppConfig { |
|
|
|
|
$rows = $result->fetchAll(); |
|
|
|
|
foreach ($rows as $row) { |
|
|
|
|
// most of the time, 'lazy' is not in the select because its value is already known |
|
|
|
|
if (($row['lazy'] ?? ($lazy ?? 0) ? 1 : 0) === 1) { |
|
|
|
|
if ($lazy && ((int)$row['lazy']) === 1) { |
|
|
|
|
$this->lazyCache[$row['appid']][$row['configkey']] = $row['configvalue'] ?? ''; |
|
|
|
|
} else { |
|
|
|
|
$this->fastCache[$row['appid']][$row['configkey']] = $row['configvalue'] ?? ''; |
|
|
|
|
} |
|
|
|
|
$this->valueTypes[$row['appid']][$row['configkey']] = (int)($row['type'] ?? 0); |
|
|
|
|
} |
|
|
|
|
$result->closeCursor(); |
|
|
|
|
$this->setAsLoaded($lazy); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* if $lazy is: |
|
|
|
|
* - false: will returns true if fast config is loaded |
|
|
|
|
* - true : will returns true if lazy config is loaded |
|
|
|
|
* - null : will returns true if both config are loaded |
|
|
|
|
* |
|
|
|
|
* @param bool $lazy |
|
|
|
|
* |
|
|
|
|
* @return bool |
|
|
|
|
*/ |
|
|
|
|
private function isLoaded(?bool $lazy): bool { |
|
|
|
|
if ($lazy === null) { |
|
|
|
|
return $this->lazyLoaded && $this->fastLoaded; |
|
|
|
|
} |
|
|
|
|
$result->closeCursor(); |
|
|
|
|
$this->localCache?->set( |
|
|
|
|
self::LOCAL_CACHE_KEY, |
|
|
|
|
[ |
|
|
|
|
'fastCache' => $this->fastCache, |
|
|
|
|
'lazyCache' => $this->lazyCache, |
|
|
|
|
'valueTypes' => $this->valueTypes, |
|
|
|
|
], |
|
|
|
|
self::LOCAL_CACHE_TTL, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return $lazy ? $this->lazyLoaded : $this->fastLoaded; |
|
|
|
|
$this->fastLoaded = true; |
|
|
|
|
$this->lazyLoaded = $lazy; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* if $lazy is: |
|
|
|
|
* - false: set fast config as loaded |
|
|
|
|
* - true : set lazy config as loaded |
|
|
|
|
* - null : set both config as loaded |
|
|
|
|
* |
|
|
|
|
* @param bool $lazy |
|
|
|
|
* @param bool $lazy - If set to true then also check if lazy values are loaded |
|
|
|
|
*/ |
|
|
|
|
private function setAsLoaded(?bool $lazy): void { |
|
|
|
|
if ($lazy === null) { |
|
|
|
|
$this->fastLoaded = true; |
|
|
|
|
$this->lazyLoaded = true; |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($lazy) { |
|
|
|
|
$this->lazyLoaded = true; |
|
|
|
|
} else { |
|
|
|
|
$this->fastLoaded = true; |
|
|
|
|
} |
|
|
|
|
private function isLoaded(bool $lazy = false): bool { |
|
|
|
|
return $this->fastLoaded && (!$lazy || $this->lazyLoaded); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -1386,7 +1389,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
* |
|
|
|
|
* @param string $app app |
|
|
|
|
* @param string $key key |
|
|
|
|
* @param string $default = null, default value if the key does not exist |
|
|
|
|
* @param string $default - Default value if the key does not exist |
|
|
|
|
* |
|
|
|
|
* @return string the value or $default |
|
|
|
|
* @deprecated 29.0.0 use getValue*() |
|
|
|
@ -1394,7 +1397,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
* This function gets a value from the appconfig table. If the key does |
|
|
|
|
* not exist the default value will be returned |
|
|
|
|
*/ |
|
|
|
|
public function getValue($app, $key, $default = null) { |
|
|
|
|
public function getValue($app, $key, $default = '') { |
|
|
|
|
$this->loadConfig($app); |
|
|
|
|
$this->matchAndApplyLexiconDefinition($app, $key); |
|
|
|
|
|
|
|
|
@ -1421,7 +1424,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
* or enabled (lazy=lazy-2) |
|
|
|
|
* |
|
|
|
|
* this solution would remove the loading of config values from disabled app |
|
|
|
|
* unless calling the method {@see loadConfigAll()} |
|
|
|
|
* unless calling the method. |
|
|
|
|
*/ |
|
|
|
|
return $this->setTypedValue($app, $key, (string)$value, false, self::VALUE_MIXED); |
|
|
|
|
} |
|
|
|
@ -1733,7 +1736,7 @@ class AppConfig implements IAppConfig { |
|
|
|
|
* |
|
|
|
|
* @return bool TRUE if conflict can be fully ignored, FALSE if action should be not performed |
|
|
|
|
* @throws AppConfigUnknownKeyException if strictness implies exception |
|
|
|
|
* @see ILexicon::getStrictness() |
|
|
|
|
* @see \OCP\Config\Lexicon\ILexicon::getStrictness() |
|
|
|
|
*/ |
|
|
|
|
private function applyLexiconStrictness( |
|
|
|
|
?Strictness $strictness, |
|
|
|
@ -1772,8 +1775,9 @@ class AppConfig implements IAppConfig { |
|
|
|
|
$configLexicon = $bootstrapCoordinator->getRegistrationContext()?->getConfigLexicon($appId); |
|
|
|
|
foreach ($configLexicon?->getAppConfigs() ?? [] as $configEntry) { |
|
|
|
|
$entries[$configEntry->getKey()] = $configEntry; |
|
|
|
|
if ($configEntry->getRename() !== null) { |
|
|
|
|
$aliases[$configEntry->getRename()] = $configEntry->getKey(); |
|
|
|
|
$newName = $configEntry->getRename(); |
|
|
|
|
if ($newName !== null) { |
|
|
|
|
$aliases[$newName] = $configEntry->getKey(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1819,4 +1823,8 @@ class AppConfig implements IAppConfig { |
|
|
|
|
} |
|
|
|
|
return $this->appVersionsCache; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function clearLocalCache(): void { |
|
|
|
|
$this->localCache?->remove(self::LOCAL_CACHE_KEY); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|