diff --git a/assets/actions/gameServer.php b/assets/actions/gameServer.php index dd6786de54ee418b9caca8d4781feab0f20e7364..cb498fde4ef8d6db77b7601daa8ca107f6793cb1 100644 --- a/assets/actions/gameServer.php +++ b/assets/actions/gameServer.php @@ -3,3 +3,21 @@ // utiliser le fichier Database.php pour charger les trois premiers jeux dans la base de données et les retourner en JSON. (2 points) require_once __DIR__ . '/../db/Database.php'; + +// Get start and count parameters from the AJAX request +$start = $_GET["start"]; + +// Create a new instance of the Database class to interact with the database +$games = new Database(); + +// Retrieve the requested games from the database +$projectData = $games->getGames($start); + +// Convert the project data to a JSON-encoded string +$jsonData = json_encode($projectData); + +// Set the content type header to application/json +header("Content-Type: application/json"); + +// Echo the JSON-encoded project data back to the client +echo $jsonData; diff --git a/assets/actions/gameTableSize.php b/assets/actions/gameTableSize.php index ebe98e0cc4f72b90c37b601b4c256995d279273e..61d24075ba68f01fd80e6fbd8ad14299a7f9426e 100644 --- a/assets/actions/gameTableSize.php +++ b/assets/actions/gameTableSize.php @@ -3,3 +3,18 @@ // utiliser le fichier Database.php pour charger le nombre de jeu total dans la base et le retourner en JSON. (1 points) require_once __DIR__ . '/../db/Database.php'; + +// Create a new instance of the Database class to interact with the database +$db = new Database(); + +// Retrieve the requested db from the database +$tableSize = $db->getGameTableSize(); + +// Convert the project data to a JSON-encoded string +$jsonData = json_encode($tableSize); + +// Set the content type header to application/json +header("Content-Type: application/json"); + +// Echo the JSON-encoded project data back to the client +echo $jsonData; diff --git a/assets/actions/register.php b/assets/actions/register.php index c816c019d41381bc9d56fbdf1d4bcbc1d0ee349f..5a1065acc805f3fcb730b56f19de0caaf9ccb246 100644 --- a/assets/actions/register.php +++ b/assets/actions/register.php @@ -6,3 +6,18 @@ */ require_once __DIR__ . '/../db/Database.php'; +$db = new Database(); + +$result = $db->register( + $_POST['username'], + $_POST['password'], +); + + +if ($result) { + // Page de connexion + header('Location: /login.php'); +} else { + // Toujours page d'inscription. + header('Location: /register.php'); +} diff --git a/assets/css/index.css b/assets/css/index.css index 1ffcc07971331634b07b77f462778d6f1b7eab12..36abe6388942c378387f86f3e40cfe938fe446ea 100644 --- a/assets/css/index.css +++ b/assets/css/index.css @@ -7,53 +7,83 @@ body > header { background-size: cover; display: flex; align-items: center; - justify-content: center; } - body > header h1 { - background-color: rgba(255, 255, 255, 0.5); - padding: 20px 40px; - border-radius: 5px; - font-size: 3rem; - backdrop-filter: blur(10px); } + justify-content: center; +} +body > header h1 { + background-color: rgba(255, 255, 255, 0.5); + padding: 20px 40px; + border-radius: 5px; + font-size: 3rem; + backdrop-filter: blur(10px); +} main { - margin: 0 4rem; } - main section a { - color: black; } - main section a article { - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - border: 1px solid var(--color-primary); - background-color: var(--color-primary-transparent); - box-sizing: border-box; - border-radius: 1rem; } - main section a article header { - position: relative; - height: 200px; - display: flex; - flex-direction: column; - align-items: stretch; - justify-content: center; - width: 100%; } - main section a article header img { - left: 0; - right: 0; - top: 0; - width: 100%; - height: 200px; - object-fit: cover; - border-radius: 1rem 1rem 0 0; - position: absolute; - z-index: -1; } - main section a article header h3 { - padding: 1rem 0; - text-align: center; - width: 100%; - font-size: 2rem; - background-color: rgba(255, 255, 255, 0.5); } - main section a article p { - padding: 0.75rem; - font-size: 0.75rem; } + margin: 0 4rem; +} + +main section a { + color: black; +} + +main section a article { + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + border: 1px solid var(--color-primary); + background-color: var(--color-primary-transparent); + box-sizing: border-box; + border-radius: 1rem; +} +main section a article header { + position: relative; + height: 200px; + display: flex; + flex-direction: column; + align-items: stretch; + justify-content: center; + width: 100%; +} +main section a article header img { + left: 0; + right: 0; + top: 0; + width: 100%; + height: 200px; + object-fit: cover; + border-radius: 1rem 1rem 0 0; + position: absolute; + z-index: -1; +} +main section a article header h3 { + padding: 1rem 0; + text-align: center; + width: 100%; + font-size: 2rem; + background-color: rgba(255, 255, 255, 0.5); +} +main section a article p { + padding: 0.75rem; + font-size: 0.75rem; +} + +main section { + display: grid; + grid-template-columns: 1fr; + gap: 5px 5px; +} /*# sourceMappingURL=index.css.map */ +@media all and (min-width: 742px) { + /* Tablettte */ + main section { + grid-template-columns: 1fr 1fr; + } +} + +@media all and (min-width: 1140px) { + /* Ordinateur */ + main section { + grid-template-columns: 1fr 1fr 1fr; + } +} diff --git a/assets/db/Database.php b/assets/db/Database.php index e24cb94ac718b10ebe58b24b37a036a2908c5cb9..22bf3ec1024c178aca46c06beab8374f0b4b7299 100644 --- a/assets/db/Database.php +++ b/assets/db/Database.php @@ -2,20 +2,20 @@ class Database { - private PDO $pdo; + private PDO $pdo; - public function __construct() - { - $this->pdo = new PDO('sqlite:' . __DIR__ . '/database.sqlite'); - $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + public function __construct() + { + $this->pdo = new PDO('sqlite:' . __DIR__ . '/database.sqlite'); + $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); - $this->initGameTable(); - } + $this->initGameTable(); + } - private function initGameTable(): void - { - $this->pdo->exec('CREATE TABLE IF NOT EXISTS game ( + private function initGameTable(): void + { + $this->pdo->exec('CREATE TABLE IF NOT EXISTS game ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(255) NOT NULL, image VARCHAR(255) NOT NULL, @@ -23,129 +23,142 @@ class Database price FLOAT NOT NULL, release_date DATE NOT NULL )'); - $this->pdo->exec('CREATE TABLE IF NOT EXISTS user ( + $this->pdo->exec('CREATE TABLE IF NOT EXISTS user ( id INTEGER PRIMARY KEY AUTOINCREMENT, password VARCHAR(255) NOT NULL, username VARCHAR(255) NOT NULL UNIQUE )'); + } + + public function getGames($startPosition) + { + // Charger ici les jeux de la base de données trois par trois + $statement = $this->pdo->prepare( + 'SELECT * FROM game + ORDER BY id + LIMIT :start, 3' + ); + $statement->bindValue(':start', $startPosition, PDO::PARAM_INT); + $statement->execute(); + + return $statement->fetchAll(); + } + + /** + * @param $id + * @return mixed + */ + public function getGame($id) + { + $statement = $this->pdo->prepare('SELECT * FROM game WHERE id = :id'); + $statement->bindValue(':id', $id, PDO::PARAM_INT); + $statement->execute(); + + return $statement->fetch(); + } + + public function getGameTableSize() + { + // Retourner le nombre de jeux dans la base de données + $statement = $this->pdo->prepare('SELECT COUNT(*) as gameSize + FROM game;'); + $statement->execute(); + return $statement->fetchColumn(); + } + + /** + * @param $username + * @param $password + * @return bool + */ + public function register($username, $password) + { + // Faire une fonction pour enregistrer un utilisateur dans la base de données. + } + + public function login($username, $password) + { + $statement = $this->pdo->prepare('SELECT * FROM user WHERE username = :username'); + $statement->bindValue(':username', htmlspecialchars($username), PDO::PARAM_STR); + $statement->execute(); + $user = $statement->fetch(); + + if ($user) { + return password_verify($password, $user['password']); } - public function getGames() - { - // Charger ici les jeux de la base de données trois par trois - } + return false; + } + + public function insertGame($name, $picture, $description, $price, $releaseDate) + { + if ( + $this->checkField($name, true, 2, 255) && + $this->checkField($description, false) && + $this->checkField($price, true, 1, 255, '/^[0-9,.]+$/') && + $this->checkField($releaseDate, true, 1, 255, '/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/') + ) { + try { + $pictureName = $this->savePicture($picture); + + if (!$pictureName) { + return false; + } - /** - * @param $id - * @return mixed - */ - public function getGame($id) - { - $statement = $this->pdo->prepare('SELECT * FROM game WHERE id = :id'); - $statement->bindValue(':id', $id, PDO::PARAM_INT); - $statement->execute(); - - return $statement->fetch(); + $statement = $this->pdo->prepare('INSERT INTO game (name, image, description, price, release_date) VALUES (:name, :image, :description, :price, :release_date)'); + $statement->bindValue(':name', htmlspecialchars($name), PDO::PARAM_STR); + $statement->bindValue(':image', $pictureName, PDO::PARAM_STR); + $statement->bindValue(':description', htmlspecialchars($description), PDO::PARAM_STR); + $statement->bindValue(':price', $price, PDO::PARAM_INT); + $statement->bindValue(':release_date', $releaseDate, PDO::PARAM_STR); + return $statement->execute(); + } catch (Exception $e) { + return false; + } } - public function getGameTableSize() - { - // Retourner le nombre de jeux dans la base de données + return false; + } + + /** + * @param $field + * @param $isRequired + * @param $minLength + * @param $maxLength + * @param $regex + * + * @return bool + */ + private function checkField($field, $isRequired, $minLength = null, $maxLength = null, $regex = null) + { + if ($isRequired && empty($field)) { + return false; } - - /** - * @param $username - * @param $password - * @return bool - */ - public function register($username, $password) - { - // Faire une fonction pour enregistrer un utilisateur dans la base de données. + if ($minLength && strlen($field) < $minLength) { + return false; } - public function login($username, $password) - { - $statement = $this->pdo->prepare('SELECT * FROM user WHERE username = :username'); - $statement->bindValue(':username', htmlspecialchars($username), PDO::PARAM_STR); - $statement->execute(); - $user = $statement->fetch(); - - if ($user) { - return password_verify($password, $user['password']); - } - - return false; + if ($maxLength && strlen($field) > $maxLength) { + return false; } - public function insertGame($name, $picture, $description, $price, $releaseDate) - { - if ( - $this->checkField($name, true, 2, 255) && - $this->checkField($description, false) && - $this->checkField($price, true, 1, 255, '/^[0-9,.]+$/') && - $this->checkField($releaseDate, true, 1, 255, '/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/') - ) { - try { - $pictureName = $this->savePicture($picture); - - if (!$pictureName) { - return false; - } - - $statement = $this->pdo->prepare('INSERT INTO game (name, image, description, price, release_date) VALUES (:name, :image, :description, :price, :release_date)'); - $statement->bindValue(':name', htmlspecialchars($name), PDO::PARAM_STR); - $statement->bindValue(':image', $pictureName, PDO::PARAM_STR); - $statement->bindValue(':description', htmlspecialchars($description), PDO::PARAM_STR); - $statement->bindValue(':price', $price, PDO::PARAM_INT); - $statement->bindValue(':release_date', $releaseDate, PDO::PARAM_STR); - return $statement->execute(); - } catch (Exception $e) { - return false; - } - } - - return false; + if ($regex && !preg_match($regex, $field)) { + return false; } - /** - * @param $field - * @param $isRequired - * @param $minLength - * @param $maxLength - * @param $regex - * - * @return bool - */ - private function checkField($field, $isRequired, $minLength = null, $maxLength = null, $regex = null) - { - if ($isRequired && empty($field)) { - return false; - } - if ($minLength && strlen($field) < $minLength) { - return false; - } - - if ($maxLength && strlen($field) > $maxLength) { - return false; - } + return true; + } - if ($regex && !preg_match($regex, $field)) { - return false; - } + public function savePicture($picture) + { + $extension = pathinfo($picture['name'], PATHINFO_EXTENSION); + $filename = uniqid() . '.' . $extension; + $result = move_uploaded_file($picture['tmp_name'], __DIR__ . '/../../public/uploads/' . $filename); - return true; + if (!$result) { + return false; } - public function savePicture($picture) - { - $extension = pathinfo($picture['name'], PATHINFO_EXTENSION); - $filename = uniqid() . '.' . $extension; - $result = move_uploaded_file($picture['tmp_name'], __DIR__ . '/../../public/uploads/' . $filename); - - if (!$result) { - return false; - } - - return $filename; - } + return $filename; + } } diff --git a/assets/js/loadGame.js b/assets/js/loadGame.js index 4f82f01fd05ae1abb7017ce828f4adfa6a6b6b35..ff50b2954f2cb5ba01611dcee8c458362d85610d 100644 --- a/assets/js/loadGame.js +++ b/assets/js/loadGame.js @@ -3,3 +3,58 @@ * ajouter une fonction pour charger, en ajax, la quantité totale de jeux dans la base ( API = /assets/actions/gameTableSize.php). (3 points) * ajouter un événement sur le bouton "Load more" pour lancer la fonction créée au premier point. (1 point) */ +const loadBtnElement = document.querySelector("button"); +const gamesContainer = document.querySelector("main section"); +let start = 0; +function loadMore() { + fetch("/assets/actions/gameServer.php?start=" + start) + .then(function (response) { + if (response.ok) { + return response.json(); + } + throw new Error("Network response was not ok."); + }) + .then(function (projects) { + // Append projects to container element + projects.forEach(function (game) { + const html = ` + <a> + <article> + <header> + <img src="/public/uploads/${game.image}"/> + <h3>${game.name}</h3> + </header> + <p>${game.description}</p> + </article> + </a> + `; + + gamesContainer.insertAdjacentHTML("beforeend", html); + }); + + // Update start index for next fetch call + start += 3; + console.log(start); + if (start >= gameTableSize) { + loadBtnElement.remove(); + } + }) + .catch(function (error) { + console.error("Error:", error); + }); +} + +async function gameTotalSize() { + try { + let result = await fetch("/assets/actions/gameTableSize.php"); + let game = await result.json(); + return game; + } catch (error) { + console.error("Error:", error); + } +} + +const gameTableSize = await gameTotalSize(); +loadBtnElement.addEventListener("click", function () { + loadMore(); +}); diff --git a/assets/template/registerForm.php b/assets/template/registerForm.php new file mode 100644 index 0000000000000000000000000000000000000000..d3061268a78ef3c0331c49075aef2b6729ff9ce7 --- /dev/null +++ b/assets/template/registerForm.php @@ -0,0 +1,19 @@ +<main> + <div> + <h2><?= $title ?></h2> + + <form action="<?= $action ?>" method="post"> + <label> + <?= $translate->getTrad('login.username') ?>* + <input type="text" name="username" required> + </label> + + <label> + <?= $translate->getTrad('login.password') ?>* + <input type="password" name="password" required> + </label> + + <button type="submit"><?= $button ?></button> + </form> + </div> +</main> \ No newline at end of file diff --git a/login.php b/login.php index 86ad726e875efa6840723589ec67e2f4c6525114..8430f09ebc5fe466810b1b32e1f054cb3a14c5d6 100644 --- a/login.php +++ b/login.php @@ -23,4 +23,3 @@ $button = $translate->getTrad('login.submit'); require_once __DIR__ . '/assets/template/registerLoginForm.php'; require_once __DIR__ . '/assets/template/footer.php'; -?> diff --git a/register.php b/register.php index 1dcff4356d30f2006708b18a056eacae73ba9a5e..a4463c4bc53d993cb4382a6992d1a87626c26ed8 100644 --- a/register.php +++ b/register.php @@ -16,10 +16,12 @@ if ($userConnected) { } require_once __DIR__ . '/assets/template/nav.php'; -?> -<!-- ajouter un formulaire pour permettre à l'utilisateur de s'inscrire sur le site. Attention un style existe déjà , utilisez une structure pour permettre de l'adapter au mieux. --> -<?php +$title = $translate->getTrad('register.title'); +$action = '/assets/actions/register.php' . (isset($_GET['target']) ? '?target=' . $_GET['target'] : ''); +$button = $translate->getTrad('register.submit'); + +require_once __DIR__ . '/assets/template/registerForm.php'; + require_once __DIR__ . '/assets/template/footer.php'; -?>