getConnection(); // Évaluation $stmt = $db->prepare("SELECT * FROM evaluations WHERE id_evaluation = ?"); $stmt->execute([$id_evaluation]); $evaluation = $stmt->fetch(PDO::FETCH_ASSOC); if (!$evaluation) { die('Évaluation non trouvée'); } // Questions $stmt = $db->prepare("SELECT * FROM questions WHERE id_evaluation = ? ORDER BY ordre ASC"); $stmt->execute([$id_evaluation]); $questions = $stmt->fetchAll(PDO::FETCH_ASSOC); // Tentatives (CORRECTION: date_fin au lieu de date_soumission) $stmt = $db->prepare(" SELECT te.*, TIMESTAMPDIFF(MINUTE, te.date_debut, COALESCE(te.date_fin, NOW())) as duree_minutes_calc, u.login, u.nom, u.prenom, c.nom_classe FROM tentatives_eleves te JOIN utilisateurs u ON te.id_eleve = u.id_utilisateur LEFT JOIN classes c ON u.id_classe = c.id_classe WHERE te.id_evaluation = ? ORDER BY u.nom, u.prenom "); $stmt->execute([$id_evaluation]); $tentatives = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($format === 'csv') { exportCSV($evaluation, $questions, $tentatives); } else { exportJSON($evaluation, $questions, $tentatives); } } catch (Exception $e) { die('Erreur: ' . $e->getMessage()); } /** * Extrait réponse correcte depuis reponse_correcte_json * Format réel: {"reponse": "x = 4"} */ function extraireReponseCorrecte($question) { // 1. Essayer reponse_correcte_json d'abord (pour type number, text, etc.) $correcte_data = json_decode($question['reponse_correcte_json'] ?? '{}', true); if (isset($correcte_data['reponse'])) { $rep = $correcte_data['reponse']; if (is_array($rep)) { return implode(' | ', $rep); } return $rep; } // 2. Fallback: chercher dans options_json (pour checkbox, qcm, select) $options = json_decode($question['options_json'] ?? '{}', true); if (isset($options['reponses']) && is_array($options['reponses'])) { $correctes = []; foreach ($options['reponses'] as $rep) { if (isset($rep['est_correcte']) && $rep['est_correcte'] === true) { $correctes[] = $rep['texte'] ?? $rep['id']; } } if (!empty($correctes)) { return implode(' + ', $correctes); } } // 2b. Format avec 'options' (select) if (isset($options['options']) && is_array($options['options'])) { foreach ($options['options'] as $opt) { if (isset($opt['est_correcte']) && $opt['est_correcte'] === true) { return $opt['texte']; } } } // 3. Fallback ultime: options_json peut être un simple array ["opt1", "opt2"] if (isset($options['correct_answer'])) { return $options['correct_answer']; } return 'N/A'; } function exportCSV($evaluation, $questions, $tentatives) { $filename = sprintf( 'eval_%d_%s_%s.csv', $evaluation['id_evaluation'], preg_replace('/[^a-z0-9]/i', '_', substr($evaluation['titre'], 0, 30)), date('Ymd_His') ); header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename="' . $filename . '"'); header('Pragma: no-cache'); header('Expires: 0'); $output = fopen('php://output', 'w'); fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF)); // En-tête $headers = ['ID', 'Élève', 'Classe', 'Login', 'Statut', 'Début', 'Fin', 'Durée(min)', 'Note', 'Note sur', '%']; foreach ($questions as $q) { $headers[] = 'Q' . $q['ordre']; } foreach ($questions as $q) { $headers[] = 'Q' . $q['ordre'] . '_Correcte'; } fputcsv($output, $headers, ';'); // Données foreach ($tentatives as $t) { $reponses = json_decode($t['reponses_json'] ?? '{}', true) ?: []; $row = [ $t['id_tentative'], $t['prenom'] . ' ' . $t['nom'], $t['nom_classe'] ?: 'Libre', $t['login'], $t['statut'], $t['date_debut'], $t['date_fin'] ?: '-', $t['temps_passe'] ?? $t['duree_minutes_calc'], $t['note'] !== null ? number_format($t['note'], 2, ',', '') : 'N/A', $t['note_sur'] ?? $evaluation['note_totale'], $t['pourcentage'] !== null ? number_format($t['pourcentage'], 1, ',', '') . '%' : 'N/A' ]; // Réponses élève foreach ($questions as $q) { $rep = $reponses[$q['id_question']] ?? ''; if (is_array($rep)) { $rep = implode(' + ', $rep); } elseif (is_object($rep)) { $rep = json_encode($rep, JSON_UNESCAPED_UNICODE); } $row[] = $rep; } // Réponses correctes foreach ($questions as $q) { $row[] = extraireReponseCorrecte($q); } fputcsv($output, $row, ';'); } fclose($output); exit; } function exportJSON($evaluation, $questions, $tentatives) { $filename = sprintf( 'eval_%d_%s_%s.json', $evaluation['id_evaluation'], preg_replace('/[^a-z0-9]/i', '_', substr($evaluation['titre'], 0, 30)), date('Ymd_His') ); header('Content-Type: application/json; charset=utf-8'); header('Content-Disposition: attachment; filename="' . $filename . '"'); $export = [ 'metadata' => [ 'date_export' => date('Y-m-d H:i:s'), 'exporteur' => $_SESSION['login'] ?? 'Enseignant' ], 'evaluation' => [ 'id' => (int)$evaluation['id_evaluation'], 'titre' => $evaluation['titre'], 'description' => $evaluation['description'] ?? '', 'type' => $evaluation['type'], 'duree_minutes' => (int)$evaluation['duree_minutes'], 'note_totale' => (float)$evaluation['note_totale'], 'nb_questions' => count($questions), 'tentatives_max' => (int)$evaluation['tentatives_max'] ], 'questions' => [], 'tentatives' => [] ]; foreach ($questions as $q) { $export['questions'][] = [ 'id' => (int)$q['id_question'], 'ordre' => (int)$q['ordre'], 'type' => $q['type_question'], 'enonce' => $q['enonce'], 'options' => json_decode($q['options_json'] ?? '[]', true), 'reponse_correcte' => extraireReponseCorrecte($q), 'points' => (float)$q['points'], 'explication' => $q['explication'] ?? null ]; } foreach ($tentatives as $t) { $reponses = json_decode($t['reponses_json'] ?? '{}', true) ?: []; $details = []; foreach ($questions as $q) { $details[] = [ 'question_id' => (int)$q['id_question'], 'ordre' => (int)$q['ordre'], 'reponse_eleve' => $reponses[$q['id_question']] ?? null, 'reponse_correcte' => extraireReponseCorrecte($q) ]; } $export['tentatives'][] = [ 'id' => (int)$t['id_tentative'], 'eleve' => [ 'id' => (int)$t['id_eleve'], 'nom' => $t['nom'], 'prenom' => $t['prenom'], 'login' => $t['login'], 'classe' => $t['nom_classe'] ?? 'Libre' ], 'numero_tentative' => (int)$t['numero_tentative'], 'statut' => $t['statut'], 'note' => $t['note'] !== null ? (float)$t['note'] : null, 'note_sur' => $t['note_sur'] !== null ? (float)$t['note_sur'] : (float)$evaluation['note_totale'], 'pourcentage' => $t['pourcentage'] !== null ? (float)$t['pourcentage'] : null, 'dates' => [ 'debut' => $t['date_debut'], 'fin' => $t['date_fin'] ], 'temps_passe_minutes' => $t['temps_passe'] ?? (int)$t['duree_minutes_calc'], 'reponses_detaillees' => $details ]; } echo json_encode($export, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } ?>