Files
nat-as-server/lib/client_code_range.php
Tom Hempel 4afab336ee
Some checks failed
PHPUnit / test (push) Has been cancelled
bulk client creation
2026-07-07 16:53:35 +02:00

75 lines
2.1 KiB
PHP

<?php
declare(strict_types=1);
/**
* @return array{prefix: string, digits: string, suffix: string}
*/
function qdb_parse_client_code_pattern(string $code): array
{
if (!preg_match('/\d/u', $code)) {
throw new InvalidArgumentException(
'Code must contain a numeric segment (e.g. C001 or A01Demo)',
);
}
$suffix = '';
if (preg_match('/[^0-9]+$/u', $code, $suffixMatch)) {
$suffix = $suffixMatch[0];
$core = substr($code, 0, -strlen($suffix));
} else {
$core = $code;
}
if (!preg_match('/^(.*?)(\d+)$/u', $core, $match) || $match[2] === '') {
throw new InvalidArgumentException(
'Code must contain a numeric segment (e.g. C001 or A01Demo)',
);
}
return [
'prefix' => $match[1],
'digits' => $match[2],
'suffix' => $suffix,
];
}
/**
* Expand a client-code range such as C001…C050 or A01Demo…A10Demo.
*
* @return list<string>
*/
function qdb_expand_client_code_range(string $from, string $to, int $maxCount = 500): array
{
$fromParts = qdb_parse_client_code_pattern($from);
$toParts = qdb_parse_client_code_pattern($to);
if ($fromParts['prefix'] !== $toParts['prefix'] || $fromParts['suffix'] !== $toParts['suffix']) {
throw new InvalidArgumentException(
'Prefix and suffix must match between from and to (e.g. C001…C050 or A01Demo…A10Demo)',
);
}
$prefix = $fromParts['prefix'];
$suffix = $fromParts['suffix'];
$padWidth = strlen($fromParts['digits']);
$start = (int) $fromParts['digits'];
$end = (int) $toParts['digits'];
if ($start > $end) {
throw new InvalidArgumentException('From number must be less than or equal to to');
}
$count = $end - $start + 1;
if ($count > $maxCount) {
throw new InvalidArgumentException("Range exceeds maximum of $maxCount clients");
}
$codes = [];
for ($n = $start; $n <= $end; $n++) {
$codes[] = $prefix . str_pad((string) $n, $padWidth, '0', STR_PAD_LEFT) . $suffix;
}
return $codes;
}