Mise en place du système des énigmes.

This commit is contained in:
antux18 2023-06-28 20:38:52 +02:00
parent dcc512876d
commit 35c9aeaae5
15 changed files with 327 additions and 61 deletions

57
answer.php Normal file
View File

@ -0,0 +1,57 @@
<?php
require_once "require/base.php";
$database = new Database();
if (isset($_GET["code"]) && isset($_GET["team"]) && isset($_GET["id"])) {
$art_id = htmlspecialchars($_GET["id"]);
$team_id = htmlspecialchars($_GET["team"]);
$stmt = $database->pdo_article->prepare("SELECT * FROM puzzles WHERE id == :id");
$stmt->bindValue(":id", $art_id);
$stmt->execute();
$article = $stmt->fetch();
// Vérification de l'existence du groupe et de l'énigme :
$stmt = $database->pdo_teams->prepare("SELECT * FROM teams WHERE id == :id");
$stmt->bindValue(":id", $team_id);
$stmt->execute();
if (empty($article) || empty($stmt->fetchAll())) {
header("Location: index.php");
die();
}
$stmt = $database->pdo_article->prepare("SELECT * FROM puzzles WHERE code == :code");
$stmt->bindValue(":code", htmlspecialchars($_GET["code"]));
$stmt->execute();
$article = $stmt->fetch();
// Vérification de l'existence du groupe :
$stmt = $database->pdo_teams->prepare("SELECT * FROM teams WHERE id == :id");
$stmt->bindValue(":id", $team_id);
$stmt->execute();
if (empty($stmt->fetchAll())) {
header("Location: index.php");
die();
}
if (empty($article)) {
echo 0;
}
else {
$data = [
"infos" => $article["infos"],
"place" => $article["place"]
];
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);
}
}
else {
header("Location: index.php");
die();
}
?>

View File

@ -5,11 +5,36 @@
$database = new Database(); $database = new Database();
if (isset($_GET["id"])) { if (isset($_GET["id"]) && isset($_GET["team"])) {
$stmt = $database->pdo_article->prepare("SELECT * FROM article WHERE id == :id"); $art_id = htmlspecialchars($_GET["id"]);
$stmt->bindValue(":id", htmlspecialchars($_GET["id"])); $team_id = htmlspecialchars($_GET["team"]);
$stmt = $database->pdo_article->prepare("SELECT * FROM puzzles WHERE id == :id");
$stmt->bindValue(":id", $art_id);
$stmt->execute(); $stmt->execute();
$article = $stmt->fetch(); $article = $stmt->fetch();
// Vérification de l'existence du groupe et de l'énigme :
$stmt = $database->pdo_teams->prepare("SELECT * FROM teams WHERE id == :id");
$stmt->bindValue(":id", $team_id);
$stmt->execute();
if (empty($article) || empty($stmt->fetchAll())) {
header("Location: index.php");
die();
}
else {
$stmt = $database->pdo_teams->prepare("SELECT * FROM solved WHERE (team_id == :team_id AND puzzle_id == :puzzle_id)");
$stmt->bindValue(":team_id", $team_id);
$stmt->bindValue(":puzzle_id", $art_id);
$stmt->execute();
$solved = !empty($stmt->fetch());
}
}
else {
header("Location: index.php");
die();
} }
?> ?>
@ -19,7 +44,8 @@
<?php <?php
require_once $rq_path . "head.php"; require_once $rq_path . "head.php";
?> ?>
<title><?= $tr["tab_title"]["article"]?></title> <title><?= $tr["tab_title"]["article"] ?></title>
<script type="module" src="<?= $rq_path ?>js/qrscan.js"></script>
</head> </head>
<body> <body>
<header> <header>
@ -29,12 +55,27 @@
</header> </header>
<main> <main>
<header> <header>
<h1><?= $article["title"] ?></h1> <h1><?= $tr["page_title"]["article"] . $art_id ?></h1>
<p><?= $article["summary"] ?></p> <p><?= $article["text"] ?></p>
</header> </header>
<article> <article>
<img src=<?= $article["cover_path"] ?> alt=<?= $article["cover_alt"] ?>> <?php if ($solved) : ?>
<p><?= $article["content"] ?></p> <p><?= $tr["article"]["success"] ?></p>
<p><?= $article["infos"] ?></p>
<p><?= $article["place"] ?></p>
<?php else : ?>
<p><?= $tr["article"]["message"] ?></p>
<p></p> <!-- Emplacement du message d'erreur JS concernant la caméra. !-->
<button><?= $tr["article"]["qr_but"] ?></button>
<video></video>
<p><?= $tr["article"]["cam_sel"] ?></p>
<select>
<option value="rear" selected><?= $tr["article"]["r_cam"] ?></option>
<option value="front"><?= $tr["article"]["f_cam"] ?></option>
</select>
<!-- <p>Scanner depuis un fichier</p>
<input type="file" id="file-selector"> -->
<?php endif; ?>
</article> </article>
</main> </main>
<footer> <footer>

Binary file not shown.

BIN
data/teams.db Normal file

Binary file not shown.

BIN
images/phqr1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

BIN
images/phqr2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

View File

@ -1,5 +1,11 @@
<?php <?php
require_once "require/base.php"; require_once "require/base.php";
$database = new Database();
$stmt = $database->pdo_teams->prepare("SELECT * FROM teams");
$stmt->execute();
$teams = $stmt->fetchAll();
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
@ -9,7 +15,6 @@
require_once $rq_path . "head.php"; require_once $rq_path . "head.php";
?> ?>
<title><?= $tr["tab_title"]["home"]?></title> <title><?= $tr["tab_title"]["home"]?></title>
<script type="module" src="<?= $rq_path ?>js/qrscan.js"></script>
</head> </head>
<body> <body>
<header> <header>
@ -24,16 +29,11 @@
<p><?= $tr["home"]["message"]?></p> <p><?= $tr["home"]["message"]?></p>
</header> </header>
<article> <article>
<button>Scanner un QR code</button> <ul>
<p></p> <?php foreach ($teams as $team) : ?>
<video></video> <li><a href="puzzles.php?team=<?= $team["id"] ?>"><?= $tr["home"]["team"] . $team["id"] ?></a></li>
<p>Caméra sélectionnée :</p> <?php endforeach; ?>
<select> </ul>
<option value="rear" selected>Caméra arrière</option>
<option value="front">Caméra avant</option>
</select> <!-- Emplacement du message d'erreur JS concernant la caméra. !-->
<p>Scanner depuis un fichier</p>
<input type="file" id="file-selector">
</article> </article>
</main> </main>
<footer> <footer>

66
puzzles.php Normal file
View File

@ -0,0 +1,66 @@
<?php
require_once "require/base.php";
$database = new Database();
if (isset($_GET["team"])) {
$team_id = htmlspecialchars($_GET["team"]);
// Vérification de l'existence du groupe :
$stmt = $database->pdo_teams->prepare("SELECT * FROM teams WHERE id == :id");
$stmt->bindValue(":id", $team_id);
$stmt->execute();
if (empty($stmt->fetchAll())) {
header("Location: index.php");
die();
}
else {
$stmt = $database->pdo_article->prepare("SELECT * FROM puzzles");
$stmt->execute();
$puzzles = $stmt->fetchAll();
}
}
else {
header("Location: index.php");
die();
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<?php
require_once $rq_path . "head.php";
?>
<title><?= $tr["tab_title"]["puzzles"]?></title>
</head>
<body>
<header>
<?php
require_once $rq_path . "nav.php";
?>
</header>
<main>
<header>
<h1><?= $tr["page_title"]["puzzles"] . $team_id ?></h1>
<p></p>
<p><?= $tr["puzzles"]["message"]?></p>
</header>
<article>
<ul>
<?php foreach ($puzzles as $puzzle) : ?>
<li><a href="article.php?team=<?= $team_id ?>&id=<?= $puzzle["id"] ?>"><?= $puzzle["text"] ?></a></li>
<?php endforeach; ?>
</ul>
</article>
</main>
<footer>
<?php
require_once $rq_path . "footer.php";
?>
</footer>
</body>
</html>

View File

@ -1,18 +1,28 @@
<?php <?php
class Database { class Database {
public PDO $pdo_article; public PDO $pdo_article;
public PDO $pdo_teams;
public function __construct() { public function __construct() {
$data_path = "/../data/"; $data_path = "/../data/";
try { try {
$this->pdo_article = new PDO("sqlite:" . dirname(__FILE__) . $data_path . "article.db"); $this->pdo_article = new PDO("sqlite:" . dirname(__FILE__) . $data_path . "article.db");
$this->pdo_article->query("CREATE TABLE IF NOT EXISTS article ( $this->pdo_article->query('CREATE TABLE IF NOT EXISTS "puzzles" (
id INTEGER NOT NULL UNIQUE PRIMARY KEY AUTOINCREMENT, "id" INTEGER NOT NULL UNIQUE,
title VARCHAR(100), "text" TEXT NOT NULL,
content VARCHAR(1000), "hint" TEXT,
summary VARCHAR(200), "infos" TEXT NOT NULL,
cover_path VARCHAR(4096) "place" TEXT NOT NULL,
)"); "code" TEXT NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT)
)');
$this->pdo_teams = new PDO("sqlite:" . dirname(__FILE__) . $data_path . "teams.db");
$this->pdo_teams->query('CREATE TABLE IF NOT EXISTS "teams" (
"id" INTEGER NOT NULL UNIQUE,
"solved_id" INTEGER[],
PRIMARY KEY("id" AUTOINCREMENT)
)');
} }
catch (PDOException $exception) { catch (PDOException $exception) {
@ -22,7 +32,12 @@
} }
public function getArticleNb() { public function getArticleNb() {
$query = $this->pdo_article->query("SELECT COUNT(*) FROM article;"); $query = $this->pdo_article->query("SELECT COUNT(*) FROM puzzles");
return $query->fetch()["COUNT(*)"];
}
public function getTeamsNb() {
$query = $this->pdo_teams->query("SELECT COUNT(*) FROM teams");
return $query->fetch()["COUNT(*)"]; return $query->fetch()["COUNT(*)"];
} }
} }

26
require/js/answer.js Normal file
View File

@ -0,0 +1,26 @@
// Gestion de la langue :
var url_string = window.location.href;
var url = new URL(url_string);
var lg = url.searchParams.get("lg");
if (lg == null) {
lg = "en"; // Langue par défaut
// Recherche dans les cookies :
var cookies = decodeURIComponent(document.cookie);
if (cookies != "") {
// On part du principe qu'on n'a qu'un cookie, et que c'est celui de la langue
// 9 caractères pour "language", et 2 pour la langue
lg = cookies.substring(9, 11);
}
}
export async function puzzleSolve(code, team_id, art_id) {
try {
const response = await fetch("/answer.php?lg=" + lg + "&team=" + team_id + "&code=" + code + "&id=" + art_id);
const data = await response.text();
console.log(data);
}
catch (error) {
console.log(error);
}
}

View File

@ -1,17 +1,48 @@
import QrScanner from "./qr-scanner/qr-scanner.min.js"; import QrScanner from "./qr-scanner/qr-scanner.min.js";
import {puzzleSolve} from "./answer.js";
const video = document.querySelector("video"); const video = document.querySelector("video");
const camList = document.querySelector("select"); const camList = document.querySelector("select");
const fileSelector = document.querySelector("input[type='file']"); // const fileSelector = document.querySelector("input[type='file']");
// Gestion de la langue :
var url_string = window.location.href;
var url = new URL(url_string);
var lg = url.searchParams.get("lg");
var team_id = url.searchParams.get("team");
var art_id = url.searchParams.get("id");
if (lg == null) {
lg = "en"; // Langue par défaut
// Recherche dans les cookies :
var cookies = decodeURIComponent(document.cookie);
if (cookies != "") {
// On part du principe qu'on n'a qu'un cookie, et que c'est celui de la langue
// 9 caractères pour "language", et 2 pour la langue
lg = cookies.substring(9, 11);
}
}
var cam_error = "cam_error";
if (lg == "en") {
var cam_error = "No camera detected !";
}
if (lg == "fr") {
var cam_error = "Aucune caméra détectée !";
}
function scanAction(result) { function scanAction(result) {
console.log(result.data); puzzleSolve(result.data, team_id, art_id);
console.log(result.data); // TODO : retirer
scanner.stop();
} }
function checkCam(hasCamera) { function checkCam(hasCamera) {
const errorP = document.querySelector("article p:first-of-type"); const errorP = document.querySelector("article p:nth-of-type(2)");
if (!hasCamera) { if (!hasCamera) {
errorP.innerHTML = "⚠️ Aucune caméra détectée !"; errorP.innerHTML = "⚠️ " + cam_error;
} }
else { else {
errorP.text = ""; errorP.text = "";
@ -55,11 +86,11 @@ document.querySelector("button").addEventListener("click", () => {
// scanner.stop(); // scanner.stop();
// }); // });
// Scan de fichier : // // Scan de fichier :
fileSelector.addEventListener("change", () => { // fileSelector.addEventListener("change", () => {
const file = fileSelector.files[0]; // const file = fileSelector.files[0];
if (file) { // if (file) {
QrScanner.scanImage(file, {returnDetailedScanResult: true}) // QrScanner.scanImage(file, {returnDetailedScanResult: true})
.then(result => scanAction(result)); // .then(result => scanAction(result));
} // }
}); // });

View File

@ -1,24 +1,37 @@
<?php <?php
$tr = [ $tr = [
"tab_title" => [ "tab_title" => [
"home" => "Home", "home" => "Home - Lycée Pange Treasure Hunt",
"article" => "", "puzzles" => "Puzzles list - Lycée Pange Treasure Hunt",
"article" => "Puzzle - Lycée Pange Treasure Hunt"
], ],
"page_title" => [ "page_title" => [
"home" => "", "home" => "Treasure Hunt",
"article" => "", "puzzles" => "Puzzles list for team n°",
"article" => "Puzzle n°"
], ],
"home" => [ "home" => [
"subtitle" => "", "subtitle" => "Welcome to the treasure hunt of Lycée Jean de Pange of Sarreguemines !",
"message" => "", "message" => "Select your team to begin :",
"art_but" => "Show ", "team" => "Team n°"
],
"article" => [
"message" => "This puzzle describes a specific place. Head to that place, then scan the QR code you'll find there.",
"success" => "Well done ! Your team solved this puzzle !",
"qr_but" => "Scan QR code",
"cam_sel" => "Selected camera :",
"f_cam" => "Front camera",
"r_cam" => "Rear camera"
],
"puzzles" => [
"message" => "Select a puzzle in the list below :"
], ],
"nav" => [ "nav" => [
"title" => "", "title" => "Treasure Hunt Pange",
"home" => "Home", "home" => "Home"
], ],
"footer" => [ "footer" => [
"text" => "Lycée Jean de Pange Sarreguemines", "text" => "Lycée Jean de Pange Sarreguemines"
], ]
]; ];
?> ?>

View File

@ -1,24 +1,37 @@
<?php <?php
$tr = [ $tr = [
"tab_title" => [ "tab_title" => [
"home" => "Accueil", "home" => "Accueil - Chasse au trésor Lycée Pange",
"article" => "", "puzzles" => "Liste des énigmes - Chasse au trésor Lycée Pange",
"article" => "Énigme - Chasse au trésor Lycée Pange"
], ],
"page_title" => [ "page_title" => [
"home" => "Accueil", "home" => "Chasse au trésor",
"article" => "", "puzzles" => "Liste des puzzles pour l'équipe n°",
"article" => "Énigme n°"
], ],
"home" => [ "home" => [
"subtitle" => "Bienvenue !", "subtitle" => "Bienvenue à la chasse au trésor du Lycée Jean de Pange de Sarreguemines !",
"message" => "Page dédiée au test de scan de QR code.", "message" => "Pour commencer, veuillez choisir votre groupe :",
"art_but" => "Voir ", "team" => "Équipe n°"
],
"article" => [
"message" => "Cette énigme décrit un endroit précis. Dirigez-vous vers cet endroit, puis scannez le QR code que vous-y trouverez.",
"success" => "Bien joué ! Votre équipe a résolu cette énigme !",
"qr_but" => "Scanner le QR code",
"cam_sel" => "Caméra sélectionnée :",
"f_cam" => "Caméra avant",
"r_cam" => "Caméra arrière"
],
"puzzles" => [
"message" => "Choisissez une énigme dans la liste ci-dessous :"
], ],
"nav" => [ "nav" => [
"title" => "", "title" => "Chasse au trésor Pange",
"home" => "Accueil", "home" => "Accueil"
], ],
"footer" => [ "footer" => [
"text" => "Lycée Jean de Pange Sarreguemines", "text" => "Lycée Jean de Pange Sarreguemines"
], ]
]; ];
?> ?>

View File

@ -1,5 +1,8 @@
<?php <?php
$url = $_SERVER["PHP_SELF"] . "?"; $url = $_SERVER["PHP_SELF"] . "?";
if (isset($_GET["team"])) {
$url = $url . "team=" . htmlspecialchars($_GET["team"]) . "&";
}
if (isset($_GET["id"])) { if (isset($_GET["id"])) {
$url = $url . "id=" . htmlspecialchars($_GET["id"]) . "&"; $url = $url . "id=" . htmlspecialchars($_GET["id"]) . "&";
} }

View File

@ -304,6 +304,7 @@ section article {
article p:first-of-type { article p:first-of-type {
text-align: center; text-align: center;
font-weight: bold;
} }
footer { footer {