diff --git a/contrib/openldap/core-fd-conf.schema b/contrib/openldap/core-fd-conf.schema index 32291dc1f04be61a5b19cdef3c28f4cf464c40d6..a27f7f7227403abc842b34acfe58f8d9c4ddeeb3 100644 --- a/contrib/openldap/core-fd-conf.schema +++ b/contrib/openldap/core-fd-conf.schema @@ -425,6 +425,13 @@ attributetype ( 1.3.6.1.4.1.38414.8.18.12 NAME 'fdAclTargetFilterLimit' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) +attributetype ( 1.3.6.1.4.1.38414.8.18.13 NAME 'fdIncrementalModifierStates' + DESC 'FusionDirectory - States of the incremental modifier intances, with keys value and date, encoded as JSON' + EQUALITY caseExactMatch + SUBSTR caseExactSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 + SINGLE-VALUE ) + # Plugins attributetype ( 1.3.6.1.4.1.38414.8.19.1 NAME 'fdOGroupRDN' @@ -610,6 +617,7 @@ objectclass ( 1.3.6.1.4.1.38414.8.2.1 NAME 'fusionDirectoryConf' fdTabHook $ fdShells $ fdDefaultShell $ fdDisplayHookOutput $ fdPluginsMenuBlacklist $ fdManagementConfig $ fdManagementUserConfig $ fdAclTabOnObjects $ fdDepartmentCategories $ fdAclTargetFilterLimit $ + fdIncrementalModifierStates $ fdSslCaCertPath $ fdSslKeyPath $ fdSslCertPath $ fdCasActivated $ fdCasServerCaCertPath $ fdCasHost $ fdCasPort $ fdCasContext $ fdLoginMethod diff --git a/include/class_Lock.inc b/include/class_Lock.inc index 3b1a110d18ebc91f02bcdbbf7a9efd0f2688658f..0e370eefcf7732b36bb2cce725b5a1f9fb5d4fb0 100644 --- a/include/class_Lock.inc +++ b/include/class_Lock.inc @@ -38,7 +38,7 @@ class Lock * \brief Add a lock for object(s) * * Adds a lock by the specified user for one ore multiple objects. - * If the lock for that object already exists, an error is triggered. + * If a lock for that object already exists from another user, an error is triggered. * * \param array $object The object or array of objects to lock * @@ -267,6 +267,34 @@ class Lock return $locks; } + + /*! + * \brief Add a lock for object(s) or fail + * + * Adds a lock by the specified user for one ore multiple objects. + * If the lock for that object already exists, waits a bit and retry. + * If a lock cannot be set, throws. + * + * \param array|string $object The object or array of objects to lock + * + * \param string $user The user who shall own the lock + * + * \param int $retries how many times we can retry (waiting a second each time) + */ + public static function addOrFail ($object, string $user = NULL, int $retries = 10) + { + $wait = $retries; + while (!empty($locks = Lock::get($object))) { + sleep(1); + + /* Oups - timed out */ + if ($wait-- == 0) { + throw new FusionDirectoryException(_('Timeout while waiting for lock!')); + } + } + Lock::add($object, $user); + } + /*! * \brief Generate a lock message * diff --git a/include/class_templateHandling.inc b/include/class_templateHandling.inc index 18b382a45ff713d971303fca56e03730f51016d9..1ccf38406a0e87ee8567d0c0391d082408c22144 100644 --- a/include/class_templateHandling.inc +++ b/include/class_templateHandling.inc @@ -436,6 +436,11 @@ class templateHandling return [$dateObject->format($args[1])]; } + /* + First parameter is whether the number should always be there or only in case of duplicates (1 or 0, defaults to 0). + Second parameter is starting number, defaults to 1. + Third parameter is step, defaults to 1. + */ private static function modifierNumber (array $args) { if (count($args) < 1) { @@ -462,6 +467,53 @@ class templateHandling return $numberGenerator($args[0], $args[1], $args[2]); } + /* + Modifier parameters: + * id + * starting number, defaults to 1. + * step, defaults to 1. + */ + private static function modifierIncremental (array $args): array + { + global $config; + + if (count($args) < 1) { + throw new FusionDirectoryException(_('Missing id parameter for incremental modifier')); + } + if (count($args) < 2) { + $args[] = 1; + } + if (count($args) < 3) { + $args[] = 1; + } + $configDn = CONFIGRDN.$config->current['BASE']; + Lock::addOrFail($configDn); + $tabObject = objects::open($configDn, 'configuration'); + $json = $tabObject->getBaseObject()->fdIncrementalModifierStates; + if (empty($json)) { + $modifierStates = []; + } else { + $modifierStates = json_decode($json, TRUE); + } + if (isset($modifierStates[$args[0]])) { + $value = $modifierStates[$args[0]]['value'] + $args[2]; + } else { + $value = $args[1]; + } + $modifierStates[$args[0]] = [ + 'value' => $value, + 'date' => date('Y-m-d'), + ]; + $tabObject->getBaseObject()->fdIncrementalModifierStates = json_encode($modifierStates); + $errors = $tabObject->save(); + Lock::deleteByObject($configDn); + if (!empty($errors)) { + throw $errors[0]; + } + + return [$value]; + } + private static function modifierTitleCase ($str) { return [mb_convert_case($str, MB_CASE_TITLE, 'UTF-8')]; @@ -581,6 +633,10 @@ class templateHandling // title case $result = static::modifierTitleCase($str); break; + case 'e': + // incremental number + $result = static::modifierIncremental($args); + break; default: trigger_error("Unkown modifier '$m'"); $result = [$str]; diff --git a/plugins/config/class_configInLdap.inc b/plugins/config/class_configInLdap.inc index 456e4d76c72450d6e42c7f11caaa557b6569f74f..8c5bac2cfc27f8b541905cad978e841057d96a38 100644 --- a/plugins/config/class_configInLdap.inc +++ b/plugins/config/class_configInLdap.inc @@ -72,6 +72,7 @@ class configInLdap extends simplePlugin ['America/New_York'] ), new HiddenAttribute('fusionConfigMd5'), + new HiddenAttribute('fdIncrementalModifierStates'), ] ], 'core_settings' => [