Files
2026-06-11 11:46:12 -04:00

208 lines
5.1 KiB
PHP

<?php
namespace App\Services\Badges;
use FPDF;
class BadgeTextFormatter
{
public function normalizeIds(array $ids): array
{
return array_values(array_unique(array_filter(array_map(static function ($v) {
if (is_string($v)) {
$v = trim($v);
}
if ($v === '' || $v === null) {
return null;
}
return (int) $v;
}, $ids), static fn ($v) => $v !== null && $v > 0)));
}
public function norm(?string $s): string
{
$s = (string) $s;
$s = str_replace(["\xC2\xA0", "\xA0"], ' ', $s);
$s = preg_replace('/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]/u', '', $s) ?? $s;
$s = preg_replace('/\s+/u', ' ', $s) ?? $s;
return trim($s);
}
public function toPdf(string $s): string
{
if (function_exists('iconv')) {
$o = @iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $s);
if ($o !== false && $o !== '') {
return $o;
}
}
if (function_exists('mb_convert_encoding')) {
$o = @mb_convert_encoding($s, 'ISO-8859-1', 'UTF-8');
if ($o !== '') {
return $o;
}
}
$o = @utf8_decode($s);
return $o !== '' ? $o : 'STAFF';
}
public function fitText(FPDF $pdf, string $text, int $startSize, int $minSize, float $maxWidth): int
{
$size = $startSize;
while ($size >= $minSize) {
$pdf->SetFontSize($size);
if ($pdf->GetStringWidth($text) <= $maxWidth) {
return $size;
}
$size--;
}
return $minSize;
}
public function formatRole(?string $role): string
{
$role = (string) $role;
$role = str_replace(['-', '_'], ' ', $role);
$role = preg_replace('/\s+/u', ' ', trim($role));
if ($role === '') {
return '';
}
$special = [
'of' => 'of',
'head' => 'Head',
];
$tokens = explode(' ', $role);
$out = [];
foreach ($tokens as $tok) {
if ($tok === '') {
continue;
}
$core = preg_replace('/^\P{L}+|\P{L}+$/u', '', $tok);
$start = strpos($tok, $core);
if ($start === false) {
$out[] = ucfirst(mb_strtolower($tok, 'UTF-8'));
continue;
}
$pre = substr($tok, 0, $start);
$suf = substr($tok, $start + strlen($core));
$lw = mb_strtolower($core, 'UTF-8');
if (isset($special[$lw])) {
$coreFmt = $special[$lw];
} elseif (preg_match('/^\p{L}{1,4}$/u', $core)) {
$coreFmt = mb_strtoupper($core, 'UTF-8');
} else {
$coreFmt = preg_replace_callback(
'/\p{L}+/u',
static fn ($m) => mb_strtoupper(mb_substr($m[0], 0, 1, 'UTF-8'), 'UTF-8')
.mb_strtolower(mb_substr($m[0], 1, null, 'UTF-8'), 'UTF-8'),
mb_strtolower($core, 'UTF-8')
);
}
$out[] = $pre.$coreFmt.$suf;
}
return implode(' ', $out);
}
public function formatRolesCsv(?string $csv): string
{
if ($csv === null) {
return '';
}
$parts = array_filter(array_map('trim', explode(',', (string) $csv)), 'strlen');
if (empty($parts)) {
return '';
}
return implode(', ', array_map(fn ($r) => $this->formatRole($r), $parts));
}
public function formatClass(string $class): string
{
$c = trim($class);
if ($c === '') {
return '';
}
$lc = strtolower($c);
if ($lc === 'kg' || $lc === 'kindergarten') {
return 'KG';
}
if ($lc === 'youth') {
return 'Youth';
}
return $c;
}
public function resolveRole(array $info): string
{
$candidates = [
'role',
'active_role',
'role_name',
fn ($r) => ! empty($r['roles'])
? (array_values(array_filter(array_map('trim', explode(',', (string) $r['roles']))))[0] ?? '')
: '',
'job_title',
'title',
'position',
'staff_role',
'department_role',
'dept_role',
];
foreach ($candidates as $key) {
if (is_callable($key)) {
$v = $key($info);
if ($this->norm($v) !== '') {
return $this->norm($v);
}
} else {
if (! empty($info[$key])) {
$v = $this->norm((string) $info[$key]);
if ($v !== '') {
return $v;
}
}
}
}
return 'STAFF';
}
public function firstExisting(array $paths): ?string
{
foreach ($paths as $path) {
if (! empty($path) && file_exists($path)) {
return $path;
}
}
return null;
}
}