fix issues on examdraft view and event print page

This commit is contained in:
root
2026-05-05 01:38:20 -04:00
parent 45d7895182
commit 92016f90d0
4 changed files with 412 additions and 45 deletions
+68 -11
View File
@@ -102,11 +102,9 @@ class ExamDraftController extends BaseController
session()->set('class_section_id', $selectedClass);
}
$allDrafts = $this->examDraftModel
->select($this->draftSelectColumns())
->select('cs.class_section_name')
->join('classSection cs', 'cs.class_section_id = exam_drafts.class_section_id', 'left')
->where($this->authorIdColumn, $teacherId)
$classSectionIds = array_map(static fn($a) => (int) $a['class_section_id'], $assignments);
$allDrafts = $this->visibleTeacherDraftsQuery($teacherId, $classSectionIds)
->orderBy('created_at', 'DESC')
->findAll();
@@ -117,10 +115,10 @@ class ExamDraftController extends BaseController
$row['final_pdf_file'] = $pdf;
}
}
$row = $this->attachTeacherDraftContext($row, $teacherId);
}
unset($row);
$classSectionIds = array_map(static fn($a) => (int) $a['class_section_id'], $assignments);
$legacyExams = [];
// Guard against missing schema column in older databases
if ($this->hasIsLegacyColumn) {
@@ -129,8 +127,9 @@ class ExamDraftController extends BaseController
$legacyQuery = $this->examDraftModel
->select($this->draftSelectColumns())
->select('cs.class_section_name')
->select('cs.class_section_name, u.firstname AS teacher_first, u.lastname AS teacher_last')
->join('classSection cs', 'cs.class_section_id = exam_drafts.class_section_id', 'left')
->join('users u', 'u.id = exam_drafts.' . $this->authorIdColumn, 'left')
->where('exam_drafts.is_legacy', 1)
->where('exam_drafts.status', 'legacy')
->where('exam_drafts.final_file IS NOT NULL', null, false);
@@ -143,6 +142,11 @@ class ExamDraftController extends BaseController
->orderBy('cs.class_section_name', 'ASC')
->orderBy('exam_drafts.created_at', 'DESC')
->findAll();
foreach ($legacyExams as &$row) {
$row = $this->attachTeacherDraftContext($row, $teacherId);
}
unset($row);
} else {
// Legacy column absent, show all drafts and skip legacy tab query
$drafts = $allDrafts;
@@ -768,10 +772,11 @@ class ExamDraftController extends BaseController
return $this->response->setStatusCode(401);
}
$drafts = $this->examDraftModel
->select($this->draftSelectColumns())
->select('id, status, acceptance_type, updated_at, reviewed_at')
->where($this->authorIdColumn, $teacherId)
$assignments = $this->teacherClassModel->getClassAssignmentsByUserId($teacherId, $this->schoolYear);
$classSectionIds = array_map(static fn($a) => (int) $a['class_section_id'], $assignments);
$drafts = $this->visibleTeacherDraftsQuery($teacherId, $classSectionIds)
->select('exam_drafts.id, exam_drafts.status, exam_drafts.acceptance_type, exam_drafts.updated_at, exam_drafts.reviewed_at')
->orderBy('updated_at', 'DESC')
->findAll();
@@ -817,6 +822,58 @@ class ExamDraftController extends BaseController
return $validIds[0] ?? 0;
}
private function visibleTeacherDraftsQuery(int $teacherId, array $classSectionIds)
{
$query = $this->examDraftModel
->select($this->draftSelectColumns())
->select('cs.class_section_name, u.firstname AS teacher_first, u.lastname AS teacher_last')
->join('classSection cs', 'cs.class_section_id = exam_drafts.class_section_id', 'left')
->join('users u', 'u.id = exam_drafts.' . $this->authorIdColumn, 'left');
if (empty($classSectionIds)) {
return $query->where('exam_drafts.' . $this->authorIdColumn, $teacherId);
}
$query->groupStart()
->where('exam_drafts.' . $this->authorIdColumn, $teacherId)
->orGroupStart()
->whereIn('exam_drafts.class_section_id', $classSectionIds)
->where('exam_drafts.' . $this->authorIdColumn . ' !=', $teacherId)
->where('exam_drafts.status !=', 'draft');
if ($this->schoolYear !== '') {
$query->where('exam_drafts.school_year', $this->schoolYear);
}
if ($this->semester !== '') {
$query->where('exam_drafts.semester', $this->semester);
}
$query->groupEnd()
->groupEnd();
return $query;
}
private function attachTeacherDraftContext(array $row, int $viewerId): array
{
$isOwn = $this->draftTeacherId($row) === $viewerId;
$row['is_own_submission'] = $isOwn;
$row['teacher_display_name'] = $isOwn ? 'You' : $this->draftTeacherName($row);
return $row;
}
private function draftTeacherName(array $draft): string
{
$name = trim(((string) ($draft['teacher_first'] ?? '')) . ' ' . ((string) ($draft['teacher_last'] ?? '')));
if ($name !== '') {
return $name;
}
$teacherId = $this->draftTeacherId($draft);
return $teacherId > 0 ? 'Teacher #' . $teacherId : 'Teacher';
}
private function statusBadgeMap(): array
{
return [
+53
View File
@@ -224,6 +224,10 @@ class FilesController extends Controller
throw PageNotFoundException::forPageNotFound();
}
if (!$this->canAccessExamDraftFile($name, $subdir)) {
return $this->response->setStatusCode(403, 'You are not allowed to access this file.');
}
$mime = 'application/octet-stream';
if (function_exists('finfo_open')) {
$fi = finfo_open(FILEINFO_MIME_TYPE);
@@ -317,4 +321,53 @@ class FilesController extends Controller
}
return 'teacher_file';
}
private function canAccessExamDraftFile(string $filename, string $subdir): bool
{
$userId = (int) (session()->get('user_id') ?? 0);
if ($userId <= 0) {
return false;
}
$role = strtolower((string) (session()->get('role') ?? ''));
if ($role === 'admin') {
return true;
}
$db = Database::connect();
$fileColumn = $subdir === 'finals' ? 'final_file' : $this->resolveExamDraftFileColumn($db);
$draft = $db->table('exam_drafts ed')
->select('ed.class_section_id, ed.school_year, ed.teacher_id, ed.author_id')
->where('ed.' . $fileColumn, $filename)
->limit(1)
->get()
->getRowArray();
if (empty($draft)) {
return false;
}
$authorId = (int) ($draft['teacher_id'] ?? $draft['author_id'] ?? 0);
if ($authorId > 0 && $authorId === $userId) {
return true;
}
$classSectionId = (int) ($draft['class_section_id'] ?? 0);
if ($classSectionId <= 0) {
return false;
}
$assignmentQuery = $db->table('teacher_class')
->select('id')
->where('teacher_id', $userId)
->where('class_section_id', $classSectionId);
$schoolYear = trim((string) ($draft['school_year'] ?? ''));
if ($schoolYear !== '') {
$assignmentQuery->where('school_year', $schoolYear);
}
return $assignmentQuery->limit(1)->countAllResults() > 0;
}
}