Merge pull request #29 from Yasder5/besnik

Besnik
This commit is contained in:
Yass 2026-02-24 16:15:09 +01:00 committed by GitHub
commit 46c6d53651
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 998 additions and 1023 deletions

View file

@ -7,63 +7,15 @@
require("./entities/project_entity.php"); require("./entities/project_entity.php");
class UserCtrl extends MotherCtrl { class UserCtrl extends MotherCtrl {
public function login(){ /**
* Fonction d'inscription d'un utilisateur
$strMail = $_POST['user_mail']??""; * Effectue les validations du formulaire,
$strPwd = $_POST['user_password']??""; * vérifie l'unicité du mail et du pseudo,
* puis insère l'utilisateur en base de données
// Tester le formulaire * @return void
$arrError = []; */
if (count($_POST) > 0) { public function signup(){
// Vérifier le formulaire
if ($strMail == ""){
$arrError['mail'] = "Le mail est obligatoire";
}
if ($strPwd == ""){
$arrError['pwd'] = "Le mot de passe est obligatoire";
}
// Si le formulaire est rempli correctement
if (count($arrError) == 0){
// Vérifier l'utilisateur en BDD
$objUserModel = new UserModel;
$arrResult = $objUserModel->verifUser($strMail, $strPwd);
//var_dump($arrResult);
if ($arrResult === false){ // Si la base de données ne renvoie rien
$arrError[] = "Mail ou mot de passe invalide";
}else{
// Ajoute l'utilisateur en session
$_SESSION['user'] = $arrResult;
$_SESSION['success'] = "Bienvenue, vous êtes bien connecté";
header("Location:index.php");
exit;
}
}
}
$this->_arrData['arrError'] = $arrError;
$this->_display("login");
}
public function logout(){
session_start();
/*session_destroy();
session_start();*/
// on supprime l'utilisateur en session
unset($_SESSION['user']);
$_SESSION['success'] = "Vous êtes bien déconnecté";
header("Location:index.php");
exit;
}
public function signin(){
// Entité pour réafficher les valeurs dans le formulaire // Entité pour réafficher les valeurs dans le formulaire
$objUser = new User(); $objUser = new User();
@ -101,33 +53,40 @@ class UserCtrl extends MotherCtrl {
} }
if (trim($objUser->getMail()) === "") { if (trim($objUser->getMail()) === "") {
$arrError['user_mail'] = "Le mail est obligatoire"; $arrError['user_mail'] = "L'adresse e-mail est obligatoire";
} elseif (!filter_var($objUser->getMail(), FILTER_VALIDATE_EMAIL)) { } elseif (!filter_var($objUser->getMail(), FILTER_VALIDATE_EMAIL)) {
$arrError['user_mail'] = "Le format du mail n'est pas correct"; $arrError['user_mail'] = "Le format de l'adresse e-mail est invalide";
} }
if (trim($objUser->getPseudo()) === "") { if (trim($objUser->getPseudo()) === "") {
$arrError['user_pseudo'] = "Le pseudo est obligatoire"; $arrError['user_pseudo'] = "Le pseudo est obligatoire";
} }
$strRegex = "/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{16,}$/"; $strRegex = "/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{15,}$/";
if ($objUser->getPwd() == ""){ if ($objUser->getPwd() == ""){
$arrError['user_password'] = "Le mot de passe est obligatoire"; $arrError['user_password'] = "Le mot de passe est obligatoire";
}else if (!preg_match($strRegex, $objUser->getPwd())){ }else if (!preg_match($strRegex, $objUser->getPwd())){
$arrError['user_password'] = "Le mot de passe ne correspond pas aux règles"; $arrError['user_password'] = "Le mot de passe ne respecte pas les critères";
}else if($objUser->getPwd() != $strPwdConfirm){ }else if($objUser->getPwd() != $strPwdConfirm){
$arrError['pwd_confirm'] = "Le mot de passe et sa confirmation ne sont pas identiques"; $arrError['pwd_confirm'] = "La confirmation du mot de passe ne correspond pas";
} }
// Si pas d'erreurs => insertion // Si pas d'erreurs => insertion
if (count($arrError) === 0) { if (count($arrError) === 0) {
$objUserModel = new UserModel(); $objUserModel = new UserModel();
// Vérif mail
if ($objUserModel->mailExists($objUser->getMail())) { if ($objUserModel->mailExists($objUser->getMail())) {
$arrError['user_mail'] = "Impossible de créer le compte avec ces informations";
}
$arrError['user_mail'] = "Ce mail existe déjà"; // Vérif pseudo
} else { if ($objUserModel->pseudoExists($objUser->getPseudo())) {
$arrError['user_pseudo'] = "Ce pseudo existe déjà";
}
// Si aucune erreur => insert
if (count($arrError) === 0) {
$boolInsert = $objUserModel->insert($objUser); $boolInsert = $objUserModel->insert($objUser);
if ($boolInsert === true) { if ($boolInsert === true) {
@ -142,172 +101,236 @@ class UserCtrl extends MotherCtrl {
} }
// Affichage de la vue inscription // Affichage de la vue inscription
$this->_arrData["arrError"] = $arrError; $this->_arrData['objUser'] = $objUser;
$this->_display("inscription"); $this->_arrData['arrError'] = $arrError;
} $this->_display("signup");
/**
* le controlleur affichage de la page user
*/
public function user(){
/**$intId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($intId <= 0) {
header("Location: index.php");
exit;
}
//affichage info utilisateur
$objUserModel = new UserModel;
$arrUserData = $objUserModel->findUserById($intId);
if ($arrUserData === false) {
header("Location: index.php");
exit;
}*/
$strPseudo = $_GET['pseudo']??'';
$objUserModel = new UserModel;
$arrUserData = $objUserModel->findUserByPseudo($strPseudo);
if ($arrUserData === false) {
header("Location: index.php");
exit;
}
$objUser = new User;
$objUser->hydrate($arrUserData);
//affichage projet de l'utilisateur
$objProjectModel = new ProjectModel;
$arrProjects = $objProjectModel->findAll(0,'',$objUser->getId());
$arrProjectToDisplay = array();
foreach($arrProjects as $projectData) {
$objProject = new Project();
$objProject->hydrate($projectData);
$arrProjectToDisplay[] = $objProject;
}
$this->_arrData['user'] = $objUser;
$this->_arrData['arrProjectToDisplay'] = $arrProjectToDisplay;
$this->_display("user");
}
public function edit(){
if(!isset($_SESSION['user'])){
header("Location: index.php");
exit;
} }
$objUserModel = new UserModel; /**
$arrError = []; * Fonction de connexion d'un utilisateur
$objUser = new User; * Vérifie les informations envoyées par le formulaire
$arrUserData = $objUserModel->findUserById($_SESSION['user']['user_id']); * et crée la session si les identifiants sont valides
$objUser->hydrate($arrUserData); * @return void
if (!empty($_POST)) { */
if ($objUserModel->mailExists($_POST['user_mail']) && ($_POST['user_mail'] != $objUser->getMail())) { public function login(){
$arrError['user_mail'] = "Ce mail est déjà associé"; $strMail = $_POST['user_mail']??"";
} else { $strPwd = $_POST['user_password']??"";
if ($objUserModel->pseudoExists($_POST['user_pseudo']) && ($_POST['user_pseudo'] != $objUser->getPseudo())){
$arrError['user_pseudo'] = "Ce pseudo est déjà utiliser"; // Tester le formulaire
}else{ $arrError = [];
$objUser->hydrate($_POST); if (count($_POST) > 0) {
$objUser->setId($_SESSION['user']['user_id']); // Vérifier le formulaire
if ($strMail == ""){
// Vérification de l'image $arrError['mail'] = "L'adresse e-mail est obligatoire";
$arrTypeAllowed = array('image/jpeg', 'image/png', 'image/webp'); }
$boolImageOk = true; if ($strPwd == ""){
$arrError['pwd'] = "Le mot de passe est obligatoire";
if ($_FILES['image']['error'] != 4) { }
if (!in_array($_FILES['image']['type'], $arrTypeAllowed)) {
$arrError['image'] = "Le type de fichier n'est pas autorisé"; // Si le formulaire est rempli correctement
} else { if (count($arrError) == 0){
switch ($_FILES['image']['error']) { // Vérifier l'utilisateur en BDD
case 0: $objUserModel = new UserModel;
$strImageName = uniqid() . ".webp"; $arrResult = $objUserModel->verifUser($strMail, $strPwd);
$strOldImg = $objUser->getImage(); //var_dump($arrResult);
$objUser->setImage($strImageName); if ($arrResult === false){ // Si la base de données ne renvoie rien
break; $arrError[] = "Identifiants incorrects";
case 1: }else{
case 2: // Ajoute l'utilisateur en session
$arrError['image'] = "Le fichier est trop volumineux"; $_SESSION['user'] = $arrResult;
break; $_SESSION['success'] = "Bienvenue, vous êtes bien connecté";
case 3:
$arrError['image'] = "Le fichier a été partiellement téléchargé"; header("Location:index.php");
break; exit;
case 6:
$arrError['image'] = "Le répertoire temporaire est manquant";
break;
default:
$arrError['image'] = "Erreur sur l'image";
break;
}
}
}
// Traitement de l'image si pas d'erreur
if (count($arrError) == 0 && isset($strImageName)) {
$strDest = $_ENV['IMG_USER_PATH'] . $strImageName;
$strSource = $_FILES['image']['tmp_name'];
list($intWidth, $intHeight) = getimagesize($strSource);
$intDestWidth = 200; $intDestHeight = 200;
$fltDestRatio = $intDestWidth / $intDestHeight;
$fltSourceRatio = $intWidth / $intHeight;
if ($fltSourceRatio > $fltDestRatio) {
$intCropHeight = $intHeight;
$intCropWidth = (int)round($intHeight * $fltDestRatio);
$intCropX = (int)(($intWidth - $intCropWidth) / 2);
$intCropY = 0;
} else {
$intCropWidth = $intWidth;
$intCropHeight = (int)round($intWidth / $fltDestRatio);
$intCropX = 0;
$intCropY = (int)(($intHeight - $intCropHeight) / 2);
}
$objDest = imagecreatetruecolor($intDestWidth, $intDestHeight);
switch ($_FILES['image']['type']) {
case 'image/jpeg': $objSource = imagecreatefromjpeg($strSource); break;
case 'image/png': $objSource = imagecreatefrompng($strSource); break;
case 'image/webp': $objSource = imagecreatefromwebp($strSource); break;
}
imagecopyresampled($objDest, $objSource, 0, 0, $intCropX, $intCropY, $intDestWidth, $intDestHeight, $intCropWidth, $intCropHeight);
$boolImageOk = imagewebp($objDest, $strDest);
imagedestroy($objDest);
imagedestroy($objSource);
}
$boolInsert = $objUserModel->update($objUser);
if ($boolInsert === true) {
if (isset($strOldImg) && !empty($strOldImg) && isset($strImageName)) {
$strOldFile = $_ENV['IMG_USER_PATH'] . $strOldImg;
if (file_exists($strOldFile)) unlink($strOldFile);
}
$arrNewInfo = $objUserModel->findUserByPseudo($objUser->getPseudo());
$_SESSION['user'] = $arrNewInfo;
$_SESSION['success'] = "Compte modifier avec succès";
header("Location:?ctrl=user&action=user&pseudo=".$objUser->getPseudo());
exit;
} else {
$arrError['global'] = "Erreur lors de l'update";
}
}
} }
}
}
$this->_arrData['arrError'] = $arrError;
$this->_display("login");
}
public function logout(){
session_start();
/*session_destroy();
session_start();*/
// on supprime l'utilisateur en session
unset($_SESSION['user']);
$_SESSION['success'] = "Vous êtes bien déconnecté";
header("Location:index.php");
exit;
}
/**
* le controlleur affichage de la page user
*/
public function user(){
/**$intId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($intId <= 0) {
header("Location: index.php");
exit;
}
//affichage info utilisateur
$objUserModel = new UserModel;
$arrUserData = $objUserModel->findUserById($intId);
if ($arrUserData === false) {
header("Location: index.php");
exit;
}*/
$strPseudo = $_GET['pseudo']??'';
$objUserModel = new UserModel;
$arrUserData = $objUserModel->findUserByPseudo($strPseudo);
if ($arrUserData === false) {
header("Location: index.php");
exit;
}
$objUser = new User;
$objUser->hydrate($arrUserData);
//affichage projet de l'utilisateur
$objProjectModel = new ProjectModel;
$arrProjects = $objProjectModel->findAll(0,'',$objUser->getId());
$arrProjectToDisplay = array();
foreach($arrProjects as $projectData) {
$objProject = new Project();
$objProject->hydrate($projectData);
$arrProjectToDisplay[] = $objProject;
}
$this->_arrData['user'] = $objUser;
$this->_arrData['arrProjectToDisplay'] = $arrProjectToDisplay;
$this->_display("user");
} }
$this->_arrData["arrError"] = $arrError; public function edit(){
$this->_arrData['objUser'] = $objUser; if(!isset($_SESSION['user'])){
$this->_display("useredit"); header("Location: index.php");
exit;
}
$objUserModel = new UserModel;
$arrError = [];
$objUser = new User;
$arrUserData = $objUserModel->findUserById($_SESSION['user']['user_id']);
$objUser->hydrate($arrUserData);
if (!empty($_POST)) {
if ($objUserModel->mailExists($_POST['user_mail']) && ($_POST['user_mail'] != $objUser->getMail())) {
} $arrError['user_mail'] = "Ce mail est déjà associé";
} else {
if ($objUserModel->pseudoExists($_POST['user_pseudo']) && ($_POST['user_pseudo'] != $objUser->getPseudo())){
$arrError['user_pseudo'] = "Ce pseudo est déjà utiliser";
}else{
$objUser->hydrate($_POST);
$objUser->setId($_SESSION['user']['user_id']);
// Vérification de l'image
$arrTypeAllowed = array('image/jpeg', 'image/png', 'image/webp');
$boolImageOk = true;
if ($_FILES['image']['error'] != 4) {
if (!in_array($_FILES['image']['type'], $arrTypeAllowed)) {
$arrError['image'] = "Le type de fichier n'est pas autorisé";
} else {
switch ($_FILES['image']['error']) {
case 0:
$strImageName = uniqid() . ".webp";
$strOldImg = $objUser->getImage();
$objUser->setImage($strImageName);
break;
case 1:
case 2:
$arrError['image'] = "Le fichier est trop volumineux";
break;
case 3:
$arrError['image'] = "Le fichier a été partiellement téléchargé";
break;
case 6:
$arrError['image'] = "Le répertoire temporaire est manquant";
break;
default:
$arrError['image'] = "Erreur sur l'image";
break;
}
}
}
// Traitement de l'image si pas d'erreur
if (count($arrError) == 0 && isset($strImageName)) {
$strDest = $_ENV['IMG_USER_PATH'] . $strImageName;
$strSource = $_FILES['image']['tmp_name'];
list($intWidth, $intHeight) = getimagesize($strSource);
$intDestWidth = 200; $intDestHeight = 200;
$fltDestRatio = $intDestWidth / $intDestHeight;
$fltSourceRatio = $intWidth / $intHeight;
if ($fltSourceRatio > $fltDestRatio) {
$intCropHeight = $intHeight;
$intCropWidth = (int)round($intHeight * $fltDestRatio);
$intCropX = (int)(($intWidth - $intCropWidth) / 2);
$intCropY = 0;
} else {
$intCropWidth = $intWidth;
$intCropHeight = (int)round($intWidth / $fltDestRatio);
$intCropX = 0;
$intCropY = (int)(($intHeight - $intCropHeight) / 2);
}
$objDest = imagecreatetruecolor($intDestWidth, $intDestHeight);
switch ($_FILES['image']['type']) {
case 'image/jpeg': $objSource = imagecreatefromjpeg($strSource); break;
case 'image/png': $objSource = imagecreatefrompng($strSource); break;
case 'image/webp': $objSource = imagecreatefromwebp($strSource); break;
}
imagecopyresampled($objDest, $objSource, 0, 0, $intCropX, $intCropY, $intDestWidth, $intDestHeight, $intCropWidth, $intCropHeight);
$boolImageOk = imagewebp($objDest, $strDest);
imagedestroy($objDest);
imagedestroy($objSource);
}
$boolInsert = $objUserModel->update($objUser);
if ($boolInsert === true) {
if (isset($strOldImg) && !empty($strOldImg) && isset($strImageName)) {
$strOldFile = $_ENV['IMG_USER_PATH'] . $strOldImg;
if (file_exists($strOldFile)) unlink($strOldFile);
}
$arrNewInfo = $objUserModel->findUserByPseudo($objUser->getPseudo());
$_SESSION['user'] = $arrNewInfo;
$_SESSION['success'] = "Compte modifier avec succès";
header("Location:?ctrl=user&action=user&pseudo=".$objUser->getPseudo());
exit;
} else {
$arrError['global'] = "Erreur lors de l'update";
}
}
}
}
$this->_arrData["arrError"] = $arrError;
$this->_arrData['objUser'] = $objUser;
$this->_display("useredit");
}
} }

View file

@ -5,7 +5,7 @@
<li><a href="#">Découvrir</a> <li><a href="#">Découvrir</a>
<li><a href="#">Customisation</a> <li><a href="#">Customisation</a>
<li><a href="#">Emploi</a> <li><a href="#">Emploi</a>
<li><a href="#">A propos</a> <li><a href="?ctrl=project&action=about">A propos</a>
</ul> </ul>
</div> </div>
<div class="col-3"> <div class="col-3">
@ -19,7 +19,7 @@
<div class="col-3"> <div class="col-3">
<ul> <ul>
<li><a href="#">Politique de confidentialité</a> <li><a href="#">Politique de confidentialité</a>
<li><a href="#">Politique sur les données</a> <li><a href="?ctrl=project&action=mentions">Mentions légales</a>
<li><a href="#">CGU</a> <li><a href="#">CGU</a>
<li><a href="#">CGV</a> <li><a href="#">CGV</a>
</ul> </ul>
@ -31,4 +31,4 @@
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="js/scripts.js"></script> <script src="js/scripts.js"></script>
</body> </body>
</html> </html>

View file

@ -7,7 +7,7 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script> <script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
<title>Folliow</title> <title>Folliow{block name="title"}{/block}</title>
</head> </head>
<body class="d-flex flex-column min-vh-100"> <body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-expand-lg navbar-light"> <nav class="navbar navbar-expand-lg navbar-light">
@ -51,7 +51,7 @@
{* Utilisateur non connecté *} {* Utilisateur non connecté *}
<ul class="navbar-nav"> <ul class="navbar-nav">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="index.php?ctrl=user&action=signin" title="Créer un compte" aria-label="Créer un compte"> <a class="nav-link" href="index.php?ctrl=user&action=signup" title="Créer un compte" aria-label="Créer un compte">
S'inscrire S'inscrire
</a> </a>
</li> </li>

View file

@ -1,161 +1,160 @@
{extends file="views/layout.tpl"} {extends file="views/layout.tpl"}
{assign var='strPage' value='about'} {block name="title" append} - À propos{/block}
{block name="title" append}À propos{/block} {block name="h2"}À propos de FOLLIOW{/block}
{block name="h2"}À propos de FOLLIOW{/block} {block name="p"}Plateforme de partage de projets Projet pédagogique{/block}
{block name="p"}Plateforme de partage de projets Projet pédagogique{/block}
{block name="content"}
{block name="content"}
<section aria-label="À propos de FOLLIOW">
<section aria-label="À propos de FOLLIOW"> <div class="row g-5">
<div class="row g-5">
<!-- Présentation principale -->
<!-- Présentation principale --> <div class="col-lg-8">
<div class="col-lg-8">
<section aria-labelledby="presentation">
<section aria-labelledby="presentation"> <h3 id="presentation" class="h4 mb-3">
<h3 id="presentation" class="h4 mb-3"> <i class="fas fa-lightbulb me-2 text-primary"></i>
<i class="fas fa-lightbulb me-2 text-primary"></i> Présentation du projet
Présentation du projet </h3>
</h3>
<p>
<p> <strong>FOLLIOW</strong> est une plateforme web développée dans le cadre dun projet pédagogique.
<strong>FOLLIOW</strong> est une plateforme web développée dans le cadre dun projet pédagogique. Elle permet aux utilisateurs de publier, consulter et partager des projets numériques
Elle permet aux utilisateurs de publier, consulter et partager des projets numériques à travers une interface simple et structurée.
à travers une interface simple et structurée. </p>
</p>
<p>
<p> Ce projet a été conçu afin de mettre en pratique les compétences acquises en
Ce projet a été conçu afin de mettre en pratique les compétences acquises en développement web, notamment larchitecture MVC, la gestion des bases de données
développement web, notamment larchitecture MVC, la gestion des bases de données et la sécurisation des échanges.
et la sécurisation des échanges. </p>
</p> </section>
</section>
<section aria-labelledby="fonctionnalites" class="mt-4">
<section aria-labelledby="fonctionnalites" class="mt-4"> <h3 id="fonctionnalites" class="h4 mb-3">
<h3 id="fonctionnalites" class="h4 mb-3"> <i class="fas fa-cogs me-2 text-primary"></i>
<i class="fas fa-cogs me-2 text-primary"></i> Fonctionnalités principales
Fonctionnalités principales </h3>
</h3>
<ul>
<ul> <li>Création et gestion de projets</li>
<li>Création et gestion de projets</li> <li>Affichage dynamique des contenus</li>
<li>Affichage dynamique des contenus</li> <li>Gestion des utilisateurs</li>
<li>Gestion des utilisateurs</li> <li>Partage dun projet par email</li>
<li>Partage dun projet par email</li> <li>Interface responsive et accessible</li>
<li>Interface responsive et accessible</li> </ul>
</ul> </section>
</section>
<section aria-labelledby="objectifs" class="mt-4">
<section aria-labelledby="objectifs" class="mt-4"> <h3 id="objectifs" class="h4 mb-3">
<h3 id="objectifs" class="h4 mb-3"> <i class="fas fa-bullseye me-2 text-primary"></i>
<i class="fas fa-bullseye me-2 text-primary"></i> Objectifs pédagogiques
Objectifs pédagogiques </h3>
</h3>
<p>
<p> Lobjectif principal de FOLLIOW est de démontrer la capacité à concevoir
Lobjectif principal de FOLLIOW est de démontrer la capacité à concevoir une application web complète, structurée et sécurisée.
une application web complète, structurée et sécurisée. </p>
</p>
<ul>
<ul> <li>Structuration dun projet en architecture MVC</li>
<li>Structuration dun projet en architecture MVC</li> <li>Manipulation de bases de données relationnelles</li>
<li>Manipulation de bases de données relationnelles</li> <li>Validation et sécurisation des données</li>
<li>Validation et sécurisation des données</li> <li>Implémentation dun système denvoi demails</li>
<li>Implémentation dun système denvoi demails</li> <li>Respect des bonnes pratiques (RGPD, accessibilité, organisation du code)</li>
<li>Respect des bonnes pratiques (RGPD, accessibilité, organisation du code)</li> </ul>
</ul> </section>
</section>
<section aria-labelledby="technologies" class="mt-4">
<section aria-labelledby="technologies" class="mt-4"> <h3 id="technologies" class="h4 mb-3">
<h3 id="technologies" class="h4 mb-3"> <i class="fas fa-code me-2 text-primary"></i>
<i class="fas fa-code me-2 text-primary"></i> Technologies utilisées
Technologies utilisées </h3>
</h3>
<div class="row g-3">
<div class="row g-3"> <div class="col-md-6">
<div class="col-md-6"> <div class="card h-100 border-0 shadow-sm">
<div class="card h-100 border-0 shadow-sm"> <div class="card-body">
<div class="card-body"> <strong>Backend</strong>
<strong>Backend</strong> <p class="small mb-0">
<p class="small mb-0"> PHP orienté objet Architecture MVC MySQL
PHP orienté objet Architecture MVC MySQL </p>
</p> </div>
</div> </div>
</div> </div>
</div>
<div class="col-md-6">
<div class="col-md-6"> <div class="card h-100 border-0 shadow-sm">
<div class="card h-100 border-0 shadow-sm"> <div class="card-body">
<div class="card-body"> <strong>Frontend</strong>
<strong>Frontend</strong> <p class="small mb-0">
<p class="small mb-0"> HTML5 CSS3 Bootstrap Smarty
HTML5 CSS3 Bootstrap Smarty </p>
</p> </div>
</div> </div>
</div> </div>
</div>
<div class="col-md-6">
<div class="col-md-6"> <div class="card h-100 border-0 shadow-sm">
<div class="card h-100 border-0 shadow-sm"> <div class="card-body">
<div class="card-body"> <strong>Emails</strong>
<strong>Emails</strong> <p class="small mb-0">
<p class="small mb-0"> PHPMailer SMTP Brevo
PHPMailer SMTP Brevo </p>
</p> </div>
</div> </div>
</div> </div>
</div>
<div class="col-md-6">
<div class="col-md-6"> <div class="card h-100 border-0 shadow-sm">
<div class="card h-100 border-0 shadow-sm"> <div class="card-body">
<div class="card-body"> <strong>Sécurité</strong>
<strong>Sécurité</strong> <p class="small mb-0">
<p class="small mb-0"> Validation des données Protection des formulaires Gestion des sessions
Validation des données Protection des formulaires Gestion des sessions </p>
</p> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </section>
</section>
</div>
</div>
<!-- Sidebar -->
<!-- Sidebar --> <div class="col-lg-4">
<div class="col-lg-4"> <div class="card shadow-sm p-4">
<div class="card shadow-sm p-4">
<h4 class="h5 mb-3">
<h4 class="h5 mb-3"> <i class="fas fa-graduation-cap me-2 text-primary"></i>
<i class="fas fa-graduation-cap me-2 text-primary"></i> Projet pédagogique
Projet pédagogique </h4>
</h4>
<p class="small">
<p class="small"> FOLLIOW a été réalisé dans le cadre dune formation en développement web.
FOLLIOW a été réalisé dans le cadre dune formation en développement web. Il sagit dun projet démonstratif à visée éducative.
Il sagit dun projet démonstratif à visée éducative. </p>
</p>
<hr>
<hr>
<h4 class="h5 mb-3">
<h4 class="h5 mb-3"> <i class="fas fa-envelope me-2 text-primary"></i>
<i class="fas fa-envelope me-2 text-primary"></i> Contact
Contact </h4>
</h4>
<p class="small mb-1">
<p class="small mb-1"> Pour toute question :
Pour toute question : </p>
</p>
<a href="mailto:projet.folliow@hotmail.com" class="small">
<a href="mailto:projet.folliow@hotmail.com" class="small"> projet.folliow@hotmail.com
projet.folliow@hotmail.com </a>
</a>
</div>
</div> </div>
</div>
</div>
</div> </section>
</section>
{/block} {/block}

View file

@ -1,197 +0,0 @@
{extends file="views/layout.tpl"}
{block name="content"}
<!-- Page : Inscription -->
<main class="container py-5">
<!-- Centrage horizontal du formulaire -->
<div class="row justify-content-center position-relative">
<div class="col-12 col-md-10 col-lg-6">
<!-- Carte contenant le formulaire d'inscription -->
<div class="card shadow-sm border-0 rounded-4 p-4 p-lg-5">
<!-- Titre principal de la page -->
<h1 class="h3 fw-bold mb-1">Inscription</h1>
<!-- Texte descriptif -->
<p class="text-secondary mb-4">
Créez votre compte utilisateur.
</p>
{if (isset($arrError) && count($arrError) > 0) }
<div class="alert alert-danger">
{foreach $arrError as $strError}
<p>{$strError}</p>
{/foreach}
</div>
{/if}
<!-- Formulaire d'inscription -->
<!-- Les données seront traitées côté serveur en PHP via la méthode POST -->
<form method="POST">
<div class="row g-3">
<!-- Champ : prénom de l'utilisateur -->
<div class="col-md-6">
<label class="form-label" for="user_firstname">
Prénom *
</label>
<input
class="form-control"
type="text"
id="user_firstname"
name="user_firstname"
required >
</div>
<!-- Champ : nom de l'utilisateur -->
<div class="col-md-6">
<label class="form-label" for="user_name">
Nom *
</label>
<input
class="form-control"
type="text"
id="user_name"
name="user_name"
required
>
</div>
<!-- Champ : pseudo -->
<div class="col-12">
<label class="form-label" for="user_pseudo">
Pseudo *
</label>
<div class="input-group">
<span class="input-group-text">@</span>
<input
class="form-control"
type="text"
id="user_pseudo"
name="user_pseudo"
required
>
</div>
</div>
<!-- Champ : adresse e-mail -->
<div class="col-12">
<label class="form-label" for="user_mail">
Adresse e-mail *
</label>
<input
class="form-control"
type="email"
id="user_mail"
name="user_mail"
required
>
</div>
<!-- Champ : mot de passe -->
<div class="col-12">
<label class="form-label" for="user_password">
Mot de passe *
</label>
<input
class="form-control"
type="password"
id="user_password"
name="user_password"
required
>
</div>
<!-- Champ : confirmer le mot de passe -->
<div class="col-12">
<label class="form-label" for="pwd_confirm">
Confirmer le Mot de passe *
</label>
<input
class="form-control"
type="password"
id="pwd_confirm"
name="pwd_confirm"
required
>
</div>
<!-- Champ optionnel : numéro de téléphone -->
<div class="col-12">
<label class="form-label" for="user_phone">
Téléphone
</label>
<input
class="form-control"
type="text"
id="user_phone"
name="user_phone"
>
</div>
<!-- Champ optionnel : profession de l'utilisateur -->
<div class="col-12">
<label class="form-label" for="user_work">
Profession
</label>
<input
class="form-control"
type="text"
id="user_work"
name="user_work"
>
</div>
<!-- Champ optionnel : localisation de l'utilisateur -->
<div class="col-12">
<label class="form-label" for="user_location">
Localisation
</label>
<input
class="form-control"
type="text"
id="user_location"
name="user_location"
>
</div>
<!-- Champ optionnel : phrase d'accroche -->
<div class="col-12">
<label class="form-label" for="user_description">
Phrase d'accroche
</label>
<textarea
class="form-control"
id="user_description"
name="user_description"
rows="3"
></textarea>
</div>
<!-- Bouton de soumission du formulaire -->
<div class="col-12 d-grid mt-2">
<button type="submit" class="btn btn-primary btn-lg rounded-3">
Créer mon compte
</button>
</div>
<!-- Lien vers la page de connexion -->
<div class="col-12 text-center">
<small class="text-secondary">
Déjà un compte ?
<a href="index.php?ctrl=user&action=login">Se connecter</a>
</small>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
{/block}

View file

@ -1,42 +1,28 @@
{extends file="views/layout.tpl"} {extends file="views/layout.tpl"}
{block name="title" append} - Connexion{/block}
{block name="content"} {block name="content"}
<section aria-label="Se connecter"> <section aria-label="Se connecter">
{* Affichage des erreurs *}
{if $arrError|count > 0}
<div class="alert alert-danger">
{foreach from=$arrError item=strError}
<p>{$strError}</p>
{/foreach}
</div>
{/if}
<!-- Contenu principal de la page -->
<main class="container py-5">
<!-- Centrage horizontal du formulaire --> <div class="py-5">
<div class="row justify-content-center"> <!-- Centrage horizontal du formulaire -->
<!-- Contenu principal de la page --> <div class="row justify-content-center">
<main class="container py-5">
<!-- Centrage horizontal du formulaire -->
<div class="row justify-content-center">
<div class="col-12 col-md-8 col-lg-5"> <div class="col-12 col-md-8 col-lg-5">
<!-- Carte contenant le formulaire de connexion --> <!-- Carte contenant le formulaire de connexion -->
<div class="card shadow-sm border-0 rounded-4 p-4 p-lg-5"> <div class="card shadow-sm border-0 rounded-4 p-4 p-lg-5">
<!-- Titre principal --> <!-- Titre principal -->
<h1 class="h3 fw-bold mb-1">Connexion</h1> <h1 class="h3 fw-bold mb-1">Connexion</h1>
<!-- Texte descriptif --> <!-- Texte descriptif -->
<p class="text-secondary mb-4"> <p class="text-secondary mb-4">
Connectez-vous à votre compte. Connectez-vous à votre compte.
</p> </p>
<!-- Formulaire de connexion --> <!-- Formulaire de connexion -->
<!-- Le traitement sera effectué en PHP via la méthode POST --> <!-- Le traitement sera effectué en PHP via la méthode POST -->
<form method="POST"> <form method="POST">
<div class="row g-3"> <div class="row g-3">
<!-- Champ : adresse e-mail de l'utilisateur --> <!-- Champ : adresse e-mail de l'utilisateur -->
@ -45,13 +31,12 @@
Adresse e-mail Adresse e-mail
</label> </label>
<input <input
value="{$strMail|default:''}" value="{$strMail|default:''}"
type="email" type="email"
class="form-control {if isset($arrError.mail)}is-invalid{/if}" class="form-control {if isset($arrError.user_mail)}is-invalid{/if}"
id="user_mail" id="user_mail"
name="user_mail" name="user_mail"
required required
> >
</div> </div>
@ -62,24 +47,13 @@
</label> </label>
<input <input
type="password" type="password"
class="form-control {if isset($arrError.pwd)}is-invalid{/if}" class="form-control {if isset($arrError.user_password)}is-invalid{/if}"
id="user_password" id="user_password"
name="user_password" name="user_password"
required required
> >
</div> </div>
<!-- Option "Se souvenir de moi" (fonctionnalité optionnelle côté PHP) -->
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="remember_me" name="remember_me">
<label class="form-check-label" for="remember_me">
Se souvenir de moi
</label>
</div>
</div>
<!-- Bouton de soumission du formulaire --> <!-- Bouton de soumission du formulaire -->
<div class="col-12 d-grid mt-2"> <div class="col-12 d-grid mt-2">
<button type="submit" class="btn btn-primary btn-lg rounded-3"> <button type="submit" class="btn btn-primary btn-lg rounded-3">
@ -91,15 +65,8 @@
<div class="col-12 text-center"> <div class="col-12 text-center">
<small class="text-secondary"> <small class="text-secondary">
Pas encore de compte ? Pas encore de compte ?
<a href="index.php?ctrl=user&action=signin" class="link-primary">Créer un compte</a> <a href="index.php?ctrl=user&action=signup" class="link-primary">
</small> Créer un compte
</div>
<!-- Lien pour la récupération du mot de passe -->
<div class="col-12 text-center">
<small>
<a href="#" class="link-primary">
Mot de passe oublié ?
</a> </a>
</small> </small>
</div> </div>
@ -110,7 +77,8 @@
</div> </div>
</div> </div>
</div> </div>
</main> </div>
</section> </section>
{/block} {/block}

View file

@ -1,287 +1,288 @@
{extends file="views/layout.tpl"} {extends file="views/layout.tpl"}
{block name="title" append}Mentions légales{/block} {block name="title" append} - Mentions légales{/block}
{block name="h2"}Mentions légales{/block}
{block name="p"}Informations légales et politique de confidentialité{/block} {block name="h2"}Mentions légales{/block}
{block name="p"}Informations légales et politique de confidentialité{/block}
{block name="date_maj"}
<p class="text-muted small mb-0"> {block name="date_maj"}
<i class="fas fa-calendar-alt me-2" aria-hidden="true"></i> <p class="text-muted small mb-0">
Dernière mise à jour : <time datetime="2026-02-20">20 février 2026</time> <i class="fas fa-calendar-alt me-2" aria-hidden="true"></i>
</p> Dernière mise à jour : <time datetime="2026-02-20">20 février 2026</time>
{/block} </p>
{/block}
{block name="js_footer" append}
<script> {block name="js_footer" append}
{literal} <script>
document.querySelectorAll('a[href^="#"]').forEach(anchor => { {literal}
anchor.addEventListener('click', function (e) { document.querySelectorAll('a[href^="#"]').forEach(anchor => {
e.preventDefault(); anchor.addEventListener('click', function (e) {
const target = document.querySelector(this.getAttribute('href')); e.preventDefault();
if (target) { const target = document.querySelector(this.getAttribute('href'));
target.scrollIntoView({ if (target) {
behavior: 'smooth', target.scrollIntoView({
block: 'start' behavior: 'smooth',
}); block: 'start'
target.focus(); });
} target.focus();
}); }
}); });
{/literal} });
</script> {/literal}
{/block} </script>
{/block}
{block name="content"}
<section aria-label="Mentions légales"> {block name="content"}
<h2 class="visually-hidden">Mentions légales</h2> <section aria-label="Mentions légales">
<h2 class="visually-hidden">Mentions légales</h2>
<div class="row g-5">
<div class="col-md-12"> <div class="row g-5">
<div class="col-md-12">
<!-- Table des matières -->
<nav class="table-of-contents" aria-labelledby="toc-heading"> <!-- Table des matières -->
<h3 id="toc-heading" class="h5 mb-3"> <nav class="table-of-contents" aria-labelledby="toc-heading">
<i class="fas fa-list me-2" aria-hidden="true"></i> <h3 id="toc-heading" class="h5 mb-3">
Sommaire <i class="fas fa-list me-2" aria-hidden="true"></i>
</h3> Sommaire
<ul class="list-unstyled ms-3"> </h3>
<li class="mb-2"><a href="#editeur">1. Éditeur du site</a></li> <ul class="list-unstyled ms-3">
<li class="mb-2"><a href="#hebergeur">2. Hébergement</a></li> <li class="mb-2"><a href="#editeur">1. Éditeur du site</a></li>
<li class="mb-2"><a href="#propriete">3. Propriété intellectuelle</a></li> <li class="mb-2"><a href="#hebergeur">2. Hébergement</a></li>
<li class="mb-2"><a href="#rgpd">4. Protection des données personnelles (RGPD)</a></li> <li class="mb-2"><a href="#propriete">3. Propriété intellectuelle</a></li>
<li class="mb-2"><a href="#cookies">5. Cookies</a></li> <li class="mb-2"><a href="#rgpd">4. Protection des données personnelles (RGPD)</a></li>
<li class="mb-2"><a href="#responsabilite">6. Limitation de responsabilité</a></li> <li class="mb-2"><a href="#cookies">5. Cookies</a></li>
<li class="mb-2"><a href="#liens">7. Liens hypertextes</a></li> <li class="mb-2"><a href="#responsabilite">6. Limitation de responsabilité</a></li>
<li class="mb-2"><a href="#droit">8. Droit applicable</a></li> <li class="mb-2"><a href="#liens">7. Liens hypertextes</a></li>
</ul> <li class="mb-2"><a href="#droit">8. Droit applicable</a></li>
</nav> </ul>
</nav>
<!-- Section 1 : Éditeur -->
<section id="editeur" class="legal-section" aria-labelledby="editeur-heading"> <!-- Section 1 : Éditeur -->
<h3 id="editeur-heading" class="h4"> <section id="editeur" class="legal-section" aria-labelledby="editeur-heading">
<i class="fas fa-building me-2 text-primary" aria-hidden="true"></i> <h3 id="editeur-heading" class="h4">
1. Éditeur du site <i class="fas fa-building me-2 text-primary" aria-hidden="true"></i>
</h3> 1. Éditeur du site
</h3>
<p class="text-muted">
FOLLIOW est un <strong>projet pédagogique</strong> réalisé dans le cadre dun exercice de formation. <p class="text-muted">
</p> FOLLIOW est un <strong>projet pédagogique</strong> réalisé dans le cadre dun exercice de formation.
</p>
<dl class="row">
<dt class="col-sm-3">Nom du projet</dt> <dl class="row">
<dd class="col-sm-9">FOLLIOW</dd> <dt class="col-sm-3">Nom du projet</dt>
<dd class="col-sm-9">FOLLIOW</dd>
<dt class="col-sm-3">Nature</dt>
<dd class="col-sm-9">Projet scolaire / démonstration technique</dd> <dt class="col-sm-3">Nature</dt>
<dd class="col-sm-9">Projet scolaire / démonstration technique</dd>
<dt class="col-sm-3">Établissement</dt>
<dd class="col-sm-9">FOLLIOW</dd> <dt class="col-sm-3">Établissement</dt>
<dd class="col-sm-9">FOLLIOW</dd>
<dt class="col-sm-3">Forme juridique</dt>
<dd class="col-sm-9">Non applicable (projet pédagogique)</dd> <dt class="col-sm-3">Forme juridique</dt>
<dd class="col-sm-9">Non applicable (projet pédagogique)</dd>
<dt class="col-sm-3">Capital social</dt>
<dd class="col-sm-9">Non applicable</dd> <dt class="col-sm-3">Capital social</dt>
<dd class="col-sm-9">Non applicable</dd>
<dt class="col-sm-3">Adresse</dt>
<dd class="col-sm-9">4 Rue du Rhin, 68000 Colmar</dd> <dt class="col-sm-3">Adresse</dt>
<dd class="col-sm-9">4 Rue du Rhin, 68000 Colmar</dd>
<dt class="col-sm-3">Téléphone</dt>
<dd class="col-sm-9">03 68 67 20 00</dd> <dt class="col-sm-3">Téléphone</dt>
<dd class="col-sm-9">03 68 67 20 00</dd>
<dt class="col-sm-3">Email</dt>
<dd class="col-sm-9"> <dt class="col-sm-3">Email</dt>
<a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a> <dd class="col-sm-9">
</dd> <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a>
</dd>
<dt class="col-sm-3">Directeur de publication</dt>
<dd class="col-sm-9">Léquipe du projet FOLLIOW</dd> <dt class="col-sm-3">Directeur de publication</dt>
<dd class="col-sm-9">Léquipe du projet FOLLIOW</dd>
<dt class="col-sm-3">SIRET</dt>
<dd class="col-sm-9">Non applicable (projet scolaire)</dd> <dt class="col-sm-3">SIRET</dt>
</dl> <dd class="col-sm-9">Non applicable (projet scolaire)</dd>
</section> </dl>
</section>
<!-- Section 2 : Hébergeur -->
<section id="hebergeur" class="legal-section" aria-labelledby="hebergeur-heading"> <!-- Section 2 : Hébergeur -->
<h3 id="hebergeur-heading" class="h4"> <section id="hebergeur" class="legal-section" aria-labelledby="hebergeur-heading">
<i class="fas fa-server me-2 text-primary" aria-hidden="true"></i> <h3 id="hebergeur-heading" class="h4">
2. Hébergement <i class="fas fa-server me-2 text-primary" aria-hidden="true"></i>
</h3> 2. Hébergement
</h3>
<p>Le site est hébergé sur une infrastructure pédagogique mise à disposition pour le projet :</p>
<p>Le site est hébergé sur une infrastructure pédagogique mise à disposition pour le projet :</p>
<dl class="row">
<dt class="col-sm-3">Hébergeur</dt> <dl class="row">
<dd class="col-sm-9">OVH<dd> <dt class="col-sm-3">Hébergeur</dt>
<dd class="col-sm-9">OVH<dd>
<dt class="col-sm-3">Domaine / accès</dt>
<dd class="col-sm-9">php.boulayoune.com</dd> <dt class="col-sm-3">Domaine / accès</dt>
<dd class="col-sm-9">php.boulayoune.com</dd>
<dt class="col-sm-3">Adresse</dt>
<dd class="col-sm-9">4 Rue du Rhin, 68000 Colmar</dd> <dt class="col-sm-3">Adresse</dt>
<dd class="col-sm-9">4 Rue du Rhin, 68000 Colmar</dd>
<dt class="col-sm-3">Téléphone</dt>
<dd class="col-sm-9">03 68 67 20 00</dd> <dt class="col-sm-3">Téléphone</dt>
</dl> <dd class="col-sm-9">03 68 67 20 00</dd>
</section> </dl>
</section>
<!-- Section 3 : Propriété intellectuelle -->
<section id="propriete" class="legal-section" aria-labelledby="propriete-heading"> <!-- Section 3 : Propriété intellectuelle -->
<h3 id="propriete-heading" class="h4"> <section id="propriete" class="legal-section" aria-labelledby="propriete-heading">
<i class="fas fa-copyright me-2 text-primary" aria-hidden="true"></i> <h3 id="propriete-heading" class="h4">
3. Propriété intellectuelle <i class="fas fa-copyright me-2 text-primary" aria-hidden="true"></i>
</h3> 3. Propriété intellectuelle
<p> </h3>
Sauf mention contraire, lensemble des contenus présents sur FOLLIOW (textes, visuels, logo, éléments dinterface) <p>
est utilisé dans le cadre du projet et reste la propriété de leurs auteurs respectifs. Sauf mention contraire, lensemble des contenus présents sur FOLLIOW (textes, visuels, logo, éléments dinterface)
</p> est utilisé dans le cadre du projet et reste la propriété de leurs auteurs respectifs.
<p> </p>
Toute reproduction ou réutilisation à des fins commerciales est interdite sans autorisation préalable. <p>
</p> Toute reproduction ou réutilisation à des fins commerciales est interdite sans autorisation préalable.
<p> </p>
Les éventuels contenus tiers (images, icônes, bibliothèques) restent soumis à leurs licences dorigine. <p>
</p> Les éventuels contenus tiers (images, icônes, bibliothèques) restent soumis à leurs licences dorigine.
</section> </p>
</section>
<!-- Section 4 : RGPD -->
<section id="rgpd" class="legal-section" aria-labelledby="rgpd-heading"> <!-- Section 4 : RGPD -->
<h3 id="rgpd-heading" class="h4"> <section id="rgpd" class="legal-section" aria-labelledby="rgpd-heading">
<i class="fas fa-shield-alt me-2 text-primary" aria-hidden="true"></i> <h3 id="rgpd-heading" class="h4">
4. Protection des données personnelles (RGPD) <i class="fas fa-shield-alt me-2 text-primary" aria-hidden="true"></i>
</h3> 4. Protection des données personnelles (RGPD)
</h3>
<h4 class="h5 mt-4">4.1 Responsable du traitement</h4>
<p> <h4 class="h5 mt-4">4.1 Responsable du traitement</h4>
Le responsable du traitement est léquipe du projet FOLLIOW (projet pédagogique). <p>
</p> Le responsable du traitement est léquipe du projet FOLLIOW (projet pédagogique).
</p>
<h4 class="h5 mt-4">4.2 Données collectées</h4>
<p>Selon lutilisation du site, les données pouvant être collectées sont :</p> <h4 class="h5 mt-4">4.2 Données collectées</h4>
<ul> <p>Selon lutilisation du site, les données pouvant être collectées sont :</p>
<li>Nom / Prenom <li> <ul>
<li>Pseudo </li> <li>Nom / Prenom <li>
<li>Adresse email (inscription, connexion, partage de projet par email)</li> <li>Pseudo </li>
<li>Contenus déposés par lutilisateur (projets, descriptions, images)</li> <li>Adresse email (inscription, connexion, partage de projet par email)</li>
<li>Données techniques minimales (logs de sécurité, adresse IP) à des fins de protection et de diagnostic</li> <li>Contenus déposés par lutilisateur (projets, descriptions, images)</li>
</ul> <li>Données techniques minimales (logs de sécurité, adresse IP) à des fins de protection et de diagnostic</li>
</ul>
<h4 class="h5 mt-4">4.3 Finalités du traitement</h4>
<ul> <h4 class="h5 mt-4">4.3 Finalités du traitement</h4>
<li>Création et gestion de compte</li> <ul>
<li>Publication et affichage de projets</li> <li>Création et gestion de compte</li>
<li>Partage dun projet par email à la demande de lutilisateur</li> <li>Publication et affichage de projets</li>
<li>Sécurisation du site et prévention des abus</li> <li>Partage dun projet par email à la demande de lutilisateur</li>
</ul> <li>Sécurisation du site et prévention des abus</li>
</ul>
<h4 class="h5 mt-4">4.4 Durée de conservation</h4>
<p> <h4 class="h5 mt-4">4.4 Durée de conservation</h4>
Dans le cadre de ce projet pédagogique, les données sont conservées pendant la durée du projet et des évaluations, <p>
puis supprimées ou anonymisées, sauf obligation légale contraire. Dans le cadre de ce projet pédagogique, les données sont conservées pendant la durée du projet et des évaluations,
</p> puis supprimées ou anonymisées, sauf obligation légale contraire.
</p>
<h4 class="h5 mt-4">4.5 Vos droits</h4>
<p>Conformément au RGPD, vous disposez de droits daccès, de rectification, deffacement et dopposition.</p> <h4 class="h5 mt-4">4.5 Vos droits</h4>
<p> <p>Conformément au RGPD, vous disposez de droits daccès, de rectification, deffacement et dopposition.</p>
Pour exercer ces droits, contactez-nous à : <p>
<a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a> Pour exercer ces droits, contactez-nous à :
</p> <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a>
<p> </p>
Vous pouvez également introduire une réclamation auprès de la CNIL <p>
(<a href="https://www.cnil.fr" target="_blank" rel="noopener">www.cnil.fr</a>). Vous pouvez également introduire une réclamation auprès de la CNIL
</p> (<a href="https://www.cnil.fr" target="_blank" rel="noopener">www.cnil.fr</a>).
</section> </p>
</section>
<!-- Section 5 : Cookies -->
<section id="cookies" class="legal-section" aria-labelledby="cookies-heading"> <!-- Section 5 : Cookies -->
<h3 id="cookies-heading" class="h4"> <section id="cookies" class="legal-section" aria-labelledby="cookies-heading">
<i class="fas fa-cookie-bite me-2 text-primary" aria-hidden="true"></i> <h3 id="cookies-heading" class="h4">
5. Cookies <i class="fas fa-cookie-bite me-2 text-primary" aria-hidden="true"></i>
</h3> 5. Cookies
</h3>
<p>
FOLLIOW peut utiliser des cookies <strong>strictement nécessaires</strong> au fonctionnement du site <p>
(ex : session de connexion). Aucun cookie publicitaire nest utilisé. FOLLIOW peut utiliser des cookies <strong>strictement nécessaires</strong> au fonctionnement du site
</p> (ex : session de connexion). Aucun cookie publicitaire nest utilisé.
</p>
<h4 class="h5 mt-4">5.1 Quest-ce quun cookie ?</h4>
<p> <h4 class="h5 mt-4">5.1 Quest-ce quun cookie ?</h4>
Un cookie est un petit fichier texte déposé sur votre appareil lors de la visite dun site. <p>
Il permet notamment de conserver une session ou des préférences. Un cookie est un petit fichier texte déposé sur votre appareil lors de la visite dun site.
</p> Il permet notamment de conserver une session ou des préférences.
</p>
<h4 class="h5 mt-4">5.2 Types de cookies utilisés</h4>
<ul> <h4 class="h5 mt-4">5.2 Types de cookies utilisés</h4>
<li><strong>Cookies techniques</strong> : indispensables (session, sécurité)</li> <ul>
<li><strong>Cookies de préférence</strong> : éventuels (langue, affichage) si implémentés</li> <li><strong>Cookies techniques</strong> : indispensables (session, sécurité)</li>
</ul> <li><strong>Cookies de préférence</strong> : éventuels (langue, affichage) si implémentés</li>
</ul>
<h4 class="h5 mt-4">5.3 Gestion des cookies</h4>
<p> <h4 class="h5 mt-4">5.3 Gestion des cookies</h4>
Vous pouvez configurer votre navigateur pour refuser les cookies. Certaines fonctionnalités du site <p>
peuvent alors ne pas fonctionner correctement. Vous pouvez configurer votre navigateur pour refuser les cookies. Certaines fonctionnalités du site
</p> peuvent alors ne pas fonctionner correctement.
</section> </p>
</section>
<!-- Section 6 : Limitation de responsabilité -->
<section id="responsabilite" class="legal-section" aria-labelledby="responsabilite-heading"> <!-- Section 6 : Limitation de responsabilité -->
<h3 id="responsabilite-heading" class="h4"> <section id="responsabilite" class="legal-section" aria-labelledby="responsabilite-heading">
<i class="fas fa-exclamation-triangle me-2 text-primary" aria-hidden="true"></i> <h3 id="responsabilite-heading" class="h4">
6. Limitation de responsabilité <i class="fas fa-exclamation-triangle me-2 text-primary" aria-hidden="true"></i>
</h3> 6. Limitation de responsabilité
<p> </h3>
Les informations présentées sur FOLLIOW sont fournies à titre démonstratif dans le cadre dun projet pédagogique. <p>
Léquipe sefforce de maintenir le site accessible, sans garantie dabsence derreurs ou dinterruptions. Les informations présentées sur FOLLIOW sont fournies à titre démonstratif dans le cadre dun projet pédagogique.
</p> Léquipe sefforce de maintenir le site accessible, sans garantie dabsence derreurs ou dinterruptions.
<p> </p>
Léquipe FOLLIOW ne pourra être tenue responsable des dommages directs ou indirects résultant de lutilisation du site, <p>
notamment en cas dindisponibilité ou de perte de données. Léquipe FOLLIOW ne pourra être tenue responsable des dommages directs ou indirects résultant de lutilisation du site,
</p> notamment en cas dindisponibilité ou de perte de données.
</section> </p>
</section>
<!-- Section 7 : Liens hypertextes -->
<section id="liens" class="legal-section" aria-labelledby="liens-heading"> <!-- Section 7 : Liens hypertextes -->
<h3 id="liens-heading" class="h4"> <section id="liens" class="legal-section" aria-labelledby="liens-heading">
<i class="fas fa-link me-2 text-primary" aria-hidden="true"></i> <h3 id="liens-heading" class="h4">
7. Liens hypertextes <i class="fas fa-link me-2 text-primary" aria-hidden="true"></i>
</h3> 7. Liens hypertextes
<p> </h3>
Le site peut contenir des liens vers des sites tiers. FOLLIOW nexerce aucun contrôle sur ces sites et décline toute <p>
responsabilité quant à leur contenu ou leur disponibilité. Le site peut contenir des liens vers des sites tiers. FOLLIOW nexerce aucun contrôle sur ces sites et décline toute
</p> responsabilité quant à leur contenu ou leur disponibilité.
</section> </p>
</section>
<!-- Section 8 : Droit applicable -->
<section id="droit" class="legal-section" aria-labelledby="droit-heading"> <!-- Section 8 : Droit applicable -->
<h3 id="droit-heading" class="h4"> <section id="droit" class="legal-section" aria-labelledby="droit-heading">
<i class="fas fa-gavel me-2 text-primary" aria-hidden="true"></i> <h3 id="droit-heading" class="h4">
8. Droit applicable et juridiction compétente <i class="fas fa-gavel me-2 text-primary" aria-hidden="true"></i>
</h3> 8. Droit applicable et juridiction compétente
<p> </h3>
Les présentes mentions légales sont régies par le droit français. En cas de litige, et à défaut daccord amiable, <p>
les tribunaux français seront seuls compétents. Les présentes mentions légales sont régies par le droit français. En cas de litige, et à défaut daccord amiable,
</p> les tribunaux français seront seuls compétents.
</section> </p>
</section>
<!-- Contact -->
<section class="mt-5 p-4 bg-light rounded" aria-labelledby="contact-legal"> <!-- Contact -->
<h3 id="contact-legal" class="h4 mb-3"> <section class="mt-5 p-4 bg-light rounded" aria-labelledby="contact-legal">
<i class="fas fa-envelope me-2 text-primary" aria-hidden="true"></i> <h3 id="contact-legal" class="h4 mb-3">
Questions ou réclamations <i class="fas fa-envelope me-2 text-primary" aria-hidden="true"></i>
</h3> Questions ou réclamations
<p> </h3>
Pour toute question concernant ces mentions légales ou pour exercer vos droits, vous pouvez nous contacter : <p>
</p> Pour toute question concernant ces mentions légales ou pour exercer vos droits, vous pouvez nous contacter :
<ul class="list-unstyled"> </p>
<li class="mb-2"> <ul class="list-unstyled">
<i class="fas fa-envelope me-2" aria-hidden="true"></i> <li class="mb-2">
Par email : <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a> <i class="fas fa-envelope me-2" aria-hidden="true"></i>
</li> Par email : <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a>
</li>
</ul>
</section> </ul>
</section>
</div>
</div> </div>
</section> </div>
{/block} </section>
{/block}

View file

@ -1,118 +1,96 @@
{extends file="views/layout.tpl"} {extends file="views/layout.tpl"}
{block name="title" append} - Portfolio{/block}
{block name="content"} {block name="content"}
<main class="container mt-5 py-5"> <div class="mt-5">
<!-- Message après l'envoi d'email --> <!-- Message après l'envoi d'email -->
{if isset($smarty.get.mail) && $smarty.get.mail === 'ok'} {if isset($smarty.get.mail) && $smarty.get.mail === 'ok'}
<div class="alert alert-success">Email envoyé avec succès.</div> <div class="alert alert-success">Email envoyé avec succès.</div>
{elseif isset($smarty.get.mail) && $smarty.get.mail === 'fail'} {elseif isset($smarty.get.mail) && $smarty.get.mail === 'fail'}
<div class="alert alert-danger">Erreur lors de l'envoi de l'email.</div> <div class="alert alert-danger">Erreur lors de l'envoi de l'email.</div>
{/if} {/if}
<div class="row g-4"> <div class="row g-4">
<!-- Contenu principal du projet --> <!-- Contenu principal du projet -->
<div class="col-lg-8"> <div class="col-lg-8">
<h1 class="fw-bold">{$objProject->getTitle()}</h1> <h1 class="fw-bold">{$objProject->getTitle()}</h1>
<p class="text-muted"> <p class="text-muted">
{$arrProject.category_name ?? 'Général'} {$arrProject.category_name ?? 'Général'}
</p> </p>
<div class="mb-4 shadow-sm"> <div class="mb-4 shadow-sm">
<img src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}" <img
class="img-fluid rounded w-100"> src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}"
</div> class="img-fluid rounded w-100"
alt="Aperçu du projet"
>
</div>
<div class="bg-light p-4 rounded mb-4"> <div class="bg-light p-4 rounded mb-4">
<h4 class="border-bottom pb-2">Description</h4> <h4 class="border-bottom pb-2">Description</h4>
<p class="lead">{$objProject->getDescription()}</p> <p class="lead">{$objProject->getDescription()}</p>
<div class="mt-4"> <div class="mt-4">
{$objProject->getContent()} {$objProject->getContent()}
</div> </div>
</div> </div>
<!-- Images du projet -->
<section id="galerie-projet">
<h2>Galerie du projet</h2>
<div class="row">
{foreach $arrImages as $image}
{* On affiche l'image si elle est approuvée OU si l'utlilisateur possède le projet OU si l'utlilisateur est Modérateur*}
{if ($image.image_status == 'approuvé') ||
(isset($smarty.session.user) && $smarty.session.user.user_status == 2) ||
(isset($smarty.session.user) && $smarty.session.user.user_id == $objProject->getUser_id())}
<div class="col-md-4 mb-4">
<div class="card {if $image.image_status != 'approuvé'}border-warning shadow-none opacity-75{/if}">
<img src="{$smarty.env.IMG_PROJECT_PATH}{$image.image_name}" class="card-img-top" alt="{$image.image_alt}">
{* Visible uniquement par le modérateur *} <!-- Formulaire qui envoie la demande au contrôleur (shareProject) -->
{if isset($smarty.session.user.user_status) && $smarty.session.user.user_status == 2} <div class="card shadow-sm p-4 mb-5">
<div class="moderator-tools border-top pt-2 mt-2"> <form method="post" action="index.php?ctrl=project&action=shareProject">
<div class="d-flex gap-2">
<a href="index.php?ctrl=project&action=change_image_status&id_img={$image.image_id}&status=approuvé"
class="btn btn-sm btn-success">Valider</a>
<a href="index.php?ctrl=project&action=delete_image&id_img={$image.image_id}"
class="btn btn-sm btn-outline-danger"
onclick="return confirm('Supprimer définitivement ?')">Supprimer</a>
</div>
</div>
{/if}
</div>
</div>
{/if}
{foreachelse}
<p>Aucune image disponible pour ce projet.</p>
{/foreach}
</div>
</section>
<!-- Formulaire qui envoie la demande au contrôleur (shareProject) -->
<div class="card shadow-sm p-4 mb-5">
<form method="post" action="index.php?ctrl=project&action=shareProject">
<input type="hidden" name="project_id" <input
value="{$objProject->getId()}"> type="hidden"
name="project_id"
value="{$objProject->getId()}"
>
<input type="email" name="to_email" <input
class="form-control mb-3" type="email"
placeholder="Adresse email" required> name="to_email"
class="form-control mb-3"
placeholder="Adresse email"
required
>
<button type="submit" class="btn btn-primary w-100"> <button type="submit" class="btn btn-primary w-100">
Envoyer par email Envoyer par email
</button> </button>
</form> </form>
</div> </div>
</div> </div>
<!-- Sidebar : informations du créateur --> <!-- Sidebar : informations du créateur -->
<div class="col-lg-4"> <div class="col-lg-4">
<div class="card text-center shadow-sm p-4">
<a href="index.php?ctrl=user&action=user&pseudo={$objProject->getCreatorname()}" class="text-decoration-none text-dark">
<img src="{$smarty.env.IMG_USER_PATH}{$objProject->getUser_image() ?? "images.jpg"}"
class="rounded-circle mb-3 mx-auto"
style="width:100px;height:100px;object-fit:cover;">
</a>
<h5>{$objProject->getCreatorName()}</h5>
<p class="text-muted small"> <div class="card text-center shadow-sm p-4">
Publié le {$objProject->getCreation_date()} <a
</p> href="index.php?ctrl=user&action=user&id={$objProject->getUser_id()}"
class="text-decoration-none text-dark"
>
<img
src="{$smarty.env.IMG_USER_PATH}{$objProject->getUser_image()|default:'images.jpg'}"
class="rounded-circle mb-3 mx-auto"
style="width:100px;height:100px;object-fit:cover;"
alt="Photo du créateur"
>
</a>
<button class="btn btn-primary">Contacter le talent</button> <h5>{$objProject->getCreatorName()}</h5>
</div> <p class="text-muted small">
{*Controle de l'utilisateur ainsi que du status du projet + Suppression disponible pour l'utilisateur possédant le projet*} Publié le {$objProject->getCreation_date()}
</p>
<button class="btn btn-primary">Contacter le talent</button>
</div>
{*Controle de l'utilisateur ainsi que du status du projet + Suppression disponible pour l'utilisateur possédant le projet*}
{if isset($smarty.session.user)} {if isset($smarty.session.user)}
{if ($smarty.session.user.user_status == 2 || $smarty.session.user.user_id == $objProject->getUser_id())} {if ($smarty.session.user.user_status == 2 || $smarty.session.user.user_id == $objProject->getUser_id())}
<div class="border rounded text-center"> <div class="border rounded text-center">

View file

@ -1,4 +1,5 @@
{extends file="views/layout.tpl"} {extends file="views/layout.tpl"}
{block name="title" append} - Rechercher{/block}
{block name="content"} {block name="content"}
<section aria-label="Blog"> <section aria-label="Blog">
@ -186,4 +187,4 @@
// Initialisation au chargement // Initialisation au chargement
toggleDateFields(); toggleDateFields();
</script> </script>
{/block} {/block}

202
views/signup.tpl Normal file
View file

@ -0,0 +1,202 @@
{extends file="views/layout.tpl"}
{block name="title" append} - Inscription{/block}
{block name="content"}
<!-- Page : Inscription -->
<div class="py-5">
<!-- Centrage horizontal du formulaire -->
<div class="row justify-content-center">
<div class="col-12 col-md-10 col-lg-6">
<!-- Carte contenant le formulaire d'inscription -->
<div class="card shadow-sm border-0 rounded-4 p-4 p-lg-5">
<!-- Titre principal de la page -->
<h1 class="h3 fw-bold mb-1">Inscription</h1>
<!-- Texte descriptif -->
<p class="text-secondary mb-4">
Créez votre compte utilisateur.
</p>
<!-- Formulaire d'inscription -->
<!-- Les données seront traitées côté serveur en PHP via la méthode POST -->
<form method="POST">
<div class="row g-3">
<!-- Champ : prénom de l'utilisateur -->
<div class="col-md-6">
<label class="form-label" for="user_firstname">
Prénom *
</label>
<input
class="form-control"
type="text"
id="user_firstname"
name="user_firstname"
value="{$objUser->getFirstname()|default:''}"
required
>
</div>
<!-- Champ : nom de l'utilisateur -->
<div class="col-md-6">
<label class="form-label" for="user_name">
Nom *
</label>
<input
class="form-control"
type="text"
id="user_name"
name="user_name"
value="{$objUser->getName()|default:''}"
required
>
</div>
<!-- Champ : pseudo -->
<div class="col-12">
<label class="form-label" for="user_pseudo">
Pseudo *
</label>
<div class="input-group">
<span class="input-group-text">@</span>
<input
class="form-control"
type="text"
id="user_pseudo"
name="user_pseudo"
value="{$objUser->getPseudo()|default:''}"
required
>
</div>
</div>
<!-- Champ : adresse e-mail -->
<div class="col-12">
<label class="form-label" for="user_mail">
Adresse e-mail *
</label>
<input
class="form-control"
type="email"
id="user_mail"
name="user_mail"
value="{$objUser->getMail()|default:''}"
required
>
</div>
<!-- Champ : mot de passe -->
<div class="col-12">
<label class="form-label" for="user_password">
Mot de passe *
</label>
<input
class="form-control"
type="password"
id="user_password"
name="user_password"
required
>
</div>
<!-- Champ : confirmer le mot de passe -->
<div class="col-12">
<label class="form-label" for="pwd_confirm">
Confirmer le mot de passe *
</label>
<input
class="form-control"
type="password"
id="pwd_confirm"
name="pwd_confirm"
required
>
</div>
<!-- Champ optionnel : numéro de téléphone -->
<div class="col-12">
<label class="form-label" for="user_phone">
Téléphone
</label>
<input
class="form-control"
type="text"
id="user_phone"
name="user_phone"
value="{$objUser->getPhone()|default:''}"
>
</div>
<!-- Champ optionnel : profession de l'utilisateur -->
<div class="col-12">
<label class="form-label" for="user_work">
Profession
</label>
<input
class="form-control"
type="text"
id="user_work"
name="user_work"
value="{$objUser->getWork()|default:''}"
>
</div>
<!-- Champ optionnel : localisation de l'utilisateur -->
<div class="col-12">
<label class="form-label" for="user_location">
Localisation
</label>
<input
class="form-control"
type="text"
id="user_location"
name="user_location"
value="{$objUser->getLocation()|default:''}"
>
</div>
<!-- Champ optionnel : phrase d'accroche -->
<div class="col-12">
<label class="form-label" for="user_description">
Phrase d'accroche
</label>
<textarea
class="form-control"
id="user_description"
name="user_description"
value="{$objUser->getDescription()|default:''}"
rows="3"
></textarea>
</div>
<!-- Bouton de soumission du formulaire -->
<div class="col-12 d-grid mt-2">
<button type="submit" class="btn btn-primary btn-lg rounded-3">
Créer mon compte
</button>
</div>
<!-- Lien vers la page de connexion -->
<div class="col-12 text-center">
<small class="text-secondary">
Déjà un compte ?
<a class="link-primary" href="index.php?ctrl=user&action=login">
Se connecter
</a>
</small>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{/block}