138 lines
5.1 KiB
PHP
Executable File
138 lines
5.1 KiB
PHP
Executable File
<?php
|
|
// app/Libraries/AttendancePolicy.php
|
|
namespace App\Libraries;
|
|
|
|
use App\Models\RoleModel;
|
|
|
|
class AttendancePolicy
|
|
{
|
|
/**
|
|
* Return a normalized set of tokens (slug and name variants) for roles
|
|
* considered "admin-like" according to the roles table.
|
|
*
|
|
* Rule: any active role whose slug is NOT in the excluded non-admin set
|
|
* (guest, parent, student, teacher, teacher_assistant, ta) is treated
|
|
* as admin-like. Fallback to config('Roles')->roles if the table is
|
|
* unavailable.
|
|
*/
|
|
private static function adminRoleTokens(): array
|
|
{
|
|
static $cache = null;
|
|
if ($cache !== null) return $cache;
|
|
|
|
$normalize = static function (string $v): string {
|
|
$v = strtolower(trim($v));
|
|
return str_replace([' ', '-'], '_', $v);
|
|
};
|
|
|
|
$tokens = [];
|
|
try {
|
|
$model = new RoleModel();
|
|
$rows = $model
|
|
->select('name, slug')
|
|
->where('is_active', 1)
|
|
->findAll();
|
|
|
|
// Slugs that are explicitly NOT admin-like
|
|
$excluded = ['guest','parent','student','teacher','teacher_assistant','ta'];
|
|
$excluded = array_map($normalize, $excluded);
|
|
|
|
foreach ($rows as $r) {
|
|
$name = $normalize((string)($r['name'] ?? ''));
|
|
$slug = $normalize((string)($r['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;
|
|
}
|
|
|
|
// Safety net: ensure common admin labels are present if defined
|
|
foreach (['administrator','admin','principal','vice_principal','vice-principal'] as $s) {
|
|
$tokens[$normalize($s)] = true;
|
|
}
|
|
} catch (\Throwable $e) {
|
|
// Fallback: use Roles config (if provided)
|
|
try {
|
|
$cfg = config('Roles');
|
|
if ($cfg && is_array($cfg->roles ?? null)) {
|
|
foreach ($cfg->roles as $r) {
|
|
$tokens[$normalize((string)$r)] = true;
|
|
}
|
|
}
|
|
} catch (\Throwable $e2) {
|
|
// minimal fallback
|
|
foreach (['administrator','admin','principal','vice_principal'] as $r) {
|
|
$tokens[$normalize($r)] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $cache = array_keys($tokens);
|
|
}
|
|
|
|
public static function canManageEarlyDismissals(array $userRoles): bool
|
|
{
|
|
$normalizedRoles = array_map(static function ($r) {
|
|
$r = strtolower((string) $r);
|
|
$r = str_replace([' ', '-'], '_', $r);
|
|
return $r;
|
|
}, $userRoles);
|
|
|
|
$adminTokens = self::adminRoleTokens();
|
|
$isAdminLike = count(array_intersect($normalizedRoles, $adminTokens)) > 0;
|
|
|
|
$isTeacher = in_array('teacher', $normalizedRoles, true) || in_array('teacher_assistant', $normalizedRoles, true);
|
|
|
|
return $isAdminLike || $isTeacher;
|
|
}
|
|
|
|
public static function canEditDay(array $day, array $user): bool
|
|
{
|
|
// Normalize roles (e.g., "Vice Principal" -> "vice_principal")
|
|
$roles = array_map(static function ($r) {
|
|
$r = strtolower((string) $r);
|
|
$r = str_replace([' ', '-'], '_', $r);
|
|
return $r;
|
|
}, (array) ($user['roles'] ?? []));
|
|
|
|
// Helper: permissions may be provided either as an associative map
|
|
// ['attendance.admin_edit' => true] or as a flat list ['attendance.admin_edit']
|
|
$perms = $user['permissions'] ?? [];
|
|
$hasPerm = static function (string $key) use ($perms): bool {
|
|
if (is_array($perms)) {
|
|
// Associative-style map
|
|
if (array_key_exists($key, $perms)) {
|
|
return (bool) $perms[$key];
|
|
}
|
|
// Flat list of strings
|
|
return in_array($key, $perms, true);
|
|
}
|
|
return false;
|
|
};
|
|
|
|
// Determine admin-like status from roles table
|
|
$adminTokens = self::adminRoleTokens();
|
|
$isAdminLike = count(array_intersect($roles, $adminTokens)) > 0;
|
|
|
|
// Allow via explicit permissions as well
|
|
$canAdminEditSubmitted = $hasPerm('attendance.admin_edit') || $hasPerm('attendance_admin_edit');
|
|
$canOverridePublished = $hasPerm('attendance.override_publish') || $hasPerm('attendance_override_publish');
|
|
|
|
switch ($day['status']) {
|
|
case 'draft':
|
|
// Open for teachers and admins
|
|
return true;
|
|
case 'submitted':
|
|
// Teachers locked; allow admin-like users, or holders of admin-edit permission
|
|
return $isAdminLike || $canAdminEditSubmitted;
|
|
case 'published':
|
|
// Only allow if explicit override permission is granted
|
|
return $canOverridePublished;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
}
|