'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

Utilisez "demo/demo" pour tester l'application avec des données simulées

Dashboard

- Semestre

Mode simulation - Données non réelles

/20
Moyenne générale
Rang : /
Déconnexion
Moyenne générale
/20
Meilleure note
/20
Notes > 15
%
Notes < 10
%

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): ?>

/20
Moy. promo: /20
Rang: / %

Ressources

$resourceInfo): ?>
/20

Aucune ressource associée

SAEs

$saeInfo): ?>
/20

Aucune SAE associée

$resource): ?> $ue) { if (isset($ue['ressources']) && array_key_exists($resourceId, $ue['ressources'])) { $linkedUEs[] = $ueId; } } ?>

/20
éval.

Évaluations

/20
1): ?>

Situations d'Apprentissage et d'Évaluation

$sae): ?> $ue) { if (isset($ue['saes']) && array_key_exists($saeId, $ue['saes'])) { $linkedUEs[] = $ueId; } } ?>

/20
éval.

Évaluations

/20
1): ?>

É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'); ?>
  • format('d/m/Y'); ?>

Comparaison d'éléments

Éléments sélectionnés

Aucun élément sélectionné pour la comparaison