getConnection(); $id_evaluation = isset($_POST['id_evaluation']) ? (int)$_POST['id_evaluation'] : (isset($_GET['id_evaluation']) ? (int)$_GET['id_evaluation'] : (isset($_GET['id']) ? (int)$_GET['id'] : 0)); $id_tentative = isset($_POST['id_tentative']) ? (int)$_POST['id_tentative'] : (isset($_GET['id_tentative']) ? (int)$_GET['id_tentative'] : 0); $auto_submit = isset($_GET['auto']) && $_GET['auto'] == 1; if ($id_tentative <= 0 || $id_evaluation <= 0) { die("Données invalides"); } // Vérifier que la tentative appartient à l'élève $stmt = $db->prepare(" SELECT * FROM tentatives_eleves WHERE id_tentative = ? AND id_eleve = ? AND statut = 'en_cours' "); $stmt->execute([$id_tentative, $user['id_utilisateur']]); $tentative = $stmt->fetch(PDO::FETCH_ASSOC); if (!$tentative) { die("Tentative introuvable ou déjà terminée"); } // Récupérer les réponses finales si soumission manuelle if (!$auto_submit && $_SERVER['REQUEST_METHOD'] === 'POST') { $reponses = []; foreach ($_POST as $key => $value) { if (strpos($key, 'reponse_') === 0) { $id_question = str_replace('reponse_', '', $key); $reponses[$id_question] = $value; } } // Mettre à jour les réponses finales $reponses_json = json_encode($reponses, JSON_UNESCAPED_UNICODE); $stmt = $db->prepare(" UPDATE tentatives_eleves SET reponses_json = ? WHERE id_tentative = ? "); $stmt->execute([$reponses_json, $id_tentative]); // Recharger la tentative avec les nouvelles réponses $stmt = $db->prepare("SELECT * FROM tentatives_eleves WHERE id_tentative = ?"); $stmt->execute([$id_tentative]); $tentative = $stmt->fetch(PDO::FETCH_ASSOC); } // Récupérer toutes les questions de l'évaluation $stmt = $db->prepare(" SELECT * FROM questions WHERE id_evaluation = ? ORDER BY ordre ASC "); $stmt->execute([$id_evaluation]); $questions = $stmt->fetchAll(PDO::FETCH_ASSOC); // Décoder les réponses de l'élève $reponses_eleve = json_decode($tentative['reponses_json'], true) ?: []; // CALCUL DE LA NOTE $points_obtenus = 0; $points_totaux = 0; foreach ($questions as $question) { $id_question = $question['id_question']; $points_question = (float)$question['points']; $points_totaux += $points_question; // Récupérer la réponse de l'élève $reponse_eleve = $reponses_eleve[$id_question] ?? null; // Récupérer les options et la réponse correcte de la question $options = json_decode($question['options_json'], true); $reponse_correcte_data = json_decode($question['reponse_correcte_json'], true); // Vérifier la réponse selon le type switch ($question['type_question']) { case 'checkbox': // Trouver toutes les réponses correctes $reponses_correctes = []; if (isset($options['reponses'])) { foreach ($options['reponses'] as $rep) { if (isset($rep['est_correcte']) && $rep['est_correcte'] === true) { $reponses_correctes[] = $rep['texte']; } } } $reponses_eleve_array = is_array($reponse_eleve) ? $reponse_eleve : []; // Toutes correctes = points complets sort($reponses_correctes); sort($reponses_eleve_array); if ($reponses_correctes === $reponses_eleve_array) { $points_obtenus += $points_question; } else { // Points partiels selon le nombre de bonnes réponses $nb_correctes = count($reponses_correctes); if ($nb_correctes > 0) { $nb_bonnes = count(array_intersect($reponses_correctes, $reponses_eleve_array)); $nb_mauvaises = count(array_diff($reponses_eleve_array, $reponses_correctes)); $points_partiels = max(0, ($nb_bonnes - $nb_mauvaises) / $nb_correctes * $points_question); $points_obtenus += $points_partiels; } } break; case 'qcm': // Trouver la réponse correcte dans le tableau reponses $reponse_correcte = null; if (isset($options['reponses'])) { foreach ($options['reponses'] as $rep) { if (isset($rep['est_correcte']) && $rep['est_correcte'] === true) { $reponse_correcte = $rep['texte']; break; } } } if ($reponse_eleve === $reponse_correcte) { $points_obtenus += $points_question; } break; case 'number': // La réponse correcte est dans reponse_correcte_json: {"reponse": "18"} $reponse_correcte = $reponse_correcte_data['reponse'] ?? null; // Normaliser les deux réponses (gère entiers, fractions, décimaux) $valeur_eleve = normaliser_reponse_mathematique($reponse_eleve); $valeur_attendue = normaliser_reponse_mathematique($reponse_correcte); // Comparer avec tolérance if ($valeur_eleve !== false && $valeur_attendue !== false) { if (comparer_reponses_mathematiques($valeur_attendue, $valeur_eleve)) { $points_obtenus += $points_question; } } break; case 'text': // Pour les questions texte, nécessite correction manuelle // On compte 0 point automatiquement, à corriger manuellement break; case 'select': // La réponse correcte est dans reponse_correcte_json: {"id": "opt2"} // Les options sont dans options_json: {"options": [{"id": "opt1", "texte": "...", "est_correcte": false}, ...]} $id_reponse_correcte = $reponse_correcte_data['id'] ?? null; // L'élève peut avoir répondu avec l'ID ou le texte, on vérifie les deux $est_correct = false; if ($id_reponse_correcte && isset($options['options'])) { // Trouver le texte correspondant à l'ID correct $texte_correct = null; foreach ($options['options'] as $opt) { if (($opt['id'] ?? '') === $id_reponse_correcte) { $texte_correct = $opt['texte'] ?? null; break; } } // Vérifier si la réponse de l'élève correspond (ID ou texte) if ($reponse_eleve === $id_reponse_correcte || $reponse_eleve === $texte_correct) { $est_correct = true; } } if ($est_correct) { $points_obtenus += $points_question; } break; case 'text_trous': $trous = $options['trous'] ?? []; $reponses_eleve_trous = is_array($reponse_eleve) ? $reponse_eleve : []; $nb_trous = count($trous); $nb_corrects = 0; foreach ($trous as $trou) { $trou_id = $trou['id']; $reponse_correcte = $trou['reponse_correcte']; $reponse_eleve_trou = $reponses_eleve_trous[$trou_id] ?? ''; if (trim(strtolower($reponse_eleve_trou)) === trim(strtolower($reponse_correcte))) { $nb_corrects++; } } $points_obtenus += ($nb_corrects / $nb_trous) * $points_question; break; } } // Calculer le pourcentage $pourcentage = $points_totaux > 0 ? ($points_obtenus / $points_totaux) * 100 : 0; // Récupérer la note totale de l'évaluation $stmt = $db->prepare("SELECT note_totale FROM evaluations WHERE id_evaluation = ?"); $stmt->execute([$id_evaluation]); $eval = $stmt->fetch(PDO::FETCH_ASSOC); $note_sur = $eval['note_totale'] ?? 20; // Calculer la note finale $note_finale = ($pourcentage / 100) * $note_sur; // Calculer le temps passé $date_debut = new DateTime($tentative['date_debut']); $date_fin = new DateTime(); $temps_passe = $date_fin->getTimestamp() - $date_debut->getTimestamp(); // Mettre à jour la tentative try { $stmt = $db->prepare(" UPDATE tentatives_eleves SET statut = 'terminee', note = ?, note_sur = ?, pourcentage = ?, temps_passe = ?, date_fin = NOW() WHERE id_tentative = ? "); $stmt->execute([ round($note_finale, 2), $note_sur, round($pourcentage, 2), $temps_passe, $id_tentative ]); // Redirection vers la page de résultat header('Location: resultat_evaluation.php?id=' . $id_evaluation); exit(); } catch (Exception $e) { error_log("Erreur soumission évaluation: " . $e->getMessage()); die("Erreur lors de la soumission de l'évaluation"); } ?>