add tests batch 20

This commit is contained in:
root
2026-06-09 01:03:53 -04:00
parent 95efb9652e
commit 6be4875c5e
1502 changed files with 13797 additions and 11313 deletions
+18 -17
View File
@@ -8,7 +8,8 @@ class BadgeFormDataService
protected BadgeUserLookupService $lookupService,
protected BadgeStudentLookupService $studentLookupService,
protected BadgeTextFormatter $formatter
) {}
) {
}
public function build(
?string $schoolYear,
@@ -23,7 +24,7 @@ class BadgeFormDataService
$students = $this->studentLookupService->fetchStudentList($schoolYear, $selectedStudentIds);
foreach ($users as &$u) {
if (! isset($u['user_id']) && isset($u['id'])) {
if (!isset($u['user_id']) && isset($u['id'])) {
$u['user_id'] = (int) $u['id'];
}
@@ -45,7 +46,7 @@ class BadgeFormDataService
$u['class_section_id'] = $u['class_section_id'] ?? null;
$u['class_section_name'] = $u['class_section_name'] ?? null;
$u['entity_type'] = 'user';
$u['row_id'] = 'user:'.(int) ($u['user_id'] ?? 0);
$u['row_id'] = 'user:' . (int) ($u['user_id'] ?? 0);
$u['role_group'] = $this->detectRoleGroup(
strtolower((string) ($u['roles_raw'] ?? ($u['role_name_raw'] ?? '')))
);
@@ -56,7 +57,7 @@ class BadgeFormDataService
$rolesDetect = strtolower((string) ($u['roles_raw'] ?? ($u['role_name_raw'] ?? '')));
$isTeacherish = str_contains($rolesDetect, 'teacher') || preg_match('/\bta\b/', $rolesDetect);
if ($isTeacherish && ! empty($u['user_id'])) {
if ($isTeacherish && !empty($u['user_id'])) {
$assign = $this->lookupService->getLatestClassForUser((int) $u['user_id'], $schoolYear);
if ($assign) {
$u['class_section_id'] = $assign['class_section_id'] ?? null;
@@ -68,7 +69,7 @@ class BadgeFormDataService
foreach ($students as &$student) {
$student['entity_type'] = 'student';
$student['row_id'] = 'student:'.(int) ($student['student_id'] ?? 0);
$student['row_id'] = 'student:' . (int) ($student['student_id'] ?? 0);
$student['role_group'] = 'student';
$student['class_section_id'] = null;
@@ -83,17 +84,17 @@ class BadgeFormDataService
$rows = array_merge($users, $students);
usort($rows, static function (array $a, array $b): int {
return strcasecmp(
trim((string) ($a['lastname'] ?? '')).' '.trim((string) ($a['firstname'] ?? '')),
trim((string) ($b['lastname'] ?? '')).' '.trim((string) ($b['firstname'] ?? ''))
trim((string) ($a['lastname'] ?? '')) . ' ' . trim((string) ($a['firstname'] ?? '')),
trim((string) ($b['lastname'] ?? '')) . ' ' . trim((string) ($b['firstname'] ?? ''))
);
});
$rolesTabs = [
'all' => 'All',
'all' => 'All',
'teacher' => 'Teachers',
'ta' => 'Teacher Assistants',
'admin' => 'Admins',
'staff' => 'Staff',
'ta' => 'Teacher Assistants',
'admin' => 'Admins',
'staff' => 'Staff',
'student' => 'Students',
];
@@ -102,13 +103,13 @@ class BadgeFormDataService
: 'all';
return [
'users' => $rows,
'schoolYears' => $this->lookupService->getAvailableSchoolYears(),
'selectedYear' => $schoolYear,
'selectedUserIds' => $selectedUserIds,
'users' => $rows,
'schoolYears' => $this->lookupService->getAvailableSchoolYears(),
'selectedYear' => $schoolYear,
'selectedUserIds' => $selectedUserIds,
'selectedStudentIds' => $selectedStudentIds,
'rolesTabs' => $rolesTabs,
'active_role' => $activeRole,
'rolesTabs' => $rolesTabs,
'active_role' => $activeRole,
];
}
+62 -61
View File
@@ -33,13 +33,14 @@ class BadgePdfService
protected BadgeUserLookupService $userLookupService,
protected BadgePrintLogService $printLogService,
protected BadgeTextFormatter $formatter,
) {}
) {
}
/**
* Letter landscape PDF, 8 badges per page — students and/or staff (FPDF + QR PNG).
*
* @param int[] $studentIds Primary keys on `students.id`
* @param int[] $userIds Staff/admin/teacher keys on `users.id`
* @param int[] $userIds Staff/admin/teacher keys on `users.id`
*/
public function generate(
array $studentIds,
@@ -85,7 +86,7 @@ class BadgePdfService
try {
$qrPayload = (string) ($staffRow['user_id_for_qr'] ?? $staffRow['user_id'] ?? '');
if ($qrPayload === '' || ! preg_match('/^[A-Za-z0-9_-]+$/', $qrPayload)) {
if ($qrPayload === '' || !preg_match('/^[A-Za-z0-9_-]+$/', $qrPayload)) {
$qrPayload = (string) (int) ($staffRow['user_id'] ?? 0);
}
@@ -143,7 +144,7 @@ class BadgePdfService
): string {
$html = $this->buildHtmlDocument($rows, $schoolName, $motto, $footerBlock);
$options = new Options;
$options = new Options();
$options->set('isHtml5ParserEnabled', true);
$options->set('isRemoteEnabled', true);
$options->set('defaultFont', 'DejaVu Sans');
@@ -167,7 +168,7 @@ class BadgePdfService
$this->tempQrFiles = [];
try {
if (! class_exists('FPDF', false)) {
if (!class_exists('FPDF', false)) {
require_once base_path('app/ThirdParty/fpdf/fpdf.php');
}
@@ -199,7 +200,7 @@ class BadgePdfService
for ($gridCol = 0; $gridCol < 4; $gridCol++) {
$idx = ($gridRow * 4) + $gridCol;
$row = $slots[$idx];
if (! is_array($row)) {
if (!is_array($row)) {
continue;
}
@@ -261,7 +262,7 @@ class BadgePdfService
array $classesMap
): ?array {
$info = $this->userLookupService->getUserInfoById($userId, $schoolYear);
if (! $info || ! is_array($info)) {
if (!$info || !is_array($info)) {
return null;
}
@@ -275,7 +276,7 @@ class BadgePdfService
$roleResolved = $this->formatter->formatRole($roleResolved);
$info['role_resolved'] = $roleResolved;
if (! empty($classesMap[$resolvedId])) {
if (!empty($classesMap[$resolvedId])) {
$info['class_section_name'] = (string) $classesMap[$resolvedId];
}
@@ -290,11 +291,11 @@ class BadgePdfService
if ($isTeacherish && $class !== '') {
if (strtolower($class) === 'youth') {
$display = 'Youth '.$roleResolved;
$display = 'Youth ' . $roleResolved;
} elseif ($class === 'KG') {
$display = 'KG '.$roleResolved;
$display = 'KG ' . $roleResolved;
} else {
$display = 'Grade '.$class.' '.$roleResolved;
$display = 'Grade ' . $class . ' ' . $roleResolved;
}
} elseif ($roleResolved !== '') {
$display = $roleResolved;
@@ -308,7 +309,7 @@ class BadgePdfService
$year = $this->formatter->norm((string) ($info['school_year'] ?? ($schoolYear ?? '')));
$schoolId = trim((string) ($info['school_id'] ?? ''));
if ($schoolId === '' || ! preg_match('/^[A-Za-z0-9_-]+$/', $schoolId)) {
if ($schoolId === '' || !preg_match('/^[A-Za-z0-9_-]+$/', $schoolId)) {
return null;
}
@@ -363,10 +364,10 @@ class BadgePdfService
}
return '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Badges PDF</title><style>'
.$this->badgeCss()
.'</style></head><body>'
.$badgesHtml
.'</body></html>';
. $this->badgeCss()
. '</style></head><body>'
. $badgesHtml
. '</body></html>';
}
protected function buildBadgeHtml(
@@ -375,7 +376,8 @@ class BadgePdfService
string $motto,
string $footerBlock,
?string $logoDataUri
): string {
): string
{
$kind = (string) ($row['_badge_kind'] ?? 'student');
$idLabel = $kind === 'staff' ? 'User ID' : 'School ID';
$title = $this->escapeHtml((string) ($row['fullname'] ?? ''));
@@ -402,8 +404,8 @@ class BadgePdfService
<div class="info-row">
<span class="icon-badge">G</span>
<span class="info-copy">
<span class="label">'.$gradeLabel.'</span>
<span class="value">'.$grade.'</span>
<span class="label">' . $gradeLabel . '</span>
<span class="value">' . $grade . '</span>
</span>
</div>';
}
@@ -413,15 +415,15 @@ class BadgePdfService
<span class="icon-badge">Y</span>
<span class="info-copy">
<span class="label">Academic Year</span>
<span class="value">'.$year.'</span>
<span class="value">' . $year . '</span>
</span>
</div>
<div class="info-row">
<span class="icon-badge">ID</span>
<span class="info-copy">
<span class="label">'.$this->escapeHtml($idLabel).'</span>
<span class="value">'.$schoolId.'</span>
<span class="label">' . $this->escapeHtml($idLabel) . '</span>
<span class="value">' . $schoolId . '</span>
</span>
</div>';
@@ -430,18 +432,18 @@ class BadgePdfService
<div class="header-wrap">
<div class="header">
<div class="header-mark">'
.($logoDataUri !== null
? '<img src="'.$logoDataUri.'" alt="School Logo">'
: '<span>AS</span>').
. ($logoDataUri !== null
? '<img src="' . $logoDataUri . '" alt="School Logo">'
: '<span>AS</span>') .
'</div>
<div class="header-copy">
<div class="school-name">'.$this->escapeHtml($headerMainTitle).'</div>
'.($schoolLevel !== ''
? '<div class="sub-school">'.$this->escapeHtml($schoolLevel).'</div>'
: '').'
'.($headerMotto !== ''
? '<div class="motto">'.$this->escapeHtml($headerMotto).'</div>'
: '').'
<div class="school-name">' . $this->escapeHtml($headerMainTitle) . '</div>
' . ($schoolLevel !== ''
? '<div class="sub-school">' . $this->escapeHtml($schoolLevel) . '</div>'
: '') . '
' . ($headerMotto !== ''
? '<div class="motto">' . $this->escapeHtml($headerMotto) . '</div>'
: '') . '
</div>
</div>
<div class="header-accent"></div>
@@ -449,25 +451,25 @@ class BadgePdfService
</div>
<div class="body">
<div class="student-name">'.mb_strtoupper($title, 'UTF-8').'</div>
<div class="student-name">' . mb_strtoupper($title, 'UTF-8') . '</div>
<div class="name-divider">
<span class="divider-line"></span>
<span class="divider-dot"></span>
<span class="divider-line"></span>
</div>
<div class="role">'.mb_strtoupper($role, 'UTF-8').'</div>
<div class="role">' . mb_strtoupper($role, 'UTF-8') . '</div>
<table class="content">
<tr>
<td class="info">
'.$infoRows.'
' . $infoRows . '
</td>
<td class="qr-col">
<div class="qr-box">'
.($qrSrc !== ''
? '<img src="'.$qrSrc.'" alt="QR Code">'
: '').
. ($qrSrc !== ''
? '<img src="' . $qrSrc . '" alt="QR Code">'
: '') .
'</div>
<div class="scan-pill">Scan to verify</div>
</td>
@@ -475,18 +477,18 @@ class BadgePdfService
</table>
<div class="barcode-wrap">
<div class="barcode-bars">'.$this->buildBarcodeHtml($barcodeValue).'</div>
<div class="barcode-text">'.$barcodeText.'</div>
<div class="barcode-bars">' . $this->buildBarcodeHtml($barcodeValue) . '</div>
<div class="barcode-text">' . $barcodeText . '</div>
</div>
</div>
<div class="footer">
<span class="footer-mark">'
.($logoDataUri !== null
? '<img src="'.$logoDataUri.'" alt="School Logo">'
: '<span>S</span>').
. ($logoDataUri !== null
? '<img src="' . $logoDataUri . '" alt="School Logo">'
: '<span>S</span>') .
'</span>
<span class="footer-copy">'.$footer.'</span>
<span class="footer-copy">' . $footer . '</span>
</div>
</div>
';
@@ -897,7 +899,7 @@ CSS;
default => '4px',
};
$bars[] = '<span class="barcode-bar" style="width:'.$width.'"></span>';
$bars[] = '<span class="barcode-bar" style="width:' . $width . '"></span>';
$bars[] = '<span class="barcode-bar" style="width:1px"></span>';
}
@@ -915,7 +917,7 @@ CSS;
return null;
}
$tmpPath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'badge_qr_'.bin2hex(random_bytes(8)).'.png';
$tmpPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'badge_qr_' . bin2hex(random_bytes(8)) . '.png';
if (@file_put_contents($tmpPath, $png) === false) {
return null;
}
@@ -1000,11 +1002,11 @@ CSS;
{
return $this->formatter->firstExisting([
public_path($filename),
public_path('badges/'.$filename),
public_path('assets/images/'.$filename),
public_path('assets/images/badges/'.$filename),
storage_path('app/public/'.$filename),
storage_path('app/public/badges/'.$filename),
public_path('badges/' . $filename),
public_path('assets/images/' . $filename),
public_path('assets/images/badges/' . $filename),
storage_path('app/public/' . $filename),
storage_path('app/public/badges/' . $filename),
]);
}
@@ -1085,7 +1087,7 @@ CSS;
/**
* Shrink text until it fits in the available width. FPDF, bravely, does not do this for us.
*
* @param array{0:int,1:int,2:int} $rgb
* @param array{0:int,1:int,2:int} $rgb
*/
protected function fitCenteredText(
\FPDF $pdf,
@@ -1147,7 +1149,7 @@ CSS;
}
/**
* @param array{0:int,1:int,2:int} $rgb
* @param array{0:int,1:int,2:int} $rgb
*/
protected function fitLeftText(
\FPDF $pdf,
@@ -1445,7 +1447,6 @@ CSS;
foreach ($segments as [$type, $segmentWidth]) {
if ($type === 'gap') {
$cursor += $segmentWidth;
continue;
}
@@ -1509,7 +1510,7 @@ CSS;
protected function preparedLogoPath(): ?string
{
$path = $this->logoFilePath();
if ($path === null || ! is_readable($path)) {
if ($path === null || !is_readable($path)) {
return null;
}
@@ -1518,7 +1519,7 @@ CSS;
return $path;
}
$tmpPath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'badge_logo_'.bin2hex(random_bytes(8)).'.png';
$tmpPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'badge_logo_' . bin2hex(random_bytes(8)) . '.png';
if (@file_put_contents($tmpPath, $png) === false) {
return $path;
}
@@ -1531,7 +1532,7 @@ CSS;
protected function logoDataUri(): ?string
{
$path = $this->logoFilePath();
if ($path === null || ! is_readable($path)) {
if ($path === null || !is_readable($path)) {
return null;
}
@@ -1543,9 +1544,10 @@ CSS;
return null;
}
return 'data:image/png;base64,'.base64_encode($bytes);
return 'data:image/png;base64,' . base64_encode($bytes);
}
protected function headerMainTitle(string $schoolName): string
{
$name = trim($schoolName) !== '' ? trim($schoolName) : 'Al Rahma Sunday School';
@@ -1577,7 +1579,7 @@ CSS;
{
$address = trim((string) config('badges.footer_address', ''));
if ($address !== '') {
return $schoolName."\n".$address;
return $schoolName . "\n" . $address;
}
return $schoolName;
@@ -1585,7 +1587,7 @@ CSS;
protected function makeCircularPngBytesFromPath(string $path): ?string
{
if (! function_exists('imagecreatetruecolor') || ! function_exists('imagepng')) {
if (!function_exists('imagecreatetruecolor') || !function_exists('imagepng')) {
return null;
}
@@ -1624,7 +1626,6 @@ CSS;
$circle = imagecreatetruecolor($size, $size);
if ($circle === false) {
imagedestroy($square);
return null;
}
+4 -3
View File
@@ -10,7 +10,8 @@ class BadgePrintLogService
public function __construct(
protected BadgePrintLog $badgePrintLogModel,
protected BadgeTextFormatter $formatter
) {}
) {
}
public function getStatus(array $userIds, ?string $schoolYear): array
{
@@ -50,7 +51,7 @@ class BadgePrintLogService
try {
$this->log($userIds, $actorId, $schoolYear, $rolesMap, $classesMap, $copies);
} catch (\Throwable $e) {
Log::error('Failed to log badge prints: '.$e->getMessage());
Log::error('Failed to log badge prints: ' . $e->getMessage());
}
}
}
}
+31 -31
View File
@@ -23,7 +23,8 @@ class BadgeService
protected TeacherClass $teacherClassModel,
protected ClassSection $classSectionModel,
protected BadgePrintLog $badgePrintLogModel
) {}
) {
}
public function generateBadgePdf(
array $userIds,
@@ -54,7 +55,7 @@ class BadgeService
foreach ($userIds as $uid) {
$info = $this->getUserInfoById($uid, $schoolYear);
if (! $info || ! is_array($info)) {
if (!$info || !is_array($info)) {
continue;
}
@@ -69,13 +70,13 @@ class BadgeService
$roleResolved = $this->formatRole($roleResolved);
$info['role_resolved'] = $roleResolved;
if (! empty($classesMap[$userId])) {
if (!empty($classesMap[$userId])) {
$info['class_section_name'] = (string) $classesMap[$userId];
}
$class = $this->norm($info['class_section_name'] ?? '');
$badgeKey = strtolower(trim($userId.'|'.$name.'|'.$roleResolved.'|'.$class));
$badgeKey = strtolower(trim($userId . '|' . $name . '|' . $roleResolved . '|' . $class));
if (isset($seen[$badgeKey])) {
continue;
}
@@ -116,7 +117,7 @@ class BadgeService
1
);
} catch (\Throwable $e) {
Log::error('Failed to log badge prints: '.$e->getMessage());
Log::error('Failed to log badge prints: ' . $e->getMessage());
}
return response($pdfString, 200, [
@@ -158,7 +159,7 @@ class BadgeService
$users = $this->fetchStaffList($schoolYear, $selectedUserIds);
foreach ($users as &$u) {
if (! isset($u['user_id'])) {
if (!isset($u['user_id'])) {
if (isset($u['id'])) {
$u['user_id'] = (int) $u['id'];
}
@@ -189,7 +190,7 @@ class BadgeService
$rolesDetect = strtolower($u['roles_raw'] ?? ($u['role_name_raw'] ?? ''));
$isTeacherish = str_contains($rolesDetect, 'teacher') || preg_match('/\bta\b/', $rolesDetect);
if ($isTeacherish && ! empty($u['user_id'])) {
if ($isTeacherish && !empty($u['user_id'])) {
$assign = $this->getLatestClassForUser((int) $u['user_id'], $schoolYear);
if ($assign) {
$u['class_section_id'] = $assign['class_section_id'] ?? null;
@@ -233,11 +234,11 @@ class BadgeService
])
->groupBy('users.id', 'users.firstname', 'users.lastname');
if (! empty($selectedUserIds)) {
if (!empty($selectedUserIds)) {
$query->whereIn('users.id', $selectedUserIds);
}
if (! empty($schoolYear) && Schema::hasColumn('user_roles', 'school_year')) {
if (!empty($schoolYear) && Schema::hasColumn('user_roles', 'school_year')) {
$query->where('user_roles.school_year', $schoolYear);
}
@@ -254,7 +255,7 @@ class BadgeService
])
->where('tc.teacher_id', $userId);
if (! empty($schoolYear)) {
if (!empty($schoolYear)) {
$query->where('tc.school_year', $schoolYear);
}
@@ -264,7 +265,7 @@ class BadgeService
->orderByDesc('tc.id')
->first();
if (! $row || empty($row->class_section_id)) {
if (!$row || empty($row->class_section_id)) {
return null;
}
@@ -281,12 +282,12 @@ class BadgeService
->where('id', $id)
->first();
if (! $u) {
if (!$u) {
return null;
}
$userId = (int) $u->user_id;
$fullname = trim(($u->firstname ?? '').' '.($u->lastname ?? ''));
$fullname = trim(($u->firstname ?? '') . ' ' . ($u->lastname ?? ''));
$rolesRows = DB::table('user_roles as ur')
->join('roles as r', 'r.id', '=', 'ur.role_id')
@@ -309,7 +310,7 @@ class BadgeService
->select(['class_section_id', 'updated_at', 'id', 'position', 'school_year'])
->where('teacher_id', $userId);
if (! empty($schoolYear)) {
if (!empty($schoolYear)) {
$tcQuery->where('school_year', $schoolYear);
}
@@ -321,7 +322,7 @@ class BadgeService
$position = strtolower(trim((string) ($assignment->position ?? '')));
$className = null;
if (! empty($classId)) {
if (!empty($classId)) {
$className = $this->resolveClassName((int) $classId);
}
@@ -329,7 +330,7 @@ class BadgeService
$roleLabel = 'Teacher Assistant';
} elseif ($position === 'teacher' || $position === 'main') {
$roleLabel = 'Teacher';
} elseif (! empty($allRoles)) {
} elseif (!empty($allRoles)) {
$roleLabel = $allRoles[0];
} else {
$roleLabel = 'Staff';
@@ -346,11 +347,11 @@ class BadgeService
]);
$jobTitle = '';
if (! empty($roleLabel) && ! empty($className)) {
if (!empty($roleLabel) && !empty($className)) {
$jobTitle = "{$roleLabel} - {$className}";
} elseif (! empty($roleLabel)) {
} elseif (!empty($roleLabel)) {
$jobTitle = $roleLabel;
} elseif (! empty($className)) {
} elseif (!empty($className)) {
$jobTitle = $className;
}
@@ -378,10 +379,10 @@ class BadgeService
$pdf->Rect($x, $y, $w, $h);
$logoSize = 6;
if (! empty($data['school_logo']) && file_exists($data['school_logo'])) {
if (!empty($data['school_logo']) && file_exists($data['school_logo'])) {
$pdf->Image($data['school_logo'], $x + $w - 6 - $logoSize, $y + 4, $logoSize + 3, $logoSize - 1);
}
if (! empty($data['isgl_logo']) && file_exists($data['isgl_logo'])) {
if (!empty($data['isgl_logo']) && file_exists($data['isgl_logo'])) {
$pdf->Image($data['isgl_logo'], $x + 4, $y + 4, $logoSize + 3, $logoSize - 1);
}
@@ -417,11 +418,11 @@ class BadgeService
if ($isTeacherish && $class !== '') {
if (strtolower($class) === 'youth') {
$display = 'Youth '.$roleResolved;
$display = 'Youth ' . $roleResolved;
} elseif ($class === 'KG') {
$display = 'KG '.$roleResolved;
$display = 'KG ' . $roleResolved;
} else {
$display = 'Grade '.$class.' '.$roleResolved;
$display = 'Grade ' . $class . ' ' . $roleResolved;
}
} elseif ($roleResolved !== '') {
$display = $roleResolved;
@@ -460,7 +461,7 @@ class BadgeService
'role',
'active_role',
'role_name',
fn ($r) => ! empty($r['roles'])
fn ($r) => !empty($r['roles'])
? (array_filter(array_map('trim', explode(',', (string) $r['roles'])))[0] ?? '')
: '',
'job_title',
@@ -478,7 +479,7 @@ class BadgeService
return $this->norm($v);
}
} else {
if (! empty($info[$key])) {
if (!empty($info[$key])) {
$v = $this->norm((string) $info[$key]);
if ($v !== '') {
return $v;
@@ -578,7 +579,6 @@ class BadgeService
if ($start === false) {
$out[] = ucfirst(mb_strtolower($tok, 'UTF-8'));
continue;
}
@@ -594,12 +594,12 @@ class BadgeService
$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(mb_substr($m[0], 1, null, 'UTF-8'), 'UTF-8'),
mb_strtolower($core, 'UTF-8')
);
}
$out[] = $pre.$coreFmt.$suf;
$out[] = $pre . $coreFmt . $suf;
}
return implode(' ', $out);
@@ -640,7 +640,7 @@ class BadgeService
protected function firstExisting(array $paths): ?string
{
foreach ($paths as $path) {
if (! empty($path) && file_exists($path)) {
if (!empty($path) && file_exists($path)) {
return $path;
}
}
@@ -697,4 +697,4 @@ class BadgeService
return $schoolYears;
}
}
}
@@ -12,7 +12,8 @@ class BadgeStudentLookupService
{
public function __construct(
protected BadgeTextFormatter $formatter
) {}
) {
}
/**
* Active student roster for the badge picker.
@@ -28,7 +29,7 @@ class BadgeStudentLookupService
->leftJoin('student_class as sc', function ($join) use ($schoolYear) {
$join->on('sc.student_id', '=', 'students.id');
if (! empty($schoolYear)) {
if (!empty($schoolYear)) {
$join->where('sc.school_year', '=', $schoolYear);
}
})
@@ -54,9 +55,9 @@ class BadgeStudentLookupService
->orderBy('students.lastname')
->orderBy('students.firstname');
if (! empty($selectedStudentIds)) {
if (!empty($selectedStudentIds)) {
$query->whereIn('students.id', $selectedStudentIds);
} elseif (! empty($schoolYear)) {
} elseif (!empty($schoolYear)) {
$query->where(function ($q) use ($schoolYear) {
$q->where('students.school_year', $schoolYear)
->orWhereNotNull('sc.student_id');
@@ -73,7 +74,7 @@ class BadgeStudentLookupService
}
$schoolId = trim((string) ($row['school_id'] ?? ''));
if ($schoolId === '' || ! preg_match('/^[A-Za-z0-9_-]+$/', $schoolId)) {
if ($schoolId === '' || !preg_match('/^[A-Za-z0-9_-]+$/', $schoolId)) {
continue;
}
@@ -116,7 +117,7 @@ class BadgeStudentLookupService
$out = [];
foreach ($rows as $student) {
$schoolId = trim((string) ($student->school_id ?? ''));
if ($schoolId === '' || ! preg_match('/^[A-Za-z0-9_-]+$/', $schoolId)) {
if ($schoolId === '' || !preg_match('/^[A-Za-z0-9_-]+$/', $schoolId)) {
continue;
}
+6 -7
View File
@@ -78,7 +78,7 @@ class BadgeTextFormatter
}
$special = [
'of' => 'of',
'of' => 'of',
'head' => 'Head',
];
@@ -95,7 +95,6 @@ class BadgeTextFormatter
if ($start === false) {
$out[] = ucfirst(mb_strtolower($tok, 'UTF-8'));
continue;
}
@@ -111,12 +110,12 @@ class BadgeTextFormatter
$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(mb_substr($m[0], 1, null, 'UTF-8'), 'UTF-8'),
mb_strtolower($core, 'UTF-8')
);
}
$out[] = $pre.$coreFmt.$suf;
$out[] = $pre . $coreFmt . $suf;
}
return implode(' ', $out);
@@ -164,7 +163,7 @@ class BadgeTextFormatter
'role',
'active_role',
'role_name',
fn ($r) => ! empty($r['roles'])
fn ($r) => !empty($r['roles'])
? (array_values(array_filter(array_map('trim', explode(',', (string) $r['roles']))))[0] ?? '')
: '',
'job_title',
@@ -182,7 +181,7 @@ class BadgeTextFormatter
return $this->norm($v);
}
} else {
if (! empty($info[$key])) {
if (!empty($info[$key])) {
$v = $this->norm((string) $info[$key]);
if ($v !== '') {
return $v;
@@ -197,7 +196,7 @@ class BadgeTextFormatter
public function firstExisting(array $paths): ?string
{
foreach ($paths as $path) {
if (! empty($path) && file_exists($path)) {
if (!empty($path) && file_exists($path)) {
return $path;
}
}
+26 -25
View File
@@ -9,7 +9,8 @@ class BadgeUserLookupService
{
public function __construct(
protected BadgeTextFormatter $formatter
) {}
) {
}
public function fetchStaffList(?string $schoolYear, array $selectedUserIds = []): array
{
@@ -24,7 +25,7 @@ class BadgeUserLookupService
])
->groupBy('users.id', 'users.firstname', 'users.lastname');
if (! empty($selectedUserIds)) {
if (!empty($selectedUserIds)) {
$query->whereIn('users.id', $selectedUserIds);
}
@@ -64,7 +65,7 @@ class BadgeUserLookupService
])
->where('tc.teacher_id', $userId);
if (! empty($schoolYear)) {
if (!empty($schoolYear)) {
$query->where('tc.school_year', $schoolYear);
}
@@ -74,12 +75,12 @@ class BadgeUserLookupService
->orderByDesc('tc.id')
->first();
if (! $row || empty($row->class_section_id)) {
if (!$row || empty($row->class_section_id)) {
return null;
}
return [
'class_section_id' => (int) $row->class_section_id,
'class_section_id' => (int) $row->class_section_id,
'class_section_name' => $row->class_section_name ?? null,
];
}
@@ -91,12 +92,12 @@ class BadgeUserLookupService
->where('id', $id)
->first();
if (! $u) {
if (!$u) {
return null;
}
$userId = (int) $u->user_id;
$fullname = trim(($u->firstname ?? '').' '.($u->lastname ?? ''));
$fullname = trim(($u->firstname ?? '') . ' ' . ($u->lastname ?? ''));
$schoolId = trim((string) ($u->school_id ?? ''));
if ($schoolId === '') {
$schoolId = trim((string) ($u->account_id ?? ''));
@@ -123,7 +124,7 @@ class BadgeUserLookupService
->select(['class_section_id', 'updated_at', 'id', 'position', 'school_year'])
->where('teacher_id', $userId);
if (! empty($schoolYear)) {
if (!empty($schoolYear)) {
$tcQuery->where('school_year', $schoolYear);
}
@@ -135,7 +136,7 @@ class BadgeUserLookupService
$position = strtolower(trim((string) ($assignment->position ?? '')));
$className = null;
if (! empty($classId)) {
if (!empty($classId)) {
$className = $this->resolveClassName((int) $classId);
}
@@ -143,7 +144,7 @@ class BadgeUserLookupService
$roleLabel = 'Teacher Assistant';
} elseif ($position === 'teacher' || $position === 'main') {
$roleLabel = 'Teacher';
} elseif (! empty($allRoles)) {
} elseif (!empty($allRoles)) {
$roleLabel = $allRoles[0];
} else {
$roleLabel = 'Staff';
@@ -160,27 +161,27 @@ class BadgeUserLookupService
]);
$jobTitle = '';
if (! empty($roleLabel) && ! empty($className)) {
if (!empty($roleLabel) && !empty($className)) {
$jobTitle = "{$roleLabel} - {$className}";
} elseif (! empty($roleLabel)) {
} elseif (!empty($roleLabel)) {
$jobTitle = $roleLabel;
} elseif (! empty($className)) {
} elseif (!empty($className)) {
$jobTitle = $className;
}
return [
'user_id' => $userId,
'name' => $fullname !== '' ? $fullname : 'STAFF',
'role' => $roleLabel,
'roles' => $rolesCsv,
'class_section_id' => $classId ? (int) $classId : null,
'class_section_name' => $className,
'job_title' => $jobTitle,
'school_name' => 'Al Rahma Sunday School',
'school_id' => $schoolId,
'school_logo' => $schoolLogo,
'isgl_logo' => $isglLogo,
'school_year' => $assignment->school_year ?? $schoolYear,
'user_id' => $userId,
'name' => $fullname !== '' ? $fullname : 'STAFF',
'role' => $roleLabel,
'roles' => $rolesCsv,
'class_section_id' => $classId ? (int) $classId : null,
'class_section_name' => $className,
'job_title' => $jobTitle,
'school_name' => 'Al Rahma Sunday School',
'school_id' => $schoolId,
'school_logo' => $schoolLogo,
'isgl_logo' => $isglLogo,
'school_year' => $assignment->school_year ?? $schoolYear,
];
}