Programme du TRACKING défi
Catégorie | Cours |
---|
Déroulé de la séquence
- Vous allez faire un défi chez vous : 30 minutes de logique par jour
- Présentation rapide du projet de programme tracking défi
- Description des étapes de création d’un programme
- description du programme
- définition de la base de données
- algorithme du programme
- les écrans du programme
- les technologies utilisées
- création de la base de données
- le codage du programme
- étape 1 : ajouter un utilisateur
- étape 2 : ajouter un défi
- étape 3 : ajouter une session de travail
- étape 4 : ajouter un rapport
ÉTAPE DE CRÉATION D’UN PROGRAMME
- description du programme
- définition de la base de données
- algorithme du programme
- les écrans du programme
- les technologies utilisées
- création de la base de données
- le codage du programme
Description du programme “Suivi de défis” (Challenge Tracker)
Ce programme, développé en PHP, a pour objectif de permettre aux utilisateurs de suivre leurs défis personnels au quotidien. Il s’agit notamment de mesurer et d’analyser leur engagement sur des objectifs réguliers, comme par exemple : “faire 30 minutes d’exercice de logique par jour.”
Fonctionnalités principales :
- Création d’un défi personnalisé :
- Nom du défi
- Objectif du défi (ex. : durée quotidienne, fréquence, etc.)
- Pseudo de l’utilisateur
- Adresse e-mail de l’utilisateur (utilisée pour l’envoi de rapports hebdomadaires)
- Tracking des séances :
- Pour chaque occurrence d’une activité liée au défi, l’utilisateur enregistre :
- La date
- L’heure
- La durée de la session
- Pour chaque occurrence d’une activité liée au défi, l’utilisateur enregistre :
- Base de données :
La base stockera les informations suivantes :
- Utilisateur (pseudo, email)
- Défis (nom, objectif)
- Sessions de suivi (date, heure, durée, lien avec un défi et un utilisateur)
- Rapport automatique hebdomadaire :
- Envoyé chaque dimanche soir par e-mail
- Contenu du rapport :
- Nombre d’occurrences de l’activité durant la semaine et le mois
- Durée totale réalisée
- Pourcentage d’accomplissement par rapport à l’objectif défini
- Comparaison avec les semaines/mois précédents (sous forme de tableau)
Structure de la base de données (MCD/MLD)
Tables :
- Un utilisateur peut avoir plusieurs défis
- Un défi appartient à un seul utilisateur
- Un défi peut avoir plusieurs suivis
- Chaque suivi est rattaché à un seul défi
- utilisateurs (id_util, pseudo, email)
- defis (id_defi, nom_defi, objectif, duree_session_defi, id__defi_util)
- Suivis (id_suivi, id_suivi_defi, date_session, heure_session, duree_session_suivi)
CREATE TABLE utilisateurs (
id_util INT AUTO_INCREMENT PRIMARY KEY,
pseudo VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE
);
CREATE TABLE defis (
id_defi INT AUTO_INCREMENT PRIMARY KEY,
nom_defi VARCHAR(100) NOT NULL,
objectif VARCHAR(255) NOT NULL,
duree_session_defi INT NOT NULL,
id__defi_util INT NOT NULL,
FOREIGN KEY (id__defi_util) REFERENCES utilisateurs(id_util) ON DELETE CASCADE
);
CREATE TABLE suivis (
id_suivi INT AUTO_INCREMENT PRIMARY KEY,
id_suivi_defi INT NOT NULL,
date_session DATE NOT NULL,
heure_session TIME NOT NULL,
duree_session_suivi INT NOT NULL,
FOREIGN KEY (id_suivi_defi) REFERENCES defis(id_defi) ON DELETE CASCADE
);
Algorithme
DEBUT
Afficher le menu principal :
1 - Créer un compte utilisateur
2 - Créer un défi
3 - Enregistrer une session d'activité
4 - Générer un rapport hebdomadaire
5 - Quitter
TANT QUE l'utilisateur ne choisit pas "Quitter" :
Lire le choix utilisateur
SELON le choix :
CAS 1 : Créer un compte utilisateur
Demander pseudo et email
Enregistrer dans la table `utilisateurs`
CAS 2 : Créer un défi
Demander l’ID utilisateur, le nom du défi, l’objectif (texte), la durée quotidienne visée (en minutes)
Enregistrer dans la table `defis`
CAS 3 : Enregistrer une session d'activité
Demander l’ID du défi, la date, l’heure et la durée en minutes
Enregistrer dans la table `suivis`
CAS 4 : Générer un rapport hebdomadaire
POUR chaque utilisateur :
Récupérer les défis de l'utilisateur
POUR chaque défi :
Calculer le nombre de sessions cette semaine et ce mois
Aller dans la table suivis
Sélectionner toutes les entrées (sessions d’activité) liées à ce défi (defi_id = ...)
Filtrer par date, pour ne garder que celles de cette semaine (ou ce mois)
Compter combien de lignes il y a
Calculer la durée totale effectuée par période
Aller dans la table suivis
Sélectionner toutes les entrées (sessions d’activité) liées à ce défi (defi_id = ...)
Faire la somme de la colonne duree
Calculer le taux d’accomplissement :
calculé l'objectif total à atteindre :
(duree_session_defi * nombre de jours de la période)
(durée totale effectuée / objectif total à atteindre) * 100
Générer un rapport texte
Envoyer un e-mail avec ce rapport
CAS 5 : Quitter
Afficher "Au revoir"
FIN
CAS PAR DEFAUT :
Afficher "Choix invalide"
Taux d’accomplissement : l’objectif à atteindre représente 100%, la durée totale effectuée multipliée par 100 et divisée par l’objectif à atteindre représente le taux.
Remarques
- Pour calculer le nombre de jours concernés par un défi actif, on peut supposer que l’objectif est quotidien.
- Le rapport doit être lancé automatiquement tous les dimanches à 23h via un script PHP exécuté par cron job (ou Scheduled Task).
- On peut stocker l’historique des envois dans une table rapports_envoyes si besoin.
Les technologies utilisées
- affichage page web : HTML, CSS
- fonctionnalités : php
- stockage des données : base de données MySql
Code HTML et PHP pour créer, enregistrer, et suivre les défis
Création du projet
- XAMPP
- démarrer Apache depuis le panneau de contrôle XAMPP
- le projet PHP doit être enregistré dans le dossier racine du serveur web Apache
C:\xampp\htdocs\suivi-defis\
- MySQL
- XAMPP : démarré MySQL depuis le panneau de contrôle XAMPP
- Créer une base de données “defis” interclassement utf8mb4_unicode_520_ci
- Ajouter les tables avec les 3 requêtes SQL de création (DQL Data Query Language)
- VSC
- Chrome ou Firefox
- Pour voir les erreurs PHP
C:\xampp\php\php.ini
- fichier
php.ini
display_errors = On display_startup_errors = On error_reporting = E_ALL
- redémarrer Apache
- Les erreurs seront dans ce fichier :
C:\xampp\apache\logs\error.log
Ajouter un utilisateur
- Outil PDO utilisé avec PHP afin que le programme PHP dialogue avec la base de données
- utilisateur MySQL est "root" sans mot de passe (valeurs par défaut XAMPP)
Fichier index.php
<?php
require_once 'creer_utilisateur.php';
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Suivi de Défis</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Suivi de Défis</h1>
<!-- Formulaire : Créer un utilisateur -->
<section>
<h2>Créer un utilisateur</h2>
<form method="post">
<input type="hidden" name="action" value="creer_utilisateur">
<div>
<label for="pseudo">Pseudo :</label>
<input type="text" id="pseudo" name="pseudo" required>
</div>
<div>
<label for="email">Email :</label>
<input type="email" id="email" name="email" required>
</div>
<button type="submit">Créer utilisateur</button>
</form>
<?php if ($message_util): ?>
<p><?= $message_util ?></p>
<?php endif; ?>
</section>
<hr>
</body>
</html>
Fichier style.css
div {
margin-bottom: 10px;
}
Fichier creer_utilisateur.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
if ($_POST['action'] === 'creer_utilisateur') {
// Récupérer les données du formulaire
$pseudo = $_POST['pseudo'];
$email = $_POST['email'];
// Connexion à la base de données avec PDO
try {
$pdo = new PDO("mysql:host=localhost;dbname=defis;charset=utf8mb4", "root", "root");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Préparer la requête SQL d'insertion
$sql = "INSERT INTO utilisateurs (pseudo, email) VALUES (:pseudo, :email)";
$stmt = $pdo->prepare($sql);
// Exécuter la requête avec les valeurs du formulaire
$stmt->execute([
':pseudo' => $pseudo,
':email' => $email
]);
$message_util = "<p>✅ Utilisateur <strong>$pseudo</strong> créé avec succès.</p>";
} catch (PDOException $e) {
$message_util = "<p>‼️ Erreur lors de la connexion ou de l'insertion : " . $e->getMessage() . "</p>";
}
}
}
Ajouter un défi
Fichier index.php
- ajouter
require_once 'recup_info_menu_deroulant.php';
etrequire_once 'creer_defi.php';
- ajouter la section <!-- Formulaire : Créer un défi -->
require_once 'recup_info_menu_deroulant.php';
require_once 'creer_defi.php';
<!-- Formulaire : Créer un défi -->
<section>
<h2>Créer un défi</h2>
<form method="post">
<input type="hidden" name="action" value="creer_defi">
<div>
<label for="utilisateur_id">ID Utilisateur :</label>
<select name="utilisateur_id" required>
<option value="">-- Sélectionner --</option>
<?php foreach ($utilisateurs as $u): ?>
<option value="<?= $u['id_util'] ?>"><?= $u['id_util'] ?>
- <?= htmlspecialchars($u['pseudo']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="nom_defi">Nom du défi :</label>
<input type="text" id="nom_defi" name="nom_defi" required>
</div>
<div>
<label for="objectif">Objectif (ex : 30 min de logique) :</label>
<input type="text" id="objectif" name="objectif" required>
</div>
<div>
<label for="duree_objectif">Durée quotidienne (en minutes) :</label>
<input type="number" id="duree_objectif" name="duree_objectif" required>
</div>
<button type="submit">Créer défi</button>
</form>
<?php if ($message_defi): ?>
<p><?= $message_defi ?></p>
<?php endif; ?>
</section>
<hr>
Fichier creer_defi.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
if ($_POST['action'] === 'creer_defi') {
// Récupérer les données du formulaire
$nom = $_POST['nom_defi'];
$objectif = $_POST['objectif'];
$duree_objectif = (int) $_POST['duree_objectif'];
$utilisateur_id = (int) $_POST['utilisateur_id'];
try {
$pdo = new PDO("mysql:host=localhost;dbname=defis;charset=utf8mb4", "root", "root");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO defis (nom_defi, objectif, duree_session_defi, id_defi_util)
VALUES (:nom, :objectif, :duree, :uid)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
':nom' => $nom,
':objectif' => $objectif,
':duree' => $duree_objectif,
':uid' => $utilisateur_id
]);
$message_defi = "<p>✅ Défi <strong>$nom</strong> ajouté avec succès pour l'utilisateur #$utilisateur_id.</p>";
} catch (PDOException $e) {
$message_defi = "<p>‼️ Erreur lors de l'insertion du défi : " . $e->getMessage() . "</p>";
}
}
}
Fichier recup_info_menu_deroulant.php
<?php
// Connexion à la base
try {
$pdo = new PDO("mysql:host=localhost;dbname=defis;charset=utf8mb4", "root", "root");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Charger les utilisateurs
$utilisateurs = $pdo->query("SELECT id_util, pseudo FROM utilisateurs ORDER BY pseudo")->fetchAll(PDO::FETCH_ASSOC);
// Charger les défis
$defis = $pdo->query("
SELECT d.id_defi, d.nom_defi, u.pseudo
FROM defis d
JOIN utilisateurs u ON d.id_defi_util = u.id_util
ORDER BY u.pseudo, d.nom_defi
")->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo "Erreur de connexion : " . $e->getMessage();
$utilisateurs = [];
$defis = [];
}
Ajouter une session de travail
Fichier index.php
- ajouter
require_once 'creer_session.php';
- ajouter la section <!-- Formulaire : Créer un défi -->
require_once 'creer_session.php';
<!-- Formulaire : Enregistrer une session -->
<section>
<h2>Enregistrer une session</h2>
<form method="post">
<input type="hidden" name="action" value="creer_session">
<div>
<label for="defi_id">ID du défi :</label>
<select name="defi_id" required>
<option value="">-- Sélectionner un défi --</option>
<?php foreach ($defis as $defi): ?>
<option value="<?= $defi['id_defi'] ?>">
<?= $defi['id_defi'] ?> - <?= htmlspecialchars($defi['nom_defi']) ?>
(<?= htmlspecialchars($defi['pseudo']) ?>)
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="date">Date :</label>
<input type="date" id="date" name="date" required>
</div>
<div>
<label for="heure">Heure :</label>
<input type="time" id="heure" name="heure" required>
</div>
<div>
<label for="duree">Durée (en minutes) :</label>
<input type="number" id="duree" name="duree" required>
</div>
<button type="submit">Enregistrer session</button>
</form>
<?php if ($message_session): ?>
<p><?= $message_session ?></p>
<?php endif; ?>
</section>
<hr>
Fichier creer_session.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
if ($_POST['action'] === 'creer_session') {
// Récupérer les données du formulaire
$defi_id = (int) $_POST['defi_id'];
$date = $_POST['date'];
$heure = $_POST['heure'];
$duree = (int) $_POST['duree'];
try {
$pdo = new PDO("mysql:host=localhost;dbname=defis;charset=utf8mb4", "root", "root");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO suivis (id_suivi_defi, date_session, heure_session, duree_session_suivi)
VALUES (:defi_id, :date, :heure, :duree)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
':defi_id' => $defi_id,
':date' => $date,
':heure' => $heure,
':duree' => $duree
]);
$message_session = "✅ Suivi ajouté avec succès pour le défi #$defi_id.";
} catch (PDOException $e) {
$message_session = "‼️ Erreur lors de l'ajout du suivi : " . $e->getMessage();
}
}
}
Ajouter un rapport
Fichier index.php
- ajouter
require_once 'rapport.php';
- ajouter la section
<!-- Rapport -->
require_once 'rapport.php';
<!-- Rapport -->
<section>
<h2>Afficher un rapport des suivis</h2>
<form method="post">
<input type="hidden" name="action" value="rapport">
<button type="submit">Afficher rapport</button>
</form>
<?php if (isset($rapport)): ?>
<br>
<table border="3" cellpadding="6">
<thead>
<tr>
<th>ID Défi</th>
<th>Nom du défi</th>
<th>Utilisateur</th>
<th>Sessions effectuées cette semaine</th>
<th>Sessions à faire</th>
<th>Taux semaine (%)</th>
<th>Sessions effectuées ce mois</th>
<th>Sessions à faire</th>
<th>Taux mois (%)</th>
</tr>
</thead>
<tbody>
<?php foreach ($rapport as $ligne): ?>
<tr>
<td><?= $ligne['id'] ?></td>
<td><?= htmlspecialchars($ligne['nom']) ?></td>
<td><?= htmlspecialchars($ligne['pseudo']) ?></td>
<td><?= $ligne['sessions_semaine'] ?></td>
<td><?= $ligne['attendues_semaine'] ?></td>
<td><?= $ligne['taux_semaine'] ?>%</td>
<td><?= $ligne['sessions_mois'] ?></td>
<td><?= $ligne['attendues_mois'] ?></td>
<td><?= $ligne['taux_mois'] ?>%</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</section>
Fichier rapport.php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
if ($_POST['action'] === 'rapport') {
try {
$pdo = new PDO("mysql:host=localhost;dbname=defis;charset=utf8mb4", "root", "root");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Calcul des dates de début de semaine et de mois
$today = date('Y-m-d');
$debut_semaine = date('Y-m-d', strtotime('monday this week'));
$debut_mois = date('Y-m-01');
// Nombre de jours entre lundi et aujourd'hui
$nb_jours_semaine = (new DateTime($debut_semaine))->diff(new DateTime($today))->days + 1;
// Nombre de jours entre le début du mois et aujourd'hui
$nb_jours_mois = (new DateTime($debut_mois))->diff(new DateTime($today))->days + 1;
// Récupérer tous les défis et leur nombre de sessions cette semaine et ce mois
$stmt = $pdo->query("
SELECT d.id_defi, d.nom_defi, u.pseudo,
(SELECT COUNT(*) FROM suivis s WHERE s.id_suivi_defi = d.id_defi AND s.date_session >= '$debut_semaine') AS sessions_semaine,
(SELECT COUNT(*) FROM suivis s WHERE s.id_suivi_defi = d.id_defi AND s.date_session >= '$debut_mois') AS sessions_mois
FROM defis d
JOIN utilisateurs u ON d.id_defi_util = u.id_util
ORDER BY u.pseudo, d.nom_defi
");
$rapport = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Ajouter sessions attendues
foreach ($rapport as &$ligne) {
$ligne['attendues_semaine'] = $nb_jours_semaine;
$ligne['attendues_mois'] = $nb_jours_mois;
if ($ligne['attendues_semaine'] > 0) {
$ligne['taux_semaine'] = round(($ligne['sessions_semaine'] / $ligne['attendues_semaine']) * 100, 1);
} else {
$ligne['taux_semaine'] = 0;
}
if ($ligne['attendues_mois'] > 0) {
$ligne['taux_mois'] = round(($ligne['sessions_mois'] / $ligne['attendues_mois']) * 100, 1);
} else {
$ligne['taux_mois'] = 0;
}
}
} catch (PDOException $e) {
$rapport = [];
$message_rapport = "Erreur lors de la récupération du rapport : " . $e->getMessage();
}
}
}