fix the exam draft

This commit is contained in:
root
2026-04-02 00:03:59 -04:00
parent ed67836701
commit 61facee902
6 changed files with 111 additions and 39 deletions
@@ -98,6 +98,10 @@ class ClassProgressController extends BaseController
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors()); return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
} }
if (! $this->hasIslamicUnitSelection()) {
return redirect()->back()->withInput()->with('error', 'Please select at least one Islamic Studies unit.');
}
$attachmentErrors = $this->validateAttachmentFiles($subjectSections); $attachmentErrors = $this->validateAttachmentFiles($subjectSections);
if (! empty($attachmentErrors)) { if (! empty($attachmentErrors)) {
return redirect()->back()->withInput()->with('errors', $attachmentErrors); return redirect()->back()->withInput()->with('errors', $attachmentErrors);
@@ -431,6 +435,10 @@ class ClassProgressController extends BaseController
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors()); return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
} }
if (! $this->hasIslamicUnitSelection()) {
return redirect()->back()->withInput()->with('error', 'Please select at least one Islamic Studies unit.');
}
$attachmentErrors = $this->validateAttachmentFiles($subjectSections); $attachmentErrors = $this->validateAttachmentFiles($subjectSections);
if (! empty($attachmentErrors)) { if (! empty($attachmentErrors)) {
return redirect()->back()->withInput()->with('errors', $attachmentErrors); return redirect()->back()->withInput()->with('errors', $attachmentErrors);
@@ -694,6 +702,17 @@ class ClassProgressController extends BaseController
return mb_strlen($summary) > 120 ? mb_substr($summary, 0, 120) : $summary; return mb_strlen($summary) > 120 ? mb_substr($summary, 0, 120) : $summary;
} }
protected function hasIslamicUnitSelection(): bool
{
$unitValues = array_map('trim', (array) $this->request->getPost('unit_islamic'));
foreach ($unitValues as $value) {
if ($value !== '') {
return true;
}
}
return false;
}
protected function parseUnitChapterSummary(string $summary): array protected function parseUnitChapterSummary(string $summary): array
{ {
$summary = trim($summary); $summary = trim($summary);
+42 -31
View File
@@ -240,23 +240,23 @@ class ExamDraftController extends BaseController
// Group legacy uploads (admin-uploaded finalized exams) by class_section for separate tab // Group legacy uploads (admin-uploaded finalized exams) by class_section for separate tab
$legacyByClass = []; $legacyByClass = [];
if ($this->hasIsLegacyColumn) { if ($this->hasIsLegacyColumn) {
// Keep all submissions visible; additionally surface legacy items in a separate tab // Keep legacy items out of the main submissions list; show them in the legacy tab only.
$drafts = $allDrafts; $drafts = [];
foreach ($allDrafts as $d) { foreach ($allDrafts as $d) {
$isLegacy = !empty($d['is_legacy']); $isLegacy = !empty($d['is_legacy']);
if (!$isLegacy) { if ($isLegacy) {
$cid = (int)($d['class_section_id'] ?? 0);
if (!isset($legacyByClass[$cid])) {
$legacyByClass[$cid] = [
'class_section_id' => $cid,
'class_section_name' => $d['class_section_name'] ?? 'Class ' . $cid,
'items' => [],
];
}
$legacyByClass[$cid]['items'][] = $d;
continue; continue;
} }
$cid = (int)($d['class_section_id'] ?? 0); $drafts[] = $d;
if (!isset($legacyByClass[$cid])) {
$legacyByClass[$cid] = [
'class_section_id' => $cid,
'class_section_name' => $d['class_section_name'] ?? 'Class ' . $cid,
'items' => [],
];
}
$legacyByClass[$cid]['items'][] = $d;
} }
} else { } else {
// Column missing: keep behavior simple and avoid legacy tab // Column missing: keep behavior simple and avoid legacy tab
@@ -284,13 +284,17 @@ class ExamDraftController extends BaseController
return redirect()->to('/login'); return redirect()->to('/login');
} }
$classSectionId = (int) ($this->request->getPost('class_section_id') ?? 0); $classSectionIds = $this->request->getPost('class_section_ids');
if (!is_array($classSectionIds)) {
$classSectionIds = [$classSectionIds];
}
$classSectionIds = array_values(array_filter(array_map('intval', $classSectionIds)));
$schoolYear = trim((string) ($this->request->getPost('school_year') ?? $this->schoolYear)); $schoolYear = trim((string) ($this->request->getPost('school_year') ?? $this->schoolYear));
$semester = trim((string) ($this->request->getPost('semester') ?? $this->semester)); $semester = trim((string) ($this->request->getPost('semester') ?? $this->semester));
$examType = trim((string) $this->request->getPost('exam_type')); $examType = trim((string) $this->request->getPost('exam_type'));
if ($classSectionId <= 0) { if (empty($classSectionIds)) {
return redirect()->back()->withInput()->with('error', 'Select a class section.'); return redirect()->back()->withInput()->with('error', 'Select at least one class section.');
} }
if ($schoolYear === '') { if ($schoolYear === '') {
return redirect()->back()->withInput()->with('error', 'School year is required.'); return redirect()->back()->withInput()->with('error', 'School year is required.');
@@ -309,9 +313,17 @@ class ExamDraftController extends BaseController
return redirect()->back()->withInput()->with('error', 'File type not allowed or upload failed.'); return redirect()->back()->withInput()->with('error', 'File type not allowed or upload failed.');
} }
$payload = [ $pdfName = null;
if (strtolower($file->getClientExtension()) === 'pdf') {
$pdfName = $stored;
} else {
$pdfName = $this->convertDocToPdf(
$this->fullUploadPath(self::FINAL_UPLOAD_DIR, $stored),
self::FINAL_UPLOAD_DIR
);
}
$basePayload = [
'teacher_id' => $adminId, // store under admin user since legacy uploads are admin-only 'teacher_id' => $adminId, // store under admin user since legacy uploads are admin-only
'class_section_id' => $classSectionId,
'semester' => ucfirst(strtolower($semester)), 'semester' => ucfirst(strtolower($semester)),
'school_year' => $schoolYear, 'school_year' => $schoolYear,
'exam_type' => $examType === '' ? null : $examType, 'exam_type' => $examType === '' ? null : $examType,
@@ -325,23 +337,22 @@ class ExamDraftController extends BaseController
'version' => 1, 'version' => 1,
]; ];
if ($this->hasIsLegacyColumn) { if ($this->hasIsLegacyColumn) {
$payload['is_legacy'] = 1; $basePayload['is_legacy'] = 1;
}
$pdfName = null;
if (strtolower($file->getClientExtension()) === 'pdf') {
$pdfName = $stored;
} else {
$pdfName = $this->convertDocToPdf(
$this->fullUploadPath(self::FINAL_UPLOAD_DIR, $stored),
self::FINAL_UPLOAD_DIR
);
} }
if ($pdfName !== null && $this->hasFinalPdfColumn) { if ($pdfName !== null && $this->hasFinalPdfColumn) {
$payload['final_pdf_file'] = $pdfName; $basePayload['final_pdf_file'] = $pdfName;
} }
if ($this->examDraftModel->insert($payload)) { $saved = 0;
foreach ($classSectionIds as $classSectionId) {
$payload = $basePayload;
$payload['class_section_id'] = $classSectionId;
if ($this->examDraftModel->insert($payload)) {
$saved++;
}
}
if ($saved > 0) {
return redirect()->to('/administrator/exam-drafts')->with('success', 'Old exam uploaded successfully.'); return redirect()->to('/administrator/exam-drafts')->with('success', 'Old exam uploaded successfully.');
} }
+26 -5
View File
@@ -168,12 +168,33 @@
$weekLabel .= ' ' . date('M d, Y', strtotime($group['week_end'])); $weekLabel .= ' ' . date('M d, Y', strtotime($group['week_end']));
} }
$reports = $group['reports'] ?? []; $reports = $group['reports'] ?? [];
$teacherName = ''; $teacherCounts = [];
$teacherLatest = [];
foreach ($reports as $report) { foreach ($reports as $report) {
if (! empty($report['teacher_name'])) { $name = trim((string) ($report['teacher_name'] ?? ''));
$teacherName = $report['teacher_name']; if ($name === '') {
break; continue;
} }
$teacherCounts[$name] = ($teacherCounts[$name] ?? 0) + 1;
$stamp = (string) ($report['updated_at'] ?? $report['created_at'] ?? '');
if ($stamp !== '' && (!isset($teacherLatest[$name]) || $stamp > $teacherLatest[$name])) {
$teacherLatest[$name] = $stamp;
}
}
$teacherLabel = '-';
if (!empty($teacherCounts)) {
$bestName = '';
$bestCount = -1;
$bestStamp = '';
foreach ($teacherCounts as $name => $count) {
$stamp = $teacherLatest[$name] ?? '';
if ($count > $bestCount || ($count === $bestCount && $stamp > $bestStamp)) {
$bestName = $name;
$bestCount = $count;
$bestStamp = $stamp;
}
}
$teacherLabel = $bestName ?: '-';
} }
$exampleId = $reports ? reset($reports)['id'] : null; $exampleId = $reports ? reset($reports)['id'] : null;
?> ?>
@@ -198,7 +219,7 @@
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
</td> </td>
<td><?= esc($teacherName ?: '-') ?></td> <td><?= esc($teacherLabel) ?></td>
<td class="text-end"> <td class="text-end">
<?php if ($exampleId): ?> <?php if ($exampleId): ?>
<a class="btn btn-sm btn-outline-primary" href="<?= base_url('admin/progress/view/' . $exampleId) ?>">View</a> <a class="btn btn-sm btn-outline-primary" href="<?= base_url('admin/progress/view/' . $exampleId) ?>">View</a>
+3 -3
View File
@@ -182,13 +182,13 @@
<form method="post" action="<?= base_url('/administrator/exam-drafts/upload-legacy') ?>" enctype="multipart/form-data" class="row g-3"> <form method="post" action="<?= base_url('/administrator/exam-drafts/upload-legacy') ?>" enctype="multipart/form-data" class="row g-3">
<?= csrf_field() ?> <?= csrf_field() ?>
<div class="col-md-4"> <div class="col-md-4">
<label class="form-label small">Class Section</label> <label class="form-label small">Class Sections</label>
<select name="class_section_id" class="form-select" required> <select name="class_section_ids[]" class="form-select" multiple required>
<option value="">Select class</option>
<?php foreach ($classSections as $cs): ?> <?php foreach ($classSections as $cs): ?>
<option value="<?= esc($cs['class_section_id']) ?>"><?= esc($cs['class_section_name']) ?></option> <option value="<?= esc($cs['class_section_id']) ?>"><?= esc($cs['class_section_name']) ?></option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<div class="form-text">Hold Ctrl (Windows) or Command (Mac) to select multiple sections.</div>
</div> </div>
<div class="col-md-2"> <div class="col-md-2">
<label class="form-label small">School Year</label> <label class="form-label small">School Year</label>
@@ -306,6 +306,14 @@
const forms = document.querySelectorAll('.needs-validation'); const forms = document.querySelectorAll('.needs-validation');
Array.from(forms).forEach(form => { Array.from(forms).forEach(form => {
form.addEventListener('submit', event => { form.addEventListener('submit', event => {
const islamicUnits = form.querySelectorAll('input[name="unit_islamic[]"]');
const hasIslamicUnit = Array.from(islamicUnits).some(input => input.value.trim() !== '');
if (!hasIslamicUnit) {
event.preventDefault();
event.stopPropagation();
alert('Please select at least one Islamic Studies unit.');
return;
}
if (!form.checkValidity()) { if (!form.checkValidity()) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@@ -461,6 +469,10 @@
confirmButton.addEventListener('click', () => { confirmButton.addEventListener('click', () => {
confirmInput.value = '1'; confirmInput.value = '1';
const form = confirmButton.closest('form') || document.querySelector('form.needs-validation'); const form = confirmButton.closest('form') || document.querySelector('form.needs-validation');
if (form && typeof form.requestSubmit === 'function') {
form.requestSubmit();
return;
}
if (form) { if (form) {
form.submit(); form.submit();
} }
+9
View File
@@ -137,6 +137,9 @@
<a href="<?= base_url('exam-drafts/files/teacher/' . $draft['teacher_file']) ?>" target="_blank"> <a href="<?= base_url('exam-drafts/files/teacher/' . $draft['teacher_file']) ?>" target="_blank">
<?= esc($draft['teacher_filename'] ?? 'Download submitted file') ?> <?= esc($draft['teacher_filename'] ?? 'Download submitted file') ?>
</a> </a>
<a href="<?= base_url('exam-drafts/files/teacher/' . $draft['teacher_file']) ?>" target="_blank" class="btn btn-sm btn-outline-secondary ms-2">
View
</a>
</div> </div>
<?php else: ?> <?php else: ?>
<div class="text-muted small">No file uploaded</div> <div class="text-muted small">No file uploaded</div>
@@ -152,6 +155,9 @@
<a href="<?= base_url('exam-drafts/files/final/' . $draft['final_file']) ?>" target="_blank" class="link-success small"> <a href="<?= base_url('exam-drafts/files/final/' . $draft['final_file']) ?>" target="_blank" class="link-success small">
<?= esc($draft['final_filename'] ?? 'Download final draft') ?> <?= esc($draft['final_filename'] ?? 'Download final draft') ?>
</a> </a>
<a href="<?= base_url('exam-drafts/files/final/' . $draft['final_file']) ?>" target="_blank" class="btn btn-sm btn-outline-secondary ms-2">
View
</a>
</div> </div>
<?php endif; ?> <?php endif; ?>
</td> </td>
@@ -199,6 +205,9 @@
<a href="<?= base_url('exam-drafts/files/final/' . $item['final_file']) ?>" target="_blank" class="btn btn-sm btn-outline-primary"> <a href="<?= base_url('exam-drafts/files/final/' . $item['final_file']) ?>" target="_blank" class="btn btn-sm btn-outline-primary">
Download Download
</a> </a>
<a href="<?= base_url('exam-drafts/files/final/' . $item['final_file']) ?>" target="_blank" class="btn btn-sm btn-outline-secondary ms-2">
View
</a>
<?php else: ?> <?php else: ?>
<span class="text-muted small">File missing</span> <span class="text-muted small">File missing</span>
<?php endif; ?> <?php endif; ?>