From 039c977d63e3fa71e6694ce79a5f13334e8a74f0 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Fri, 11 Sep 2026 00:13:36 +0300 Subject: [PATCH] Decouple curriculum tree lesson enrichment from optional teacher_submissions table --- .../app/Controllers/CurriculumController.php | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/backend/app/Controllers/CurriculumController.php b/backend/app/Controllers/CurriculumController.php index 6c02bc7..fe1c3ec 100644 --- a/backend/app/Controllers/CurriculumController.php +++ b/backend/app/Controllers/CurriculumController.php @@ -207,14 +207,43 @@ class CurriculumController $removeUnpublishedResources($tree); try { - $published = Database::select("SELECT cl.uuid, cl.source_manifest_path, COUNT(vv.id) AS video_count FROM curriculum_lessons cl LEFT JOIN teacher_submissions ts ON ts.curriculum_lesson_id=cl.id AND ts.status='published' LEFT JOIN video_versions vv ON vv.id=ts.current_published_video_version_id AND vv.status='published' WHERE cl.source_status='approved' GROUP BY cl.id, cl.uuid, cl.source_manifest_path"); - $byPath=[]; - foreach ($published as $row) $byPath[(string)$row['source_manifest_path']]=['curriculum_lesson_id'=>$row['uuid'],'has_video'=>(int)$row['video_count']>0]; - foreach ($tree as &$grade) foreach (($grade['subjects'] ?? []) as &$subject) foreach (($subject['semesters'] ?? []) as &$semester) foreach (($semester['units'] ?? []) as &$unit) foreach (($unit['lessons'] ?? []) as &$lesson) { - $path=(string)($lesson['file'] ?? ''); - if (isset($byPath[$path])) $lesson=array_merge($lesson,$byPath[$path]); + $approvedLessons = Database::select("SELECT id, uuid, source_manifest_path FROM curriculum_lessons WHERE source_status='approved'"); + $byPath = []; + $lessonMap = []; + foreach ($approvedLessons as $row) { + $p = (string)$row['source_manifest_path']; + $byPath[$p] = [ + 'curriculum_lesson_id' => (string)$row['uuid'], + 'has_video' => false, + ]; + $lessonMap[(int)$row['id']] = $p; } - unset($grade,$subject,$semester,$unit,$lesson); + + if (!empty($lessonMap)) { + try { + $videoCounts = Database::select( + "SELECT ts.curriculum_lesson_id, COUNT(vv.id) AS video_count + FROM teacher_submissions ts + JOIN video_versions vv ON vv.id = ts.current_published_video_version_id AND vv.status = 'published' + WHERE ts.status = 'published' + GROUP BY ts.curriculum_lesson_id" + ); + foreach ($videoCounts as $vc) { + $lid = (int)$vc['curriculum_lesson_id']; + if (isset($lessonMap[$lid]) && (int)$vc['video_count'] > 0) { + $byPath[$lessonMap[$lid]]['has_video'] = true; + } + } + } catch (\Throwable $ve) { + // teacher_submissions or video_versions not yet populated or migrated; keep has_video = false + } + } + + foreach ($tree as &$grade) foreach (($grade['subjects'] ?? []) as &$subject) foreach (($subject['semesters'] ?? []) as &$semester) foreach (($semester['units'] ?? []) as &$unit) foreach (($unit['lessons'] ?? []) as &$lesson) { + $path = (string)($lesson['file'] ?? ''); + if (isset($byPath[$path])) $lesson = array_merge($lesson, $byPath[$path]); + } + unset($grade, $subject, $semester, $unit, $lesson); // The manifest describes intake files only. Student-visible resources // are rebuilt from approved, rights-cleared assets in a published