109 lines
3.8 KiB
PHP
109 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Core\Database;
|
|
use App\Core\Env;
|
|
|
|
class AiLessonEnhancerService
|
|
{
|
|
/**
|
|
* Extracts the lively script, cheat sheet, and Socratic quiz using Gemini.
|
|
*/
|
|
public static function generateFromText(string $title, string $content): ?array
|
|
{
|
|
$prompt = self::buildPrompt($title, $content);
|
|
return self::callGemini($prompt);
|
|
}
|
|
|
|
public static function enhanceLesson(int $lessonId): bool
|
|
{
|
|
$lesson = Database::selectOne(
|
|
"SELECT l.*, c.subject_id FROM lessons l JOIN courses c ON l.course_id = c.id WHERE l.id = ?",
|
|
[$lessonId]
|
|
);
|
|
|
|
if (!$lesson || empty($lesson['markdown_content'])) {
|
|
return false;
|
|
}
|
|
|
|
$prompt = self::buildPrompt($lesson['title'], $lesson['markdown_content']);
|
|
$result = self::callGemini($prompt);
|
|
|
|
if (!$result) return false;
|
|
|
|
// Save to Database
|
|
Database::execute(
|
|
"UPDATE lessons SET cheat_sheet_markdown = ?, socratic_quiz_json = ? WHERE id = ?",
|
|
[
|
|
$result['cheat_sheet'] ?? null,
|
|
json_encode($result['socratic_quiz'] ?? []),
|
|
$lessonId
|
|
]
|
|
);
|
|
|
|
// Return true if successful
|
|
return true;
|
|
}
|
|
|
|
private static function buildPrompt(string $title, string $content): string
|
|
{
|
|
return "أنت خبير تعليمي وصانع محتوى محترف (تعمل بآلية مشابهة لـ Google NotebookLM).
|
|
بناءً على نص الدرس التالي، قم بتوليد حزمة تعليمية متكاملة بصيغة JSON فقط.
|
|
|
|
أريد الإجابة بصيغة JSON صارمة تحتوي على المفاتيح التالية:
|
|
{
|
|
\"video_script\": \"سيناريو حواري حيوي للمعلم يشرح الدرس بحماس مع التوجيهات البصرية.\",
|
|
\"cheat_sheet\": \"ملخص الدرس بخطوات سريعة ومبسطة جداً (بصيغة Markdown).\",
|
|
\"socratic_quiz\": {
|
|
\"question\": \"سؤال ذكي متعدد الخيارات\",
|
|
\"options\": [\"خيار A\", \"خيار B\", \"خيار C\", \"خيار D\"],
|
|
\"correct_answer\": \"النص الدقيق للخيار الصحيح\",
|
|
\"explanation\": \"تفسير سبب صحة هذا الخيار\"
|
|
}
|
|
}
|
|
|
|
عنوان الدرس: {$title}
|
|
محتوى الدرس: {$content}";
|
|
}
|
|
|
|
private static function callGemini(string $prompt): ?array
|
|
{
|
|
$apiKey = Env::get('GEMINI_API_KEY');
|
|
if (!$apiKey) {
|
|
$keys = explode(',', getenv('GEMINI_API_KEY'));
|
|
$apiKey = trim($keys[0] ?? '');
|
|
}
|
|
if (!$apiKey) return null;
|
|
|
|
$model = Env::get('GEMINI_MODEL') ?: 'gemini-1.5-flash';
|
|
$url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent?key={$apiKey}";
|
|
|
|
$payload = [
|
|
'contents' => [['parts' => [['text' => $prompt]]]],
|
|
'generationConfig' => ['responseMimeType' => 'application/json', 'temperature' => 0.7]
|
|
];
|
|
|
|
$ch = curl_init($url);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => json_encode($payload),
|
|
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 60
|
|
]);
|
|
$res = curl_exec($ch);
|
|
curl_close($ch);
|
|
|
|
if (!$res) return null;
|
|
|
|
$json = json_decode($res, true);
|
|
$text = $json['candidates'][0]['content']['parts'][0]['text'] ?? '';
|
|
|
|
$text = preg_replace('/^```json\s*/i', '', $text);
|
|
$text = preg_replace('/```\s*$/i', '', $text);
|
|
|
|
return json_decode(trim($text), true);
|
|
}
|
|
}
|