fix parent pages to adopt the school year logic
Tests / PHPUnit (push) Successful in 1m20s

This commit is contained in:
root
2026-07-17 00:02:53 -04:00
parent a5517b516a
commit 539d0eb220
12 changed files with 258 additions and 51 deletions
+96 -19
View File
@@ -5,7 +5,9 @@ namespace App\Controllers;
use App\Controllers\ClassProgressController;
use App\Models\ClassProgressAttachmentModel;
use App\Models\ClassProgressReportModel;
use App\Models\ConfigurationModel;
use App\Models\EnrollmentModel;
use App\Services\SemesterRangeService;
use CodeIgniter\Database\BaseConnection;
use CodeIgniter\Exceptions\PageNotFoundException;
use Config\Database;
@@ -15,8 +17,10 @@ class ParentProgressController extends BaseController
protected ClassProgressReportModel $reportModel;
protected ClassProgressAttachmentModel $attachmentModel;
protected EnrollmentModel $enrollmentModel;
protected ConfigurationModel $configModel;
protected BaseConnection $db;
private ?array $parentSectionIds = null;
private array $parentSectionIdsByYear = [];
public function __construct()
{
@@ -24,6 +28,7 @@ class ParentProgressController extends BaseController
$this->reportModel = new ClassProgressReportModel();
$this->attachmentModel = new ClassProgressAttachmentModel();
$this->enrollmentModel = new EnrollmentModel();
$this->configModel = new ConfigurationModel();
$this->db = Database::connect();
}
@@ -43,8 +48,8 @@ class ParentProgressController extends BaseController
->select('class_progress_reports.*, cs.class_section_name, CONCAT(IFNULL(u.firstname, ""), " ", IFNULL(u.lastname, "")) AS teacher_name')
->join('classSection cs', 'cs.class_section_id = class_progress_reports.class_section_id', 'left')
->join('users u', 'u.id = class_progress_reports.teacher_id', 'left')
->whereIn('class_progress_reports.class_section_id', $sectionIds)
->where('class_progress_reports.school_year', $schoolYear);
->whereIn('class_progress_reports.class_section_id', $sectionIds);
$this->applyProgressSchoolYearScope($builder, $schoolYear);
$rows = $builder
->orderBy('week_start', 'DESC')
@@ -82,21 +87,29 @@ class ParentProgressController extends BaseController
->select('class_progress_reports.*, cs.class_section_name, CONCAT(IFNULL(u.firstname, ""), " ", IFNULL(u.lastname, "")) AS teacher_name')
->join('classSection cs', 'cs.class_section_id = class_progress_reports.class_section_id', 'left')
->join('users u', 'u.id = class_progress_reports.teacher_id', 'left')
->where('class_progress_reports.school_year', $schoolYear)
->find((int) $id);
->where('class_progress_reports.id', (int) $id)
->first();
if (! $row || ! $this->isSectionAccessible($row['class_section_id'] ?? null)) {
if (! $row) {
throw new PageNotFoundException('Progress report not found.');
}
$reportSchoolYear = trim((string) ($row['school_year'] ?? ''));
$effectiveSchoolYear = $reportSchoolYear !== '' ? $reportSchoolYear : $schoolYear;
if (! $this->isSectionAccessible($row['class_section_id'] ?? null, $effectiveSchoolYear)) {
throw new PageNotFoundException('Progress report not found.');
}
$row['status_label'] = ClassProgressController::STATUS_OPTIONS[$row['status']] ?? 'Unknown';
$row['flags'] = $this->decodeFlags($row['flags_json']);
$weeklyReports = $this->reportModel
$weeklyReportsQuery = $this->reportModel
->select('class_progress_reports.*')
->where('class_section_id', $row['class_section_id'])
->where('week_start', $row['week_start'])
->where('school_year', $schoolYear)
->where('week_start', $row['week_start']);
$this->applyProgressSchoolYearScope($weeklyReportsQuery, $effectiveSchoolYear);
$weeklyReports = $weeklyReportsQuery
->orderBy('subject', 'ASC')
->findAll();
@@ -122,7 +135,14 @@ class ParentProgressController extends BaseController
public function attachment($id)
{
$row = $this->reportModel->find((int) $id);
if (! $row || ! $this->isSectionAccessible($row['class_section_id'] ?? null) || empty($row['attachment_path'])) {
if (! $row) {
throw new PageNotFoundException('Attachment not found.');
}
$reportSchoolYear = trim((string) ($row['school_year'] ?? ''));
$effectiveSchoolYear = $reportSchoolYear !== '' ? $reportSchoolYear : $this->currentSchoolYearName();
if (! $this->isSectionAccessible($row['class_section_id'] ?? null, $effectiveSchoolYear) || empty($row['attachment_path'])) {
throw new PageNotFoundException('Attachment not found.');
}
@@ -142,7 +162,14 @@ class ParentProgressController extends BaseController
}
$report = $this->reportModel->find((int) ($attachment['report_id'] ?? 0));
if (! $report || ! $this->isSectionAccessible($report['class_section_id'] ?? null)) {
if (! $report) {
throw new PageNotFoundException('Attachment not found.');
}
$reportSchoolYear = trim((string) ($report['school_year'] ?? ''));
$effectiveSchoolYear = $reportSchoolYear !== '' ? $reportSchoolYear : $this->currentSchoolYearName();
if (! $this->isSectionAccessible($report['class_section_id'] ?? null, $effectiveSchoolYear)) {
throw new PageNotFoundException('Attachment not found.');
}
@@ -155,22 +182,30 @@ class ParentProgressController extends BaseController
return $this->response->download($file, null)->setFileName($downloadName);
}
protected function getParentSectionIds(): array
protected function getParentSectionIds(?string $schoolYear = null): array
{
if ($this->parentSectionIds !== null) {
$schoolYear = trim((string) ($schoolYear ?? $this->currentSchoolYearName()));
if ($schoolYear === $this->currentSchoolYearName() && $this->parentSectionIds !== null) {
return $this->parentSectionIds;
}
if (isset($this->parentSectionIdsByYear[$schoolYear])) {
return $this->parentSectionIdsByYear[$schoolYear];
}
$parentId = (int) session()->get('user_id');
if ($parentId === 0) {
$this->parentSectionIds = [];
return $this->parentSectionIds;
$this->parentSectionIdsByYear[$schoolYear] = [];
if ($schoolYear === $this->currentSchoolYearName()) {
$this->parentSectionIds = [];
}
return [];
}
$rows = $this->enrollmentModel
->select('class_section_id')
->where('parent_id', $parentId)
->where('school_year', $this->currentSchoolYearName())
->where('school_year', $schoolYear)
->where('is_withdrawn', 0)
->groupBy('class_section_id')
->findAll();
@@ -183,8 +218,12 @@ class ParentProgressController extends BaseController
}
}
$this->parentSectionIds = array_values(array_unique($ids));
return $this->parentSectionIds;
$ids = array_values(array_unique($ids));
$this->parentSectionIdsByYear[$schoolYear] = $ids;
if ($schoolYear === $this->currentSchoolYearName()) {
$this->parentSectionIds = $ids;
}
return $ids;
}
protected function buildSectionOptions(array $sectionIds): array
@@ -263,12 +302,50 @@ class ParentProgressController extends BaseController
return $reportGroups;
}
protected function isSectionAccessible(?int $classSectionId): bool
protected function isSectionAccessible(?int $classSectionId, ?string $schoolYear = null): bool
{
if (! $classSectionId) {
return false;
}
return in_array((int) $classSectionId, $this->getParentSectionIds(), true);
return in_array((int) $classSectionId, $this->getParentSectionIds($schoolYear), true);
}
protected function applyProgressSchoolYearScope($builder, string $schoolYear): void
{
if ($schoolYear === '') {
return;
}
$hasReportYear = $this->db->fieldExists('school_year', 'class_progress_reports');
$semesterResolver = new SemesterRangeService($this->configModel);
[$rangeStart, $rangeEnd] = $semesterResolver->getSchoolYearRange($schoolYear);
if ($hasReportYear) {
if ($rangeStart !== '' && $rangeEnd !== '') {
$builder
->groupStart()
->where('class_progress_reports.school_year', $schoolYear)
->orGroupStart()
->groupStart()
->where('class_progress_reports.school_year IS NULL', null, false)
->orWhere('class_progress_reports.school_year', '')
->groupEnd()
->where('class_progress_reports.week_start >=', $rangeStart)
->where('class_progress_reports.week_start <=', $rangeEnd)
->groupEnd()
->groupEnd();
return;
}
$builder->where('class_progress_reports.school_year', $schoolYear);
return;
}
if ($rangeStart !== '' && $rangeEnd !== '') {
$builder
->where('class_progress_reports.week_start >=', $rangeStart)
->where('class_progress_reports.week_start <=', $rangeEnd);
}
}
protected function resolveAttachmentFile(array $row): ?string