'chemistry_10', 'الرياضيات' => 'math_10', 'الفيزياء' => 'physics_10', 'الأحياء' => 'biology_10', 'حياتية' => 'biology_10', 'علوم الأرض' => 'earth_sciences_10', 'اللغة العربية' => 'arabic_10', 'العربية' => 'arabic_10', 'الإنجليزية' => 'english_10', 'الانجليزية' => 'english_10', 'التربية الإسلامية' => 'islamic_10', 'الإسلامية' => 'islamic_10', 'تاريخ' => 'history_10', 'جغرافيا' => 'geography_10', 'الوطنية' => 'civics_10', 'المالية' => 'financial_10', 'الرقمية' => 'digital_skills_10', 'حاسوب' => 'digital_skills_10', ]; $publishedCount = 0; foreach ($pdfFiles as $filePath) { $filename = basename($filePath); $sha256 = hash_file('sha256', $filePath); $bytes = filesize($filePath); // Identify subject $matchedSubject = null; foreach ($subjectMap as $keyword => $subKey) { if (str_contains($filename, $keyword)) { $matchedSubject = $subKey; break; } } if (!$matchedSubject) { echo " - Skipping unclassified PDF: {$filename}\n"; continue; } $semesterKey = str_contains($filename, 'الثاني') ? 'semester_2' : 'semester_1'; echo "\nProcessing: [{$matchedSubject} - {$semesterKey}] {$filename}\n"; // Destination in curriculum storage $relativeDest = "textbooks/grade_10/{$matchedSubject}/" . basename($filePath); $fullDest = $curriculumRoot . '/' . $relativeDest; if ($apply) { $destDir = dirname($fullDest); if (!is_dir($destDir)) { mkdir($destDir, 0755, true); } if (!file_exists($fullDest) || hash_file('sha256', $fullDest) !== $sha256) { copy($filePath, $fullDest); } } // Find the representative published bundle for this subject $lesson = Database::selectOne( "SELECT cl.id, cl.uuid FROM curriculum_lessons cl JOIN publication_bundles pb ON pb.curriculum_lesson_id = cl.id WHERE cl.grade_key = 'grade_10' AND cl.subject_key = ? AND cl.semester_key = ? ORDER BY cl.unit_key ASC, cl.lesson_key ASC LIMIT 1", [$matchedSubject, $semesterKey] ); if (!$lesson) { // Fallback: any lesson in the subject $lesson = Database::selectOne( "SELECT cl.id, cl.uuid FROM curriculum_lessons cl WHERE cl.grade_key = 'grade_10' AND cl.subject_key = ? ORDER BY cl.id ASC LIMIT 1", [$matchedSubject] ); } if (!$lesson) { echo " - No curriculum lesson found for {$matchedSubject}.\n"; continue; } $lessonId = (int)$lesson['id']; // Ensure publication bundle exists $bundle = Database::selectOne( "SELECT id FROM publication_bundles WHERE curriculum_lesson_id = ? AND status = 'published' LIMIT 1", [$lessonId] ); $bundleId = 0; if ($bundle) { $bundleId = (int)$bundle['id']; } elseif ($apply) { $bUuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)); $bundleId = (int)Database::insert( "INSERT INTO publication_bundles (uuid, curriculum_lesson_id, bundle_version, status, published_at) VALUES (?, ?, 'grade10-intake-2026-09-10', 'published', NOW())", [$bUuid, $lessonId] ); } // Ensure content_asset exists $asset = Database::selectOne( "SELECT id, uuid FROM content_assets WHERE sha256 = ? LIMIT 1", [$sha256] ); $assetId = 0; if ($asset) { $assetId = (int)$asset['id']; echo " - Asset exists (ID: {$assetId})\n"; if ($apply) { Database::query( "UPDATE content_assets SET review_status = 'approved', rights_status = 'cleared', storage_key = ? WHERE id = ?", [$relativeDest, $assetId] ); } } elseif ($apply) { $aUuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)); $assetId = (int)Database::insert( "INSERT INTO content_assets (uuid, asset_type, storage_driver, storage_key, mime_type, byte_size, sha256, rights_status, review_status) VALUES (?, 'textbook_pdf', 'local', ?, 'application/pdf', ?, ?, 'cleared', 'approved')", [$aUuid, $relativeDest, $bytes, $sha256] ); echo " - Created content_asset ID {$assetId}\n"; } // Link in publication_bundle_assets if ($apply && $bundleId > 0 && $assetId > 0) { Database::query( "INSERT INTO publication_bundle_assets (publication_bundle_id, content_asset_id, role, sort_order) VALUES (?, ?, 'textbook', 1) ON DUPLICATE KEY UPDATE role = 'textbook'", [$bundleId, $assetId] ); echo " - Linked to publication bundle {$bundleId} as textbook.\n"; $publishedCount++; } } if ($apply) { echo "\n=== Successfully published {$publishedCount} textbooks! ===\n"; } else { echo "\nDRY RUN complete. Run with --apply to execute.\n"; }