prepare("SELECT is_superadmin FROM auth_users WHERE id = ?"); $st->execute([$userId]); self::$superadmin = ($st->fetchColumn() === 'Y'); self::$memberships = self::loadMemberships($userId); // TEMPORANEO (fase monoscuola): utente senza scuola -> agganciato a Seregno if (empty(self::$memberships) && !self::$superadmin) { $ins = $pdo->prepare( "INSERT IGNORE INTO school_user (user_id, idschool, school_role) VALUES (?, ?, 'student')" ); $ins->execute([$userId, self::DEFAULT_SCHOOL]); self::$memberships = self::loadMemberships($userId); } $requested = isset($_SESSION['idschool']) ? (int) $_SESSION['idschool'] : 0; $selected = self::pick($requested); if ($selected === null) { http_response_code(403); die('Nessuna scuola attiva associata a questo account.'); } $selected['idschool'] = (int) $selected['idschool']; $_SESSION['idschool'] = $selected['idschool']; self::$school = $selected; return self::$school; } /** Cambia scuola corrente. False se l'utente non può accedervi. */ public static function switchTo(int $idschool): bool { if ($idschool <= 0) { return false; } foreach (self::available() as $s) { if ((int) $s['idschool'] === $idschool) { $_SESSION['idschool'] = $idschool; self::$school = null; self::resolve(self::$userId); return true; } } return false; } /** Scuole selezionabili (permessi reali). Superadmin: tutte. */ public static function available(): array { if (!self::$superadmin) { return self::$memberships; } $roles = []; foreach (self::$memberships as $m) { $roles[(int) $m['idschool']] = $m['school_role']; } $all = self::pdo()->query("SELECT * FROM schools ORDER BY name")->fetchAll(); foreach ($all as &$s) { $s['school_role'] = $roles[(int) $s['idschool']] ?? 'superadmin'; } unset($s); return $all; } /* ================================================================== */ /* VISTA ATTIVA */ /* ================================================================== */ /** * Viste consentite in base ai permessi REALI, dalla più alta alla più bassa. * @return array chiave => etichetta */ public static function viewModes(): array { $real = self::realRole(); $modes = []; if (self::$superadmin) { $modes['superadmin'] = 'Superadmin'; } if (self::$superadmin || in_array($real, ['owner', 'admin'], true)) { $modes['school'] = 'Scuola'; } if ($real === 'teacher') { $modes['teacher'] = 'Insegnante'; } $modes['student'] = 'Allievo'; return $modes; } /** Vista attiva (se quella in sessione non è consentita: la più alta) */ public static function viewMode(): string { $modes = self::viewModes(); $req = $_SESSION['view_mode'] ?? ''; if (isset($modes[$req])) { return $req; } return (string) array_key_first($modes); } public static function setViewMode(string $mode): bool { if (!isset(self::viewModes()[$mode])) { return false; } $_SESSION['view_mode'] = $mode; return true; } /** Pagina iniziale per la vista attiva */ public static function landingPage(): string { switch (self::viewMode()) { case 'superadmin': return 'sa-schools.php'; case 'school': case 'teacher': return 'adminpanel.php'; default: return 'userpanel.php'; } } /* ================================================================== */ /* GETTER E CONTROLLI (tengono conto della vista) */ /* ================================================================== */ public static function id(): int { return self::get()['idschool']; } public static function get(): array { if (self::$school === null) { throw new RuntimeException('SchoolContext::resolve() non ancora chiamato'); } return self::$school; } /** Ruolo REALE nella scuola: owner|admin|teacher|student|superadmin */ public static function realRole(): string { return self::get()['school_role']; } /** Alias storico di realRole() */ public static function role(): string { return self::realRole(); } public static function isRealSuperadmin(): bool { return self::$superadmin; } public static function isSuperadmin(): bool { return self::viewMode() === 'superadmin'; } public static function isOwner(): bool { return self::realRole() === 'owner' && self::isSchoolAdmin(); } /** Gestisce la scuola (vista superadmin o scuola) */ public static function isSchoolAdmin(): bool { return in_array(self::viewMode(), ['superadmin', 'school'], true); } /** Staff: amministratori + insegnanti */ public static function isStaff(): bool { return self::isSchoolAdmin() || self::viewMode() === 'teacher'; } public static function requireSchoolAdmin(): void { if (!self::isSchoolAdmin()) { self::deny(); } } public static function requireStaff(): void { if (!self::isStaff()) { self::deny(); } } public static function requireSuperadmin(): void { if (!self::isSuperadmin()) { self::deny(); } } /* ================================================================== */ /* INTERNI */ /* ================================================================== */ private static function deny(): void { http_response_code(403); $home = self::$school ? self::landingPage() : 'userpanel.php'; die('Accesso non autorizzato con la vista attuale. Torna alla pagina iniziale'); } private static function pick(int $requested): ?array { foreach (self::$memberships as $m) { if ((int) $m['idschool'] === $requested) { return $m; } } if (self::$superadmin) { $pdo = self::pdo(); if ($requested > 0) { $st = $pdo->prepare("SELECT * FROM schools WHERE idschool = ?"); $st->execute([$requested]); $row = $st->fetch(); if ($row) { $row['school_role'] = 'superadmin'; return $row; } } if (!empty(self::$memberships)) { return self::$memberships[0]; } $row = $pdo->query("SELECT * FROM schools ORDER BY idschool LIMIT 1")->fetch(); if ($row) { $row['school_role'] = 'superadmin'; return $row; } return null; } return self::$memberships[0] ?? null; } private static function loadMemberships(int $userId): array { $st = self::pdo()->prepare( "SELECT s.*, su.school_role FROM school_user su JOIN schools s ON s.idschool = su.idschool WHERE su.user_id = ? AND su.active = 'Y' AND s.status <> 'suspended' ORDER BY s.name" ); $st->execute([$userId]); return $st->fetchAll(); } private static function pdo(): PDO { return DBHandlerSelect::getInstance()->getConnection(); } }