aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2025-06-20 15:52:56 +0200
committerMaxence Lange <maxence@artificial-owl.com>2025-06-25 19:46:53 +0200
commitba11c713c05b66fc9466844b305c33bec67e33c9 (patch)
treea52f41f650a891ab4c73e806266d1562c4a6cfb5 /lib/private
parent0f94ceace12e96f2ffffba029cdb3d69dea46e14 (diff)
downloadnextcloud-server-feat/noid/lexicon-events.tar.gz
nextcloud-server-feat/noid/lexicon-events.zip
feat(lexicon): events onSet() and initialize()feat/noid/lexicon-events
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/AppConfig.php34
-rw-r--r--lib/private/Config/UserConfig.php41
2 files changed, 51 insertions, 24 deletions
diff --git a/lib/private/AppConfig.php b/lib/private/AppConfig.php
index b6412b410bb..976c33a9644 100644
--- a/lib/private/AppConfig.php
+++ b/lib/private/AppConfig.php
@@ -438,7 +438,8 @@ class AppConfig implements IAppConfig {
): string {
$this->assertParams($app, $key, valueType: $type);
$origKey = $key;
- if (!$this->matchAndApplyLexiconDefinition($app, $key, $lazy, $type, $default)) {
+ /** @var ConfigLexiconEntry $lexiconEntry */
+ if (!$this->matchAndApplyLexiconDefinition($app, $key, $lazy, $type, $default, lexiconEntry: $lexiconEntry)) {
return $default; // returns default if strictness of lexicon is set to WARNING (block and report)
}
$this->loadConfig($app, $lazy);
@@ -469,6 +470,13 @@ class AppConfig implements IAppConfig {
} elseif (isset($this->fastCache[$app][$key])) {
$value = $this->fastCache[$app][$key];
} else {
+ // unknown value, might want to execute something instead of just returning default.
+ // default value will be stored in database, unless false is returned
+ if (($lexiconEntry?->executeOnInit() !== null)
+ && $lexiconEntry->executeOnInit()($default) !== false) {
+ $this->setTypedValue($app, $key, $default, $lazy, $type);
+ }
+
return $default;
}
@@ -748,11 +756,18 @@ class AppConfig implements IAppConfig {
int $type,
): bool {
$this->assertParams($app, $key);
- if (!$this->matchAndApplyLexiconDefinition($app, $key, $lazy, $type)) {
+ /** @var ConfigLexiconEntry $lexiconEntry */
+ if (!$this->matchAndApplyLexiconDefinition($app, $key, $lazy, $type, lexiconEntry: $lexiconEntry)) {
return false; // returns false as database is not updated
}
$this->loadConfig(null, $lazy);
+ // might want to execute something before storing new value
+ // will cancel storing of new value in database if false is returned
+ if ($lexiconEntry?->executeOnSet() !== null && $lexiconEntry?->executeOnSet()($value) === false) {
+ return false;
+ }
+
$sensitive = $this->isTyped(self::VALUE_SENSITIVE, $type);
$inserted = $refreshCache = false;
@@ -1593,6 +1608,7 @@ class AppConfig implements IAppConfig {
?bool &$lazy = null,
int &$type = self::VALUE_MIXED,
string &$default = '',
+ ?ConfigLexiconEntry &$lexiconEntry = null,
): bool {
if (in_array($key,
[
@@ -1617,23 +1633,23 @@ class AppConfig implements IAppConfig {
return true;
}
- /** @var ConfigLexiconEntry $configValue */
- $configValue = $configDetails['entries'][$key];
+ /** @var ConfigLexiconEntry $lexiconEntry */
+ $lexiconEntry = $configDetails['entries'][$key];
$type &= ~self::VALUE_SENSITIVE;
- $appConfigValueType = $configValue->getValueType()->toAppConfigFlag();
+ $appConfigValueType = $lexiconEntry->getValueType()->toAppConfigFlag();
if ($type === self::VALUE_MIXED) {
$type = $appConfigValueType; // we overwrite if value was requested as mixed
} elseif ($appConfigValueType !== $type) {
throw new AppConfigTypeConflictException('The app config key ' . $app . '/' . $key . ' is typed incorrectly in relation to the config lexicon');
}
- $lazy = $configValue->isLazy();
- $default = $configValue->getDefault() ?? $default; // default from Lexicon got priority
- if ($configValue->isFlagged(self::FLAG_SENSITIVE)) {
+ $lazy = $lexiconEntry->isLazy();
+ $default = $lexiconEntry->getDefault() ?? $default; // default from Lexicon got priority
+ if ($lexiconEntry->isFlagged(self::FLAG_SENSITIVE)) {
$type |= self::VALUE_SENSITIVE;
}
- if ($configValue->isDeprecated()) {
+ if ($lexiconEntry->isDeprecated()) {
$this->logger->notice('App config key ' . $app . '/' . $key . ' is set as deprecated.');
}
diff --git a/lib/private/Config/UserConfig.php b/lib/private/Config/UserConfig.php
index f8c59a13d3d..f1418124fbd 100644
--- a/lib/private/Config/UserConfig.php
+++ b/lib/private/Config/UserConfig.php
@@ -721,7 +721,8 @@ class UserConfig implements IUserConfig {
): string {
$this->assertParams($userId, $app, $key);
$origKey = $key;
- if (!$this->matchAndApplyLexiconDefinition($userId, $app, $key, $lazy, $type, default: $default)) {
+ /** @var ConfigLexiconEntry $lexiconEntry */
+ if (!$this->matchAndApplyLexiconDefinition($userId, $app, $key, $lazy, $type, default: $default, lexiconEntry: $lexiconEntry)) {
// returns default if strictness of lexicon is set to WARNING (block and report)
return $default;
}
@@ -753,6 +754,13 @@ class UserConfig implements IUserConfig {
} elseif (isset($this->fastCache[$userId][$app][$key])) {
$value = $this->fastCache[$userId][$app][$key];
} else {
+ // unknown value, might want to execute something instead of just returning default.
+ // default value will be stored in database, unless false is returned
+ if (($lexiconEntry?->executeOnInit() !== null)
+ && $lexiconEntry->executeOnInit()($default) !== false) {
+ $this->setTypedValue($userId, $app, $key, $default, $lazy, 0, $type);
+ }
+
return $default;
}
@@ -1067,18 +1075,20 @@ class UserConfig implements IUserConfig {
int $flags,
ValueType $type,
): bool {
- // Primary email addresses are always(!) expected to be lowercase
- if ($app === 'settings' && $key === 'email') {
- $value = strtolower($value);
- }
-
$this->assertParams($userId, $app, $key);
- if (!$this->matchAndApplyLexiconDefinition($userId, $app, $key, $lazy, $type, $flags)) {
+ /** @var ConfigLexiconEntry $lexiconEntry */
+ if (!$this->matchAndApplyLexiconDefinition($userId, $app, $key, $lazy, $type, $flags, lexiconEntry: $lexiconEntry)) {
// returns false as database is not updated
return false;
}
$this->loadConfig($userId, $lazy);
+ // might want to execute something before storing new value
+ // will cancel storing of new value in database if false is returned
+ if ($lexiconEntry?->executeOnSet() !== null && $lexiconEntry?->executeOnSet()($value) === false) {
+ return false;
+ }
+
$inserted = $refreshCache = false;
$origValue = $value;
$sensitive = $this->isFlagged(self::FLAG_SENSITIVE, $flags);
@@ -1887,6 +1897,7 @@ class UserConfig implements IUserConfig {
ValueType &$type = ValueType::MIXED,
int &$flags = 0,
string &$default = '',
+ ?ConfigLexiconEntry &$lexiconEntry = null,
): bool {
$configDetails = $this->getConfigDetailsFromLexicon($app);
if (array_key_exists($key, $configDetails['aliases']) && !$this->ignoreLexiconAliases) {
@@ -1903,18 +1914,18 @@ class UserConfig implements IUserConfig {
return true;
}
- /** @var ConfigLexiconEntry $configValue */
- $configValue = $configDetails['entries'][$key];
+ /** @var ConfigLexiconEntry $lexiconEntry */
+ $lexiconEntry = $configDetails['entries'][$key];
if ($type === ValueType::MIXED) {
// we overwrite if value was requested as mixed
- $type = $configValue->getValueType();
- } elseif ($configValue->getValueType() !== $type) {
+ $type = $lexiconEntry->getValueType();
+ } elseif ($lexiconEntry->getValueType() !== $type) {
throw new TypeConflictException('The user config key ' . $app . '/' . $key . ' is typed incorrectly in relation to the config lexicon');
}
- $lazy = $configValue->isLazy();
- $flags = $configValue->getFlags();
- if ($configValue->isDeprecated()) {
+ $lazy = $lexiconEntry->isLazy();
+ $flags = $lexiconEntry->getFlags();
+ if ($lexiconEntry->isDeprecated()) {
$this->logger->notice('User config key ' . $app . '/' . $key . ' is set as deprecated.');
}
@@ -1925,7 +1936,7 @@ class UserConfig implements IUserConfig {
}
// default from Lexicon got priority but it can still be overwritten by admin
- $default = $this->getSystemDefault($app, $configValue) ?? $configValue->getDefault() ?? $default;
+ $default = $this->getSystemDefault($app, $lexiconEntry) ?? $lexiconEntry->getDefault() ?? $default;
// returning false will make get() returning $default and set() not changing value in database
return !$enforcedValue;