exam draft fix

This commit is contained in:
root
2026-04-11 15:33:12 -04:00
parent 89e95b7851
commit 7bc999643a
13 changed files with 582 additions and 180 deletions
@@ -763,7 +763,13 @@ class AdministratorController extends BaseController
[$progressExpectedWeeks, $progressSubmittedBySection] = $this->buildClassProgressStats($sectionIds);
$examDraftCounts = [];
$examDraftDeadline = $this->resolveExamDraftDeadline($semester, $schoolYear);
$examDraftDeadline = $this->resolveTeacherDashboardExamDraftDeadline($semester, $schoolYear);
$examDraftDeadlineConfig = trim((string) ($this->configModel->getConfig('exam_draft_deadline') ?? ''));
$examDraftDeadlineFormatted = '';
if ($examDraftDeadlineConfig !== '') {
$parsedUi = $this->parseExamDraftDeadlineConfigValue();
$examDraftDeadlineFormatted = $parsedUi !== null ? $parsedUi->format('M j, Y') : '';
}
$homeworkCounts = [];
if (! empty($sectionIds)) {
$draftBuilder = $examDrafts
@@ -1066,6 +1072,8 @@ class AdministratorController extends BaseController
'notificationHistory' => $historyMap,
'summary' => $summary,
'lowProgressSectionIds' => $lowProgressSectionIds,
'examDraftDeadlineConfig' => $examDraftDeadlineConfig,
'examDraftDeadlineFormatted' => $examDraftDeadlineFormatted,
]);
}
@@ -1299,6 +1307,7 @@ class AdministratorController extends BaseController
$progressUrl = site_url('teacher/progress/history');
$examDraftUrl = site_url('teacher/exam-drafts');
$homeworkUrl = site_url('teacher/addHomework');
$examDraftDeadlineEmailHtml = $this->buildExamDraftDeadlineEmailHtml();
$sentCount = 0;
$failCount = 0;
@@ -1347,7 +1356,8 @@ class AdministratorController extends BaseController
} else {
$draftLabel = 'exam draft';
}
$examDraftNote = "<p>" . ucfirst($draftLabel) . " submissions can be updated at <a href=\"{$examDraftUrl}\">Teacher Exam Drafts</a>.</p>";
$examDraftNote = "<p>" . ucfirst($draftLabel) . " submissions can be updated at <a href=\"{$examDraftUrl}\">Teacher Exam Drafts</a>.</p>"
. $examDraftDeadlineEmailHtml;
}
$homeworkNote = '';
if (in_array('homework', $missingItems, true)) {
@@ -1485,6 +1495,60 @@ class AdministratorController extends BaseController
];
}
/**
* Exam draft due date for the teacher submissions dashboard: prefers the configuration key
* `exam_draft_deadline` (same as automated reminders); otherwise fall/spring exam deadlines.
*/
private function resolveTeacherDashboardExamDraftDeadline(string $semester, string $schoolYear): ?\DateTimeImmutable
{
$fromExamDraftKey = $this->parseExamDraftDeadlineConfigValue();
if ($fromExamDraftKey !== null) {
return $fromExamDraftKey;
}
return $this->resolveExamDraftDeadline($semester, $schoolYear);
}
/**
* Parses the `exam_draft_deadline` configuration value using the application timezone (midnight that calendar day).
*/
private function parseExamDraftDeadlineConfigValue(): ?\DateTimeImmutable
{
$raw = trim((string) ($this->configModel->getConfig('exam_draft_deadline') ?? ''));
if ($raw === '') {
return null;
}
$tz = new \DateTimeZone(config('App')->appTimezone ?? 'UTC');
try {
$deadline = new \DateTimeImmutable($raw, $tz);
} catch (\Throwable $e) {
return null;
}
return $deadline->setTime(0, 0, 0);
}
/**
* HTML snippet for reminder emails when exam draft is included (deadline from exam_draft_deadline config).
*/
private function buildExamDraftDeadlineEmailHtml(): string
{
$raw = trim((string) ($this->configModel->getConfig('exam_draft_deadline') ?? ''));
if ($raw === '') {
return '';
}
$parsed = $this->parseExamDraftDeadlineConfigValue();
$display = $parsed !== null
? htmlspecialchars($parsed->format('l, F j, Y'), ENT_QUOTES, 'UTF-8')
: htmlspecialchars($raw, ENT_QUOTES, 'UTF-8');
$rawEsc = htmlspecialchars($raw, ENT_QUOTES, 'UTF-8');
return '<p><strong>Exam draft submission deadline</strong> (<code>exam_draft_deadline</code>): '
. "<strong>{$display}</strong>"
. ($parsed !== null && $rawEsc !== $display ? " <span style=\"color:#555;\">(configured value: {$rawEsc})</span>" : '')
. '.</p>';
}
private function resolveExamDraftDeadline(string $semester, string $schoolYear): ?\DateTimeImmutable
{
$semesterKey = strtolower(trim($semester));