Globinours/app/Services/Ids.php

73 lines
2 KiB
PHP

<?php
declare(strict_types=1);
final class Ids
{
public static function validRna(string $value): bool
{
$value = strtoupper(preg_replace('/\s+/', '', trim($value)) ?? '');
return $value === '' || preg_match('/^W[0-9]{9}$/', $value) === 1;
}
public static function validSiret(string $value): bool
{
$digits = preg_replace('/\D+/', '', trim($value)) ?? '';
if ($digits === '') {
return true;
}
if (strlen($digits) !== 14) {
return false;
}
$sum = 0;
foreach (str_split($digits) as $index => $digit) {
$number = (int) $digit * ($index % 2 === 0 ? 2 : 1);
$sum += $number > 9 ? $number - 9 : $number;
}
return $sum % 10 === 0;
}
public static function slugifyUpper(string $s): string
{
$s = trim($s);
if ($s === '') {
return 'SANS-NOM';
}
// translit: accents -> ascii (si dispo)
$t = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s);
if ($t !== false) {
$s = $t;
}
$s = strtoupper($s);
$s = preg_replace('/[^A-Z0-9]+/', '-', $s) ?? $s;
$s = trim($s, '-');
return $s !== '' ? $s : 'SANS-NOM';
}
public static function nextAnimalCode(string $name, ?int $year = null): string
{
$year = $year ?? (int) date('Y');
$slug = self::slugifyUpper($name);
$db = DB::pdo();
$stmt = $db->prepare(
'SELECT internal_code FROM animals WHERE internal_code LIKE :p ORDER BY internal_code DESC LIMIT 1',
);
$stmt->execute([':p' => $year . '-%']);
$last = (string) ($stmt->fetchColumn() ?: '');
$n = 1;
if ($last !== '') {
// format attendu: YYYY-NNN-...
$parts = explode('-', $last);
if (count($parts) >= 2 && ctype_digit($parts[1])) {
$n = (int) $parts[1] + 1;
}
}
return sprintf('%d-%03d-%s', $year, $n, $slug);
}
}