Merge pull request #28 from Yasder5/yass

Yass
This commit is contained in:
Yass 2026-02-23 19:46:46 +01:00 committed by GitHub
commit d5f740687d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 406 additions and 40 deletions

View file

@ -151,10 +151,10 @@ class UserCtrl extends MotherCtrl {
*/ */
public function user(){ public function user(){
$intId = isset($_GET['id']) ? (int)$_GET['id'] : 0; /**$intId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($intId <= 0) { if ($intId <= 0) {
header("Location:index.php"); header("Location: index.php");
exit; exit;
} }
@ -163,15 +163,26 @@ class UserCtrl extends MotherCtrl {
$arrUserData = $objUserModel->findUserById($intId); $arrUserData = $objUserModel->findUserById($intId);
if ($arrUserData === false) { if ($arrUserData === false) {
header("Location:index.php"); header("Location: index.php");
exit;
}*/
$strPseudo = $_GET['pseudo']??'';
$objUserModel = new UserModel;
$arrUserData = $objUserModel->findUserByPseudo($strPseudo);
if ($arrUserData === false) {
header("Location: index.php");
exit; exit;
} }
$objUser = new User; $objUser = new User;
$objUser->hydrate($arrUserData); $objUser->hydrate($arrUserData);
//affichage projet de l'utilisateur //affichage projet de l'utilisateur
$objProjectModel = new ProjectModel; $objProjectModel = new ProjectModel;
$arrProjects = $objProjectModel->findAll(0,'',$intId); $arrProjects = $objProjectModel->findAll(0,'',$objUser->getId());
$arrProjectToDisplay = array(); $arrProjectToDisplay = array();
foreach($arrProjects as $projectData) { foreach($arrProjects as $projectData) {
@ -185,4 +196,118 @@ class UserCtrl extends MotherCtrl {
$this->_display("user"); $this->_display("user");
} }
public function edit(){
if(!isset($_SESSION['user'])){
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

@ -20,7 +20,7 @@
string $strEndDate='', int $intCategory=0, bool $bool6Months=false):array{ string $strEndDate='', int $intCategory=0, bool $bool6Months=false):array{
$strRq = "SELECT project.*, $strRq = "SELECT project.*,
CONCAT(user_firstname, ' ', user_name) 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";

View file

@ -18,7 +18,7 @@
* @return array * @return array
*/ */
public function findAllUsers():array{ public function findAllUsers():array{
$strRq = "SELECT user_id, user_firstname, user_name, user_image, user_status, authorisation_name $strRq = "SELECT user_id, user_firstname, user_name, user_image, user_status, authorisation_name, user_pseudo
FROM users INNER JOIN authorisation ON authorisation.authorisation_id = users.user_status FROM users INNER JOIN authorisation ON authorisation.authorisation_id = users.user_status
WHERE user_deleted_at IS NULL"; WHERE user_deleted_at IS NULL";
return $this->_db->query($strRq)->fetchAll(); return $this->_db->query($strRq)->fetchAll();
@ -32,7 +32,7 @@
*/ */
public function verifUser(string $strMail, string $strPwd):array|bool{ public function verifUser(string $strMail, string $strPwd):array|bool{
$strRq = "SELECT user_id, user_name, user_firstname, user_password, user_image, user_status, authorisation_name $strRq = "SELECT user_id, user_name, user_firstname, user_password, user_image, user_status, authorisation_name, user_pseudo
FROM users INNER JOIN authorisation ON authorisation.authorisation_id = users.user_status FROM users INNER JOIN authorisation ON authorisation.authorisation_id = users.user_status
WHERE user_mail = '".$strMail."'"; WHERE user_mail = '".$strMail."'";
@ -70,6 +70,37 @@
return $rqPrep->execute(); return $rqPrep->execute();
} }
public function update(object $objUser):bool{
$strRq = "UPDATE users SET
user_name = :name,
user_firstname = :firstname,
user_pseudo = :pseudo,
user_mail = :mail,
user_phone = :phone,
user_work = :work,
user_location = :location,
user_description = :description,
user_image = :image
WHERE user_id = :id";
$rqPrep = $this->_db->prepare($strRq);
$rqPrep->bindValue(":id", $objUser->getId(), PDO::PARAM_INT);
$rqPrep->bindValue(":name", $objUser->getName(), PDO::PARAM_STR);
$rqPrep->bindValue(":firstname", $objUser->getFirstname(), PDO::PARAM_STR);
$rqPrep->bindValue(":pseudo", $objUser->getPseudo(), PDO::PARAM_STR);
$rqPrep->bindValue(":mail", $objUser->getMail(), PDO::PARAM_STR);
$rqPrep->bindValue(':phone', $objUser->getPhone() ?? "", PDO::PARAM_STR);
$rqPrep->bindValue(':work', $objUser->getWork() ?? "", PDO::PARAM_STR);
$rqPrep->bindValue(':location', $objUser->getLocation() ?? "", PDO::PARAM_STR);
$rqPrep->bindValue(':description', $objUser->getDescription() ?? "", PDO::PARAM_STR);
$rqPrep->bindValue(':image', $objUser->getImage() ?? "", PDO::PARAM_STR);
return $rqPrep->execute();
}
/** /**
* Fonction de vérification de mail * Fonction de vérification de mail
* @param string $mail * @param string $mail
@ -125,7 +156,9 @@
*/ */
public function findUserById(int $intId): array|bool { public function findUserById(int $intId): array|bool {
$strRq = "SELECT * FROM users WHERE user_id = :id"; $strRq = "SELECT user_id,user_status ,user_image ,user_name, user_firstname, user_pseudo, user_mail, user_phone, user_work, user_location, user_description, authorisation_name
FROM users INNER JOIN authorisation ON authorisation.authorisation_id = users.user_status
WHERE user_id = :id";
$prep = $this->_db->prepare($strRq); $prep = $this->_db->prepare($strRq);
$prep->bindValue(':id', $intId, PDO::PARAM_INT); $prep->bindValue(':id', $intId, PDO::PARAM_INT);
@ -133,4 +166,26 @@
return $prep->fetch(); return $prep->fetch();
} }
public function findUserByPseudo(string $strPseudo): array|bool {
$strRq = "SELECT user_id,user_image, user_status ,user_name, user_firstname, user_pseudo, user_mail, user_phone, user_work, user_location, user_description, authorisation_name
FROM users INNER JOIN authorisation ON authorisation.authorisation_id = users.user_status
WHERE user_pseudo = :pseudo";
$prep = $this->_db->prepare($strRq);
$prep->bindValue(':pseudo', $strPseudo, PDO::PARAM_STR);
$prep->execute();
return $prep->fetch();
}
public function pseudoExists(string $pseudo): bool{
$rq = $this->_db->prepare("SELECT 1 FROM users WHERE user_pseudo = :pseudo LIMIT 1");
$rq->bindValue(":pseudo", $pseudo, PDO::PARAM_STR);
$rq->execute();
return $rq->fetchColumn();
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

View file

@ -65,15 +65,15 @@
{* Utilisateur connecté *} {* Utilisateur connecté *}
<ul class="navbar-nav"> <ul class="navbar-nav">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="edit_account.php" title="Modifier mon compte" aria-label="Modifier mon compte"> <a class="nav-link" href="index.php?ctrl=user&action=user&pseudo={$smarty.session.user.user_pseudo}" title="Modifier mon compte" aria-label="Modifier mon compte">
<img src="{$smarty.session.user.user_image}" <img src="{$smarty.env.IMG_USER_PATH}{$smarty.session.user.user_image}"
class="rounded-circle flex-shrink-0 mt-2 ml-5" class="rounded-circle flex-shrink-0 mt-2 ml-5"
style="width: 36px; height: 36px; object-fit: cover;" style="width: 36px; height: 36px; object-fit: cover;"
alt="Photo de profil"> alt="Photo de profil">
</a> </a>
</li> </li>
<li class="nav-item"> <li>
<a class="nav-link" href="index.php?ctrl=user&action=logout" title="Se déconnecter" aria-label="Se déconnecter"> <a class="nav-link" href="index.php?ctrl=user&action=logout" title="Se déconnecter" aria-label="Se déconnecter">
Se déconnecter Se déconnecter
</a> </a>

View file

@ -3,7 +3,7 @@
{* IMAGE (partie supérieure - plus grande) *} {* IMAGE (partie supérieure - plus grande) *}
<div class="ratio ratio-4x3"> <div class="ratio ratio-4x3">
<img src=".{$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">
@ -13,7 +13,7 @@
<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) *}
<img src="{$objProject->getUser_image()}" <img src="{$smarty.env.IMG_USER_PATH}{$objProject->getUser_image()}"
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">
@ -23,7 +23,7 @@
<h3 class="h6 fw-bold mb-2 mt-1">{$objProject->getTitle()}</h3> <h3 class="h6 fw-bold mb-2 mt-1">{$objProject->getTitle()}</h3>
<p class="small text-muted mb-1"> <p class="small text-muted mb-1">
<i class="bi bi-person"></i> <i class="bi bi-person"></i>
<a href="index.php?ctrl=user&action=user&id={$objProject->getUser_id()}" <a href="index.php?ctrl=user&action=user&pseudo={$objProject->getCreatorname()}"
class="text-decoration-none text-muted" class="text-decoration-none text-muted"
style="position: relative; z-index: 2;"> style="position: relative; z-index: 2;">
{$objProject->getCreatorname()} {$objProject->getCreatorname()}

View file

@ -5,11 +5,11 @@
<section class="user-profile mb-5 mt-5/*vh /*"> <section class="user-profile mb-5 mt-5/*vh /*">
<div class="row"> <div class="row">
<div class="col-md-4 text-center"> <div class="col-md-4 text-center">
<img src="{$user->getImage()}" alt="Avatar de {$user->getPseudo()}" class="rounded-circle flex-shrink-0 border border-2 border-white" <img src="{$smarty.env.IMG_USER_PATH}{$user->getImage()}" alt="Avatar de {$user->getPseudo()}" class="rounded-circle flex-shrink-0 border border-2 border-white"
style="width: 256px; height: 256px; object-fit: cover; margin-top: 8px;" style="width: 256px; height: 256px; object-fit: cover; margin-top: 8px;"
> >
</div> </div>
<div class="col-md-8 d-flex align-items-center"> <div class="col-md-8 align-items-center p-0">
<div> <div>
<h1>{$user->getPseudo()}</h1> <h1>{$user->getPseudo()}</h1>
<p class="text-muted">{$user->getMail()}</p> <p class="text-muted">{$user->getMail()}</p>
@ -23,7 +23,12 @@
{/if} {/if}
<p class="mt-3">{$user->getDescription()}</p> <p class="mt-3">{$user->getDescription()}</p>
{if $smarty.session.user.user_id == $user->getId()}
<a class="btn btn-sm btn-primary flex-fill"
href="?ctrl=user&action=edit">Edit account</a>
{/if}
</div> </div>
</div> </div>
</div> </div>
</section> </section>
@ -31,13 +36,15 @@
<section> <section>
<h2 class="mb-4 border-bottom pb-2">Les projets de {$user->getPseudo()}</h2> <h2 class="mb-4 border-bottom pb-2">Les projets de {$user->getPseudo()}</h2>
<div class="row"> <div class="row m-0">
{if count($arrProjectToDisplay) > 0} {if count($arrProjectToDisplay) > 0}
{foreach $arrProjectToDisplay as $objProject} {foreach $arrProjectToDisplay as $objProject}
{include file="views/_partial/preview.tpl"} {include file="views/_partial/preview.tpl"}
{/foreach} {/foreach}
{else} {else}
<p class="alert alert-info">Cet utilisateur n'a pas encore publié de projets.</p> <div class="col-12">
<p class="col-12 alert alert-info">Cet utilisateur n'a pas encore publié de projets.</p>
</div>
{/if} {/if}
</div> </div>
</section> </section>

179
views/useredit.tpl Normal file
View file

@ -0,0 +1,179 @@
{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">Edit du profile</h1>
{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" enctype="multipart/form-data">
<div class="row g-3">
<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()}"
>
</div>
<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()}"
>
</div>
<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()}"
>
</div>
</div>
<div class="col-12">
<label class="form-label" for="image">
Photo de profil
</label>
{if $objUser->getImage()}
<div class="mb-2">
<img src="{$smarty.env.IMG_USER_PATH}{$objUser->getImage()}" alt="image actuel" class="rounded-circle" width="80" height="80">
</div>
{/if}
<input
class="form-control"
type="file"
id="image"
name="image"
accept="image/jpeg, image/png, image/webp"
>
<div class="form-text">Formats acceptés : JPG, PNG, WEBP. Laisser vide pour ne pas changer.</div>
</div>
<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()}"
>
</div>
<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()}"
>
</div>
<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()}"
>
</div>
<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()}"
>
</div>
<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"
>
{$objUser->getDescription()}
</textarea>
</div>
<div class="col-12 d-grid mt-2">
<button type="submit" class="btn btn-primary btn-lg rounded-3">
Edit profile
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</main>
{/block}