From a8d0efbbea6ed748a99c617b805c4860d1df09f7 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Sat, 29 Aug 2026 03:00:06 +0300 Subject: [PATCH] fix: Resolve getJSON method error in student national ID verification and enhance curriculum worker Gemini model handling --- backend/app/Controllers/AuthController.php | 14 ++++++++++---- backend/app/Core/Request.php | 5 +++++ backend/public/index.php | 2 +- backend/scripts/curriculum_worker.php | 11 ++++++----- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/backend/app/Controllers/AuthController.php b/backend/app/Controllers/AuthController.php index fd00ba7..42c81b5 100644 --- a/backend/app/Controllers/AuthController.php +++ b/backend/app/Controllers/AuthController.php @@ -462,7 +462,7 @@ class AuthController */ public function verifyNationalId(Request $request, Response $response): void { - $body = $request->getJSON(); + $body = $request->getBody(); $identityToken = $body['identity_token'] ?? ''; $nationalId = trim((string)($body['national_id'] ?? '')); @@ -606,13 +606,19 @@ class AuthController } else { // Legacy / Fallback for already logged-in students updating profile $studentId = (int)$request->user_id; + if (!$studentId) { + $authHeader = $request->getHeader('authorization', ''); + if ($authHeader && preg_match('/Bearer\s(\S+)/i', $authHeader, $matches)) { + $payload = Security::verifyJWT($matches[1]); + if ($payload && isset($payload['user_id'])) { + $studentId = (int)$payload['user_id']; + } + } + } if (!$studentId) { $response->status(401)->json(['status' => 'error', 'message' => 'غير مصرح']); return; } - Database::query( - "UPDATE students SET full_name = ?, grade_level = ?, stream = ?, national_id = IF(? != '', ?, national_id), updated_at = NOW() WHERE id = ?", - [$fullName, $gradeLevel, $stream, $nationalId, $nationalId, $studentId] ); $student = Database::selectOne("SELECT * FROM students WHERE id = ? LIMIT 1", [$studentId]); diff --git a/backend/app/Core/Request.php b/backend/app/Core/Request.php index 6c79487..1b124c1 100644 --- a/backend/app/Core/Request.php +++ b/backend/app/Core/Request.php @@ -63,6 +63,11 @@ class Request return $this->bodyParams; } + public function getJSON(): array + { + return $this->bodyParams; + } + public function setBody(array $bodyParams): void { $this->bodyParams = $bodyParams; diff --git a/backend/public/index.php b/backend/public/index.php index 6da8f64..3469dc5 100644 --- a/backend/public/index.php +++ b/backend/public/index.php @@ -90,7 +90,7 @@ $router->post('/api/auth/logout', [\App\Controllers\AuthController::class, $router->get('/api/auth/me', [\App\Controllers\AuthController::class, 'me'], [\App\Middlewares\AuthMiddleware::class]); $router->post('/api/auth/student/login-national-id', [\App\Controllers\AuthController::class, 'verifyNationalId'], [\App\Middlewares\RateLimitMiddleware::class]); $router->get('/api/student/profile/status', [\App\Controllers\AuthController::class, 'studentProfileStatus'], [\App\Middlewares\AuthMiddleware::class]); -$router->post('/api/student/profile/setup', [\App\Controllers\AuthController::class, 'studentProfileSetup'], [\App\Middlewares\AuthMiddleware::class]); +$router->post('/api/student/profile/setup', [\App\Controllers\AuthController::class, 'studentProfileSetup'], [\App\Middlewares\RateLimitMiddleware::class]); // Guardian Routes (Authenticated) $router->get('/api/guardian/dashboard', [\App\Controllers\GuardianController::class, 'getDashboard'], [\App\Middlewares\AuthMiddleware::class]); diff --git a/backend/scripts/curriculum_worker.php b/backend/scripts/curriculum_worker.php index b3c998c..1301f9a 100644 --- a/backend/scripts/curriculum_worker.php +++ b/backend/scripts/curriculum_worker.php @@ -182,12 +182,12 @@ $payload = [ updateState($stateFile, 'analyzing', 70, 'جاري تطبيقหน่วงزمني (4 ثوانٍ) لتفادي حدود الاستخدام (Rate Limit)...'); sleep(4); -// Allow custom model from .env (e.g. gemini-2.0-flash-lite-preview-02-05 or gemini-2.0-flash) +// Allow custom model from .env (e.g. gemini-1.5-flash or gemini-2.0-flash) $geminiModel = Env::get('GEMINI_MODEL') ?: getenv('GEMINI_MODEL'); if (empty($geminiModel)) { - $geminiModel = "gemini-flash-lite-latest"; // fallback to latest flash lite + $geminiModel = "gemini-1.5-flash"; // standard robust model } -updateState($stateFile, 'analyzing', 75, "جاري إرسال البيانات للنموذج [{$geminiModel}]..."); +updateState($stateFile, 'analyzing', 75, "جاري إرسال البيانات للنموذج [{$geminiModel}] لاستخراج الدروس والمفاهيم والمعادلات..."); $url = "https://generativelanguage.googleapis.com/v1beta/models/{$geminiModel}:generateContent?key=" . $geminiKey; $ch = curl_init($url); @@ -196,14 +196,15 @@ curl_setopt_array($ch, [ CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, - CURLOPT_TIMEOUT => 300 // AI might take 2 minutes + CURLOPT_TIMEOUT => 300 // AI might take 2-3 minutes ]); $res = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code !== 200 || empty($res)) { - updateState($stateFile, 'error', 0, 'فشل توليد المحتوى من الذكاء الاصطناعي. قد يكون الملف ضخماً جداً أو الـ API Key غير صالح.'); + $detail = !empty($res) ? $res : 'استجابة فارغة من خادم Google Gemini'; + updateState($stateFile, 'error', 0, "فشل تحليل المحتوى من الذكاء الاصطناعي (HTTP {$code}). التفاصيل: {$detail}"); return; }