added qdb_normalize_stable_key function to create stable identifiers from arbitrary key strings

This commit is contained in:
2026-05-27 20:13:43 +02:00
parent 24080bb8b9
commit 5d539c130f

View File

@ -441,12 +441,41 @@ function qdb_is_stable_key(string $s): bool {
return $s !== '' && (bool)preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $s);
}
/**
* Coerce an arbitrary key string into a stable identifier (letters, digits, underscores;
* must start with a letter). Used on import and API writes so bundles are not limited to
* pre-validated keys (e.g. numeric option labels "1", "42").
*/
function qdb_normalize_stable_key(string $s): string {
$s = trim($s);
if ($s === '') {
return '';
}
if (qdb_is_stable_key($s)) {
return $s;
}
$out = preg_replace('/[^a-zA-Z0-9_]+/', '_', $s);
$out = preg_replace('/_+/', '_', $out ?? '');
$out = trim($out, '_');
if ($out === '') {
return 'k_' . substr(hash('crc32b', $s), 0, 8);
}
if (!preg_match('/^[a-zA-Z]/', $out)) {
$out = 'k_' . $out;
}
return qdb_is_stable_key($out) ? $out : 'k_' . substr(hash('crc32b', $s), 0, 8);
}
function qdb_validate_stable_key(string $s, string $label = 'Key'): string {
$s = trim($s);
if (!qdb_is_stable_key($s)) {
json_error('INVALID_FIELD', "$label must match [a-zA-Z][a-zA-Z0-9_]*", 400);
if ($s === '') {
json_error('INVALID_FIELD', "$label is required", 400);
}
return $s;
$normalized = qdb_normalize_stable_key($s);
if (!qdb_is_stable_key($normalized)) {
json_error('INVALID_FIELD', "$label could not be normalized to a valid key", 400);
}
return $normalized;
}
/** Resolve app lookup key for a question row. */