Files
root 58726ee0e9
API CI/CD / Validate (composer + pint) (push) Successful in 3m6s
API CI/CD / Test (PHPUnit) (push) Failing after 5m48s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 1m33s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
fix tables to have school year, and remove school year from other tables.
2026-07-06 22:27:21 -04:00

193 lines
6.1 KiB
PHP

<?php
namespace App\Services\SchoolYears;
use App\Models\Configuration;
use App\Models\SchoolYear;
use App\Support\SchoolYear\SchoolYearTableRegistry;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class SchoolYearContextService
{
public function __construct(private SchoolYearResolver $resolver) {}
public function currentSchoolYear(?string $requested = null): string
{
$requested = trim((string) $requested);
if ($requested !== '') {
return $requested;
}
$current = trim((string) (Configuration::getConfig('school_year') ?? ''));
if ($current !== '') {
return $current;
}
if (Schema::hasTable('school_years')) {
$year = SchoolYear::query()->where('is_current', true)->orderByDesc('id')->first();
if ($year && trim((string) $year->name) !== '') {
return (string) $year->name;
}
}
return '';
}
public function currentSemester(?string $requested = null): string
{
$requested = trim((string) $requested);
if ($requested !== '') {
return $requested;
}
return trim((string) (Configuration::getConfig('semester') ?? ''));
}
public function options(?string $selectedSchoolYear = null, ?string $selectedSemester = null): array
{
if (Schema::hasTable('school_years')) {
$this->resolver->ensureCurrentTracked();
}
$currentSchoolYear = $this->currentSchoolYear($selectedSchoolYear);
$currentSemester = $this->currentSemester($selectedSemester);
$schoolYears = $this->schoolYears($currentSchoolYear);
$semesters = $this->semesters($currentSemester);
return [
'school_year' => $currentSchoolYear !== '' ? $currentSchoolYear : null,
'current_school_year' => $currentSchoolYear !== '' ? $currentSchoolYear : null,
'semester' => $currentSemester !== '' ? $currentSemester : null,
'current_semester' => $currentSemester !== '' ? $currentSemester : null,
'school_years' => $schoolYears,
'semesters' => $semesters,
];
}
public function schoolYears(?string $include = null): array
{
$years = [];
if (Schema::hasTable('school_years')) {
$years = SchoolYear::query()
->orderByDesc('start_date')
->orderByDesc('id')
->get()
->map(fn (SchoolYear $year) => [
'id' => (int) $year->id,
'name' => (string) $year->name,
'label' => (string) $year->name,
'start_date' => $year->start_date ? $year->start_date->format('Y-m-d') : null,
'end_date' => $year->end_date ? $year->end_date->format('Y-m-d') : null,
'status' => (string) $year->status,
'is_current' => (bool) $year->is_current,
'is_editable' => $year->status === SchoolYear::STATUS_ACTIVE,
])
->all();
}
$seen = [];
foreach ($years as $row) {
$seen[$row['name']] = true;
}
foreach ($this->legacySchoolYearNames() as $name) {
if (! isset($seen[$name])) {
$years[] = [
'id' => null,
'name' => $name,
'label' => $name,
'start_date' => null,
'end_date' => null,
'status' => 'legacy',
'is_current' => false,
'is_editable' => true,
];
$seen[$name] = true;
}
}
$include = trim((string) $include);
if ($include !== '' && ! isset($seen[$include])) {
array_unshift($years, [
'id' => null,
'name' => $include,
'label' => $include,
'start_date' => null,
'end_date' => null,
'status' => 'selected',
'is_current' => true,
'is_editable' => true,
]);
}
return $years;
}
public function semesters(?string $include = null): array
{
$names = ['Fall', 'Spring'];
$current = trim((string) $include);
if ($current !== '' && ! in_array($current, $names, true)) {
array_unshift($names, $current);
}
return array_map(fn (string $name) => [
'name' => $name,
'label' => $name,
'is_current' => $current !== '' && strcasecmp($name, $current) === 0,
], $names);
}
private function legacySchoolYearNames(): array
{
$tables = [
'student_class', 'teacher_class',
'events', 'calendar_events', 'exam_drafts',
'certificate_records', 'semester_scores', 'final_score',
'student_decisions', 'below_sixty_decisions', 'whatsapp_group_links',
];
$names = [];
foreach ($tables as $table) {
if (! SchoolYearTableRegistry::isYearScoped($table)
|| ! Schema::hasTable($table)
|| ! Schema::hasColumn($table, 'school_year')) {
continue;
}
try {
$rows = DB::table($table)
->whereNotNull('school_year')
->where('school_year', '!=', '')
->distinct()
->orderByDesc('school_year')
->limit(20)
->pluck('school_year')
->all();
} catch (\Throwable $e) {
continue;
}
foreach ($rows as $row) {
$name = trim((string) $row);
if ($name !== '') {
$names[$name] = true;
}
}
}
$configured = trim((string) (Configuration::getConfig('school_year') ?? ''));
if ($configured !== '') {
$names[$configured] = true;
}
$out = array_keys($names);
rsort($out, SORT_NATURAL);
return $out;
}
}