5 Commits

Author SHA1 Message Date
JARNOUEN DE VILLARTAY Ulysse (SAFRAN AIRCRAFT ENGINES) 0da6bcf803 refactor connexion 2026-04-15 16:54:08 +02:00
JARNOUEN DE VILLARTAY Ulysse (SAFRAN AIRCRAFT ENGINES) 44f8555fe4 Merge remote-tracking branch 'upstream/main' into correction-tp4 2026-04-15 16:49:35 +02:00
JARNOUEN DE VILLARTAY Ulysse (SAFRAN AIRCRAFT ENGINES) 17a16feb2d ex3 2026-04-15 16:20:11 +02:00
JARNOUEN DE VILLARTAY Ulysse (SAFRAN AIRCRAFT ENGINES) 553b30bdcc tp4 ex2 2026-04-15 16:06:48 +02:00
JARNOUEN DE VILLARTAY Ulysse (SAFRAN AIRCRAFT ENGINES) 74ebab4b24 tp4 ex1 2026-04-15 16:03:11 +02:00
38 changed files with 539 additions and 819 deletions
+4
View File
@@ -0,0 +1,4 @@
CINEMA_DB_HOST=dwarves.iut-fbleau.fr
CINEMA_DB_USER=foo
CINEMA_DB_PASSWORD=foo
CINEMA_DB_NAME=foo
+1
View File
@@ -328,3 +328,4 @@ TSWLatexianTemp*
# Uncomment the next line to have this generated file ignored.
#*Notes.bib
.env
-2
View File
@@ -35,8 +35,6 @@ Les notions suivantes seront abordées :
| 3 | [Intéractions avec le client](./cours/cm_interaction_client_serveur.pdf) | [tp2](./tp/tp2) |
| 4 | [PHP/MySQL](./cours/cm_extension_mysqli.pdf) | [tp3](./tp/tp3) |
| 5 | [Cookies et sessions](./cours/cm_cookies_sessions.pdf) | [tp3](./tp/tp3) , [tp4](./tp/tp4) |
| 6 | [PHP Objet](./cours/cm_objet.pdf), [MVC avec codeigniter](./cours/cm_mvc.pdf) | [tp5](./tp/tp5) |
| 7 | [securite](./cours/cm_securite.pdf) | |
Binary file not shown.
Binary file not shown.
Binary file not shown.
-57
View File
@@ -1,57 +0,0 @@
## Groupes et soutenances
Une soutenance de votre projet aura lieu le mercredi 18. Vous
devez arriver **5 minutes** avant l'horaire précisée, et préparer une machine
(navigateur avec votre application et vos sources sur grond) pour
que je teste votre site.
**Mercredi 18 juin 2025**
# GR12
- SALVIA-GILLET 13h30 224
- MERIGOT 13h50 225
- BENHAMOU-BELABED 14h10 224
- BONNET-LAURENT 14h30 225
- AMROUCHI-LECOINTRE 14h50 224
- BADIO-MOUHIB 15h10 225
- ROUX-JI 15h30 224
- SOUGOUMARANE 15h50 225
- GUINET-MILLERIOUX 16h10 224
- DOUCOURE-SLIMANI 16h30 225
- NKOUKA 16h50 224
- JDOUDI-LELIEVRE 17h10 225
- TA-GARNIER(?) 17h30 224
# GR34
- CHABOT-ALVES 9h00 224
- PRADAT-CUGUT 9h20 225
- OLIVIER-POUGET 9h40 224
- JOSSE-DICK 10h00 225
- ADDOUN 10h20 224
- DANOUSHE-NASSIM 10h40 225
- PAYEN-DE JESUS 11h00 224
- SAUNIER 11h20 225
- ABBAZ 11h40 224
- PICART-ZOUBA 12H00 225
- BRAZ MAWANA 12h20 224
- PIERRE LOUIS 12h40 225
# GR56
- (MO)OUISSI 13h30 222
- JANICOT 13h50 223
- TAFOK-GOBE 14h10 222
- OUISSI-SPOR 14h30 223
- VITARD-BLANCHARD 14h50 222
- TRENIER-LIROT 15h10 223
- GOMEZ 15h30 222
- BERNARD-MERCIER 15h50 223
- PASQUAZZO-JACKSON 16h10 222
- TALBIS 16h30 223
- PINEAU-ETIEVANT 16h50 222
- AKTAS-CHARRIERE 17h10 223
- BEDOUET-QUEUDOT 17h30 222
- MOOGIN-DUSSEAUX 17h50 223
-119
View File
@@ -1,119 +0,0 @@
# SAE S2.02 : Consultation/modificaion d'une base de jeux vidéos
> [Soutenances](./GROUPES.md)
## Le thème
Le projet utilise une [base de données](./sql/game.sql.gz) de jeux vidéos (créée par
Jérôme Cutrona, IUT de Reims). Il consiste à écrire une application web qui permet :
- la consultation/recherche d'informations contenues dans la bd (catégories, genres, jeux),
- la création, édition, suppression d'un jeu.
La [base de données](./sql/game.sql.gz) a la structure suivante :
<div align="center">
<img src="./img/game.svg">
</div>
## Principes généraux, fonctionnalités
1. La partie consultation permet l'accès à plusieurs vues :
- liste d'ensemble des catégories et genres de jeux (sous forme de lien),
- détails d'une catégorie et d'un genre avec la liste de ses jeux (sous forme de lien),
- détails d'un jeu (les genres et catégories du jeu sont des liens).
2. La partie modification permet, pour un jeu :
- l'édition (sans modification du poster)
- la création (poster facultatif)
- la suppression
3. Tri des listes de jeux par titre ou par année
4. fonction de recherche textuelle
## Contraintes de réalisations
- Votre code utilisera codeigniter v3, exactement comme en TP.
- Vous utiliserez le serveur de base de données mariaDB de l'iut, comme en TP.
- Vous travaillerez seul, ou en binôme, à l'intérieur de votre **groupe de TP**.
- Vous créerez un dépot GIT par monôme/binôme, avec le nom **sae_r301_grx** ($x\in\{12,34,56\}$) suivant votre groupe TP.
Ulysse Jarnouen et Denis Monnerat seront collaborateurs.
- Votre dépot contiendra un fichier README.md, avec :
- le prénom, nom des membres du binômes
- **l'url de votre site sur dwarves.iut-fbleau.fr**
## Usage de l'IA
### L'IA est autorisée mais ne remplace pas la compréhension
Le recours a l'IA peut être autorise comme outil d'assistance, au même titre qu'une documentation, un forum technique ou un IDE.
En revanche :
- tout code rendu doit être compris par l'étudiant;
- tout code non expliqué ou non modifiable en situation sera considéré comme non acquis;
- l'étudiant reste responsable de la qualité, de la sécurité et de la cohérence du code rendu.
## Règles communes concernant l'usage de l'IA
1. L'usage de l'IA est autorisé comme outil d'assistance.
2. Tout code rendu doit pouvoir être expliqué et modifié par l'étudiant.
3. Les propositions de l'IA doivent être relues, testées et adaptées.
4. Un code non compris ou non maitrise pourra être considére comme non acquis.
5. La transparence sur l'usage de l'IA est attendue dans le journal de bord, dans le dépôt et en soutenance.
Exemple de contenu attendu dans le journal sur la partie "Usage de l'IA":
- les prompts utilisés;
- les extraits de réponse juges utiles;
- ce qui a été retenu, adapte ou rejeté;
- les vérifications effectuées après usage.
## Organisation générale de l'évaluation
### Workflow de travail attendu
Afin de structurer le travail, de faciliter le suivi, le projet devra s'appuyer sur un workflow Git simple et obligatoire.
Pour chaque séance :
1. Vous devrez créer une branche de travail dédiée a la séance;
2. Vous devrez pousser régulièrement vos modifications sur cette branche au cours de la séance ;
3. en fin de séance, vous devrez ouvrir une "Pull Request" vers la branche cible définie (main) pour le projet;
4. Vous devrez assigner cette Pull Request a l'enseignant;
5. L'enseignant examinera et approuvera la Merge Request pour valider le travail réalisé ;
6. une fois la Merge Request approuvée, vous pourrez procéder au merge.
> Il est recommandé que les messages de commit et les titres de Merge Request soient explicites et lies a l'objectif technique traité.
### Traces de progression
Voici une liste d'éléments qui prouveront votre progression :
- dépôt Git avec commits réguliers;
- journal de bord court a chaque séance;
- liste des taches réalisées et reste a faire;
- tableau de répartition des responsabilités.
Le journal de bord doit suivre une structure simple et identique pour tous les groupes. Il peut rester concis, mais il doit être présent a chaque séance.
Structure recommandée pour chaque séance :
- objectif de la séance;
- travail réalisé;
- difficultés rencontrées;
- décisions prises ;
- travail de chacun dans le binôme;
- points a reprendre a la séance suivante;
- usage de l'IA, si applicable.
Le journal de bord doit être conservé dans un fichier Markdown (JOURNAL.md) du dépôt afin de rester consultable avec le reste des traces du projet.
## Évaluation
- L'avancement de votre travail sera mesuré à chaque fin de séance de TP (4 semaines).
- Votre réalisation sera évalué la semaine du 15 juin.
- Tout dépot avec quelques commits récents se verra fortement pénalisé.
- Un coefficient multiplicateur de 0 à 1 sera appliqué pour refléter l'équilibre du travail entre les deux membres du binôme.
### La note ne repose pas uniquement sur le livrable final
Une application fonctionnelle ne suffit pas a prouver l'acquisition des compétences. L'évaluation reposera sur plusieurs types de preuves :
- un livrable fonctionnel;
- des traces de progression;
- une explication orale individuelle;
- une courte mise en situation technique en direct.
Quand le projet est réalisé en binôme, une partie de la portera sur le travail collectif. Chaque étudiant doit notamment être en mesure d'expliquer un extrait de code introduit ou modifié par son binôme.
-108
View File
@@ -1,108 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg viewBox="125 35 1123 415" width="998px" height="380px" xmlns="http://www.w3.org/2000/svg" version="1.1">
<line x1="600" y1="350" x2="590" y2="350" style="stroke:#333;stroke-width:1;"/>
<line x1="508" y1="370" x2="498" y2="370" style="stroke:#333;stroke-width:1;"/>
<line x1="590" y1="350" x2="508" y2="370" style="stroke:#333;stroke-width:1;"/>
<line x1="592.5" y1="350" x2="596.03553390593" y2="353.53553390593" style="stroke:#333;stroke-width:2;"/>
<line x1="592.5" y1="350" x2="596.03553390593" y2="346.46446609407" style="stroke:#333;stroke-width:2;"/>
<line x1="503" y1="370" x2="506.53553390593" y2="373.53553390593" style="stroke:#333;stroke-width:2;"/>
<line x1="503" y1="370" x2="506.53553390593" y2="366.46446609407" style="stroke:#333;stroke-width:2;"/>
<line x1="726" y1="370" x2="736" y2="370" style="stroke:#333;stroke-width:1;"/>
<line x1="790" y1="370" x2="800" y2="370" style="stroke:#333;stroke-width:1;"/>
<line x1="736" y1="370" x2="790" y2="370" style="stroke:#333;stroke-width:1;"/>
<line x1="733.5" y1="370" x2="729.96446609407" y2="373.53553390593" style="stroke:#333;stroke-width:2;"/>
<line x1="733.5" y1="370" x2="729.96446609407" y2="366.46446609407" style="stroke:#333;stroke-width:2;"/>
<line x1="795" y1="370" x2="791.46446609407" y2="373.53553390593" style="stroke:#333;stroke-width:2;"/>
<line x1="795" y1="370" x2="791.46446609407" y2="366.46446609407" style="stroke:#333;stroke-width:2;"/>
<line x1="370" y1="110" x2="360" y2="110" style="stroke:#0b0;stroke-width:1;"/>
<line x1="238" y1="160" x2="228" y2="160" style="stroke:#0b0;stroke-width:1;"/>
<line x1="360" y1="110" x2="238" y2="160" style="stroke:#0b0;stroke-width:1;"/>
<line x1="362.5" y1="110" x2="366.03553390593" y2="113.53553390593" style="stroke:#0b0;stroke-width:2;"/>
<line x1="362.5" y1="110" x2="366.03553390593" y2="106.46446609407" style="stroke:#0b0;stroke-width:2;"/>
<line x1="233" y1="160" x2="236.53553390593" y2="163.53553390593" style="stroke:#0b0;stroke-width:2;"/>
<line x1="233" y1="160" x2="236.53553390593" y2="156.46446609407" style="stroke:#0b0;stroke-width:2;"/>
<line x1="483" y1="90" x2="493" y2="90" style="stroke:#bbb;stroke-width:1;"/>
<line x1="590" y1="170" x2="600" y2="170" style="stroke:#bbb;stroke-width:1;"/>
<line x1="493" y1="90" x2="590" y2="170" style="stroke:#bbb;stroke-width:1;"/>
<line x1="490.5" y1="90" x2="486.96446609407" y2="93.535533905933" style="stroke:#bbb;stroke-width:2;"/>
<line x1="490.5" y1="90" x2="486.96446609407" y2="86.464466094067" style="stroke:#bbb;stroke-width:2;"/>
<line x1="595" y1="170" x2="591.46446609407" y2="173.53553390593" style="stroke:#bbb;stroke-width:2;"/>
<line x1="595" y1="170" x2="591.46446609407" y2="166.46446609407" style="stroke:#bbb;stroke-width:2;"/>
<line x1="810" y1="80" x2="800" y2="80" style="stroke:#bbb;stroke-width:1;"/>
<line x1="736" y1="170" x2="726" y2="170" style="stroke:#bbb;stroke-width:1;"/>
<line x1="800" y1="80" x2="736" y2="170" style="stroke:#bbb;stroke-width:1;"/>
<line x1="802.5" y1="80" x2="806.03553390593" y2="83.535533905933" style="stroke:#bbb;stroke-width:2;"/>
<line x1="802.5" y1="80" x2="806.03553390593" y2="76.464466094067" style="stroke:#bbb;stroke-width:2;"/>
<line x1="731" y1="170" x2="734.53553390593" y2="173.53553390593" style="stroke:#bbb;stroke-width:2;"/>
<line x1="731" y1="170" x2="734.53553390593" y2="166.46446609407" style="stroke:#bbb;stroke-width:2;"/>
<line x1="902" y1="100" x2="912" y2="100" style="stroke:#bbb;stroke-width:1;"/>
<line x1="1010" y1="180" x2="1020" y2="180" style="stroke:#bbb;stroke-width:1;"/>
<line x1="912" y1="100" x2="1010" y2="180" style="stroke:#bbb;stroke-width:1;"/>
<line x1="909.5" y1="100" x2="905.96446609407" y2="103.53553390593" style="stroke:#bbb;stroke-width:2;"/>
<line x1="909.5" y1="100" x2="905.96446609407" y2="96.464466094067" style="stroke:#bbb;stroke-width:2;"/>
<line x1="1015" y1="180" x2="1011.4644660941" y2="183.53553390593" style="stroke:#bbb;stroke-width:2;"/>
<line x1="1015" y1="180" x2="1011.4644660941" y2="176.46446609407" style="stroke:#bbb;stroke-width:2;"/>
<rect width="88" height="20" x="140" y="130" style="fill:#007;stroke:black;"/>
<text width="88" height="20" x="145" y="144" style="fill:#fff;" font-family="Arial" font-size="16px"> category</text>
<rect width="88" height="20" x="140" y="150" style="fill:#aea;stroke:black;"/>
<text width="88" height="20" x="145" y="164" style="fill:black;" font-family="Arial" font-size="16px">id</text>
<rect width="88" height="20" x="140" y="170" style="fill:none;stroke:black;"/>
<text width="88" height="20" x="145" y="184" style="fill:black;" font-family="Arial" font-size="16px">description</text>
<rect width="78" height="20" x="420" y="340" style="fill:#007;stroke:black;"/>
<text width="78" height="20" x="425" y="354" style="fill:#fff;" font-family="Arial" font-size="16px"> developer</text>
<rect width="78" height="20" x="420" y="360" style="fill:#aea;stroke:black;"/>
<text width="78" height="20" x="425" y="374" style="fill:black;" font-family="Arial" font-size="16px">id</text>
<rect width="78" height="20" x="420" y="380" style="fill:none;stroke:black;"/>
<text width="78" height="20" x="425" y="394" style="fill:black;" font-family="Arial" font-size="16px">name</text>
<rect width="126" height="20" x="600" y="140" style="fill:#007;stroke:black;"/>
<text width="126" height="20" x="605" y="154" style="fill:#fff;" font-family="Arial" font-size="16px"> game</text>
<rect width="126" height="20" x="600" y="160" style="fill:#aea;stroke:black;"/>
<text width="126" height="20" x="605" y="174" style="fill:black;" font-family="Arial" font-size="16px">id</text>
<rect width="126" height="20" x="600" y="180" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="194" style="fill:black;" font-family="Arial" font-size="16px">name</text>
<rect width="126" height="20" x="600" y="200" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="214" style="fill:black;" font-family="Arial" font-size="16px">releaseYear</text>
<rect width="126" height="20" x="600" y="220" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="234" style="fill:black;" font-family="Arial" font-size="16px">shortDescription</text>
<rect width="126" height="20" x="600" y="240" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="254" style="fill:black;" font-family="Arial" font-size="16px">price</text>
<rect width="126" height="20" x="600" y="260" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="274" style="fill:black;" font-family="Arial" font-size="16px">windows</text>
<rect width="126" height="20" x="600" y="280" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="294" style="fill:black;" font-family="Arial" font-size="16px">linux</text>
<rect width="126" height="20" x="600" y="300" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="314" style="fill:black;" font-family="Arial" font-size="16px">mac</text>
<rect width="126" height="20" x="600" y="320" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="334" style="fill:black;" font-family="Arial" font-size="16px">metacritic</text>
<rect width="126" height="20" x="600" y="340" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="354" style="fill:black;" font-family="Arial" font-size="16px">developerId</text>
<rect width="126" height="20" x="600" y="360" style="fill:none;stroke:black;"/>
<text width="126" height="20" x="605" y="374" style="fill:black;" font-family="Arial" font-size="16px">posterId</text>
<rect width="113" height="20" x="370" y="60" style="fill:#007;stroke:black;"/>
<text width="113" height="20" x="375" y="74" style="fill:#fff;" font-family="Arial" font-size="16px"> game_category</text>
<rect width="113" height="20" x="370" y="80" style="fill:#aea;stroke:black;"/>
<text width="113" height="20" x="375" y="94" style="fill:black;" font-family="Arial" font-size="16px">gameId</text>
<rect width="113" height="20" x="370" y="100" style="fill:#aea;stroke:black;"/>
<text width="113" height="20" x="375" y="114" style="fill:black;" font-family="Arial" font-size="16px">categoryId</text>
<rect width="92" height="20" x="810" y="50" style="fill:#007;stroke:black;"/>
<text width="92" height="20" x="815" y="64" style="fill:#fff;" font-family="Arial" font-size="16px"> game_genre</text>
<rect width="92" height="20" x="810" y="70" style="fill:#aea;stroke:black;"/>
<text width="92" height="20" x="815" y="84" style="fill:black;" font-family="Arial" font-size="16px">gameId</text>
<rect width="92" height="20" x="810" y="90" style="fill:#aea;stroke:black;"/>
<text width="92" height="20" x="815" y="104" style="fill:black;" font-family="Arial" font-size="16px">genreId</text>
<rect width="88" height="20" x="1020" y="150" style="fill:#007;stroke:black;"/>
<text width="88" height="20" x="1025" y="164" style="fill:#fff;" font-family="Arial" font-size="16px"> genre</text>
<rect width="88" height="20" x="1020" y="170" style="fill:#aea;stroke:black;"/>
<text width="88" height="20" x="1025" y="184" style="fill:black;" font-family="Arial" font-size="16px">id</text>
<rect width="88" height="20" x="1020" y="190" style="fill:none;stroke:black;"/>
<text width="88" height="20" x="1025" y="204" style="fill:black;" font-family="Arial" font-size="16px">description</text>
<rect width="54" height="20" x="800" y="340" style="fill:#007;stroke:black;"/>
<text width="54" height="20" x="805" y="354" style="fill:#fff;" font-family="Arial" font-size="16px"> poster</text>
<rect width="54" height="20" x="800" y="360" style="fill:#aea;stroke:black;"/>
<text width="54" height="20" x="805" y="374" style="fill:black;" font-family="Arial" font-size="16px">id</text>
<rect width="54" height="20" x="800" y="380" style="fill:none;stroke:black;"/>
<text width="54" height="20" x="805" y="394" style="fill:black;" font-family="Arial" font-size="16px">jpeg</text>
</svg>

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.
+8
View File
@@ -19,6 +19,14 @@ SET time_zone = "+00:00";
-- --------------------------------------------------------
CREATE TABLE IF NOT EXISTS `user` (
login VARCHAR(50) NOT NULL,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
PRIMARY KEY (login)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Table structure for table `Artiste`
--
@@ -0,0 +1,46 @@
<?php
$login = isset($_GET['login']) ? trim($_GET['login']) : '';
$error = isset($_GET['error']);
$registered = isset($_GET['registered']);
$loggedOut = isset($_GET['logged_out']);
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Authentification</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
</head>
<body>
<main class="container">
<h1>Authentification</h1>
<?php if ($registered) { ?>
<article>Inscription réussie. Vous pouvez maintenant vous connecter.</article>
<?php } ?>
<?php if ($loggedOut) { ?>
<article>Vous avez été déconnecté.</article>
<?php } ?>
<?php if ($error) { ?>
<article aria-invalid="true">Login ou mot de passe incorrect.</article>
<?php } ?>
<form action="./verification.php" method="post">
<label for="login">Login</label>
<input id="login" name="login" value="<?php echo htmlspecialchars($login, ENT_QUOTES); ?>">
<label for="password">Mot de passe</label>
<input id="password" name="password" type="password">
<button type="submit">Se connecter</button>
</form>
<p><a href="./inscription.php">Créer un compte</a></p>
</main>
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
<?php
session_start();
$_SESSION = array();
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
session_destroy();
header('Location: ./authentification.php?logged_out=1');
exit;
+2 -1
View File
@@ -1,4 +1,5 @@
<?php
include_once './securite.php';
include_once './modeles/modeleFilms.php';
$currentPage = filter_input(
@@ -28,7 +29,7 @@ if ($currentPage > $totalPages && $totalFilms > 0) {
}
//
// on "charge" la vue
// On charge les fichiers de vue une fois les données prêtes.
//
include_once './vues/header.php';
+98
View File
@@ -0,0 +1,98 @@
<?php
session_start();
include_once './modeles/modeleUtilisateurs.php';
$errors = array();
$values = array(
'login' => '',
'email' => '',
);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$values['login'] = isset($_POST['login']) ? trim($_POST['login']) : '';
$values['email'] = isset($_POST['email']) ? trim($_POST['email']) : '';
$password = isset($_POST['password']) ? $_POST['password'] : '';
// On valide champ par champ pour pouvoir réafficher proprement le formulaire.
if ($values['login'] === '') {
$errors['login'] = 'Le login est obligatoire.';
} elseif (!preg_match('/^[a-zA-Z0-9_-]{3,30}$/', $values['login'])) {
$errors['login'] = 'Le login doit contenir entre 3 et 30 caractères alphanumériques, _ ou -.';
}
if ($values['email'] === '') {
$errors['email'] = 'L\'email est obligatoire.';
} elseif (!filter_var($values['email'], FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'Le format de l\'email est invalide.';
}
if ($password === '') {
$errors['password'] = 'Le mot de passe est obligatoire.';
} elseif (strlen($password) < 8) {
$errors['password'] = 'Le mot de passe doit contenir au moins 8 caractères.';
}
if ($values['login'] !== '' && findUserByLogin($values['login']) !== null) {
$errors['login'] = 'Ce login est déjà utilisé.';
}
if (empty($errors)) {
$passwordHash = password_hash($password, PASSWORD_DEFAULT);
createUser($values['login'], $values['email'], $passwordHash);
header('Location: ./authentification.php?registered=1');
exit;
}
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Inscription</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
</head>
<body>
<main class="container">
<h1>Inscription</h1>
<p>Créez un compte avant d'accéder aux pages du site.</p>
<form method="post">
<label for="login">Login</label>
<input
id="login"
name="login"
value="<?php echo htmlspecialchars($values['login'], ENT_QUOTES); ?>"
>
<?php if (isset($errors['login'])) { ?>
<small><?php echo htmlspecialchars($errors['login'], ENT_QUOTES); ?></small>
<?php } ?>
<label for="email">Email</label>
<input
id="email"
name="email"
type="email"
value="<?php echo htmlspecialchars($values['email'], ENT_QUOTES); ?>"
>
<?php if (isset($errors['email'])) { ?>
<small><?php echo htmlspecialchars($errors['email'], ENT_QUOTES); ?></small>
<?php } ?>
<label for="password">Mot de passe</label>
<input id="password" name="password" type="password">
<?php if (isset($errors['password'])) { ?>
<small><?php echo htmlspecialchars($errors['password'], ENT_QUOTES); ?></small>
<?php } ?>
<button type="submit">S'inscrire</button>
</form>
<p><a href="./authentification.php">Déjà inscrit ? Se connecter</a></p>
</main>
</body>
</html>
@@ -0,0 +1,32 @@
<?php
function getConnection()
{
static $conn = null;
if ($conn !== null) {
return $conn;
}
// On autorise deux modes de configuration :
// 1) via des variables d'environnement ;
// 2) en remplaçant directement les valeurs par votre login/mot de passe.
$host = getenv('DB_HOST');
$user = getenv('DB_USER');
$password = getenv('DB_PASSWORD');
$database = getenv('DB_NAME');
if ($user === '' || $database === '') {
die(
"Configurez d'abord l'accès MySQL dans modeles/connexion.php " .
"ou via les variables d'environnement CINEMA_DB_HOST, CINEMA_DB_USER, CINEMA_DB_PASSWORD et CINEMA_DB_NAME."
);
}
$conn = mysqli_connect($host, $user, $password, $database, 3306);
if ($conn === false) {
die('Connexion MySQL impossible : ' . mysqli_connect_error());
}
mysqli_set_charset($conn, 'utf8mb4');
return $conn;
}
@@ -1,22 +1,5 @@
<?php
function getConnection()
{
static $conn = null;
if ($conn === null) {
$host = getenv('DB_HOST') ?: 'https://dwarves.iut-fbleau.fr';
$login = getenv('DB_USER') ?: getenv('USER') ?: getenv('USERNAME') ?: 'root';
$password = getenv('DB_PASSWORD') ?: $login;
$database = getenv('DB_NAME') ?: $login;
$conn = mysqli_connect($host, $login, $password, $database);
if ($conn !== false) {
mysqli_set_charset($conn, 'utf8mb4');
}
}
return $conn;
}
include_once __DIR__ . '/connexion.php';
function getFilms($page = 1, $perPage = 10)
{
@@ -0,0 +1,53 @@
<?php
include_once __DIR__ . '/connexion.php';
function findUserByLogin($login)
{
$conn = getConnection();
$stmt = mysqli_prepare($conn, 'SELECT login, email, password FROM `user` WHERE login = ?');
if ($stmt === false) {
die('Préparation SQL impossible : ' . mysqli_error($conn));
}
mysqli_stmt_bind_param($stmt, 's', $login);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $dbLogin, $dbEmail, $dbPassword);
$user = null;
if (mysqli_stmt_fetch($stmt)) {
$user = array(
'login' => $dbLogin,
'email' => $dbEmail,
'password' => $dbPassword,
);
}
mysqli_stmt_close($stmt);
return $user;
}
function createUser($login, $email, $passwordHash)
{
$conn = getConnection();
$stmt = mysqli_prepare($conn, 'INSERT INTO `user` (login, email, password) VALUES (?, ?, ?)');
if ($stmt === false) {
die('Préparation SQL impossible : ' . mysqli_error($conn));
}
mysqli_stmt_bind_param($stmt, 'sss', $login, $email, $passwordHash);
$success = mysqli_stmt_execute($stmt);
$errorCode = mysqli_errno($conn);
mysqli_stmt_close($stmt);
// 1062 = violation de clé unique (login déjà pris).
if (!$success && $errorCode === 1062) {
return false;
}
if (!$success) {
die('Insertion SQL impossible : ' . mysqli_error($conn));
}
return true;
}
+11
View File
@@ -0,0 +1,11 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Ce fichier est inclus en tête de chaque page protégée.
// Si l'utilisateur n'est pas connecté, on le renvoie vers le formulaire.
if (!isset($_SESSION['user_login'])) {
header('Location: ./authentification.php');
exit;
}
+35
View File
@@ -0,0 +1,35 @@
<?php
session_start();
include_once './modeles/modeleUtilisateurs.php';
$login = isset($_POST['login']) ? trim($_POST['login']) : '';
$password = isset($_POST['password']) ? $_POST['password'] : '';
// Cette temporisation ralentit volontairement les tentatives répétées,
// ce qui rend les attaques par force brute moins efficaces.
usleep(500000);
if ($login === '' || $password === '') {
header('Location: ./authentification.php?error=1&login=' . urlencode($login));
exit;
}
$user = findUserByLogin($login);
if ($user === null) {
header('Location: ./authentification.php?error=1&login=' . urlencode($login));
exit;
}
if (!password_verify($password, $user['password'])) {
header('Location: ./authentification.php?error=1&login=' . urlencode($login));
exit;
}
session_regenerate_id(true);
$_SESSION['user_login'] = $user['login'];
$_SESSION['user_email'] = $user['email'];
header('Location: ./films.php');
exit;
+10
View File
@@ -12,3 +12,13 @@
</head>
<body>
<main class="container">
<nav>
<ul>
<li><strong>Cinema</strong></li>
</ul>
<ul>
<li><a href="./films.php">Films</a></li>
<li>Connecté : <?php echo htmlspecialchars(isset($_SESSION['user_login']) ? $_SESSION['user_login'] : 'inconnu', ENT_QUOTES); ?></li>
<li><a href="./deconnexion.php">Déconnexion</a></li>
</ul>
</nav>
+25 -4
View File
@@ -1,6 +1,27 @@
<?php
$osSet = ['linux','apple','windows'];
$os = "linux";
// Les valeurs autorisées servent à la fois pour la validation
// du formulaire et pour l'affichage dans la vue.
$osSet = [
'linux' => 'Linux',
'windows' => 'Windows',
'apple' => 'MacOS',
];
include './views/main.php';
?>
$cookieName = 'preferred_os';
$os = 'linux';
// Si le formulaire est soumis, on valide la valeur reçue avant
// de l'enregistrer dans un cookie valable 60 secondes.
if (isset($_POST['os']) && array_key_exists($_POST['os'], $osSet)) {
$os = $_POST['os'];
setcookie($cookieName, $os, time() + 60);
// On met aussi $_COOKIE à jour pour refléter immédiatement le choix
// sans attendre le rechargement suivant du navigateur.
$_COOKIE[$cookieName] = $os;
} elseif (isset($_COOKIE[$cookieName]) && array_key_exists($_COOKIE[$cookieName], $osSet)) {
// En l'absence de soumission, on relit la préférence mémorisée.
$os = $_COOKIE[$cookieName];
}
include_once './views/main.php';
+21 -15
View File
@@ -1,43 +1,49 @@
<!doctype html>
<html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Cookie OS préféré</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<main class="container">
<form method="POST">
<fieldset class="grid">
<legend>Changez votre os</legend>
<?php foreach ($osSet as $value => $label) { ?>
<label>
<input type="radio" name="os" value="linux">
<i class="fa fa-linux fa-2x" aria-hidden="true"></i>
</label>
<label>
<input type="radio" name="os" value="windows">
<i class="fa fa-windows fa-2x" aria-hidden="true"></i>
</label>
<label>
<input type="radio" name="os" value="apple">
<i class="fa fa-apple fa-2x" aria-hidden="true"></i>
<input
type="radio"
name="os"
value="<?php echo htmlspecialchars($value, ENT_QUOTES); ?>"
<?php echo $os === $value ? 'checked' : ''; ?>
>
<i class="fa fa-<?php echo htmlspecialchars($value, ENT_QUOTES); ?> fa-2x" aria-hidden="true"></i>
<?php echo htmlspecialchars($label, ENT_QUOTES); ?>
</label>
<?php } ?>
</fieldset>
<button type="submit">Envoyer</button>
</form>
<article>
<header>Votre os</header>
<?php echo "<i class='fa fa-$os fa-5x'></i>";?>
<p>
<!-- On affiche l'icône et le nom de l'OS courant. -->
<i class="fa fa-<?php echo htmlspecialchars($os, ENT_QUOTES); ?> fa-5x" aria-hidden="true"></i>
</p>
<p><?php echo htmlspecialchars($osSet[$os], ENT_QUOTES); ?></p>
<footer>
Rafraîchir la page <a href=""><i class="fa fa-refresh" aria-hidden="true"></i></a>
Rafraîchir la page
<a href="./" aria-label="Rafraîchir la page">
<i class="fa fa-refresh" aria-hidden="true"></i>
</a>
</footer>
</article>
</main>
</body>
</html>
+54 -25
View File
@@ -1,54 +1,83 @@
<?php
function initializeGame()
{
// Une grille vide contient 9 cases valant 0.
$_SESSION['grid'] = array_fill(0, 9, 0);
$_SESSION['playerTurn'] = 1;
}
function nextPlayer($player)
{
return $player === 1 ? 2 : 1;
}
function isWinner($grid, $player)
{
$winStates = array
(
array(0, 1, 2), array(3, 4, 5), array(6, 7, 8), // Horizontal
array(0, 3, 6), array(1, 4, 7), array(2, 5, 8), // Vertical
array(0, 4, 8), array(2, 4, 6) // Diagonal
$winStates = array(
array(0, 1, 2), array(3, 4, 5), array(6, 7, 8),
array(0, 3, 6), array(1, 4, 7), array(2, 5, 8),
array(0, 4, 8), array(2, 4, 6)
);
foreach ($winStates as $winState)
{
if ($grid[$winState[0]] == $player &&
foreach ($winStates as $winState) {
if (
$grid[$winState[0]] == $player &&
$grid[$winState[1]] == $player &&
$grid[$winState[2]] == $player)
{
$grid[$winState[2]] == $player
) {
return true;
}
}
return false;
}
function noWinner($grid)
{
for($i = 0; $i < 9; $i++)
if ($grid[$i] == 0)
for ($i = 0; $i < 9; $i++) {
if ($grid[$i] == 0) {
return false;
}
}
return true;
}
function displayGrid($grid)
function getWinner($grid)
{
if (isWinner($grid, 1)) {
return 1;
}
if (isWinner($grid, 2)) {
return 2;
}
return 0;
}
function displayGrid($grid, $isInteractive = true)
{
echo '<table class="morpion">';
for ($i = 0; $i < 3; $i ++){
echo "<tr>";
for ($j = 0; $j < 3; $j ++){
for ($i = 0; $i < 3; $i++) {
echo '<tr>';
for ($j = 0; $j < 3; $j++) {
echo '<td>';
echo "<td>";
$pos = 3*$i + $j;
if ($grid[$pos] == 0)
$pos = 3 * $i + $j;
if ($grid[$pos] == 0 && $isInteractive) {
echo "<a href='?pos=$pos'></a>";
if ($grid[$pos] == 1)
}
if ($grid[$pos] == 1) {
echo '<i class="fa fa-times" aria-hidden="true"></i>';
if ($grid[$pos] == 2)
}
if ($grid[$pos] == 2) {
echo '<i class="fa fa-circle-o" aria-hidden="true"></i>';
}
echo "</td>";
echo '</td>';
}
echo "</tr>";
echo '</tr>';
}
echo "</table>";
echo '</table>';
}
+65 -6
View File
@@ -1,11 +1,70 @@
<?php
include 'helpers.php';
session_start();
// view variables
$message = "";
$grid = [0,1,0,1,0,2,2,0,0];
$playerTurn = 1; // 1 or 2
include_once 'helpers.php';
// Si on demande une nouvelle partie, on réinitialise l'état stocké
// en session puis on recharge la page sans paramètre.
if (isset($_GET['reset'])) {
initializeGame();
header('Location: .');
exit;
}
include './views/tictactoe.php';
if (!isset($_SESSION['grid']) || !isset($_SESSION['playerTurn'])) {
initializeGame();
}
// Variables transmises à la vue.
$message = '';
$grid = $_SESSION['grid'];
$playerTurn = (int) $_SESSION['playerTurn'];
$winner = getWinner($grid);
$isGameOver = $winner !== 0 || noWinner($grid);
// On joue uniquement si la partie est encore en cours.
if (!$isGameOver && isset($_GET['pos'])) {
$pos = filter_input(
INPUT_GET,
'pos',
FILTER_VALIDATE_INT,
array('options' => array('min_range' => 0, 'max_range' => 8))
);
if ($pos === false || $pos === null) {
$message = 'Coup invalide.';
} elseif ($grid[$pos] !== 0) {
$message = 'Cette case est déjà occupée.';
} else {
// On enregistre le coup du joueur courant dans la grille.
$grid[$pos] = $playerTurn;
if (isWinner($grid, $playerTurn)) {
$message = "Le joueur $playerTurn gagne la partie.";
} elseif (noWinner($grid)) {
$message = 'Match nul.';
} else {
$playerTurn = nextPlayer($playerTurn);
}
$_SESSION['grid'] = $grid;
$_SESSION['playerTurn'] = $playerTurn;
}
$winner = getWinner($grid);
$isGameOver = $winner !== 0 || noWinner($grid);
}
// Si la page est simplement rafraîchie, on recalcule un message cohérent
// à partir de l'état stocké en session.
if ($message === '') {
if ($winner !== 0) {
$message = "Le joueur $winner gagne la partie.";
} elseif (noWinner($grid)) {
$message = 'Match nul.';
}
}
include_once './views/tictactoe.php';
+18 -6
View File
@@ -1,22 +1,34 @@
<html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Tic Tac Toe</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<main class="container center">
<h4>Tic Tac Toe : <?php echo "player $playerTurn turn";?></h4>
<h4>
<?php if ($isGameOver) { ?>
Partie terminée
<?php } else { ?>
Tic Tac Toe : joueur <?php echo $playerTurn; ?> à vous de jouer
<?php } ?>
</h4>
<?php
displayGrid($grid);
// Quand la partie est finie, les liens dans les cases vides
// disparaissent pour empêcher tout coup supplémentaire.
displayGrid($grid, !$isGameOver);
if ($message != "")
echo "<h5>$message <a href='.'>new game</a></h5>";
if ($message != '') {
echo '<h5>' . htmlspecialchars($message, ENT_QUOTES) . " <a href='?reset=1'>nouvelle partie</a></h5>";
} else {
echo "<p><a href='?reset=1'>Recommencer la partie</a></p>";
}
?>
</main>
</body>
-77
View File
@@ -1,77 +0,0 @@
# TP5 : prise en main de codeigniter
## Installation
Téléchargez les sources de [codeigniter v3](https://github.com/pocketarc/codeigniter) (il s'agit d'un fork qui évite certains
porblèmes de compatibilité avec des versions récentes de php), et placez les dans votre
`public_html`.
1. Importez dans votre base de données la table [todo.sql](src/sql/todo.sql)
2. Copiez le repertoire [assets](src/assets) à la racine de votre application.
3. Copiez les [contrôleurs](src/ci), [modèles](src/ci) et [vues](src/ci) dans votre application.
4. Configurez les paramètres nécessaires à codeigniter :
- `config/config.php`
- `config/database.php`
```php
$config['base_url']='/~login/chemin/vers/codeigniter';
```
Vous devriez obtenir une application `todolist` fonctionnelle à l'url :
```
https://dwarves.iut-fbleau.fr/~login/chemin/vers/codeigniter/index.php/todo
```
![todo](img/todo.png)
## Suppression des tâches
Modifiez le code pour la suppression des tâches.
## Edition des tâches
Modifiez le code (contrôleur et modèle) pour l'édition des tâches.
## Tri de la todolist
Ajoutez la possibilité de trier la todolist par ordre (croissant/décroissant) alphabètique
## Créer sa propre classe controller
Il est possible de redefinir, ou d'étendre les classes systèmes dans votre répertoire `application/core`. Par exemple, pour étendre la classe
controller de codeigniter, vous pouvez écrire votre propre classe `MY_Controller.php`
```php
class MY_Controller extends CI_Controller {
}
```
Utilisez ce moyen pour définir une nouvelle méthode render, qui permet d'utiliser un layout quelconque pour afficher une vue.
## Création de compte
1. Ajoutez dans votre de base de données une table `user`, qui permettra de stocker des utilisateurs.
attributs : nom, prenom, email (clé primaire), password.
2. Complétez le contrôleur de création de compte. On rappelle que la base de données doit contenir un hash du mot de passe (cf tp4).
```php
<?php
/**
* We just want to hash our password using the current DEFAULT algorithm.
* This is presently BCRYPT, and will produce a 60 character result.
*
* Beware that DEFAULT may change over time, so you would want to prepare
* By allowing your storage to expand past 60 characters (255 would be good)
*/
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT);
?>
```
```php
<?php
// Voir l'exemple fourni sur la page de la fonction password_hash()
// pour savoir d'où cela provient.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';
if (password_verify('rasmuslerdorf', $hash)) {
echo 'Le mot de passe est valide !';
} else {
echo 'Le mot de passe est invalide.';
}
?>
```
3. Ajoutez un formulaire d'authentification.
4. Utilisez une session pour proteger l'accès à la todolist par authentification.
5. Ajouter à la table todo un lien vers la table user, et modifez l'ensemble de l'application pour que
chaque utilisateur possède sa propre todolist.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

-13
View File
@@ -1,13 +0,0 @@
.action{
text-align : right;
}
.action a {
margin-right : 1rem;
}
table {
font-size : 1.5rem;
}
body {
padding : 2rem;
}
-64
View File
@@ -1,64 +0,0 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Todo extends CI_Controller {
public $filter = 'all';
public function __construct()
{
parent::__construct();
$this->load->helper('html');
$this->load->helper('url');
$this->load->helper('form');
$this->load->model('model_todo');
$this->filter = $this->input->get('filter') ?? 'all';
}
public function index()
{
$todos = $this->model_todo->getTodos($this->filter);
$this->load->view('layout/header');
$this->load->view('todos',['todos'=>$todos,'filter'=>$this->filter]);
$this->load->view('layout/footer');
}
public function delete($id)
{
// TODO
}
public function toggle($id)
{
$this->model_todo->toggleTodo($id);
redirect('/todo');
}
public function add()
{
$todo = ['text'=>$this->input->post('todo'),'done'=>0];
$this->model_todo->addTodo($todo);
$todos = $this->model_todo->getTodos();
$this->index();
}
public function edit($id)
{
$this->load->library('form_validation');
$this->load->model('model_todo');
$todo = $this->model_todo->getTodo($id);
$this->form_validation->set_rules('todo', 'Todo', 'required');
if ($this->form_validation->run() === FALSE){
$this->load->view('layout/header');
$this->load->view('edit',['todo'=>$todo]);
$this->load->view('layout/footer');
}else{
// TODO
}
}
}
-35
View File
@@ -1,35 +0,0 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class User extends CI_Controller {
public function create()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('nom', 'Nom', 'required');
$this->form_validation->set_rules('prenom', 'Prénom', 'required');
$this->form_validation->set_rules('email', 'Adresse mail', 'valid_email');
$this->form_validation->set_rules('password', 'current password', 'min_length[5]|required');
$this->form_validation->set_rules('cpassword', 'confirm password', 'required|matches[password]');
if ($this->form_validation->run() === FALSE){
$this->load->view('layout/header');
$this->load->view('create_user_form');
$this->load->view('layout/footer');
}else{
//
// TODO
//
}
}
public function auth()
{
//
// TODO
//
}
}
-57
View File
@@ -1,57 +0,0 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Model_todo extends CI_Model {
public function __construct()
{
$this->load->database();
}
public function deleteTodo($id)
{
$this->db->delete('todo',['id'=>$id]);
}
public function getTodos($filter='all')
{
$where_filter = ["done" => 1, "active" => 0, "all" => "%"];
return $this
->db
->query("SELECT * FROM todo WHERE done LIKE ?",[$where_filter[$filter]])
->result();
}
public function toggleTodo($id){
/* en utilisant Query Builder class
* $this
->db
->set('done','1-done',false)
->where('id',$id)
->update('todo');
*/
$sql = "UPDATE todo SET done = 1 - done WHERE id = ?";
$this
->db
->query($sql,[$id]);
}
public function editTodo($id,$text)
{
// TODO
}
public function getTodo($id){
$sql = "SELECT * FROM todo where id = ?";
return $this
->db
->query($sql,[$id])->row();
}
public function addTodo($todo)
{
$this->db->insert('todo', $todo);
return $this
->db
->insert_id();
}
}
@@ -1,33 +0,0 @@
<?=validation_errors(); ?>
<?=form_open('user/create')?>
<!-- Grid -->
<div class="grid">
<!-- Markup example 1: input is inside label -->
<label for="prenom">
Prénom
<input type="text" id="prenom" name="prenom" placeholder="Prénom" value="<?=set_value('prenom')?>"required>
</label>
<label for="nom">
Nom
<input type="text" id="nom" name="nom" placeholder="nom" value="<?=set_value('nom')?>" required>
</label>
</div>
<!-- Markup example 2: input is after label -->
<label for="email">Adresse mail</label>
<input type="email" id="email" name="email" placeholder="Email" value="<?=set_value('email')?>" required>
<div class="grid">
<label for="password">Password
<input type="password" id="password" name="password" placeholder="Password" value="<?=set_value('password')?>" required>
</label>
<label for="password">Confirmation password
<input type="password" id="cpassword" name="cpassword" placeholder="Password" value="<?=set_value('cpassword')?>" required>
</label>
</div>
<!-- Button -->
<button type="submit">Submit</button>
</form>
-13
View File
@@ -1,13 +0,0 @@
<article>
<?php echo form_open("/todo/edit/{$todo->id}");?>
<form>
<label for="email">Todo
<input type="text" name="todo" value="<?=set_value('todo',$todo->text)?>" required>
</label>
<!-- Button -->
<button type="submit">Submit</button>
</form>
</article>
@@ -1,3 +0,0 @@
</main>
</body>
</html>
@@ -1,15 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>TODO APP</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>
<!--link rel="stylesheet" href="https://unpkg.com/@picocss/pico@1.*/css/pico.min.css"-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<?=link_tag('assets/style.css')?>
</head>
<body>
<main class="container">
-42
View File
@@ -1,42 +0,0 @@
<article>
<header>
<nav>
<ul>
<li><strong>TODOS</strong></li>
</ul>
<ul>
<li><?=anchor("todo/?filter=all",'All', ['role'=>($filter=='all'?'button':'')])?></li>
<li><?=anchor("todo/?filter=active",'Active', ['role'=>($filter=='active'?'button':'')])?></li>
<li><?=anchor("todo/?filter=done",'Done', ['role'=>($filter=='done'?'button':'')])?></li>
</ul>
</nav>
</header>
<?=form_open('todo/add')?>
<fieldset role="group">
<input type="text" placeholder="Buy milk and eggs..." name="todo">
<button><i class="fa fa-plus"></i></button>
</fieldset>
</form>
<table>
<?php foreach($todos as $todo): ?>
<?php if ($todo->done): ?>
<tr>
<td><s><?=$todo->text?></s></td>
<td class='action'>
<?=anchor("todo/toggle/{$todo->id}", '<i class="fa fa-toggle-on"></i>')?>
<?=anchor("todo/delete/{$todo->id}", '<i class="fa fa-trash-o"></i>')?>
<?=anchor("todo/edit/{$todo->id}", '<i class="fa fa-edit"></i>')?>
<?php else: ?>
<tr><td><?=$todo->text?></td>
<td class='action'>
<?=anchor("todo/toggle/{$todo->id}", '<i class="fa fa-toggle-off"></i>')?>
<?=anchor("todo/delete/{$todo->id}", '<i class="fa fa-trash-o"></i>')?>
<?=anchor("todo/edit/{$todo->id}", '<i class="fa fa-edit"></i>')?>
<?php endif; ?>
</td></tr>
<?php endforeach; ?>
</table>
</article>
-65
View File
@@ -1,65 +0,0 @@
-- phpMyAdmin SQL Dump
-- version 5.2.1
-- https://www.phpmyadmin.net/
--
-- Hôte : localhost
-- Généré le : mar. 23 mai 2023 à 07:22
-- Version du serveur : 10.11.2-MariaDB
-- Version de PHP : 8.2.4
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
-- --------------------------------------------------------
--
-- Structure de la table `todo`
--
CREATE TABLE `todo` (
`id` int(11) NOT NULL,
`text` varchar(256) NOT NULL,
`done` tinyint(1) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Déchargement des données de la table `todo`
--
INSERT INTO `todo` (`id`, `text`, `done`) VALUES
(1, 'Avoid excessive caffeine !', 0),
(2, 'Be less provocative !', 1),
(3, 'Be nice to people', 1);
--
-- Index pour les tables déchargées
--
--
-- Index pour la table `todo`
--
ALTER TABLE `todo`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT pour les tables déchargées
--
--
-- AUTO_INCREMENT pour la table `todo`
--
ALTER TABLE `todo`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=58;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;