*/ public function sundayOptions(int $count = 12): array { return $this->buildUpcomingSundayOptions($count); } /** * legacy-aligned Sundays within semester/school-year range when configuration allows. * * @return list */ public function sundayOptionsAlignedWithCi(int $count = 12): array { $range = $this->resolveProgressDateRange(); if ($range === null) { return $this->buildUpcomingSundayOptions($count); } [$rangeStart, $rangeEnd] = $range; try { $start = new \DateTime($rangeStart); $end = new \DateTime($rangeEnd); } catch (\Exception $e) { return $this->buildUpcomingSundayOptions($count); } if ($end < $start) { [$start, $end] = [$end, $start]; } $weekday = (int) $start->format('w'); if ($weekday !== 0) { $start->modify('next sunday'); } $options = []; while ($start <= $end) { $options[] = $start->format('Y-m-d'); $start->modify('+7 days'); } return $options !== [] ? $options : $this->buildUpcomingSundayOptions($count); } /** legacy `pickDefaultWeekStart`. */ public function pickDefaultWeekStart(array $options): string { if ($options === []) { return ''; } $today = date('Y-m-d'); $default = ''; foreach ($options as $option) { if ($option <= $today) { $default = $option; continue; } break; } return $default !== '' ? $default : $options[0]; } /** * @return list */ private function buildUpcomingSundayOptions(int $count): array { $start = new \DateTime('today'); $weekday = (int) $start->format('w'); if ($weekday !== 0) { $start->modify('next sunday'); } $options = []; for ($i = 0; $i < $count; $i++) { $options[] = $start->format('Y-m-d'); $start->modify('+7 days'); } return $options; } /** * legacy `resolveProgressDateRange`. * * @return array{0:string,1:string}|null */ private function resolveProgressDateRange(): ?array { $schoolYear = (string) (Configuration::getConfig('school_year') ?? ''); if ($schoolYear === '') { return null; } /** @var SemesterRangeService $svc */ $svc = app(SemesterRangeService::class); $semester = $svc->normalizeSemester((string) (Configuration::getConfig('semester') ?? '')); if ($semester === '') { $semester = $svc->getSemesterForDate(); } if ($semester !== '') { $range = $svc->getSemesterRange($schoolYear, $semester); if ($range !== null) { return $range; } } return $svc->getSchoolYearRange($schoolYear); } public function curriculumOptions(?int $classId, ?string $schoolYear = null): array { if (! $classId) { return []; } $options = []; foreach ($this->subjectSections() as $slug => $section) { $subjects = $this->subjectLookupValues((string) $slug, is_array($section) ? $section : []); $options[$slug] = SubjectCurriculum::query() ->forClass((int) $classId) ->where(function (Builder $query) use ($subjects) { $query->whereIn('subject', $subjects); }) ->forSchoolYear($schoolYear) ->ordered() ->get() ->all(); } return $options; } public function unitOptions(?int $classId, ?string $schoolYear = null): array { $curriculum = $this->curriculumOptions($classId, $schoolYear); $units = []; foreach ($curriculum as $slug => $rows) { $seen = []; $units[$slug] = []; foreach ($rows as $row) { $unitNumber = $row->unit_number ?? null; $unitTitle = trim((string) ($row->unit_title ?? '')); if ($unitNumber === null && $unitTitle === '') { continue; } $key = ((string) $unitNumber).'|'.$unitTitle; if (isset($seen[$key])) { continue; } $seen[$key] = true; $units[$slug][] = [ 'unit_number' => $unitNumber !== null ? (int) $unitNumber : null, 'unit_title' => $unitTitle, 'label' => $this->formatUnitLabel($unitNumber !== null ? (int) $unitNumber : null, $unitTitle), ]; } } return $units; } private function formatUnitLabel(?int $unitNumber, string $unitTitle): string { if ($unitNumber !== null && $unitTitle !== '') { return 'Unit '.$unitNumber.' - '.$unitTitle; } if ($unitNumber !== null) { return 'Unit '.$unitNumber; } return $unitTitle; } /** * Curriculum rows have existed with both short slugs (`quran`) and display * subjects (`Quran/Arabic`). Query all configured aliases but keep the API * response keyed by slug for the frontend. * * @param array $section * @return list */ private function subjectLookupValues(string $slug, array $section): array { $values = [$slug]; foreach (['db_subject', 'label'] as $key) { $value = trim((string) ($section[$key] ?? '')); if ($value !== '') { $values[] = $value; } } return array_values(array_unique($values)); } }