feat(ecosystem): full Grade 10 curriculum sync, real device fingerprinting, teacher video dashboard, and official textbook assets

This commit is contained in:
Hamza-Ayed
2026-09-11 16:46:40 +03:00
parent fc8f874bf9
commit d1bc39604b
404 changed files with 118547 additions and 1093 deletions
@@ -262,7 +262,8 @@ class CurriculumController
// are rebuilt from approved, rights-cleared assets in a published
// bundle, and expose an opaque asset UUID rather than a storage path.
$resourceRows = Database::select(
"SELECT cl.subject_key, a.uuid AS asset_id, a.asset_type, a.mime_type,
"SELECT cl.subject_key, a.uuid AS asset_id, a.asset_type, a.mime_type, a.source_reference,
cl.title AS lesson_title, cl.unit_key,
pba.role, pba.sort_order
FROM publication_bundles pb
JOIN curriculum_lessons cl ON cl.id = pb.curriculum_lesson_id
@@ -276,29 +277,68 @@ class CurriculumController
ORDER BY cl.subject_key, pba.role, pba.sort_order, a.id"
);
$resourcesBySubject = [];
$seenAssetsBySubject = [];
foreach ($resourceRows as $row) {
$group = $row['role'] === 'textbook' ? 'textbooks' : 'worksheets';
$subjectKey = (string)$row['subject_key'];
$assetId = (string)$row['asset_id'];
$seenAssetsBySubject[$subjectKey] ??= [];
if (isset($seenAssetsBySubject[$subjectKey][$assetId])) {
continue;
}
$seenAssetsBySubject[$subjectKey][$assetId] = true;
$group = $row['role'] === 'textbook' ? 'textbooks' : 'worksheets';
$resourcesBySubject[$subjectKey] ??= ['textbooks' => [], 'worksheets' => []];
$title = '';
if ($group === 'textbooks') {
$ref = strtolower((string)($row['source_reference'] ?? ''));
$subjectNames = [
'math' => 'الرياضيات',
'physics' => 'الفيزياء',
'chemistry' => 'الكيمياء',
'biology' => 'العلوم الحياتية (الأحياء)',
'earth' => 'علوم الأرض والبيئة',
'arabic' => 'اللغة العربية (مهارات الاتصال)',
'english' => 'اللغة الإنجليزية (Action Pack 10)',
'islamic' => 'التربية الإسلامية',
'history' => 'تاريخ الأردن',
'geography' => 'الجغرافيا',
'civics' => 'التربية الوطنية والمدنية',
'financial' => 'الثقافة المالية',
'digital' => 'المهارات الرقمية والتكنولوجيا',
];
$foundSub = 'المقرر';
foreach ($subjectNames as $k => $name) {
if (str_contains($ref, $k) || str_contains(strtolower($subjectKey), $k)) {
$foundSub = $name;
break;
}
}
$part = '';
if (str_contains($ref, 'part1') || str_contains($ref, 'part_1') || str_contains($ref, 'semester_1')) {
$part = ' (الفصل الأول)';
} elseif (str_contains($ref, 'part2') || str_contains($ref, 'part_2') || str_contains($ref, 'semester_2')) {
$part = ' (الفصل الثاني)';
}
$title = "الكتاب المدرسي الرسمي: $foundSub$part";
} else {
$lTitle = trim((string)($row['lesson_title'] ?? ''));
$title = !empty($lTitle) ? ("ورقة عمل: " . $lTitle) : "ورقة عمل تعليمية";
}
$resourcesBySubject[$subjectKey][$group][] = [
'asset_id' => (string)$row['asset_id'],
'asset_id' => $assetId,
'asset_type' => (string)$row['asset_type'],
'mime_type' => (string)$row['mime_type'],
'type' => $group === 'textbooks' ? 'textbook' : 'worksheet',
'title' => $title,
];
}
foreach ($tree as $gKey => $grade) {
if (!isset($tree[$gKey]['subjects']) || !is_array($tree[$gKey]['subjects'])) continue;
foreach ($tree[$gKey]['subjects'] as $sKey => $subject) {
$subjectResources = $resourcesBySubject[(string)$sKey] ?? ['textbooks' => [], 'worksheets' => []];
foreach (['textbooks', 'worksheets'] as $group) {
foreach ($subjectResources[$group] as $index => &$resource) {
$resource['title'] = $group === 'textbooks'
? 'كتاب منشور ' . ($index + 1)
: 'ورقة عمل منشورة ' . ($index + 1);
}
unset($resource);
}
$tree[$gKey]['subjects'][$sKey]['resources'] = [
'textbooks' => ['items' => $subjectResources['textbooks']],
'worksheets' => ['items' => $subjectResources['worksheets']],