status(400)->json([ 'status' => 'error', 'message' => 'يرجى اختيار ملف PDF صالح للمنهاج الوزاري.' ]); return; } $file = $_FILES['pdf_file']; $origName = $file['name']; $tmpPath = $file['tmp_name']; $taskId = uniqid('task_'); // Setup processing directory $processingDir = __DIR__ . '/../../storage/curriculum/processing'; if (!is_dir($processingDir)) { mkdir($processingDir, 0777, true); } $savedPdfPath = $processingDir . '/' . $taskId . '.pdf'; move_uploaded_file($tmpPath, $savedPdfPath); // Initialize Task State $taskState = [ 'task_id' => $taskId, 'status' => 'queued', 'progress' => 0, 'message' => 'تم استلام الملف وجاري تحويله للمعالجة المعمقة...', 'orig_name' => $origName ]; file_put_contents($processingDir . '/' . $taskId . '.json', json_encode($taskState, JSON_UNESCAPED_UNICODE)); // Launch Background Worker $scriptPath = realpath(__DIR__ . '/../../scripts/curriculum_worker.php'); $logPath = $processingDir . '/' . $taskId . '.log'; $cmd = "php " . escapeshellarg($scriptPath) . " " . escapeshellarg($taskId) . " > " . escapeshellarg($logPath) . " 2>&1 &"; exec($cmd); $response->json([ 'status' => 'processing', 'task_id' => $taskId, 'message' => 'تم استلام الكتاب، وجاري المعالجة المعمقة بواسطة الذكاء الاصطناعي. يرجى الانتظار...' ]); } /** * Poll Upload Status */ public function getUploadStatus(Request $request, Response $response): void { $taskId = $request->getQueryParams()['task_id'] ?? ''; if (empty($taskId)) { $response->status(400)->json(['status' => 'error', 'message' => 'رقم المهمة مفقود']); return; } $processingDir = __DIR__ . '/../../storage/curriculum/processing'; $stateFile = $processingDir . '/' . $taskId . '.json'; if (!file_exists($stateFile)) { $response->status(404)->json(['status' => 'error', 'message' => 'المهمة غير موجودة']); return; } $state = json_decode(file_get_contents($stateFile), true); $response->json($state); } /** * Get Complete Live Tree */ public function getTree(Request $request, Response $response): void { $response->json([ 'status' => 'success', 'data' => CurriculumService::getCurriculumTree() ]); } /** * Get Single Lesson Markdown Content */ public function getLessonContent(Request $request, Response $response): void { $file = $request->getQueryParams()['file'] ?? ''; if (empty($file)) { $response->status(400)->json(['status' => 'error', 'message' => 'مسار الملف مطلوب']); return; } $content = CurriculumService::getLessonMarkdown($file); $serverFullPath = realpath(__DIR__ . '/../../storage/curriculum') . '/' . ltrim($file, '/'); $response->json([ 'status' => 'success', 'file' => $file, 'server_full_path' => $serverFullPath, 'content' => $content ]); } /** * Save Lesson Markdown Content */ public function saveLessonContent(Request $request, Response $response): void { $body = $request->getBody(); $file = $body['file'] ?? ''; $content = $body['content'] ?? ''; if (empty($file) || empty($content)) { $response->status(400)->json(['status' => 'error', 'message' => 'بيانات الحفظ غير مكتملة']); return; } CurriculumService::saveLessonMarkdown($file, $content); $serverFullPath = realpath(__DIR__ . '/../../storage/curriculum') . '/' . ltrim($file, '/'); $response->json([ 'status' => 'success', 'message' => 'تم حفظ واعتماد محتوى الدرس في المنهاج بنجاح!', 'server_full_path' => $serverFullPath ]); } }