'https://ainur.iut-fbleau.fr/auth/login?service=https%3A%2F%2Fnotes.iut-fbleau.fr%2Fservices%2FdoAuth.php%3Fhref%3Dhttps%3A%2F%2Fnotes.iut-fbleau.fr%2F',
'url_data_prefix' => 'https://notes.iut-fbleau.fr/services/data.php?q=relev%C3%A9Etudiant&semestre=',
'semestre_mapping' => [
'BUT2FI_S1' => '154',
'BUT2FI_S2' => '248',
'BUT2FI_S3' => '263',
'BUT2FI_S4' => '351',
'BUT2FA_S1' => '154',
'BUT2FA_S2' => '248',
'BUT2FA_S3' => '265'
]
];
// Couleurs pour les UEs
$ue_colors = [
'UE.1.1' => '#b80004',
'UE.1.2' => '#f97b3d',
'UE.1.3' => '#feb40b',
'UE.1.4' => '#80cb3f',
'UE.1.5' => '#05162e',
'UE.1.6' => '#548687',
'UE.2.1' => '#b80004',
'UE.2.2' => '#f97b3d',
'UE.2.3' => '#feb40b',
'UE.2.4' => '#80cb3f',
'UE.2.5' => '#05162e',
'UE.2.6' => '#548687',
'UE.3.1' => '#b80004',
'UE.3.2' => '#f97b3d',
'UE.3.3' => '#feb40b',
'UE.3.4' => '#80cb3f',
'UE.3.5' => '#05162e',
'UE.3.6' => '#548687'
];
// Fonction pour se connecter et récupérer les données
function fetchData($username, $password, $formation, $semestre) {
global $config;
// Vérifier si un semestre est sélectionné
if (!isset($semestre)) {
return ['error' => 'Semestre non valide'];
}
// Initialiser cURL pour simuler le navigateur
$ch = curl_init();
$cookie_file = tempnam(sys_get_temp_dir(), 'cookies');
// Configuration initiale de cURL avec un User-Agent de navigateur
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 1. Récupérer le formulaire de login pour obtenir les tokens potentiels
curl_setopt($ch, CURLOPT_URL, $config['url_login']);
$login_page = curl_exec($ch);
if ($login_page === false) {
return ['error' => 'Impossible de se connecter au serveur: ' . curl_error($ch)];
}
// Extraire le token CSRF ou lt/execution s'ils existent
$lt_token = '';
$execution_token = '';
// Chercher lt et execution dans le formulaire CAS
if (preg_match('/ $username,
'password' => $password,
'submitBtn' => 'Connexion'
];
// Ajouter les tokens s'ils existent
if (!empty($lt_token)) {
$post_data['lt'] = $lt_token;
}
if (!empty($execution_token)) {
$post_data['execution'] = $execution_token;
$post_data['_eventId'] = 'submit'; // Souvent utilisé avec 'execution'
}
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
// Configurer les en-têtes pour simuler une requête de formulaire
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded',
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
'Referer: ' . $config['url_login']
]);
$response_post = curl_exec($ch);
if ($response_post === false) {
return ['error' => 'Échec de la connexion: ' . curl_error($ch)];
}
// La redirection devrait nous amener à la page du bulletin
// Vérifier l'URL actuelle après redirection
$current_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
// Aller directement à la page des notes après l'authentification
curl_setopt($ch, CURLOPT_URL, 'https://notes.iut-fbleau.fr/');
curl_setopt($ch, CURLOPT_POST, false);
$bulletin_page = curl_exec($ch);
if ($bulletin_page === false) {
return ['error' => 'Impossible d\'accéder à la page des notes: ' . curl_error($ch)];
}
// Vérifier si la connexion a réussi
if (strpos($bulletin_page, "Ce relevé de notes est provisoire") === false &&
strpos($bulletin_page, "ScoDoc") === false) {
return ['error' => 'Identifiants incorrects ou problème de connexion'];
}
// 3. Récupérer les données JSON
$data_url = $config['url_data_prefix'] . $semestre;
curl_setopt($ch, CURLOPT_URL, $data_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'Referer: https://notes.iut-fbleau.fr/'
]);
$json_response = curl_exec($ch);
curl_close($ch);
if ($json_response === false) {
return ['error' => 'Impossible de récupérer les données'];
}
// Décoder les données JSON
$data = json_decode($json_response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return ['error' => 'Format de données invalide: ' . json_last_error_msg()];
}
return $data;
}
// Simuler les données pour le débogage
function getSimulatedData() {
// Détecter si un fichier data.json existe localement
if (file_exists('data.json')) {
$json_data = file_get_contents('data.json');
return json_decode($json_data, true);
}
// Structure simplifiée des données simulées
return [
'relevé' => [
'etudiant' => [
'nom' => 'DUPONT',
'prenom' => 'Jean'
],
'formation' => [
'acronyme' => 'BUT INFO'
],
'semestre' => [
'numero' => 2,
'notes' => [
'value' => '14.50',
'min' => '6.75',
'max' => '16.20',
'moy' => '12.35'
],
'rang' => [
'value' => '5',
'total' => '86'
]
],
'ues' => [
'UE.1.1' => [
'titre' => 'Développer des applications',
'moyenne' => [
'value' => '15.75',
'min' => '7.50',
'max' => '18.00',
'moy' => '13.25',
'rang' => '4',
'total' => '86'
],
'ressources' => [
'R1.01' => [
'coef' => 42,
'moyenne' => '16.50'
],
'R1.02' => [
'coef' => 18,
'moyenne' => '15.00'
]
],
'saes' => [
'S1.01' => [
'coef' => 40,
'moyenne' => '16.00'
]
]
],
'UE.1.2' => [
'titre' => 'Optimiser des applications',
'moyenne' => [
'value' => '14.00',
'min' => '6.00',
'max' => '17.50',
'moy' => '12.00',
'rang' => '8',
'total' => '86'
],
'ressources' => [
'R1.03' => [
'coef' => 24,
'moyenne' => '14.50'
],
'R1.04' => [
'coef' => 16,
'moyenne' => '13.50'
]
],
'saes' => [
'S1.02' => [
'coef' => 40,
'moyenne' => '15.00'
]
]
]
],
'ressources' => [
'R1.01' => [
'titre' => 'Initiation au développement',
'evaluations' => [
[
'id' => 1001,
'description' => 'TP noté 1',
'date' => '2023-10-15T10:00:00+02:00',
'note' => [
'value' => '17.00',
'min' => '8.00',
'max' => '19.00',
'moy' => '14.50'
],
'coef' => '1.00'
],
[
'id' => 1002,
'description' => 'Examen final',
'date' => '2023-12-20T14:00:00+01:00',
'note' => [
'value' => '16.00',
'min' => '7.00',
'max' => '18.50',
'moy' => '13.75'
],
'coef' => '2.00'
]
]
],
'R1.02' => [
'titre' => 'Programmation orientée objet',
'evaluations' => [
[
'id' => 1003,
'description' => 'Projet',
'date' => '2023-11-10T10:00:00+01:00',
'note' => [
'value' => '15.00',
'min' => '9.00',
'max' => '18.00',
'moy' => '14.00'
],
'coef' => '1.50'
]
]
],
'R1.03' => [
'titre' => 'Architecture des systèmes',
'evaluations' => [
[
'id' => 1004,
'description' => 'Contrôle',
'date' => '2023-10-05T08:00:00+02:00',
'note' => [
'value' => '14.50',
'min' => '6.00',
'max' => '17.00',
'moy' => '12.00'
],
'coef' => '1.00'
]
]
],
'R1.04' => [
'titre' => 'Systèmes d\'exploitation',
'evaluations' => [
[
'id' => 1005,
'description' => 'TP noté',
'date' => '2023-11-25T14:00:00+01:00',
'note' => [
'value' => '13.50',
'min' => '7.50',
'max' => '16.50',
'moy' => '12.50'
],
'coef' => '1.00'
]
]
]
],
'saes' => [
'S1.01' => [
'titre' => 'Implémentation d\'un besoin client',
'evaluations' => [
[
'id' => 2001,
'description' => 'Livrable',
'date' => '2023-12-10T10:00:00+01:00',
'note' => [
'value' => '16.00',
'min' => '8.50',
'max' => '18.00',
'moy' => '13.75'
],
'coef' => '1.00'
]
]
],
'S1.02' => [
'titre' => 'Comparaison d\'approches algorithmiques',
'evaluations' => [
[
'id' => 2002,
'description' => 'Rapport',
'date' => '2023-11-30T16:00:00+01:00',
'note' => [
'value' => '15.00',
'min' => '7.00',
'max' => '17.50',
'moy' => '12.50'
],
'coef' => '1.00'
]
]
]
]
]
];
}
// Analyser les statistiques globales
function calculateOverallStats($data) {
$allGrades = [];
// Récupérer toutes les notes des ressources
foreach ($data['relevé']['ressources'] as $resource) {
foreach ($resource['evaluations'] as $eval) {
if (isset($eval['note']['value'])) {
$allGrades[] = (float)$eval['note']['value'];
}
}
}
// Récupérer toutes les notes des SAEs
foreach ($data['relevé']['saes'] as $sae) {
foreach ($sae['evaluations'] as $eval) {
if (isset($eval['note']['value'])) {
$allGrades[] = (float)$eval['note']['value'];
}
}
}
// Calculer les statistiques
$min = !empty($allGrades) ? min($allGrades) : 0;
$max = !empty($allGrades) ? max($allGrades) : 0;
$avg = !empty($allGrades) ? array_sum($allGrades) / count($allGrades) : 0;
$below10Count = count(array_filter($allGrades, function($grade) { return $grade < 10; }));
$above15Count = count(array_filter($allGrades, function($grade) { return $grade >= 15; }));
return [
'count' => count($allGrades),
'min' => number_format($min, 2),
'max' => number_format($max, 2),
'avg' => number_format($avg, 2),
'below10Percent' => !empty($allGrades) ? number_format(($below10Count / count($allGrades)) * 100, 1) : 0,
'above15Percent' => !empty($allGrades) ? number_format(($above15Count / count($allGrades)) * 100, 1) : 0
];
}
// Traiter la demande de connexion
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username'], $_POST['password'], $_POST['formation'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$formation = $_POST['formation'];
// Déterminer le semestre à utiliser
$semestre = isset($config['semestre_mapping'][$formation]) ? $config['semestre_mapping'][$formation] : null;
// Vérifier si le mode de simulation est activé
if ($username === 'demo' && $password === 'demo') {
$result = getSimulatedData();
$simulation_mode = true;
} else {
$result = fetchData($username, $password, $formation, $semestre);
$simulation_mode = false;
}
if (isset($result['error'])) {
$error_message = $result['error'];
} else {
// Stocker les données dans la session
$_SESSION['bulletin_data'] = $result;
$_SESSION['username'] = $username;
$_SESSION['formation'] = $formation;
$_SESSION['simulation_mode'] = $simulation_mode;
// Rediriger vers la page du bulletin
header('Location: ' . $_SERVER['PHP_SELF'] . '?view=dashboard');
exit;
}
}
// Déconnexion
if (isset($_GET['logout'])) {
session_unset();
session_destroy();
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
}
// Récupérer la vue actuelle (dashboard ou login)
$current_view = isset($_GET['view']) && $_GET['view'] === 'dashboard' && isset($_SESSION['bulletin_data']) ? 'dashboard' : 'login';
// Récupérer l'onglet actif
$active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'overview';
// Si on est sur le dashboard, calculer les statistiques
if ($current_view === 'dashboard') {
$data = $_SESSION['bulletin_data'];
$stats = calculateOverallStats($data);
}
?>
Dashboard de Bulletins BUT
Connexion à votre bulletin
Dashboard
- Semestre
Mode simulation - Données non réelles
/20
Moyenne générale
Rang : /
Déconnexion
Performance par UE
Profil de compétences
Meilleures performances
$resource) {
foreach ($resource['evaluations'] as $eval) {
if (isset($eval['note']['value'])) {
$allEvals[] = [
'resourceId' => $resourceId,
'resourceTitle' => $resource['titre'],
'evalId' => $eval['id'],
'description' => $eval['description'],
'note' => (float)$eval['note']['value'],
'coef' => (float)$eval['coef']
];
}
}
}
foreach ($data['relevé']['saes'] as $saeId => $sae) {
foreach ($sae['evaluations'] as $eval) {
if (isset($eval['note']['value'])) {
$allEvals[] = [
'resourceId' => $saeId,
'resourceTitle' => $sae['titre'],
'evalId' => $eval['id'],
'description' => $eval['description'],
'note' => (float)$eval['note']['value'],
'coef' => (float)$eval['coef']
];
}
}
}
// Trier par note (décroissant)
usort($allEvals, function($a, $b) {
return $b['note'] <=> $a['note'];
});
// Afficher les 5 meilleures
$bestEvals = array_slice($allEvals, 0, 5);
foreach ($bestEvals as $eval):
?>
Performances à améliorer
$b['note'];
});
// Afficher les 5 moins bonnes
$worstEvals = array_slice($allEvals, 0, 5);
foreach ($worstEvals as $eval):
?>
Distribution des notes
Performances par UE
Détails des unités d'enseignement
$ue): ?>
Ressources
$resourceInfo): ?>
/20
Aucune ressource associée
SAEs
$saeInfo): ?>
/20
Aucune SAE associée
Situations d'Apprentissage et d'Évaluation
$sae): ?>
$ue) {
if (isset($ue['saes']) && array_key_exists($saeId, $ue['saes'])) {
$linkedUEs[] = $ueId;
}
}
?>
Évolution des notes
Historique des évaluations
$resource) {
foreach ($resource['evaluations'] as $eval) {
if (isset($eval['date']) && $eval['date']) {
$gradesOverTime[] = [
'date' => new DateTime($eval['date']),
'name' => $resourceId . ' - ' . $eval['description'],
'grade' => (float)$eval['note']['value'],
'type' => 'resource'
];
}
}
}
foreach ($data['relevé']['saes'] as $saeId => $sae) {
foreach ($sae['evaluations'] as $eval) {
if (isset($eval['date']) && $eval['date']) {
$gradesOverTime[] = [
'date' => new DateTime($eval['date']),
'name' => $saeId . ' - ' . $eval['description'],
'grade' => (float)$eval['note']['value'],
'type' => 'sae'
];
}
}
}
// Trier par date
usort($gradesOverTime, function($a, $b) {
return $a['date'] <=> $b['date'];
});
foreach ($gradesOverTime as $index => $event):
$colorClass = $event['grade'] >= 16 ? 'bg-green-500' : ($event['grade'] >= 10 ? 'bg-blue-500' : 'bg-red-500');
?>
-
Comparaison d'éléments
Éléments sélectionnés
Aucun élément sélectionné pour la comparaison
Graphique de comparaison