isAdminLike($roles, $permissions); $isTeacher = in_array('teacher', $roles, true) || in_array('ta', $roles, true) || in_array('teacher_assistant', $roles, true); if ($status === 'finalized' || $status === 'published') { return $isAdmin; } if ($status === 'submitted') { return $isAdmin; } if ($status === 'draft') { return $isAdmin || $isTeacher; } return $isAdmin; } public function isTeacher(array $roles): bool { $roles = array_map([$this, 'normalizeRole'], $roles); return in_array('teacher', $roles, true) || in_array('ta', $roles, true) || in_array('teacher_assistant', $roles, true) || in_array('assistant_teacher', $roles, true); } public function isAdminLike(array $roles, array $permissions = []): bool { $roles = array_map([$this, 'normalizeRole'], $roles); $adminTokens = $this->adminRoleTokens(); if (! empty($adminTokens) && count(array_intersect($roles, $adminTokens)) > 0) { return true; } foreach ($permissions as $permission) { $permission = strtolower(trim((string) $permission)); if (str_contains($permission, 'attendance.manage') || str_contains($permission, 'attendance.admin')) { return true; } } return false; } public function normalizeRole(?string $role): string { return str_replace([' ', '-'], '_', strtolower(trim((string) $role))); } public function canManageEarlyDismissals(array $userRoles): bool { $normalized = array_map([$this, 'normalizeRole'], $userRoles); $adminTokens = $this->adminRoleTokens(); $isAdminLike = count(array_intersect($normalized, $adminTokens)) > 0; $isTeacher = in_array('teacher', $normalized, true) || in_array('teacher_assistant', $normalized, true); return $isAdminLike || $isTeacher; } private function adminRoleTokens(): array { static $cache = null; if (is_array($cache)) { return $cache; } $tokens = []; $normalize = fn (string $value): string => $this->normalizeRole($value); try { $rows = Role::query() ->where('is_active', 1) ->get(['name', 'slug']); $excluded = array_map($normalize, [ 'guest', 'parent', 'student', 'teacher', 'teacher_assistant', 'ta', ]); foreach ($rows as $row) { $name = $normalize((string) ($row->name ?? '')); $slug = $normalize((string) ($row->slug ?? $name)); if ($name === '' && $slug === '') { continue; } if (in_array($slug, $excluded, true) || in_array($name, $excluded, true)) { continue; } if ($name !== '') { $tokens[$name] = true; } if ($slug !== '') { $tokens[$slug] = true; } } } catch (\Throwable) { // ignore and fall back to defaults } foreach (['administrator', 'admin', 'principal', 'vice_principal', 'vice-principal'] as $fallback) { $tokens[$normalize($fallback)] = true; } $cache = array_keys($tokens); return $cache; } }