Compare commits
7 Commits
main
..
a77b3f640e
| Author | SHA1 | Date | |
|---|---|---|---|
| a77b3f640e | |||
| 2a995d7cff | |||
| 0da6bcf803 | |||
| 44f8555fe4 | |||
| 17a16feb2d | |||
| 553b30bdcc | |||
| 74ebab4b24 |
@@ -0,0 +1,4 @@
|
||||
DB_HOST=dwarves.iut-fbleau.fr
|
||||
DB_USER=foo
|
||||
DB_PASSWORD=foo
|
||||
DB_NAME=foo
|
||||
@@ -328,3 +328,4 @@ TSWLatexianTemp*
|
||||
# Uncomment the next line to have this generated file ignored.
|
||||
#*Notes.bib
|
||||
|
||||
.env
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -1,14 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Films</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
|
||||
/>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Films</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
|
||||
/>
|
||||
|
||||
<link rel="stylesheet" href="./css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<link rel="stylesheet" href="./css/style.css">
|
||||
</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>
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,44 +1,50 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<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">
|
||||
<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="<?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>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<form method="POST">
|
||||
<fieldset class="grid">
|
||||
<legend>Changez votre os</legend>
|
||||
<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>
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<button type="submit">Envoyer</button>
|
||||
</form>
|
||||
<article>
|
||||
<header>Votre os</header>
|
||||
<?php echo "<i class='fa fa-$os fa-5x'></i>";?>
|
||||
<footer>
|
||||
Rafraîchir la page <a href=""><i class="fa fa-refresh" aria-hidden="true"></i></a>
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
<button type="submit">Envoyer</button>
|
||||
</form>
|
||||
<article>
|
||||
<header>Votre os</header>
|
||||
<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="./" aria-label="Rafraîchir la page">
|
||||
<i class="fa fa-refresh" aria-hidden="true"></i>
|
||||
</a>
|
||||
</footer>
|
||||
</article>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -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>';
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -1,23 +1,35 @@
|
||||
<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"
|
||||
/>
|
||||
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>
|
||||
</html>
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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 |
@@ -1,13 +0,0 @@
|
||||
.action{
|
||||
text-align : right;
|
||||
}
|
||||
.action a {
|
||||
margin-right : 1rem;
|
||||
}
|
||||
table {
|
||||
|
||||
font-size : 1.5rem;
|
||||
}
|
||||
body {
|
||||
padding : 2rem;
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
//
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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">
|
||||
@@ -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>
|
||||
@@ -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 */;
|
||||
Reference in New Issue
Block a user