58726ee0e9
API CI/CD / Validate (composer + pint) (push) Successful in 3m6s
API CI/CD / Test (PHPUnit) (push) Failing after 5m48s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 1m33s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
696 lines
22 KiB
PHP
696 lines
22 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Badges;
|
|
|
|
use App\Models\BadgePrintLog;
|
|
use App\Models\ClassSection;
|
|
use App\Models\Role;
|
|
use App\Models\TeacherClass;
|
|
use App\Models\User;
|
|
use App\Models\UserRole;
|
|
use FPDF;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class BadgeService
|
|
{
|
|
public function __construct(
|
|
protected User $userModel,
|
|
protected UserRole $userRoleModel,
|
|
protected Role $roleModel,
|
|
protected TeacherClass $teacherClassModel,
|
|
protected ClassSection $classSectionModel,
|
|
protected BadgePrintLog $badgePrintLogModel
|
|
) {}
|
|
|
|
public function generateBadgePdf(
|
|
array $userIds,
|
|
?string $schoolYear,
|
|
array $rolesMap = [],
|
|
array $classesMap = [],
|
|
?int $actorId = null
|
|
): Response {
|
|
$userIds = $this->normalizeIds($userIds);
|
|
|
|
$pdf = new FPDF('P', 'mm', 'A4');
|
|
$pdf->SetAutoPageBreak(false);
|
|
|
|
$badgeW = 95;
|
|
$badgeH = 67;
|
|
$marginL = 14;
|
|
$marginT = 6;
|
|
$gutterX = 0;
|
|
$gutterY = 0;
|
|
$cols = 2;
|
|
$rows = 4;
|
|
$perPage = $cols * $rows;
|
|
|
|
$pagesAdded = 0;
|
|
$i = 0;
|
|
$seen = [];
|
|
|
|
foreach ($userIds as $uid) {
|
|
$info = $this->getUserInfoById($uid, $schoolYear);
|
|
|
|
if (! $info || ! is_array($info)) {
|
|
continue;
|
|
}
|
|
|
|
$userId = (int) ($info['user_id'] ?? $uid);
|
|
$name = $this->norm($info['name'] ?? '');
|
|
|
|
$postedRole = $rolesMap[$userId] ?? null;
|
|
$roleResolved = $postedRole !== null
|
|
? $postedRole
|
|
: $this->resolveRole($info);
|
|
|
|
$roleResolved = $this->formatRole($roleResolved);
|
|
$info['role_resolved'] = $roleResolved;
|
|
|
|
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));
|
|
if (isset($seen[$badgeKey])) {
|
|
continue;
|
|
}
|
|
$seen[$badgeKey] = true;
|
|
|
|
if (($i % $perPage) === 0) {
|
|
$pdf->AddPage();
|
|
$pagesAdded++;
|
|
}
|
|
|
|
$indexOnPage = $i % $perPage;
|
|
$row = intdiv($indexOnPage, $cols);
|
|
$col = $indexOnPage % $cols;
|
|
|
|
$x = $marginL + $col * ($badgeW + $gutterX);
|
|
$y = $marginT + $row * ($badgeH + $gutterY);
|
|
|
|
$this->drawBadgeInCell($pdf, $info, $x, $y, $badgeW, $badgeH, $schoolYear);
|
|
$i++;
|
|
}
|
|
|
|
if ($pagesAdded === 0) {
|
|
$pdf->AddPage();
|
|
$pdf->SetFont('Arial', '', 10);
|
|
$pdf->SetXY(10, 20);
|
|
$pdf->MultiCell(0, 6, 'No valid staff selected or data not found.', 0, 'L');
|
|
}
|
|
|
|
$pdfString = $pdf->Output('S');
|
|
|
|
try {
|
|
$this->badgePrintLogModel->logPrints(
|
|
$userIds,
|
|
$actorId,
|
|
$schoolYear,
|
|
is_array($rolesMap) ? $rolesMap : [],
|
|
is_array($classesMap) ? $classesMap : [],
|
|
1
|
|
);
|
|
} catch (\Throwable $e) {
|
|
Log::error('Failed to log badge prints: '.$e->getMessage());
|
|
}
|
|
|
|
return response($pdfString, 200, [
|
|
'Content-Type' => 'application/pdf',
|
|
'Content-Disposition' => 'inline; filename="Staff_Badges.pdf"',
|
|
]);
|
|
}
|
|
|
|
public function getBadgePrintStatus(array $ids, ?string $schoolYear): array
|
|
{
|
|
$ids = $this->normalizeIds($ids);
|
|
|
|
return $this->badgePrintLogModel->getStatus($ids, $schoolYear);
|
|
}
|
|
|
|
public function logBadgePrint(
|
|
array $ids,
|
|
?string $schoolYear,
|
|
array $roles = [],
|
|
array $classes = [],
|
|
?int $actorId = null
|
|
): int {
|
|
$ids = $this->normalizeIds($ids);
|
|
|
|
return $this->badgePrintLogModel->logPrints(
|
|
$ids,
|
|
$actorId,
|
|
$schoolYear,
|
|
is_array($roles) ? $roles : [],
|
|
is_array($classes) ? $classes : [],
|
|
1
|
|
);
|
|
}
|
|
|
|
public function getBadgeFormData(?string $schoolYear, array $selectedUserIds = [], ?string $activeRole = null): array
|
|
{
|
|
$selectedUserIds = $this->normalizeIds($selectedUserIds);
|
|
|
|
$users = $this->fetchStaffList($schoolYear, $selectedUserIds);
|
|
|
|
foreach ($users as &$u) {
|
|
if (! isset($u['user_id'])) {
|
|
if (isset($u['id'])) {
|
|
$u['user_id'] = (int) $u['id'];
|
|
}
|
|
}
|
|
|
|
$rolesStr = $u['roles'] ?? '';
|
|
if ($rolesStr === '' && isset($u['role_name'])) {
|
|
$rolesStr = (string) $u['role_name'];
|
|
}
|
|
|
|
$u['roles_raw'] = $rolesStr;
|
|
$u['roles'] = $this->formatRolesCsv($rolesStr);
|
|
|
|
if (empty($u['role_name'])) {
|
|
$parts = array_filter(array_map('trim', explode(',', $rolesStr)));
|
|
$u['role_name'] = $parts[0] ?? '';
|
|
}
|
|
|
|
$u['role_name_raw'] = $u['role_name'];
|
|
$u['role_name'] = $this->formatRole((string) $u['role_name']);
|
|
|
|
$u['class_section_id'] = $u['class_section_id'] ?? null;
|
|
$u['class_section_name'] = $u['class_section_name'] ?? null;
|
|
}
|
|
unset($u);
|
|
|
|
foreach ($users as &$u) {
|
|
$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'])) {
|
|
$assign = $this->getLatestClassForUser((int) $u['user_id'], $schoolYear);
|
|
if ($assign) {
|
|
$u['class_section_id'] = $assign['class_section_id'] ?? null;
|
|
$u['class_section_name'] = $assign['class_section_name'] ?? null;
|
|
}
|
|
}
|
|
}
|
|
unset($u);
|
|
|
|
$schoolYears = $this->getAvailableSchoolYears();
|
|
|
|
$rolesTabs = [
|
|
'teacher' => 'Teachers',
|
|
'ta' => 'Teacher Assistants',
|
|
'admin' => 'Admins',
|
|
'staff' => 'Staff',
|
|
];
|
|
|
|
$activeRole = array_key_exists((string) $activeRole, $rolesTabs) ? (string) $activeRole : 'teacher';
|
|
|
|
return [
|
|
'users' => $users,
|
|
'schoolYears' => $schoolYears,
|
|
'selectedYear' => $schoolYear,
|
|
'selectedUserIds' => $selectedUserIds,
|
|
'rolesTabs' => $rolesTabs,
|
|
'active_role' => $activeRole,
|
|
];
|
|
}
|
|
|
|
protected function fetchStaffList(?string $schoolYear, array $selectedUserIds = []): array
|
|
{
|
|
$query = DB::table('users')
|
|
->leftJoin('user_roles', 'user_roles.user_id', '=', 'users.id')
|
|
->leftJoin('roles', 'roles.id', '=', 'user_roles.role_id')
|
|
->select([
|
|
'users.id',
|
|
'users.firstname',
|
|
'users.lastname',
|
|
DB::raw("GROUP_CONCAT(DISTINCT CASE WHEN LOWER(roles.name) != 'parent' THEN roles.name END ORDER BY roles.name SEPARATOR ', ') as roles"),
|
|
])
|
|
->groupBy('users.id', 'users.firstname', 'users.lastname');
|
|
|
|
if (! empty($selectedUserIds)) {
|
|
$query->whereIn('users.id', $selectedUserIds);
|
|
}
|
|
|
|
return array_map(static fn ($row) => (array) $row, $query->get()->all());
|
|
}
|
|
|
|
protected function getLatestClassForUser(int $userId, ?string $schoolYear = null): ?array
|
|
{
|
|
$query = DB::table('teacher_class as tc')
|
|
->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'tc.class_section_id')
|
|
->select([
|
|
'tc.class_section_id',
|
|
'cs.class_section_name',
|
|
])
|
|
->where('tc.teacher_id', $userId);
|
|
|
|
if (! empty($schoolYear)) {
|
|
$query->where('tc.school_year', $schoolYear);
|
|
}
|
|
|
|
$row = $query
|
|
->orderByRaw("FIELD(tc.position, 'main', 'ta')")
|
|
->orderByRaw('IFNULL(tc.updated_at,"0000-00-00 00:00:00") DESC')
|
|
->orderByDesc('tc.id')
|
|
->first();
|
|
|
|
if (! $row || empty($row->class_section_id)) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'class_section_id' => (int) $row->class_section_id,
|
|
'class_section_name' => $row->class_section_name ?? null,
|
|
];
|
|
}
|
|
|
|
public function getUserInfoById(int $id, ?string $schoolYear = null): ?array
|
|
{
|
|
$u = DB::table('users')
|
|
->select(['id as user_id', 'firstname', 'lastname'])
|
|
->where('id', $id)
|
|
->first();
|
|
|
|
if (! $u) {
|
|
return null;
|
|
}
|
|
|
|
$userId = (int) $u->user_id;
|
|
$fullname = trim(($u->firstname ?? '').' '.($u->lastname ?? ''));
|
|
|
|
$rolesRows = DB::table('user_roles as ur')
|
|
->join('roles as r', 'r.id', '=', 'ur.role_id')
|
|
->select(['r.id as role_id', 'r.name as role_name'])
|
|
->where('ur.user_id', $userId)
|
|
->get();
|
|
|
|
$allRoles = [];
|
|
foreach ($rolesRows as $rr) {
|
|
$name = trim((string) ($rr->role_name ?? ''));
|
|
if ($name !== '' && strtolower($name) !== 'parent') {
|
|
$allRoles[] = ucwords(strtolower($name));
|
|
}
|
|
}
|
|
|
|
$allRoles = array_values(array_unique($allRoles));
|
|
$rolesCsv = $allRoles ? implode(', ', $allRoles) : '';
|
|
|
|
$tcQuery = DB::table('teacher_class')
|
|
->select(['class_section_id', 'updated_at', 'id', 'position', 'school_year'])
|
|
->where('teacher_id', $userId);
|
|
|
|
if (! empty($schoolYear)) {
|
|
$tcQuery->where('school_year', $schoolYear);
|
|
}
|
|
|
|
$assignment = $tcQuery
|
|
->orderByRaw('IFNULL(updated_at, "1970-01-01 00:00:00") DESC, id DESC')
|
|
->first();
|
|
|
|
$classId = $assignment->class_section_id ?? null;
|
|
$position = strtolower(trim((string) ($assignment->position ?? '')));
|
|
$className = null;
|
|
|
|
if (! empty($classId)) {
|
|
$className = $this->resolveClassName((int) $classId);
|
|
}
|
|
|
|
if (in_array($position, ['ta', 'teacher_assistant', 'assistant'], true)) {
|
|
$roleLabel = 'Teacher Assistant';
|
|
} elseif ($position === 'teacher' || $position === 'main') {
|
|
$roleLabel = 'Teacher';
|
|
} elseif (! empty($allRoles)) {
|
|
$roleLabel = $allRoles[0];
|
|
} else {
|
|
$roleLabel = 'Staff';
|
|
}
|
|
|
|
$schoolLogo = $this->firstExisting([
|
|
public_path('assets/images/school_logo.png'),
|
|
public_path('assets/images/logo.png'),
|
|
]);
|
|
|
|
$isglLogo = $this->firstExisting([
|
|
public_path('assets/images/isgl_logo.png'),
|
|
public_path('assets/images/isgl.png'),
|
|
]);
|
|
|
|
$jobTitle = '';
|
|
if (! empty($roleLabel) && ! empty($className)) {
|
|
$jobTitle = "{$roleLabel} - {$className}";
|
|
} elseif (! empty($roleLabel)) {
|
|
$jobTitle = $roleLabel;
|
|
} 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' => $userId,
|
|
'school_logo' => $schoolLogo,
|
|
'isgl_logo' => $isglLogo,
|
|
'school_year' => $assignment->school_year ?? $schoolYear,
|
|
];
|
|
}
|
|
|
|
protected function drawBadgeInCell(FPDF $pdf, array $data, float $x, float $y, float $w, float $h, ?string $schoolYear): void
|
|
{
|
|
$pdf->SetFillColor(255, 255, 255);
|
|
$pdf->Rect($x, $y, $w, $h, 'F');
|
|
$pdf->SetDrawColor(200, 200, 200);
|
|
$pdf->Rect($x, $y, $w, $h);
|
|
|
|
$logoSize = 6;
|
|
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'])) {
|
|
$pdf->Image($data['isgl_logo'], $x + 4, $y + 4, $logoSize + 3, $logoSize - 1);
|
|
}
|
|
|
|
$padX = 4;
|
|
$cursorY = $y + 4 + $logoSize + 2;
|
|
|
|
$schoolName = strtoupper($this->norm($data['school_name'] ?? 'AL RAHMA SUNDAY SCHOOL'));
|
|
$pdf->SetFont('Arial', '', 16);
|
|
$pdf->SetXY($x + $padX, $cursorY);
|
|
$pdf->MultiCell($w - 2 * $padX, 5, $this->toPdf($schoolName), 0, 'C');
|
|
|
|
$pdf->Ln(9);
|
|
$pdf->SetFont('Arial', 'B', 14);
|
|
$pdf->SetX($x + $padX);
|
|
$name = strtoupper($this->norm($data['name'] ?? 'STAFF'));
|
|
$pdf->Cell($w - 2 * $padX, 6, $this->toPdf($name), 0, 1, 'C');
|
|
|
|
$roleResolved = $this->norm((string) ($data['role_resolved'] ?? ''));
|
|
if ($roleResolved === '') {
|
|
$roleResolved = $this->resolveRole($data);
|
|
}
|
|
if ($roleResolved !== '') {
|
|
$roleResolved = $this->formatRole($roleResolved);
|
|
}
|
|
|
|
$classRaw = $this->norm($data['class_section_name'] ?? '');
|
|
$class = $this->formatClass($classRaw);
|
|
|
|
$detectSrc = strtolower($this->norm(
|
|
($data['roles_raw'] ?? '') !== '' ? $data['roles_raw'] : (($data['role_name_raw'] ?? '') !== '' ? $data['role_name_raw'] : $roleResolved)
|
|
));
|
|
$isTeacherish = str_contains($detectSrc, 'teacher') || preg_match('/\bta\b/', $detectSrc);
|
|
|
|
if ($isTeacherish && $class !== '') {
|
|
if (strtolower($class) === 'youth') {
|
|
$display = 'Youth '.$roleResolved;
|
|
} elseif ($class === 'KG') {
|
|
$display = 'KG '.$roleResolved;
|
|
} else {
|
|
$display = 'Grade '.$class.' '.$roleResolved;
|
|
}
|
|
} elseif ($roleResolved !== '') {
|
|
$display = $roleResolved;
|
|
} elseif ($class !== '') {
|
|
$display = $class;
|
|
} else {
|
|
$display = 'STAFF';
|
|
}
|
|
|
|
$pdf->Ln(6);
|
|
$pdf->SetFont('Arial', '', 14);
|
|
$displayOut = $this->toPdf($display);
|
|
$maxTextWidth = $w - 2 * $padX;
|
|
$best = $this->fitText($pdf, $displayOut, 11, 7, $maxTextWidth);
|
|
$pdf->SetFont('Arial', '', $best + 4);
|
|
|
|
if ($pdf->GetStringWidth($displayOut) <= $maxTextWidth) {
|
|
$pdf->SetX($x + $padX);
|
|
$pdf->Cell($maxTextWidth, 5, $displayOut, 0, 1, 'C');
|
|
} else {
|
|
$pdf->SetX($x + $padX);
|
|
$pdf->MultiCell($maxTextWidth, 5, $displayOut, 0, 'C');
|
|
}
|
|
|
|
$footerYear = $this->norm((string) ($schoolYear ?? ($data['school_year'] ?? '')));
|
|
if ($footerYear !== '') {
|
|
$pdf->SetFont('Arial', 'I', 14);
|
|
$pdf->SetXY($x + $padX, $y + $h - 9);
|
|
$pdf->Cell($w - 2 * $padX, 4, $this->toPdf($footerYear), 0, 0, 'C');
|
|
}
|
|
}
|
|
|
|
protected function resolveRole(array $info): string
|
|
{
|
|
$candidates = [
|
|
'role',
|
|
'active_role',
|
|
'role_name',
|
|
fn ($r) => ! empty($r['roles'])
|
|
? (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';
|
|
}
|
|
|
|
protected 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)));
|
|
}
|
|
|
|
protected function norm(?string $s): string
|
|
{
|
|
$s = (string) $s;
|
|
$s = str_replace(["\xC2\xA0", "\xA0"], ' ', $s);
|
|
$s = preg_replace('/\s+/u', ' ', $s) ?? $s;
|
|
$s = preg_replace('/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]/u', '', $s) ?? $s;
|
|
|
|
return trim($s);
|
|
}
|
|
|
|
protected 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';
|
|
}
|
|
|
|
protected 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;
|
|
}
|
|
|
|
protected 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);
|
|
}
|
|
|
|
protected 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));
|
|
}
|
|
|
|
protected 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;
|
|
}
|
|
|
|
protected function firstExisting(array $paths): ?string
|
|
{
|
|
foreach ($paths as $path) {
|
|
if (! empty($path) && file_exists($path)) {
|
|
return $path;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
protected function resolveClassName(int $classSectionId): ?string
|
|
{
|
|
$row = DB::table('classSection')
|
|
->select('class_section_name')
|
|
->where('class_section_id', $classSectionId)
|
|
->first();
|
|
|
|
return $row->class_section_name ?? null;
|
|
}
|
|
|
|
protected function getAvailableSchoolYears(): array
|
|
{
|
|
$schoolYears = [];
|
|
|
|
try {
|
|
if (DB::getSchemaBuilder()->hasTable('teacher_class')) {
|
|
$schoolYears = DB::table('teacher_class')
|
|
->selectRaw('DISTINCT school_year')
|
|
->whereNotNull('school_year')
|
|
->orderByDesc('school_year')
|
|
->pluck('school_year')
|
|
->filter()
|
|
->values()
|
|
->all();
|
|
}
|
|
} catch (\Throwable) {
|
|
}
|
|
|
|
if (empty($schoolYears)) {
|
|
try {
|
|
if (
|
|
DB::getSchemaBuilder()->hasTable('user_roles') &&
|
|
DB::getSchemaBuilder()->hasColumn('user_roles', 'school_year')
|
|
) {
|
|
$schoolYears = DB::table('user_roles')
|
|
->selectRaw('DISTINCT school_year')
|
|
->whereNotNull('school_year')
|
|
->orderByDesc('school_year')
|
|
->pluck('school_year')
|
|
->filter()
|
|
->values()
|
|
->all();
|
|
}
|
|
} catch (\Throwable) {
|
|
}
|
|
}
|
|
|
|
return $schoolYears;
|
|
}
|
|
}
|