getConnection();
$message = '';
$message_type = '';
// Dossier transit
$transit_dir = '/var/www/mathematiques/evaluations_transit/';
// === TRAITEMENT DE L'IMPORT ===
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['fichier'])) {
$fichier_nom = basename($_POST['fichier']);
$fichier_path = $transit_dir . $fichier_nom;
if (!file_exists($fichier_path)) {
$message = "Fichier introuvable : $fichier_nom";
$message_type = "error";
} else {
// Lecture du JSON
$json_content = file_get_contents($fichier_path);
$data = json_decode($json_content, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$message = "Erreur JSON : " . json_last_error_msg();
$message_type = "error";
} else {
// Validation structure
$errors = [];
if (!isset($data['metadata']) || !isset($data['questions'])) {
$errors[] = "Structure JSON invalide (metadata ou questions manquants)";
}
$meta = $data['metadata'] ?? [];
$required_meta = ['titre', 'niveau', 'duree_minutes', 'bareme_total'];
foreach ($required_meta as $field) {
if (!isset($meta[$field])) {
$errors[] = "Champ metadata.$field manquant";
}
}
if (empty($data['questions'])) {
$errors[] = "Aucune question trouvée";
}
if (!empty($errors)) {
$message = "Validation échouée :
• " . implode("
• ", $errors);
$message_type = "error";
} else {
// Import dans la base de données
try {
$db->beginTransaction();
// 1. Insérer l'évaluation (ADAPTÉ AU SCHÉMA EXISTANT)
$stmt = $db->prepare("
INSERT INTO evaluations (
titre, description, type, duree_minutes, note_totale,
id_enseignant, actif, afficher_correction,
melanger_questions, tentatives_max, date_creation
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
");
$type_eval = ($meta['type_evaluation'] ?? 'formative') == 'sommative' ? 'evaluation' : 'exercice';
// Conversion des booléens en entiers
$actif = isset($meta['est_active']) ? (int)(bool)$meta['est_active'] : 0;
$afficher_correction = isset($meta['afficher_correction']) ? (int)(bool)$meta['afficher_correction'] : 1;
$melanger_questions = isset($meta['melanger_questions']) ? (int)(bool)$meta['melanger_questions'] : 0;
$tentatives_max = isset($meta['tentatives_max']) ? (int)$meta['tentatives_max'] : 1;
$stmt->execute([
$meta['titre'],
$meta['description'] ?? '',
$type_eval,
(int)$meta['duree_minutes'],
(int)$meta['bareme_total'],
$_SESSION['user_id'], // id_enseignant
$actif,
$afficher_correction,
$melanger_questions,
$tentatives_max
]);
$id_evaluation = $db->lastInsertId();
// 2. Insérer les questions (ADAPTÉ AU SCHÉMA EXISTANT)
$stmt_question = $db->prepare("
INSERT INTO questions (
id_evaluation, ordre, type_question, enonce,
points, explication, options_json, reponse_correcte_json
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
");
foreach ($data['questions'] as $q) {
// Validation question
if (!isset($q['numero']) || !isset($q['type']) || !isset($q['enonce']) || !isset($q['points'])) {
throw new Exception("Question invalide : champs manquants");
}
// Préparer options_json et reponse_correcte_json selon le type
$options_json = null;
$reponse_correcte_json = null;
switch ($q['type']) {
case 'qcm':
case 'checkbox':
if (!isset($q['reponses']) || !is_array($q['reponses'])) {
throw new Exception("Question QCM/checkbox sans réponses");
}
$options_json = json_encode([
'reponses' => $q['reponses']
], JSON_UNESCAPED_UNICODE);
// Extraire les réponses correctes
$correctes = [];
foreach ($q['reponses'] as $rep) {
if ($rep['est_correcte'] ?? false) {
$correctes[] = $rep['id'];
}
}
$reponse_correcte_json = json_encode($correctes, JSON_UNESCAPED_UNICODE);
break;
case 'text':
case 'number':
if (!isset($q['reponse_attendue'])) {
throw new Exception("Question text/number sans reponse_attendue");
}
$options_json = json_encode([
'sensible_casse' => $q['sensible_casse'] ?? false
], JSON_UNESCAPED_UNICODE);
$reponse_correcte_json = json_encode([
'reponse' => $q['reponse_attendue']
], JSON_UNESCAPED_UNICODE);
break;
case 'select':
if (!isset($q['options']) || !is_array($q['options'])) {
throw new Exception("Question select sans options");
}
$options_json = json_encode([
'options' => $q['options']
], JSON_UNESCAPED_UNICODE);
// Trouver la réponse correcte
foreach ($q['options'] as $opt) {
if ($opt['est_correcte'] ?? false) {
$reponse_correcte_json = json_encode([
'id' => $opt['id']
], JSON_UNESCAPED_UNICODE);
break;
}
}
break;
case 'text_trous':
if (!isset($q['trous']) || !is_array($q['trous'])) {
throw new Exception("Question text_trous sans trous");
}
$options_json = json_encode([
'trous' => $q['trous']
], JSON_UNESCAPED_UNICODE);
// Extraire les réponses attendues
$reponses_trous = [];
foreach ($q['trous'] as $trou) {
$reponses_trous[$trou['id']] = $trou['reponse_attendue'];
}
$reponse_correcte_json = json_encode($reponses_trous, JSON_UNESCAPED_UNICODE);
break;
default:
// Pour types non supportés par l'enum (appariement, redaction)
// On utilise 'text' comme fallback
$options_json = json_encode($q, JSON_UNESCAPED_UNICODE);
$reponse_correcte_json = json_encode(['type_original' => $q['type']], JSON_UNESCAPED_UNICODE);
break;
}
$stmt_question->execute([
$id_evaluation,
$q['numero'],
$q['type'],
$q['enonce'],
$q['points'],
$q['explication'] ?? '',
$options_json,
$reponse_correcte_json
]);
}
// 3. Gérer les accès par classe (ADAPTÉ : acces_evaluations)
if (isset($meta['classes_autorisees']) && is_array($meta['classes_autorisees'])) {
$stmt_classe = $db->prepare("
SELECT id_classe FROM classes WHERE nom_classe = ?
");
$stmt_acces = $db->prepare("
INSERT INTO acces_evaluations (
id_evaluation, id_classe, date_debut, date_fin, actif
) VALUES (?, ?, ?, ?, 1)
");
$date_debut = $meta['date_debut'] ?? date('Y-m-d H:i:s');
$date_fin = $meta['date_fin'] ?? date('Y-m-d H:i:s', strtotime('+1 year'));
foreach ($meta['classes_autorisees'] as $nom_classe) {
$stmt_classe->execute([$nom_classe]);
$id_classe = $stmt_classe->fetchColumn();
if ($id_classe) {
$stmt_acces->execute([
$id_evaluation,
$id_classe,
$date_debut,
$date_fin
]);
}
}
}
$db->commit();
// Déplacer le fichier vers un dossier "importé"
$imported_dir = $transit_dir . 'imported/';
if (!is_dir($imported_dir)) {
mkdir($imported_dir, 0777, true);
}
rename($fichier_path, $imported_dir . $fichier_nom);
$message = "✅ Évaluation importée avec succès !
" .
"ID : $id_evaluation | Titre : " . htmlspecialchars($meta['titre']) . "
" .
"Questions : " . count($data['questions']);
$message_type = "success";
// Redirection après 2 secondes
header("Refresh: 2; url=gerer_evaluation.php?id=$id_evaluation");
} catch (Exception $e) {
$db->rollBack();
$message = "Erreur lors de l'import : " . $e->getMessage();
$message_type = "error";
}
}
}
}
}
// === LISTE DES FICHIERS DISPONIBLES ===
$fichiers_disponibles = [];
if (is_dir($transit_dir)) {
$files = scandir($transit_dir);
foreach ($files as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) === 'json') {
$filepath = $transit_dir . $file;
$fichiers_disponibles[] = [
'nom' => $file,
'taille' => filesize($filepath),
'date' => filemtime($filepath)
];
}
}
// Trier par date décroissante
usort($fichiers_disponibles, function($a, $b) {
return $b['date'] - $a['date'];
});
}
?>
Importez vos évaluations JSON depuis le dossier transit
Uploadez des fichiers JSON dans le dossier transit pour les voir apparaître ici.