412 lines
12 KiB
PHP
412 lines
12 KiB
PHP
<?php
|
||
/**
|
||
* Export Mots de Passe - Enseignant
|
||
* Génération et téléchargement des listes par classe
|
||
*/
|
||
|
||
define('APP_ROOT', dirname(__DIR__));
|
||
require_once APP_ROOT . '/config/config.php';
|
||
require_once APP_ROOT . '/config/database.php';
|
||
|
||
session_start();
|
||
|
||
// Vérifier authentification enseignant
|
||
if (!isLoggedIn() || !isEnseignant()) {
|
||
redirect('index.php');
|
||
}
|
||
|
||
// $auth = new Auth(); // MIGRÉ vers SessionManager
|
||
$user = currentUser();
|
||
$db = Database::getInstance();
|
||
$exporter = new PasswordExport();
|
||
|
||
// Actions
|
||
$action = $_GET['action'] ?? '';
|
||
$message = '';
|
||
$error = '';
|
||
|
||
if ($action === 'export_classe' && isset($_GET['id_classe'])) {
|
||
$result = $exporter->exportClassePasswords((int)$_GET['id_classe']);
|
||
if ($result['success']) {
|
||
$message = 'Export réussi : ' . $result['filename'];
|
||
} else {
|
||
$error = $result['message'];
|
||
}
|
||
}
|
||
|
||
if ($action === 'export_all') {
|
||
$results = $exporter->exportAllClasses();
|
||
$success_count = count(array_filter($results, fn($r) => $r['success']));
|
||
$message = "Export terminé : $success_count classe(s) exportée(s)";
|
||
}
|
||
|
||
if ($action === 'download' && isset($_GET['file'])) {
|
||
$exporter->downloadFile($_GET['file']);
|
||
}
|
||
|
||
if ($action === 'delete' && isset($_GET['file'])) {
|
||
if ($exporter->deleteFile($_GET['file'])) {
|
||
$message = 'Fichier supprimé';
|
||
} else {
|
||
$error = 'Erreur suppression';
|
||
}
|
||
}
|
||
|
||
// Récupérer classes
|
||
$classes = $db->fetchAll("
|
||
SELECT
|
||
c.id_classe,
|
||
c.nom_classe,
|
||
c.niveau,
|
||
c.type_classe,
|
||
COUNT(u.id_utilisateur) as nb_eleves
|
||
FROM classes c
|
||
LEFT JOIN utilisateurs u ON c.id_classe = u.id_classe AND u.actif = TRUE
|
||
WHERE c.actif = TRUE
|
||
GROUP BY c.id_classe
|
||
ORDER BY c.nom_classe
|
||
");
|
||
|
||
// Fichiers exportés
|
||
$files = $exporter->listExportedFiles();
|
||
|
||
// Déconnexion
|
||
if (isset($_GET['logout'])) {
|
||
$auth->logout();
|
||
redirect('index.php');
|
||
}
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Export Mots de Passe - Enseignant</title>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
|
||
:root {
|
||
--primary: #667eea;
|
||
--secondary: #764ba2;
|
||
--success: #10b981;
|
||
--danger: #ef4444;
|
||
--warning: #f59e0b;
|
||
--gray-100: #f3f4f6;
|
||
--gray-200: #e5e7eb;
|
||
--gray-800: #1f2937;
|
||
}
|
||
|
||
body {
|
||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||
background: var(--gray-100);
|
||
color: var(--gray-800);
|
||
}
|
||
|
||
.header {
|
||
background: linear-gradient(135deg, var(--primary), var(--secondary));
|
||
color: white;
|
||
padding: 20px 0;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.header .container {
|
||
max-width: 1400px;
|
||
margin: 0 auto;
|
||
padding: 0 30px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.header h1 {
|
||
font-size: 1.8em;
|
||
}
|
||
|
||
.header .nav {
|
||
display: flex;
|
||
gap: 15px;
|
||
}
|
||
|
||
.header a {
|
||
color: white;
|
||
text-decoration: none;
|
||
padding: 10px 20px;
|
||
border-radius: 8px;
|
||
background: rgba(255,255,255,0.2);
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.header a:hover {
|
||
background: rgba(255,255,255,0.3);
|
||
}
|
||
|
||
.main-content {
|
||
max-width: 1400px;
|
||
margin: 40px auto;
|
||
padding: 0 30px;
|
||
}
|
||
|
||
.alert {
|
||
padding: 15px 20px;
|
||
border-radius: 8px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.alert-success {
|
||
background: #d1fae5;
|
||
color: #065f46;
|
||
border-left: 4px solid var(--success);
|
||
}
|
||
|
||
.alert-error {
|
||
background: #fee2e2;
|
||
color: #991b1b;
|
||
border-left: 4px solid var(--danger);
|
||
}
|
||
|
||
.alert-warning {
|
||
background: #fef3c7;
|
||
color: #92400e;
|
||
border-left: 4px solid var(--warning);
|
||
}
|
||
|
||
.section {
|
||
background: white;
|
||
padding: 30px;
|
||
border-radius: 12px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.section h2 {
|
||
margin-bottom: 20px;
|
||
color: var(--primary);
|
||
}
|
||
|
||
.btn {
|
||
padding: 10px 20px;
|
||
border-radius: 8px;
|
||
text-decoration: none;
|
||
font-weight: 600;
|
||
transition: all 0.3s;
|
||
border: none;
|
||
cursor: pointer;
|
||
display: inline-block;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: var(--primary);
|
||
color: white;
|
||
}
|
||
|
||
.btn-success {
|
||
background: var(--success);
|
||
color: white;
|
||
}
|
||
|
||
.btn-danger {
|
||
background: var(--danger);
|
||
color: white;
|
||
}
|
||
|
||
.btn-warning {
|
||
background: var(--warning);
|
||
color: white;
|
||
}
|
||
|
||
.btn:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
||
}
|
||
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
th {
|
||
background: var(--gray-100);
|
||
padding: 15px;
|
||
text-align: left;
|
||
font-weight: 600;
|
||
border-bottom: 2px solid var(--gray-200);
|
||
}
|
||
|
||
td {
|
||
padding: 15px;
|
||
border-bottom: 1px solid var(--gray-200);
|
||
}
|
||
|
||
tr:hover {
|
||
background: var(--gray-100);
|
||
}
|
||
|
||
.badge {
|
||
display: inline-block;
|
||
padding: 5px 12px;
|
||
border-radius: 20px;
|
||
font-size: 0.85em;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.badge-regular { background: #dbeafe; color: #1e40af; }
|
||
.badge-soutien { background: #fef3c7; color: #92400e; }
|
||
|
||
.actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header class="header">
|
||
<div class="container">
|
||
<h1>🔐 Export Mots de Passe</h1>
|
||
<div class="nav">
|
||
<a href="dashboard.php">← Retour Dashboard</a>
|
||
<a href="?logout=1">Déconnexion</a>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="main-content">
|
||
<?php if ($message): ?>
|
||
<div class="alert alert-success"><?= h($message) ?></div>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($error): ?>
|
||
<div class="alert alert-error"><?= h($error) ?></div>
|
||
<?php endif; ?>
|
||
|
||
<div class="alert alert-warning">
|
||
⚠️ <strong>Sécurité :</strong> Les fichiers contiennent les mots de passe en clair.
|
||
Ils sont stockés hors du dossier web dans <code>/var/backups/mathematiques/classes_passwords/</code>
|
||
avec permissions 600 (lecture seule propriétaire).
|
||
</div>
|
||
|
||
<!-- Export par classe -->
|
||
<section class="section">
|
||
<h2>📚 Export par Classe</h2>
|
||
|
||
<p style="margin-bottom: 20px;">
|
||
Générez un fichier JSON contenant tous les logins et mots de passe pour chaque classe.
|
||
</p>
|
||
|
||
<div style="margin-bottom: 20px;">
|
||
<a href="?action=export_all" class="btn btn-success"
|
||
onclick="return confirm('Exporter toutes les classes ?')">
|
||
📤 Exporter Toutes les Classes
|
||
</a>
|
||
</div>
|
||
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Classe</th>
|
||
<th>Niveau</th>
|
||
<th>Type</th>
|
||
<th>Nb Élèves</th>
|
||
<th>Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($classes as $classe): ?>
|
||
<tr>
|
||
<td><strong><?= h($classe['nom_classe']) ?></strong></td>
|
||
<td><?= h($classe['niveau']) ?></td>
|
||
<td>
|
||
<span class="badge badge-<?= $classe['type_classe'] ?>">
|
||
<?= $classe['type_classe'] === 'reguliere' ? 'Régulière' : 'Soutien' ?>
|
||
</span>
|
||
</td>
|
||
<td><?= $classe['nb_eleves'] ?></td>
|
||
<td class="actions">
|
||
<a href="?action=export_classe&id_classe=<?= $classe['id_classe'] ?>"
|
||
class="btn btn-primary">
|
||
Exporter
|
||
</a>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<!-- Fichiers exportés -->
|
||
<section class="section">
|
||
<h2>📁 Fichiers Exportés</h2>
|
||
|
||
<?php if (empty($files)): ?>
|
||
<p style="color: #6b7280;">Aucun fichier exporté pour le moment.</p>
|
||
<?php else: ?>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Fichier</th>
|
||
<th>Taille</th>
|
||
<th>Date Modification</th>
|
||
<th>Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($files as $file): ?>
|
||
<tr>
|
||
<td><code><?= h($file['filename']) ?></code></td>
|
||
<td><?= number_format($file['size'] / 1024, 2) ?> KB</td>
|
||
<td><?= date('d/m/Y H:i', $file['date_modification']) ?></td>
|
||
<td class="actions">
|
||
<a href="?action=download&file=<?= urlencode($file['filename']) ?>"
|
||
class="btn btn-success">
|
||
⬇️ Télécharger
|
||
</a>
|
||
<a href="?action=delete&file=<?= urlencode($file['filename']) ?>"
|
||
class="btn btn-danger"
|
||
onclick="return confirm('Supprimer ce fichier ?')">
|
||
🗑️ Supprimer
|
||
</a>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php endif; ?>
|
||
</section>
|
||
|
||
<!-- Informations -->
|
||
<section class="section">
|
||
<h2>ℹ️ Informations</h2>
|
||
|
||
<h3 style="margin-top: 20px;">Format du fichier JSON :</h3>
|
||
<pre style="background: var(--gray-100); padding: 15px; border-radius: 8px; overflow-x: auto;">
|
||
{
|
||
"classe": "2nde_A",
|
||
"niveau": "2nde",
|
||
"annee_scolaire": "2024-2025",
|
||
"type": "reguliere",
|
||
"date_export": "2025-10-23 10:30:00",
|
||
"nombre_eleves": 25,
|
||
"eleves": [
|
||
{
|
||
"login": "j.dupont",
|
||
"nom": "DUPONT",
|
||
"prenom": "Jean",
|
||
"date_naissance": "15/03/2009",
|
||
"mot_de_passe": "1503"
|
||
}
|
||
]
|
||
}
|
||
</pre>
|
||
|
||
<h3 style="margin-top: 20px;">Règles de génération :</h3>
|
||
<ul style="margin-left: 20px; line-height: 1.8;">
|
||
<li><strong>Login :</strong> p.nom (première lettre prénom + point + nom, minuscules)</li>
|
||
<li><strong>Doublons :</strong> ajout chiffre (j.dupont2, j.dupont3...)</li>
|
||
<li><strong>Mot de passe élève :</strong> JJMM (jour+mois naissance en 4 chiffres)</li>
|
||
<li><strong>Mot de passe enseignant :</strong> Personnalisé (n.boyer → math2025!)</li>
|
||
</ul>
|
||
</section>
|
||
</main>
|
||
</body>
|
||
</html>
|