agent foundation

This commit is contained in:
2026-03-06 00:44:52 +01:00
parent 9819cba733
commit 9a08f96c11
199 changed files with 8522 additions and 1880 deletions

View File

@@ -129,6 +129,7 @@ class TenantCustomFieldService
return ['ok' => false, 'errors' => [t('Custom field can not be updated')], 'form' => $form];
}
// When type is changed away from select/multiselect, remove orphaned option rows.
if (in_array($form['type'], ['select', 'multiselect'], true)) {
TenantCustomFieldOptionRepository::replaceForDefinition((int) $existing['id'], $form['options']);
} else {
@@ -220,6 +221,7 @@ class TenantCustomFieldService
$form['options'] = [];
}
// Text/textarea types can't be used as filters — too many distinct values to enumerate in UI.
if (!in_array($type, ['select', 'multiselect', 'boolean', 'date'], true)) {
$form['is_filterable'] = 0;
}
@@ -227,6 +229,8 @@ class TenantCustomFieldService
return $errors;
}
// Line format: "key|Label" or just "Label" (key is derived from the label when omitted).
// Duplicate keys are silently dropped — first occurrence wins.
private static function parseOptionsLines(string $value): array
{
$lines = preg_split('/\r\n|\r|\n/', $value);
@@ -261,6 +265,8 @@ class TenantCustomFieldService
return array_values($options);
}
// Transliterates accented characters (é → e, ü → u) before slugifying so non-ASCII labels
// produce readable keys. Falls back to direct slugification if iconv is unavailable.
private static function normalizeKey(string $value): string
{
$value = trim($value);
@@ -307,6 +313,7 @@ class TenantCustomFieldService
return '';
}
// Auto-increment suffix until a unique key is found; 10000 guard prevents infinite loop.
$candidate = $base;
$counter = 2;
while (true) {