commit
a53dffb0fd
30 changed files with 1058 additions and 1126 deletions
12
.github/workflows/deploy.yml
vendored
12
.github/workflows/deploy.yml
vendored
|
|
@ -22,8 +22,16 @@ jobs:
|
||||||
script: |
|
script: |
|
||||||
echo "➡️ Connexion réussie !"
|
echo "➡️ Connexion réussie !"
|
||||||
cd /var/www/projet_php
|
cd /var/www/projet_php
|
||||||
sudo git fetch origin main
|
|
||||||
sudo git reset --hard origin/main
|
echo "➡️ Mise à jour du code..."
|
||||||
|
git fetch origin main
|
||||||
|
git reset --hard origin/main
|
||||||
|
|
||||||
|
echo "➡️ Correction des permissions et nettoyage..."
|
||||||
sudo chown -R yass:www-data /var/www/projet_php
|
sudo chown -R yass:www-data /var/www/projet_php
|
||||||
sudo chmod -R 775 /var/www/projet_php/templates_c
|
sudo chmod -R 775 /var/www/projet_php/templates_c
|
||||||
sudo rm -rf /var/www/projet_php/templates_c/*
|
sudo rm -rf /var/www/projet_php/templates_c/*
|
||||||
|
sudo chmod -R 775 /var/www/projet_php/uploads/projects
|
||||||
|
sudo chmod -R 775 /var/www/projet_php/uploads/profiles
|
||||||
|
|
||||||
|
echo "✅ Déploiement terminé ! (Shin-en no Egotisu)"
|
||||||
|
|
|
||||||
98
README.md
98
README.md
|
|
@ -1,98 +0,0 @@
|
||||||
# Folliow – Projet PHP
|
|
||||||
|
|
||||||
A platform for sharing portfolios and projects, designed as a mix between Behance and LinkedIn. Folliow focuses on highlighting real projects while making it easy to connect with other users.
|
|
||||||
|
|
||||||
This project was developed as part of the **DWWM (Développeur Web et Web Mobile)** training.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- User authentication and profile management
|
|
||||||
- Portfolio and project creation
|
|
||||||
- Project showcase with descriptions and technologies
|
|
||||||
- User connections / follow system
|
|
||||||
- Project feed and discovery
|
|
||||||
- Profile and project search
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Tech Stack
|
|
||||||
|
|
||||||
**Client:** HTML, CSS, JavaScript
|
|
||||||
**Server:** PHP (MVC architecture)
|
|
||||||
**Database:** MySQL
|
|
||||||
**Web Server:** Apache
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```text
|
|
||||||
folliow/
|
|
||||||
├── app/
|
|
||||||
│ ├── controllers/
|
|
||||||
│ ├── models/
|
|
||||||
│ └── views/
|
|
||||||
├── public/
|
|
||||||
│ ├── assets/
|
|
||||||
│ └── index.php
|
|
||||||
├── config/
|
|
||||||
│ └── database.php
|
|
||||||
├── sql/
|
|
||||||
│ └── folliow.sql
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Clone the project
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/Yasder5/projet_php.git
|
|
||||||
```
|
|
||||||
|
|
||||||
Go to the project directory
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd projet_php
|
|
||||||
```
|
|
||||||
|
|
||||||
Import the database
|
|
||||||
|
|
||||||
- Use the SQL file located in the `sql/` directory
|
|
||||||
|
|
||||||
Configure database access
|
|
||||||
|
|
||||||
- Update credentials in `config/database.php`
|
|
||||||
|
|
||||||
Run the project
|
|
||||||
|
|
||||||
- Use a local server (XAMPP, WAMP, or Apache on Linux)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Learning Objectives
|
|
||||||
|
|
||||||
- Build a complete PHP web application
|
|
||||||
- Apply MVC architecture
|
|
||||||
- Manage a relational database
|
|
||||||
- Design a user-oriented portfolio platform
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Future Improvements
|
|
||||||
|
|
||||||
- Private messaging
|
|
||||||
- Likes and comments on projects
|
|
||||||
- Tags and categories
|
|
||||||
- Improved responsive design
|
|
||||||
- Advanced authentication and roles
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is for educational purposes.
|
|
||||||
BIN
assests/img/error403.jpg
Normal file
BIN
assests/img/error403.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
assests/img/error404.webp
Normal file
BIN
assests/img/error404.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
|
|
@ -25,7 +25,6 @@
|
||||||
header("Location:index.php?ctrl=error&action=error_403");
|
header("Location:index.php?ctrl=error&action=error_403");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
var_dump($_SESSION);
|
|
||||||
|
|
||||||
//gestion de l'user
|
//gestion de l'user
|
||||||
$objCategoryModel = new CategoryModel;
|
$objCategoryModel = new CategoryModel;
|
||||||
|
|
@ -44,6 +43,7 @@
|
||||||
$editCat->setId($_POST['id_to_edit']);
|
$editCat->setId($_POST['id_to_edit']);
|
||||||
$editCat->setName($_POST['new_name']);
|
$editCat->setName($_POST['new_name']);
|
||||||
$objCategoryModel->editCategory($editCat);
|
$objCategoryModel->editCategory($editCat);
|
||||||
|
$_SESSION['success'] = "La catégorie a bien été modifiée";
|
||||||
header('Location: index.php?ctrl=admin&action=admin');
|
header('Location: index.php?ctrl=admin&action=admin');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
controllers/error_controller.php
Normal file
24
controllers/error_controller.php
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
require("mother_controller.php");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Le contrôleur des erreurs
|
||||||
|
* @author Laura (largement inspiré de Christel)
|
||||||
|
*/
|
||||||
|
class ErrorCtrl extends MotherCtrl{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page erreur 404
|
||||||
|
*/
|
||||||
|
public function error_404(){
|
||||||
|
$this->_display("error_404");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page erreur 403
|
||||||
|
*/
|
||||||
|
public function error_403(){
|
||||||
|
$this->_display("error_403");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,27 @@
|
||||||
public function home(){
|
public function home(){
|
||||||
|
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user']) && isset($_COOKIE['remember_me'])) {
|
||||||
|
|
||||||
|
$token_du_cookie = $_COOKIE['remember_me'];
|
||||||
|
$hash_a_verifier = hash('sha256', $token_du_cookie);
|
||||||
|
|
||||||
|
$objUserModel = new UserModel;
|
||||||
|
// 2. On cherche le jeton dans TA table "tokens" (avec token_user_id)
|
||||||
|
$row = $objUserModel->getTokenUser($hash_a_verifier);
|
||||||
|
|
||||||
|
if ($row) {
|
||||||
|
// 3. Jeton trouvé ! On récupère les infos de l'utilisateur
|
||||||
|
$user = $objUserModel->findUserById($row['token_user_id']);
|
||||||
|
|
||||||
|
if ($user) {
|
||||||
|
// 4. On recrée la session comme lors d'un login normal
|
||||||
|
$_SESSION['user'] = $user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$intCategory = 0;
|
$intCategory = 0;
|
||||||
if (!empty($_GET['filter_cat'])) {
|
if (!empty($_GET['filter_cat'])) {
|
||||||
$intCategory = (int) $_GET['filter_cat'];
|
$intCategory = (int) $_GET['filter_cat'];
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,15 @@ class UserCtrl extends MotherCtrl {
|
||||||
// Ajoute l'utilisateur en session
|
// Ajoute l'utilisateur en session
|
||||||
$_SESSION['user'] = $arrResult;
|
$_SESSION['user'] = $arrResult;
|
||||||
$_SESSION['success'] = "Bienvenue, vous êtes bien connecté";
|
$_SESSION['success'] = "Bienvenue, vous êtes bien connecté";
|
||||||
|
if (isset($_POST['remember_me'])) {
|
||||||
|
|
||||||
|
$token = bin2hex(random_bytes(32));
|
||||||
|
$token_hash = hash('sha256', $token);
|
||||||
|
$objUserModel->remember($_SESSION['user']['user_id'],$token_hash);
|
||||||
|
|
||||||
|
setcookie('remember_me', $token, time() + (15*24*60*60), "/", "", true, true);
|
||||||
|
|
||||||
|
}
|
||||||
header("Location:index.php");
|
header("Location:index.php");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
@ -49,11 +57,15 @@ class UserCtrl extends MotherCtrl {
|
||||||
|
|
||||||
|
|
||||||
public function logout(){
|
public function logout(){
|
||||||
session_start();
|
|
||||||
/*session_destroy();
|
|
||||||
session_start();*/
|
|
||||||
|
|
||||||
// on supprime l'utilisateur en session
|
if (isset($_COOKIE['remember_me'])) {
|
||||||
|
$hash = hash('sha256', $_COOKIE['remember_me']);
|
||||||
|
|
||||||
|
$objUserModel = new UserModel;
|
||||||
|
$objUserModel->deleteToken($hash);
|
||||||
|
|
||||||
|
setcookie('remember_me', '', time() - 3600, "/");
|
||||||
|
}
|
||||||
unset($_SESSION['user']);
|
unset($_SESSION['user']);
|
||||||
|
|
||||||
$_SESSION['success'] = "Vous êtes bien déconnecté";
|
$_SESSION['success'] = "Vous êtes bien déconnecté";
|
||||||
|
|
@ -62,8 +74,14 @@ class UserCtrl extends MotherCtrl {
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
public function signin(){
|
* Fonction d'inscription d'un utilisateur
|
||||||
|
* Effectue les validations du formulaire,
|
||||||
|
* vérifie l'unicité du mail et du pseudo,
|
||||||
|
* puis insère l'utilisateur en base de données
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function signup(){
|
||||||
|
|
||||||
// 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 +119,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 +167,177 @@ 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");
|
* le controlleur affichage de la page user
|
||||||
exit;
|
*/
|
||||||
}*/
|
public function user(){
|
||||||
|
|
||||||
$strPseudo = $_GET['pseudo']??'';
|
/**$intId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||||
|
|
||||||
$objUserModel = new UserModel;
|
if ($intId <= 0) {
|
||||||
$arrUserData = $objUserModel->findUserByPseudo($strPseudo);
|
header("Location: index.php");
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
if ($arrUserData === false) {
|
//affichage info utilisateur
|
||||||
header("Location: index.php");
|
$objUserModel = new UserModel;
|
||||||
exit;
|
$arrUserData = $objUserModel->findUserById($intId);
|
||||||
}
|
|
||||||
|
|
||||||
$objUser = new User;
|
if ($arrUserData === false) {
|
||||||
$objUser->hydrate($arrUserData);
|
header("Location: index.php");
|
||||||
|
exit;
|
||||||
|
}*/
|
||||||
|
|
||||||
//affichage projet de l'utilisateur
|
$strPseudo = $_GET['pseudo']??'';
|
||||||
$objProjectModel = new ProjectModel;
|
|
||||||
$arrProjects = $objProjectModel->findAll(0,'',$objUser->getId());
|
|
||||||
|
|
||||||
$arrProjectToDisplay = array();
|
$objUserModel = new UserModel;
|
||||||
foreach($arrProjects as $projectData) {
|
$arrUserData = $objUserModel->findUserByPseudo($strPseudo);
|
||||||
$objProject = new Project();
|
|
||||||
$objProject->hydrate($projectData);
|
|
||||||
$arrProjectToDisplay[] = $objProject;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_arrData['user'] = $objUser;
|
if ($arrUserData === false) {
|
||||||
$this->_arrData['arrProjectToDisplay'] = $arrProjectToDisplay;
|
header("Location: index.php");
|
||||||
$this->_display("user");
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(){
|
$objUser = new User;
|
||||||
if(!isset($_SESSION['user'])){
|
$objUser->hydrate($arrUserData);
|
||||||
header("Location: index.php");
|
|
||||||
exit;
|
//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");
|
||||||
}
|
}
|
||||||
|
|
||||||
$objUserModel = new UserModel;
|
public function edit(){
|
||||||
$arrError = [];
|
if(!isset($_SESSION['user'])){
|
||||||
$objUser = new User;
|
header("Location: index.php");
|
||||||
$arrUserData = $objUserModel->findUserById($_SESSION['user']['user_id']);
|
exit;
|
||||||
$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é";
|
$objUserModel = new UserModel;
|
||||||
} else {
|
$arrError = [];
|
||||||
if ($objUserModel->pseudoExists($_POST['user_pseudo']) && ($_POST['user_pseudo'] != $objUser->getPseudo())){
|
$objUser = new User;
|
||||||
$arrError['user_pseudo'] = "Ce pseudo est déjà utiliser";
|
$arrUserData = $objUserModel->findUserById($_SESSION['user']['user_id']);
|
||||||
}else{
|
$objUser->hydrate($arrUserData);
|
||||||
$objUser->hydrate($_POST);
|
if (!empty($_POST)) {
|
||||||
$objUser->setId($_SESSION['user']['user_id']);
|
if ($objUserModel->mailExists($_POST['user_mail']) && ($_POST['user_mail'] != $objUser->getMail())) {
|
||||||
|
|
||||||
// Vérification de l'image
|
$arrError['user_mail'] = "Ce mail est déjà associé";
|
||||||
$arrTypeAllowed = array('image/jpeg', 'image/png', 'image/webp');
|
} else {
|
||||||
$boolImageOk = true;
|
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']);
|
||||||
|
|
||||||
if ($_FILES['image']['error'] != 4) {
|
// Vérification de l'image
|
||||||
if (!in_array($_FILES['image']['type'], $arrTypeAllowed)) {
|
$arrTypeAllowed = array('image/jpeg', 'image/png', 'image/webp');
|
||||||
$arrError['image'] = "Le type de fichier n'est pas autorisé";
|
$boolImageOk = true;
|
||||||
} 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 ($_FILES['image']['error'] != 4) {
|
||||||
if (count($arrError) == 0 && isset($strImageName)) {
|
if (!in_array($_FILES['image']['type'], $arrTypeAllowed)) {
|
||||||
$strDest = $_ENV['IMG_USER_PATH'] . $strImageName;
|
$arrError['image'] = "Le type de fichier n'est pas autorisé";
|
||||||
$strSource = $_FILES['image']['tmp_name'];
|
} else {
|
||||||
list($intWidth, $intHeight) = getimagesize($strSource);
|
switch ($_FILES['image']['error']) {
|
||||||
|
case 0:
|
||||||
$intDestWidth = 200; $intDestHeight = 200;
|
$strImageName = uniqid() . ".webp";
|
||||||
$fltDestRatio = $intDestWidth / $intDestHeight;
|
$strOldImg = $objUser->getImage();
|
||||||
$fltSourceRatio = $intWidth / $intHeight;
|
$objUser->setImage($strImageName);
|
||||||
|
break;
|
||||||
if ($fltSourceRatio > $fltDestRatio) {
|
case 1:
|
||||||
$intCropHeight = $intHeight;
|
case 2:
|
||||||
$intCropWidth = (int)round($intHeight * $fltDestRatio);
|
$arrError['image'] = "Le fichier est trop volumineux";
|
||||||
$intCropX = (int)(($intWidth - $intCropWidth) / 2);
|
break;
|
||||||
$intCropY = 0;
|
case 3:
|
||||||
} else {
|
$arrError['image'] = "Le fichier a été partiellement téléchargé";
|
||||||
$intCropWidth = $intWidth;
|
break;
|
||||||
$intCropHeight = (int)round($intWidth / $fltDestRatio);
|
case 6:
|
||||||
$intCropX = 0;
|
$arrError['image'] = "Le répertoire temporaire est manquant";
|
||||||
$intCropY = (int)(($intHeight - $intCropHeight) / 2);
|
break;
|
||||||
}
|
default:
|
||||||
|
$arrError['image'] = "Erreur sur l'image";
|
||||||
$objDest = imagecreatetruecolor($intDestWidth, $intDestHeight);
|
break;
|
||||||
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;
|
// Traitement de l'image si pas d'erreur
|
||||||
$_SESSION['success'] = "Compte modifier avec succès";
|
if (count($arrError) == 0 && isset($strImageName)) {
|
||||||
header("Location:?ctrl=user&action=user&pseudo=".$objUser->getPseudo());
|
$strDest = $_ENV['IMG_USER_PATH'] . $strImageName;
|
||||||
exit;
|
$strSource = $_FILES['image']['tmp_name'];
|
||||||
} else {
|
list($intWidth, $intHeight) = getimagesize($strSource);
|
||||||
$arrError['global'] = "Erreur lors de l'update";
|
|
||||||
}
|
$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");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_arrData["arrError"] = $arrError;
|
|
||||||
$this->_arrData['objUser'] = $objUser;
|
|
||||||
$this->_display("useredit");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,253 +0,0 @@
|
||||||
CREATE DATABASE IF NOT EXISTS `projet_folliow`
|
|
||||||
DEFAULT CHARACTER SET utf8mb4
|
|
||||||
COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
USE `projet_folliow`;
|
|
||||||
|
|
||||||
/*M!999999\- enable the sandbox mode */
|
|
||||||
-- MariaDB dump 10.19 Distrib 10.11.14-MariaDB, for debian-linux-gnu (x86_64)
|
|
||||||
--
|
|
||||||
-- Host: localhost Database: projet_folliow
|
|
||||||
-- ------------------------------------------------------
|
|
||||||
-- Server version 10.11.14-MariaDB-0+deb12u2
|
|
||||||
|
|
||||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
|
||||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
|
||||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
|
||||||
/*!40101 SET NAMES utf8mb4 */;
|
|
||||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
|
||||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
|
||||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
|
||||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
|
||||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
|
||||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `authorisation`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `authorisation`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = utf8mb4 */;
|
|
||||||
CREATE TABLE `authorisation` (
|
|
||||||
`authorisation_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifiant unique des autorisations',
|
|
||||||
`authorisation_name` varchar(30) NOT NULL COMMENT 'Administrateur, modérateur, utilisateur',
|
|
||||||
PRIMARY KEY (`authorisation_id`),
|
|
||||||
UNIQUE KEY `uk_authorisation_name` (`authorisation_name`)
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `authorisation`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `authorisation` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `authorisation` DISABLE KEYS */;
|
|
||||||
INSERT INTO `authorisation` VALUES
|
|
||||||
(1,'Administrateur'),
|
|
||||||
(2,'Modérateur'),
|
|
||||||
(3,'Utilisateur');
|
|
||||||
/*!40000 ALTER TABLE `authorisation` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `category`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `category`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = utf8mb4 */;
|
|
||||||
CREATE TABLE `category` (
|
|
||||||
`category_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifiant unique des catégorie du projet',
|
|
||||||
`category_name` varchar(150) NOT NULL COMMENT 'Nom de chaque catégorie',
|
|
||||||
`category_parent` int(10) unsigned DEFAULT NULL COMMENT 'ID de la catégorie parente (NULL = catégorie principale)',
|
|
||||||
PRIMARY KEY (`category_id`),
|
|
||||||
UNIQUE KEY `uk_category_name_parent` (`category_name`,`category_parent`),
|
|
||||||
KEY `fk_category_parent` (`category_parent`),
|
|
||||||
CONSTRAINT `fk_category_parent` FOREIGN KEY (`category_parent`) REFERENCES `category` (`category_id`) ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `category`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `category` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `category` DISABLE KEYS */;
|
|
||||||
INSERT INTO `category` VALUES
|
|
||||||
(32,'3D',4),
|
|
||||||
(34,'Aquarelle',4),
|
|
||||||
(5,'Architecture',NULL),
|
|
||||||
(36,'Architecture d\'Intérieur',5),
|
|
||||||
(35,'Architecture Moderne',5),
|
|
||||||
(24,'Backend',2),
|
|
||||||
(33,'Bande Dessinée',4),
|
|
||||||
(1,'Design',NULL),
|
|
||||||
(2,'Développement Web',NULL),
|
|
||||||
(31,'Digital Art',4),
|
|
||||||
(30,'Événementiel',3),
|
|
||||||
(23,'Frontend',2),
|
|
||||||
(25,'Full-Stack',2),
|
|
||||||
(4,'Illustration',NULL),
|
|
||||||
(20,'Logo & Identité Visuelle',1),
|
|
||||||
(39,'Marketing',NULL),
|
|
||||||
(46,'Marketing',NULL),
|
|
||||||
(26,'Mobile',2),
|
|
||||||
(21,'Motion Design',1),
|
|
||||||
(38,'Patrimoine',5),
|
|
||||||
(28,'Paysage',3),
|
|
||||||
(3,'Photographie',NULL),
|
|
||||||
(27,'Portrait',3),
|
|
||||||
(22,'Print Design',1),
|
|
||||||
(40,'Rédaction',NULL),
|
|
||||||
(47,'Rédaction',NULL),
|
|
||||||
(29,'Sport',3),
|
|
||||||
(19,'UI/UX Design',1),
|
|
||||||
(37,'Urbanisme',5),
|
|
||||||
(41,'Vidéo',NULL),
|
|
||||||
(48,'Vidéo',NULL);
|
|
||||||
/*!40000 ALTER TABLE `category` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `image`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `image`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = utf8mb4 */;
|
|
||||||
CREATE TABLE `image` (
|
|
||||||
`image_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'identifiant unique des images',
|
|
||||||
`image_name` varchar(150) NOT NULL COMMENT 'Chemin de l''image enregistrée',
|
|
||||||
`image_alt` varchar(255) DEFAULT NULL COMMENT 'Alt de l''image',
|
|
||||||
`image_status` varchar(50) NOT NULL DEFAULT 'en_attente' COMMENT 'Statut de modération de l''image',
|
|
||||||
`image_project` int(10) unsigned DEFAULT NULL COMMENT 'Identifiant du projet où se trouve l''image',
|
|
||||||
PRIMARY KEY (`image_id`),
|
|
||||||
KEY `fk_image_project` (`image_project`),
|
|
||||||
CONSTRAINT `fk_image_project` FOREIGN KEY (`image_project`) REFERENCES `project` (`project_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
CONSTRAINT `chk_image_status` CHECK (`image_status` in ('en_attente','approuvé','rejeté'))
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `image`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `image` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `image` DISABLE KEYS */;
|
|
||||||
INSERT INTO `image` VALUES
|
|
||||||
(1,'/uploads/projects/ecommerce-01.jpg','Page d\'accueil du site e-commerce refondu','approuvé',1),
|
|
||||||
(2,'/uploads/projects/ecommerce-02.jpg','Interface mobile du processus de commande','approuvé',1),
|
|
||||||
(3,'/uploads/projects/taskmanager-01.jpg','Vue kanban de l\'application','approuvé',2),
|
|
||||||
(4,'/uploads/projects/urban-01.jpg','Architecture moderne à La Défense','en_attente',3);
|
|
||||||
/*!40000 ALTER TABLE `image` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `project`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `project`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = utf8mb4 */;
|
|
||||||
CREATE TABLE `project` (
|
|
||||||
`project_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifiant unique du projet',
|
|
||||||
`project_title` varchar(150) NOT NULL COMMENT 'Titre du projet',
|
|
||||||
`project_description` text DEFAULT NULL COMMENT 'Description du projet',
|
|
||||||
`project_thumbnail` varchar(150) DEFAULT NULL COMMENT 'Image miniature du projet',
|
|
||||||
`project_content` text DEFAULT NULL COMMENT 'Contenu du projet',
|
|
||||||
`project_creation_date` date NOT NULL COMMENT 'Date de création du projet',
|
|
||||||
`project_status` varchar(30) NOT NULL DEFAULT 'brouillon' COMMENT 'Statut du projet : brouillon, publié, en_attente',
|
|
||||||
`project_user` int(10) unsigned DEFAULT NULL COMMENT 'Identifiant de l''user',
|
|
||||||
`project_category` int(10) unsigned DEFAULT NULL COMMENT 'Identifiant de la catégorie',
|
|
||||||
|
|
||||||
PRIMARY KEY (`project_id`),
|
|
||||||
KEY `fk_project_user` (`project_user`),
|
|
||||||
KEY `fk_project_category` (`project_category`),
|
|
||||||
KEY `idx_project_status` (`project_status`),
|
|
||||||
KEY `idx_project_creation_date` (`project_creation_date`),
|
|
||||||
|
|
||||||
CONSTRAINT `fk_project_category`
|
|
||||||
FOREIGN KEY (`project_category`)
|
|
||||||
REFERENCES `category` (`category_id`)
|
|
||||||
ON DELETE SET NULL
|
|
||||||
ON UPDATE CASCADE,
|
|
||||||
|
|
||||||
CONSTRAINT `fk_project_user`
|
|
||||||
FOREIGN KEY (`project_user`)
|
|
||||||
REFERENCES `users` (`user_id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE CASCADE
|
|
||||||
) ENGINE=InnoDB
|
|
||||||
DEFAULT CHARSET=utf8mb4
|
|
||||||
COLLATE=utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `project`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `project` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `project` DISABLE KEYS */;
|
|
||||||
INSERT INTO `project` VALUES
|
|
||||||
(1,'Refonte du site e-commerce','Refonte complète de l\'interface utilisateur d\'une boutique en ligne avec focus sur l\'expérience mobile','/uploads/projects/ecommerce-thumb.jpg','Ce projet visait à moderniser entièrement l\'interface d\'un site e-commerce existant. Les principales améliorations incluent une navigation simplifiée, un processus de commande optimisé et une interface responsive.','2025-12-01','publié',1,1),
|
|
||||||
(2,'Application de gestion de tâches','Développement d\'une application web pour la gestion collaborative de projets','/uploads/projects/taskmanager-thumb.jpg','Application web développée en React et Node.js permettant aux équipes de gérer leurs projets de manière collaborative. Fonctionnalités : kanban, calendrier, notifications en temps réel.','2025-12-15','publié',2,2),
|
|
||||||
(3,'Série photo urbaine','Collection de photographies capturant l\'architecture moderne de Paris','/uploads/projects/urban-thumb.jpg','Série de 30 photographies prises dans différents quartiers de Paris, mettant en valeur le contraste entre architecture classique et moderne. Travail sur la lumière naturelle et les perspectives.','2026-01-05','en_attente',3,3);
|
|
||||||
/*!40000 ALTER TABLE `project` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Table structure for table `users`
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `users`;
|
|
||||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
|
||||||
/*!40101 SET character_set_client = utf8mb4 */;
|
|
||||||
CREATE TABLE `users` (
|
|
||||||
`user_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifiant unique de l''utilisateur',
|
|
||||||
`user_name` varchar(100) NOT NULL COMMENT 'Nom de l''utilisateur',
|
|
||||||
`user_firstname` varchar(100) NOT NULL COMMENT 'Prénom de l''utilisateur',
|
|
||||||
`user_pseudo` varchar(30) NOT NULL COMMENT 'Pseudo de l''utilisateur',
|
|
||||||
`user_image` varchar(150) DEFAULT NULL COMMENT 'Photo de profil de l''utilisateur',
|
|
||||||
`user_mail` varchar(100) NOT NULL COMMENT 'Mail de l''utilisateur',
|
|
||||||
`user_password` varchar(255) NOT NULL COMMENT 'Mot de passe de l''utilisateur',
|
|
||||||
`user_phone` varchar(20) DEFAULT NULL COMMENT 'Téléphone de l''utilisateur',
|
|
||||||
`user_work` varchar(50) DEFAULT NULL COMMENT 'Profession de l''utilisateur',
|
|
||||||
`user_birth` date DEFAULT NULL COMMENT 'Date de naissance de l''utilisateur',
|
|
||||||
`user_location` varchar(150) DEFAULT NULL COMMENT 'Localisation de l''utilisateur',
|
|
||||||
`user_description` varchar(255) DEFAULT NULL COMMENT 'Phrase d''accroche de l''utilisateur',
|
|
||||||
`user_account_creation` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Date et heure de création du compte',
|
|
||||||
`user_status` int(10) unsigned DEFAULT NULL COMMENT 'identifiant de niveau d''autorisation',
|
|
||||||
PRIMARY KEY (`user_id`),
|
|
||||||
UNIQUE KEY `uk_user_mail` (`user_mail`),
|
|
||||||
UNIQUE KEY `uk_user_pseudo` (`user_pseudo`),
|
|
||||||
KEY `fk_users_authorisation` (`user_status`),
|
|
||||||
KEY `idx_user_mail` (`user_mail`),
|
|
||||||
CONSTRAINT `fk_users_authorisation` FOREIGN KEY (`user_status`) REFERENCES `authorisation` (`authorisation_id`) ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Dumping data for table `users`
|
|
||||||
--
|
|
||||||
|
|
||||||
LOCK TABLES `users` WRITE;
|
|
||||||
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
|
|
||||||
INSERT INTO `users` VALUES
|
|
||||||
(1,'Dupont','Marie','marie_design','/uploads/users/marie.jpg','marie.dupont@example.com','$2y$10$T5kWRD3NBqXKWtQqrBG3We1Qpq2Odum0/xYAoT2SaCclG7h2Y0Gvq','0612345678','Designer UI/UX','1995-03-15','Paris, France','Passionnée de design et d\'expérience utilisateur','2024-01-15 10:30:00',1),
|
|
||||||
(2,'Martin','Thomas','thomas_dev','/uploads/users/thomas.jpg','thomas.martin@example.com','$2y$10$T5kWRD3NBqXKWtQqrBG3We1Qpq2Odum0/xYAoT2SaCclG7h2Y0Gvq','0623456789','Développeur Full-Stack','1992-07-22','Lyon, France','Créateur d\'applications web modernes','2024-02-20 14:45:00',2),
|
|
||||||
(3,'Dubois','Sophie','sophie_photo','/uploads/users/sophie.jpg','sophie.dubois@example.com','$2y$10$T5kWRD3NBqXKWtQqrBG3We1Qpq2Odum0/xYAoT2SaCclG7h2Y0Gvq','0634567890','Photographe','1998-11-08','Marseille, France','Capturer l\'instant présent est ma passion','2024-03-10 09:15:00',3);
|
|
||||||
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
|
|
||||||
UNLOCK TABLES;
|
|
||||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
|
||||||
|
|
||||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
|
||||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
|
||||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
|
||||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
|
||||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
|
||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
|
||||||
|
|
||||||
-- Dump completed on 2026-01-09 17:33:08
|
|
||||||
4
env
4
env
|
|
@ -5,3 +5,7 @@ DB_HOSTNAME=boulayoune.com
|
||||||
DB_DATABASE=projet_folliow
|
DB_DATABASE=projet_folliow
|
||||||
DB_USERNAME=
|
DB_USERNAME=
|
||||||
DB_PASSWORD=
|
DB_PASSWORD=
|
||||||
|
|
||||||
|
# image path
|
||||||
|
IMG_PROJECT_PATH = uploads/projects/
|
||||||
|
IMG_USER_PATH = uploads/profiles/
|
||||||
|
|
@ -31,6 +31,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if($boolError){
|
if($boolError){
|
||||||
echo "error 404 - la page elle existe pas ";
|
header("Location:index.php?ctrl=error&action=error_404");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Pour passer sur le serveur de YASS:
|
*Pour passer sur le serveur de YASS:
|
||||||
*"mysql:host=boulayoune.com;dbname=projet_folliow", // Serveur et BDD
|
*"mysql:host=boulayoune.com;dbname=projet_folliow", // Serveur et BDD
|
||||||
"projet_user", //Nom d'utilisateur de la base de données
|
"projet_user", //Nom d'utilisateur de la base de données
|
||||||
"F0lliowRules!",// Mot de passe de la base de données
|
"F0lliowRules!",// Mot de passe de la base de données
|
||||||
Site pour BDD: https://phpmyadmin.boulayoune.com/index.php?route=/sql&pos=0&db=projet_folliow&table=project
|
Site pour BDD: https://phpmyadmin.boulayoune.com/index.php?route=/sql&pos=0&db=projet_folliow&table=project
|
||||||
|
|
||||||
Pour passer en local:
|
*Pour passer en local:
|
||||||
"mysql:host=localhost;dbname=projet_folliow", // Serveur et BDD
|
*"mysql:host=localhost;dbname=projet_folliow", // Serveur et BDD
|
||||||
"root", //Nom d'utilisateur de la base de données
|
*"root", //Nom d'utilisateur de la base de données
|
||||||
"",// Mot de passe de la base de données
|
*"",// Mot de passe de la base de données
|
||||||
*/
|
*/
|
||||||
|
|
@ -16,60 +16,45 @@
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function findAll(int $intLimit=0, string $strKeywords='', int $intAuthor=0,
|
public function findAll(int $intLimit=0, string $strKeywords='', int $intAuthor=0,
|
||||||
int $intPeriod=0, string $strDate='', string $strStartDate='',
|
int $intPeriod=0, string $strDate='', string $strStartDate='',
|
||||||
string $strEndDate='', int $intCategory=0, bool $bool6Months=false):array{
|
string $strEndDate='', int $intCategory=0, bool $boolOlderThan6Months=false): array {
|
||||||
|
|
||||||
|
|
||||||
$strRq = "SELECT project.*,
|
$strRq = "SELECT project.*,
|
||||||
user_pseudo AS 'project_creatorname',
|
user_pseudo AS 'project_creatorname',
|
||||||
user_image
|
user_image
|
||||||
FROM project
|
FROM project
|
||||||
INNER JOIN users ON user_id = project_user_id";
|
INNER JOIN users ON user_id = project_user_id
|
||||||
|
WHERE 1=1";
|
||||||
|
|
||||||
$strWhere = " WHERE ";
|
|
||||||
|
|
||||||
// Recherche par mot clé avec quote pour éviter bug du '
|
|
||||||
if ($strKeywords != '') {
|
if ($strKeywords != '') {
|
||||||
|
$strRq .= " AND (project_title LIKE :keywords OR project_content LIKE :keywords)";
|
||||||
$strSafeKeywords = $this->_db->quote("%" . $strKeywords . "%");
|
|
||||||
|
|
||||||
$strRq .= " WHERE (project_title LIKE ".$strSafeKeywords."
|
|
||||||
OR project_content LIKE ".$strSafeKeywords.") ";
|
|
||||||
|
|
||||||
//$boolWhere = true;
|
|
||||||
$strWhere = " AND ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recherche par auteur
|
|
||||||
if ($intAuthor > 0){
|
if ($intAuthor > 0){
|
||||||
$strRq .= $strWhere." user_id = ".$intAuthor;
|
$strRq .= " AND project_user_id = :author";
|
||||||
$strWhere = " AND ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recherche par catégorie
|
|
||||||
if ($intCategory > 0){
|
if ($intCategory > 0){
|
||||||
$strRq .= $strWhere." project_category = ".$intCategory;
|
$strRq .= " AND project_category = :category";
|
||||||
$strWhere = " AND ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//recherche par ancienneté
|
if ($boolOlderThan6Months === true) {
|
||||||
if ($bool6Months === true) {
|
$strRq .= " AND project_creation_date <= DATE_SUB(NOW(), INTERVAL 6 MONTH)";
|
||||||
$strRq .= $strWhere . " project_creation_date <= DATE_SUB(NOW(), INTERVAL 6 MONTH) ";
|
|
||||||
$strWhere = " AND ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recherche par dates
|
|
||||||
if ($intPeriod == 0){
|
if ($intPeriod == 0){
|
||||||
if ($strDate != ''){
|
if ($strDate != ''){
|
||||||
$strRq .= $strWhere." project_creation_date = '".$strDate."'";
|
$strRq .= " AND project_creation_date = :date_exacte";
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if ($strStartDate != '' && $strEndDate != ''){
|
if ($strStartDate != '' && $strEndDate != ''){
|
||||||
$strRq .= $strWhere." project_creation_date BETWEEN '".$strStartDate."' AND '".$strEndDate."'";
|
$strRq .= " AND project_creation_date BETWEEN :date_debut AND :date_fin";
|
||||||
}else{
|
} else {
|
||||||
if ($strStartDate != ''){
|
if ($strStartDate != ''){
|
||||||
$strRq .= $strWhere." project_creation_date >= '".$strStartDate."'";
|
$strRq .= " AND project_creation_date >= :date_debut";
|
||||||
}else if ($strEndDate != ''){
|
} else if ($strEndDate != ''){
|
||||||
$strRq .= $strWhere." project_creation_date <= '".$strEndDate."'";
|
$strRq .= " AND project_creation_date <= :date_fin";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,12 +62,45 @@
|
||||||
$strRq .= " ORDER BY project_creation_date DESC";
|
$strRq .= " ORDER BY project_creation_date DESC";
|
||||||
|
|
||||||
if ($intLimit > 0){
|
if ($intLimit > 0){
|
||||||
$strRq .= " LIMIT ".$intLimit;
|
$strRq .= " LIMIT :limit";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_db->query($strRq)->fetchAll();
|
$rqPrep = $this->_db->prepare($strRq);
|
||||||
|
|
||||||
|
if ($strKeywords != '') {
|
||||||
|
$rqPrep->bindValue(':keywords', '%' . $strKeywords . '%', PDO::PARAM_STR);
|
||||||
|
}
|
||||||
|
if ($intAuthor > 0){
|
||||||
|
$rqPrep->bindValue(':author', $intAuthor, PDO::PARAM_INT);
|
||||||
|
}
|
||||||
|
if ($intCategory > 0){
|
||||||
|
$rqPrep->bindValue(':category', $intCategory, PDO::PARAM_INT);
|
||||||
|
}
|
||||||
|
if ($intPeriod == 0){
|
||||||
|
if ($strDate != ''){
|
||||||
|
$rqPrep->bindValue(':date_exacte', $strDate, PDO::PARAM_STR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($strStartDate != '' && $strEndDate != ''){
|
||||||
|
$rqPrep->bindValue(':date_debut', $strStartDate, PDO::PARAM_STR);
|
||||||
|
$rqPrep->bindValue(':date_fin', $strEndDate, PDO::PARAM_STR);
|
||||||
|
} else {
|
||||||
|
if ($strStartDate != ''){
|
||||||
|
$rqPrep->bindValue(':date_debut', $strStartDate, PDO::PARAM_STR);
|
||||||
|
} else if ($strEndDate != ''){
|
||||||
|
$rqPrep->bindValue(':date_fin', $strEndDate, PDO::PARAM_STR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($intLimit > 0){
|
||||||
|
$rqPrep->bindValue(':limit', $intLimit, PDO::PARAM_INT);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rqPrep->execute();
|
||||||
|
return $rqPrep->fetchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fonction d'insertion d'un nouveau projet dans la bdd
|
* Fonction d'insertion d'un nouveau projet dans la bdd
|
||||||
* @param object $objProject l'objet projet
|
* @param object $objProject l'objet projet
|
||||||
|
|
@ -122,7 +140,7 @@
|
||||||
*/
|
*/
|
||||||
public function findOne(int $intId) :array{
|
public function findOne(int $intId) :array{
|
||||||
$strRq = "SELECT project.*,
|
$strRq = "SELECT project.*,
|
||||||
CONCAT(users.user_firstname, ' ', users.user_name) AS 'project_creatorname',
|
users.user_pseudo AS 'project_creatorname',
|
||||||
users.user_image,
|
users.user_image,
|
||||||
category.category_name
|
category.category_name
|
||||||
FROM project
|
FROM project
|
||||||
|
|
@ -145,12 +163,10 @@
|
||||||
*/
|
*/
|
||||||
public function accept(int $id){
|
public function accept(int $id){
|
||||||
|
|
||||||
//SQL pour changer le status en accept
|
|
||||||
$strRq = "UPDATE project
|
$strRq = "UPDATE project
|
||||||
SET project_status= 'publié'
|
SET project_status= 'publié'
|
||||||
WHERE project_id =".$id;
|
WHERE project_id =".$id;
|
||||||
|
|
||||||
//retourne la commande
|
|
||||||
return $this->_db->query($strRq);
|
return $this->_db->query($strRq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,28 @@
|
||||||
return $rqPrep->execute();
|
return $rqPrep->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function remember(int $userId, string $token):bool{
|
||||||
|
$strRq = "INSERT INTO tokens (token_user_id, token_hash, token_created_at, token_expire_at) VALUES (:id, :token, NOW(), :exp)";
|
||||||
|
$rqPrep = $this->_db->prepare($strRq);
|
||||||
|
$rqPrep->bindValue(":id", $userId, PDO::PARAM_INT);
|
||||||
|
$rqPrep->bindValue(":token", $token, PDO::PARAM_STR);
|
||||||
|
$rqPrep->bindValue(":exp",
|
||||||
|
//pour faire que le cookies soit valable 15 jours
|
||||||
|
date('Y-m-d H:i:s', time() + (15*24*60*60))
|
||||||
|
, PDO::PARAM_STR);
|
||||||
|
return $rqPrep->execute();
|
||||||
|
|
||||||
|
}
|
||||||
|
public function getTokenUser(string $hash){
|
||||||
|
$strRq = $this->_db->prepare("SELECT token_user_id FROM tokens WHERE token_hash = :hash AND token_expire_at > NOW()");
|
||||||
|
$strRq->execute(['hash' => $hash]);
|
||||||
|
return $strRq->fetch();
|
||||||
|
}
|
||||||
|
public function deleteToken(string $hash){
|
||||||
|
$strRq = $this->_db->prepare("DELETE FROM tokens WHERE token_hash = :hash");
|
||||||
|
return $strRq->execute(['hash' => $hash]);
|
||||||
|
}
|
||||||
|
|
||||||
public function update(object $objUser):bool{
|
public function update(object $objUser):bool{
|
||||||
$strRq = "UPDATE users SET
|
$strRq = "UPDATE users SET
|
||||||
user_name = :name,
|
user_name = :name,
|
||||||
|
|
|
||||||
0
sfq.txt
0
sfq.txt
Binary file not shown.
|
Before Width: | Height: | Size: 8.7 KiB |
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,24 @@
|
||||||
|
|
||||||
{* IMAGE (partie supérieure - plus grande) *}
|
{* IMAGE (partie supérieure - plus grande) *}
|
||||||
<div class="ratio ratio-4x3">
|
<div class="ratio ratio-4x3">
|
||||||
|
<a href="index.php?ctrl=project&action=display&id={$objProject->getId()}"></a>
|
||||||
<img src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}"
|
<img src="{$smarty.env.IMG_PROJECT_PATH}{$objProject->getThumbnail()}"
|
||||||
class="w-100 h-100 object-fit-cover"
|
class="w-100 h-100 object-fit-cover"
|
||||||
alt=""
|
alt=""
|
||||||
loading="lazy">
|
loading="lazy">
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{* CONTENU (photo profil + infos) *}
|
{* CONTENU (photo profil + infos) *}
|
||||||
<div class="card-body p-3 bg-light">
|
<div class="card-body p-3 bg-light">
|
||||||
<div class="d-flex align-items-start gap-3">
|
<div class="d-flex align-items-start gap-3">
|
||||||
{* PHOTO DE PROFIL (cercle à gauche - plus grand) *}
|
{* PHOTO DE PROFIL (cercle à gauche - plus grand) *}
|
||||||
|
<a href="index.php?ctrl=user&action=user&id={$objProject->getUser_id()}">
|
||||||
<img src="{$smarty.env.IMG_USER_PATH}{$objProject->getUser_image() ?? "images.jpg"}"
|
<img src="{$smarty.env.IMG_USER_PATH}{$objProject->getUser_image() ?? "images.jpg"}"
|
||||||
class="rounded-circle flex-shrink-0 border border-2 border-white"
|
class="rounded-circle flex-shrink-0 border border-2 border-white"
|
||||||
style="width: 64px; height: 64px; object-fit: cover; margin-top: 8px;"
|
style="width: 64px; height: 64px; object-fit: cover; margin-top: 8px;"
|
||||||
alt="Photo de profil">
|
alt="Photo de profil">
|
||||||
|
</a>
|
||||||
{* INFOS À DROITE *}
|
{* INFOS À DROITE *}
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1">
|
||||||
<h3 class="h6 fw-bold mb-2 mt-1">{$objProject->getTitle()}</h3>
|
<h3 class="h6 fw-bold mb-2 mt-1">{$objProject->getTitle()}</h3>
|
||||||
|
|
@ -72,7 +75,7 @@
|
||||||
name="toRefused">Refuser</a>
|
name="toRefused">Refuser</a>
|
||||||
<a class="btn btn-sm btn-danger flex-fill"
|
<a class="btn btn-sm btn-danger flex-fill"
|
||||||
href="?ctrl=project&action=delete&id={$objProject->getId()}"
|
href="?ctrl=project&action=delete&id={$objProject->getId()}"
|
||||||
name="toDelete">Supprimer</a>
|
name="toDelete" onclick="return confirm('Attention ! Êtes-vous sûr de vouloir supprimer ce projet ? Cette action est irréversible.');">Supprimer</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{elseif $objProject->getStatus() == "refusé"}
|
{elseif $objProject->getStatus() == "refusé"}
|
||||||
|
|
|
||||||
160
views/about.tpl
Normal file
160
views/about.tpl
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
{extends file="views/layout.tpl"}
|
||||||
|
|
||||||
|
{block name="title" append} - À propos{/block}
|
||||||
|
|
||||||
|
{block name="h2"}À propos de FOLLIOW{/block}
|
||||||
|
{block name="p"}Plateforme de partage de projets – Projet pédagogique{/block}
|
||||||
|
|
||||||
|
{block name="content"}
|
||||||
|
|
||||||
|
<section aria-label="À propos de FOLLIOW">
|
||||||
|
<div class="row g-5">
|
||||||
|
|
||||||
|
<!-- Présentation principale -->
|
||||||
|
<div class="col-lg-8">
|
||||||
|
|
||||||
|
<section aria-labelledby="presentation">
|
||||||
|
<h3 id="presentation" class="h4 mb-3">
|
||||||
|
<i class="fas fa-lightbulb me-2 text-primary"></i>
|
||||||
|
Présentation du projet
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>FOLLIOW</strong> est une plateforme web développée dans le cadre d’un projet pédagogique.
|
||||||
|
Elle permet aux utilisateurs de publier, consulter et partager des projets numériques
|
||||||
|
à travers une interface simple et structurée.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Ce projet a été conçu afin de mettre en pratique les compétences acquises en
|
||||||
|
développement web, notamment l’architecture MVC, la gestion des bases de données
|
||||||
|
et la sécurisation des échanges.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section aria-labelledby="fonctionnalites" class="mt-4">
|
||||||
|
<h3 id="fonctionnalites" class="h4 mb-3">
|
||||||
|
<i class="fas fa-cogs me-2 text-primary"></i>
|
||||||
|
Fonctionnalités principales
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Création et gestion de projets</li>
|
||||||
|
<li>Affichage dynamique des contenus</li>
|
||||||
|
<li>Gestion des utilisateurs</li>
|
||||||
|
<li>Partage d’un projet par email</li>
|
||||||
|
<li>Interface responsive et accessible</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section aria-labelledby="objectifs" class="mt-4">
|
||||||
|
<h3 id="objectifs" class="h4 mb-3">
|
||||||
|
<i class="fas fa-bullseye me-2 text-primary"></i>
|
||||||
|
Objectifs pédagogiques
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
L’objectif principal de FOLLIOW est de démontrer la capacité à concevoir
|
||||||
|
une application web complète, structurée et sécurisée.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Structuration d’un projet en architecture MVC</li>
|
||||||
|
<li>Manipulation de bases de données relationnelles</li>
|
||||||
|
<li>Validation et sécurisation des données</li>
|
||||||
|
<li>Implémentation d’un système d’envoi d’emails</li>
|
||||||
|
<li>Respect des bonnes pratiques (RGPD, accessibilité, organisation du code)</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section aria-labelledby="technologies" class="mt-4">
|
||||||
|
<h3 id="technologies" class="h4 mb-3">
|
||||||
|
<i class="fas fa-code me-2 text-primary"></i>
|
||||||
|
Technologies utilisées
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100 border-0 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<strong>Backend</strong>
|
||||||
|
<p class="small mb-0">
|
||||||
|
PHP orienté objet – Architecture MVC – MySQL
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100 border-0 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<strong>Frontend</strong>
|
||||||
|
<p class="small mb-0">
|
||||||
|
HTML5 – CSS3 – Bootstrap – Smarty
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100 border-0 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<strong>Emails</strong>
|
||||||
|
<p class="small mb-0">
|
||||||
|
PHPMailer – SMTP – Brevo
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100 border-0 shadow-sm">
|
||||||
|
<div class="card-body">
|
||||||
|
<strong>Sécurité</strong>
|
||||||
|
<p class="small mb-0">
|
||||||
|
Validation des données – Protection des formulaires – Gestion des sessions
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="card shadow-sm p-4">
|
||||||
|
|
||||||
|
<h4 class="h5 mb-3">
|
||||||
|
<i class="fas fa-graduation-cap me-2 text-primary"></i>
|
||||||
|
Projet pédagogique
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p class="small">
|
||||||
|
FOLLIOW a été réalisé dans le cadre d’une formation en développement web.
|
||||||
|
Il s’agit d’un projet démonstratif à visée éducative.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h4 class="h5 mb-3">
|
||||||
|
<i class="fas fa-envelope me-2 text-primary"></i>
|
||||||
|
Contact
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p class="small mb-1">
|
||||||
|
Pour toute question :
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a href="mailto:projet.folliow@hotmail.com" class="small">
|
||||||
|
projet.folliow@hotmail.com
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/block}
|
||||||
|
|
@ -13,9 +13,6 @@
|
||||||
<h2>Gestion de l'utilsateur</h2>
|
<h2>Gestion de l'utilsateur</h2>
|
||||||
<p>Changer le statut ou supprimer un utilisateur</p>
|
<p>Changer le statut ou supprimer un utilisateur</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-2">
|
|
||||||
<img src="./assests/img/Logo-Wordmark.svg" alt="" width="100">
|
|
||||||
</div>
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<select class="form-select" aria-label="Default select example" name="user_id">
|
<select class="form-select" aria-label="Default select example" name="user_id">
|
||||||
|
|
@ -24,6 +21,7 @@
|
||||||
<option value="{$user->getId()}">{$user->getName()} {$user->getFirstname()}</option>
|
<option value="{$user->getId()}">{$user->getName()} {$user->getFirstname()}</option>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</select>
|
</select>
|
||||||
|
<br>
|
||||||
<select class="form-select" aria-label="Default select example" name="new_status">
|
<select class="form-select" aria-label="Default select example" name="new_status">
|
||||||
<option value="0" selected>Modifier le statut de l'Utilisateur...</option>
|
<option value="0" selected>Modifier le statut de l'Utilisateur...</option>
|
||||||
{foreach from=$arrAuthorisationToDisplay item=arrDetAuthorisation}
|
{foreach from=$arrAuthorisationToDisplay item=arrDetAuthorisation}
|
||||||
|
|
@ -31,6 +29,7 @@
|
||||||
{/foreach}
|
{/foreach}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<br>
|
||||||
<div class="col-2">
|
<div class="col-2">
|
||||||
<button type="submit" name="action" value="update_status" class="btn bg-success text-light"> Valider</button>
|
<button type="submit" name="action" value="update_status" class="btn bg-success text-light"> Valider</button>
|
||||||
<button type="submit" name="action" value="delete_user" class="btn bg-danger text-light" onclick="return confirm('Attention ! Êtes-vous sûr de vouloir supprimer cet utilisateur ? Cette action est irréversible.');">Supprimer l'utilisateur</button>
|
<button type="submit" name="action" value="delete_user" class="btn bg-danger text-light" onclick="return confirm('Attention ! Êtes-vous sûr de vouloir supprimer cet utilisateur ? Cette action est irréversible.');">Supprimer l'utilisateur</button>
|
||||||
|
|
@ -63,7 +62,6 @@
|
||||||
<div>
|
<div>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- creation cat-->
|
<!-- creation cat-->
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
|
|
|
||||||
9
views/error_403.tpl
Normal file
9
views/error_403.tpl
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{extends file="views/layout.tpl"}
|
||||||
|
|
||||||
|
{block name="content"}
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-1">Erreur 403</h1>
|
||||||
|
<h2 class="display-3">Vous n'êtes pas autorisé à accéder à cette page !</h2>
|
||||||
|
<img class="img-fluid" src="assests/img/error403.jpg">
|
||||||
|
</div>
|
||||||
|
{/block}
|
||||||
9
views/error_404.tpl
Normal file
9
views/error_404.tpl
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{extends file="views/layout.tpl"}
|
||||||
|
|
||||||
|
{block name="content"}
|
||||||
|
<div class="text-center">
|
||||||
|
<h1 class="display-1">Erreur 404</h1>
|
||||||
|
<h2 class="display-3">Cette page n'existe pas !</h2>
|
||||||
|
<img class="img-fluid" src="assests/img/error404.webp">
|
||||||
|
</div>
|
||||||
|
{/block}
|
||||||
|
|
@ -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}
|
|
||||||
|
|
@ -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 -->
|
||||||
|
|
@ -47,11 +33,10 @@
|
||||||
<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,23 +47,16 @@
|
||||||
</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>
|
||||||
|
<div class="form-check col-12">
|
||||||
<!-- Option "Se souvenir de moi" (fonctionnalité optionnelle côté PHP) -->
|
<input type="checkbox" class="form-check-input" id="remember_me" name="remember_me">
|
||||||
<div class="col-12">
|
<label class="form-check-label" for="remember_me">Se souvenir de moi</label>
|
||||||
<div class="form-check">
|
</div>
|
||||||
<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">
|
||||||
|
|
@ -91,15 +69,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 +81,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
{/block}
|
{/block}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
{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="h2"}Mentions légales{/block}
|
||||||
{block name="p"}Informations légales et politique de confidentialité{/block}
|
{block name="p"}Informations légales et politique de confidentialité{/block}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
202
views/signup.tpl
Normal file
202
views/signup.tpl
Normal 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}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue