ajout modif besnik du 4 mars
Some checks are pending
Deploy production (servyass) / deploy (push) Waiting to run

This commit is contained in:
Yasder5 2026-03-05 13:58:08 +01:00
parent 0f70b82e4b
commit 2cb4def949
5 changed files with 220 additions and 157 deletions

View file

@ -90,45 +90,14 @@ class UserCtrl extends MotherCtrl {
$objUser = new User(); $objUser = new User();
$strPwdConfirm = $_POST['pwd_confirm'] ?? ""; $strPwdConfirm = $_POST['pwd_confirm'] ?? "";
$objUser->hydrate($_POST);
$arrError = []; $arrError = [];
if (!empty($_POST)) { if (!empty($_POST)) {
$objUser->setName($_POST['user_name'] ?? "");
$objUser->setFirstname($_POST['user_firstname'] ?? "");
$objUser->setMail($_POST['user_mail'] ?? "");
$objUser->setPseudo($_POST['user_pseudo'] ?? "");
$objUser->setPwd($_POST['user_password'] ?? "");
$objUser->setPhone($_POST['user_phone'] ?? "");
$objUser->setWork($_POST['user_work'] ?? "");
$objUser->setLocation($_POST['user_location'] ?? "");
$objUser->setDescription($_POST['user_description'] ?? "");
if (trim($objUser->getName()) === "") { $arrError = array_merge($this->_verifInfos($objUser),
$arrError['user_name'] = "Le nom est obligatoire"; $this->_verifPwd($objUser, $strPwdConfirm));
}
if (trim($objUser->getFirstname()) === "") {
$arrError['user_firstname'] = "Le prénom est obligatoire";
}
if (trim($objUser->getMail()) === "") {
$arrError['user_mail'] = "L'adresse e-mail est obligatoire";
} elseif (!filter_var($objUser->getMail(), FILTER_VALIDATE_EMAIL)) {
$arrError['user_mail'] = "Le format de l'adresse e-mail est invalide";
}
if (trim($objUser->getPseudo()) === "") {
$arrError['user_pseudo'] = "Le pseudo est obligatoire";
}
$strRegex = "/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{15,}$/";
if ($objUser->getPwd() == ""){
$arrError['user_password'] = "Le mot de passe est obligatoire";
}else if (!preg_match($strRegex, $objUser->getPwd())){
$arrError['user_password'] = "Le mot de passe ne respecte pas les critères";
}else if($objUser->getPwd() != $strPwdConfirm){
$arrError['pwd_confirm'] = "La confirmation du mot de passe ne correspond pas";
}
if (count($arrError) === 0) { if (count($arrError) === 0) {
$objUserModel = new UserModel(); $objUserModel = new UserModel();
@ -158,6 +127,55 @@ class UserCtrl extends MotherCtrl {
} }
protected function _verifInfos(User $objUser): array {
$arrError = [];
if (trim($objUser->getName()) === "") {
$arrError['user_name'] = "Le nom est obligatoire";
}
if (trim($objUser->getFirstname()) === "") {
$arrError['user_firstname'] = "Le prénom est obligatoire";
}
if (trim($objUser->getMail()) === "") {
$arrError['user_mail'] = "L'adresse e-mail est obligatoire";
} elseif (!filter_var($objUser->getMail(), FILTER_VALIDATE_EMAIL)) {
$arrError['user_mail'] = "Le format de l'adresse e-mail est invalide";
}
if (trim($objUser->getPseudo()) === "") {
$arrError['user_pseudo'] = "Le pseudo est obligatoire";
}
return $arrError;
}
/**
* Vérification du mot de passe
*/
protected function _verifPwd(User $objUser, string $strPwdConfirm): array {
$arrError = [];
$strRegex = "/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{15,}$/";
if ($objUser->getPwd() == ""){
$arrError['user_password'] = "Le mot de passe est obligatoire";
}
else if (!preg_match($strRegex, $objUser->getPwd())){
$arrError['user_password'] = "Le mot de passe ne respecte pas les critères";
}
else if ($objUser->getPwd() != $strPwdConfirm){
$arrError['pwd_confirm'] = "La confirmation du mot de passe ne correspond pas";
}
return $arrError;
}
/** /**
* le controlleur affichage de la page user * le controlleur affichage de la page user
*/ */

View file

@ -46,12 +46,19 @@
$arrUser = $rqPrep->fetch(); $arrUser = $rqPrep->fetch();
if (password_verify($strPwd, $arrUser['user_password'])){ if ($arrUser === false) {
unset($arrUser['user_password']);
return $arrUser;
}else{
return false; return false;
} }
if (empty($arrUser['user_password'])) {
return false;
}
if (!password_verify($strPwd, $arrUser['user_password'])) {
return false;
}
unset($arrUser['user_password']);
return $arrUser;
} }
/** /**

View file

@ -8,151 +8,190 @@
{block name="content"} {block name="content"}
<section aria-label="À propos de FOLLIOW"> <section aria-label="À propos de FOLLIOW">
<div class="row g-5"> <div class="row g-5">
<!-- CONTENU PRINCIPAL -->
<div class="col-lg-8"> <div class="col-lg-8">
<section aria-labelledby="presentation"> <!-- INTRO -->
<h3 id="presentation" class="h4 mb-3"> <div class="mb-5">
<i class="fas fa-lightbulb me-2 text-primary"></i> <h3 class="h4 mb-3">
<i class="bi bi-lightbulb me-2 text-primary"></i>
Présentation du projet Présentation du projet
</h3> </h3>
<p> <p class="lead fs-4">
<strong>FOLLIOW</strong> est une plateforme web développée dans le cadre dun projet pédagogique. <strong>FOLLIOW</strong> est un réseau social dédié aux portfolios numériques.
Elle permet aux utilisateurs de publier, consulter et partager des projets numériques
à travers une interface simple et structurée.
</p> </p>
<p> <p class="fs-5">
Ce projet a été conçu afin de mettre en pratique les compétences acquises en La plateforme permet à chacun de créer un profil personnalisé, de mettre en avant ses projets
développement web, notamment larchitecture MVC, la gestion des bases de données et de valoriser ses compétences à travers une présentation claire et professionnelle.
et la sécurisation des échanges.
</p> </p>
</section>
<section aria-labelledby="fonctionnalites" class="mt-4"> <p class="fs-5">
<h3 id="fonctionnalites" class="h4 mb-3"> Les recruteurs et visiteurs peuvent rechercher des profils, consulter les réalisations
<i class="fas fa-cogs me-2 text-primary"></i> et prendre contact avec les utilisateurs qui les intéressent.
</p>
<p class="fs-5">
Ce projet a été développé dans un cadre pédagogique afin de concevoir une application web
complète simulant un environnement professionnel réel.
</p>
</div>
<!-- FONCTIONNALITÉS -->
<div class="mb-5">
<h3 class="h4 mb-3">
<i class="bi bi-gear me-2 text-primary"></i>
Fonctionnalités principales Fonctionnalités principales
</h3> </h3>
<ul> <div class="row">
<li>Création et gestion de projets</li> <div class="col-md-6">
<li>Affichage dynamique des contenus</li> <ul class="list-unstyled fs-5">
<li>Gestion des utilisateurs</li> <li class="mb-2">
<li>Partage dun projet par email</li> <i class="bi bi-check-circle text-success me-2"></i>
<li>Interface responsive et accessible</li> Création et gestion de projets
</ul> </li>
</section> <li class="mb-2">
<i class="bi bi-check-circle text-success me-2"></i>
Affichage dynamique des contenus
</li>
<li class="mb-2">
<i class="bi bi-check-circle text-success me-2"></i>
Gestion des utilisateurs
</li>
</ul>
</div>
<section aria-labelledby="objectifs" class="mt-4"> <div class="col-md-6">
<h3 id="objectifs" class="h4 mb-3"> <ul class="list-unstyled fs-5">
<i class="fas fa-bullseye me-2 text-primary"></i> <li class="mb-2">
<i class="bi bi-check-circle text-success me-2"></i>
Partage dun projet par email
</li>
<li class="mb-2">
<i class="bi bi-check-circle text-success me-2"></i>
Interface responsive et accessible
</li>
</ul>
</div>
</div>
</div>
<!-- OBJECTIFS -->
<div class="mb-5">
<h3 class="h4 mb-3">
<i class="bi bi-bullseye me-2 text-primary"></i>
Objectifs pédagogiques Objectifs pédagogiques
</h3> </h3>
<p> <p class="fs-5">
Lobjectif principal de FOLLIOW est de démontrer la capacité à concevoir Lobjectif principal de FOLLIOW est de démontrer la capacité à concevoir
une application web complète, structurée et sécurisée. une application web complète, structurée et sécurisée.
</p> </p>
<ul> <ul class="fs-5">
<li>Structuration dun projet en architecture MVC</li> <li>Structuration dun projet en architecture MVC</li>
<li>Manipulation de bases de données relationnelles</li> <li>Manipulation de bases de données relationnelles</li>
<li>Validation et sécurisation des données</li> <li>Validation et sécurisation des données</li>
<li>Implémentation dun système denvoi demails</li> <li>Implémentation dun système denvoi demails</li>
<li>Respect des bonnes pratiques (RGPD, accessibilité, organisation du code)</li> <li>Respect des bonnes pratiques (RGPD, accessibilité, organisation du code)</li>
</ul> </ul>
</section> </div>
<section aria-labelledby="technologies" class="mt-4"> <!-- TECHNOLOGIES -->
<h3 id="technologies" class="h4 mb-3"> <div>
<i class="fas fa-code me-2 text-primary"></i> <h3 class="h4 mb-4">
<i class="bi bi-code-slash me-2 text-primary"></i>
Technologies utilisées Technologies utilisées
</h3> </h3>
<div class="row g-3"> <div class="row g-4">
<div class="col-md-6"> <div class="col-md-6">
<div class="card h-100 border-0 shadow-sm"> <div class="border rounded p-3 h-100">
<div class="card-body"> <strong class="fs-5">Backend</strong>
<strong>Backend</strong> <p class="small text-muted mb-0">
<p class="small mb-0"> PHP orienté objet Architecture MVC MySQL
PHP orienté objet Architecture MVC MySQL </p>
</p>
</div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="card h-100 border-0 shadow-sm"> <div class="border rounded p-3 h-100">
<div class="card-body"> <strong class="fs-5">Frontend</strong>
<strong>Frontend</strong> <p class="small text-muted mb-0">
<p class="small mb-0"> HTML5 CSS3 Bootstrap Smarty
HTML5 CSS3 Bootstrap Smarty </p>
</p>
</div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="card h-100 border-0 shadow-sm"> <div class="border rounded p-3 h-100">
<div class="card-body"> <strong class="fs-5">Emails</strong>
<strong>Emails</strong> <p class="small text-muted mb-0">
<p class="small mb-0"> PHPMailer SMTP Brevo
PHPMailer SMTP Brevo </p>
</p>
</div>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="card h-100 border-0 shadow-sm"> <div class="border rounded p-3 h-100">
<div class="card-body"> <strong class="fs-5">Sécurité</strong>
<strong>Sécurité</strong> <p class="small text-muted mb-0">
<p class="small mb-0"> Validation des données Protection des formulaires Gestion des sessions
Validation des données Protection des formulaires Gestion des sessions </p>
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
</section> </div>
</div> </div>
<!-- Sidebar --> <!-- SIDEBAR -->
<div class="col-lg-4"> <div class="col-lg-4">
<div class="card shadow-sm p-4">
<h4 class="h5 mb-3"> <div class="sticky-top" style="top: 90px;">
<i class="fas fa-graduation-cap me-2 text-primary"></i>
Projet pédagogique
</h4>
<p class="small"> <div class="border rounded p-4 mb-4">
FOLLIOW a été réalisé dans le cadre dune formation en développement web. <h4 class="h5 mb-3">
Il sagit dun projet démonstratif à visée éducative. <i class="bi bi-mortarboard me-2 text-primary"></i>
</p> Projet pédagogique
</h4>
<hr> <p class="fs-5 mb-0">
FOLLIOW a été développé dans le cadre du module PROJET WEB 2,
consacré à la conception dune application web dynamique en PHP orienté objet (architecture MVC),
au sein dune formation en Développement Web et Web Mobile à CCI Campus Colmar.
Il sagit dune plateforme démonstrative réalisée à des fins pédagogiques.
</p>
</div>
<h4 class="h5 mb-3"> <div class="border rounded p-4">
<i class="fas fa-envelope me-2 text-primary"></i> <h4 class="h5 mb-3">
Contact <i class="bi bi-envelope me-2 text-primary"></i>
</h4> Contact
</h4>
<p class="small mb-1"> <p class="fs-5 mb-2">
Pour toute question : Pour toute question :
</p> </p>
<a href="mailto:projet.folliow@hotmail.com" class="small"> <a href="mailto:projet.folliow@hotmail.com" class="fs-5 text-decoration-none">
projet.folliow@hotmail.com projet.folliow@hotmail.com
</a> </a>
</div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
{/block} {/block}

View file

@ -7,8 +7,8 @@
{block name="date_maj"} {block name="date_maj"}
<p class="text-muted small mb-0"> <p class="text-muted small mb-0">
<i class="fas fa-calendar-alt me-2" aria-hidden="true"></i> <i class="bi bi-calendar-event me-2" aria-hidden="true"></i>
Dernière mise à jour : <time datetime="2026-02-20">20 février 2026</time> Dernière mise à jour : <time datetime="2026-03-05">5 mars 2026</time>
</p> </p>
{/block} {/block}
@ -40,9 +40,9 @@
<div class="col-md-12"> <div class="col-md-12">
<!-- Table des matières --> <!-- Table des matières -->
<nav class="table-of-contents" aria-labelledby="toc-heading"> <nav class="table-of-contents bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="toc-heading">
<h3 id="toc-heading" class="h5 mb-3"> <h3 id="toc-heading" class="h5 mb-3">
<i class="fas fa-list me-2" aria-hidden="true"></i> <i class="bi bi-list-ul me-2" aria-hidden="true"></i>
Sommaire Sommaire
</h3> </h3>
<ul class="list-unstyled ms-3"> <ul class="list-unstyled ms-3">
@ -58,9 +58,9 @@
</nav> </nav>
<!-- Section 1 : Éditeur --> <!-- Section 1 : Éditeur -->
<section id="editeur" class="legal-section" aria-labelledby="editeur-heading"> <section id="editeur" class="legal-section bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="editeur-heading">
<h3 id="editeur-heading" class="h4"> <h3 id="editeur-heading" class="h4">
<i class="fas fa-building me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-building me-2 text-primary" aria-hidden="true"></i>
1. Éditeur du site 1. Éditeur du site
</h3> </h3>
@ -104,9 +104,9 @@
</section> </section>
<!-- Section 2 : Hébergeur --> <!-- Section 2 : Hébergeur -->
<section id="hebergeur" class="legal-section" aria-labelledby="hebergeur-heading"> <section id="hebergeur" class="legal-section bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="hebergeur-heading">
<h3 id="hebergeur-heading" class="h4"> <h3 id="hebergeur-heading" class="h4">
<i class="fas fa-server me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-hdd-network me-2 text-primary" aria-hidden="true"></i>
2. Hébergement 2. Hébergement
</h3> </h3>
@ -128,9 +128,9 @@
</section> </section>
<!-- Section 3 : Propriété intellectuelle --> <!-- Section 3 : Propriété intellectuelle -->
<section id="propriete" class="legal-section" aria-labelledby="propriete-heading"> <section id="propriete" class="legal-section bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="propriete-heading">
<h3 id="propriete-heading" class="h4"> <h3 id="propriete-heading" class="h4">
<i class="fas fa-copyright me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-c-circle me-2 text-primary" aria-hidden="true"></i>
3. Propriété intellectuelle 3. Propriété intellectuelle
</h3> </h3>
<p> <p>
@ -146,9 +146,9 @@
</section> </section>
<!-- Section 4 : RGPD --> <!-- Section 4 : RGPD -->
<section id="rgpd" class="legal-section" aria-labelledby="rgpd-heading"> <section id="rgpd" class="legal-section bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="rgpd-heading">
<h3 id="rgpd-heading" class="h4"> <h3 id="rgpd-heading" class="h4">
<i class="fas fa-shield-alt me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-shield-lock me-2 text-primary" aria-hidden="true"></i>
4. Protection des données personnelles (RGPD) 4. Protection des données personnelles (RGPD)
</h3> </h3>
@ -160,11 +160,10 @@
<h4 class="h5 mt-4">4.2 Données collectées</h4> <h4 class="h5 mt-4">4.2 Données collectées</h4>
<p>Selon lutilisation du site, les données pouvant être collectées sont :</p> <p>Selon lutilisation du site, les données pouvant être collectées sont :</p>
<ul> <ul>
<li>Nom / Prenom <li> <li>Nom / Prenom </li>
<li>Pseudo </li> <li>Pseudo </li>
<li>Adresse email (inscription, connexion, partage de projet par email)</li> <li>Adresse email (inscription, connexion, partage de projet par email)</li>
<li>Contenus déposés par lutilisateur (projets, descriptions, images)</li> <li>Contenus déposés par lutilisateur (projets, descriptions, images)</li>
<li>Données techniques minimales (logs de sécurité, adresse IP) à des fins de protection et de diagnostic</li>
</ul> </ul>
<h4 class="h5 mt-4">4.3 Finalités du traitement</h4> <h4 class="h5 mt-4">4.3 Finalités du traitement</h4>
@ -194,9 +193,9 @@
</section> </section>
<!-- Section 5 : Cookies --> <!-- Section 5 : Cookies -->
<section id="cookies" class="legal-section" aria-labelledby="cookies-heading"> <section id="cookies" class="legal-section bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="cookies-heading">
<h3 id="cookies-heading" class="h4"> <h3 id="cookies-heading" class="h4">
<i class="fas fa-cookie-bite me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-cookie me-2 text-primary" aria-hidden="true"></i>
5. Cookies 5. Cookies
</h3> </h3>
@ -225,9 +224,9 @@
</section> </section>
<!-- Section 6 : Limitation de responsabilité --> <!-- Section 6 : Limitation de responsabilité -->
<section id="responsabilite" class="legal-section" aria-labelledby="responsabilite-heading"> <section id="responsabilite" class="legal-section bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="responsabilite-heading">
<h3 id="responsabilite-heading" class="h4"> <h3 id="responsabilite-heading" class="h4">
<i class="fas fa-exclamation-triangle me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-exclamation-triangle me-2 text-primary" aria-hidden="true"></i>
6. Limitation de responsabilité 6. Limitation de responsabilité
</h3> </h3>
<p> <p>
@ -241,9 +240,9 @@
</section> </section>
<!-- Section 7 : Liens hypertextes --> <!-- Section 7 : Liens hypertextes -->
<section id="liens" class="legal-section" aria-labelledby="liens-heading"> <section id="liens" class="legal-section bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="liens-heading">
<h3 id="liens-heading" class="h4"> <h3 id="liens-heading" class="h4">
<i class="fas fa-link me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-link-45deg me-2 text-primary" aria-hidden="true"></i>
7. Liens hypertextes 7. Liens hypertextes
</h3> </h3>
<p> <p>
@ -253,9 +252,9 @@
</section> </section>
<!-- Section 8 : Droit applicable --> <!-- Section 8 : Droit applicable -->
<section id="droit" class="legal-section" aria-labelledby="droit-heading"> <section id="droit" class="legal-section bg-light rounded shadow-sm p-4 mb-4" aria-labelledby="droit-heading">
<h3 id="droit-heading" class="h4"> <h3 id="droit-heading" class="h4">
<i class="fas fa-gavel me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-hammer me-2 text-primary" aria-hidden="true"></i>
8. Droit applicable et juridiction compétente 8. Droit applicable et juridiction compétente
</h3> </h3>
<p> <p>
@ -265,9 +264,9 @@
</section> </section>
<!-- Contact --> <!-- Contact -->
<section class="mt-5 p-4 bg-light rounded" aria-labelledby="contact-legal"> <section class="mt-5 p-4 bg-light rounded shadow-sm" aria-labelledby="contact-legal">
<h3 id="contact-legal" class="h4 mb-3"> <h3 id="contact-legal" class="h4 mb-3">
<i class="fas fa-envelope me-2 text-primary" aria-hidden="true"></i> <i class="bi bi-envelope me-2 text-primary" aria-hidden="true"></i>
Questions ou réclamations Questions ou réclamations
</h3> </h3>
<p> <p>
@ -275,7 +274,7 @@
</p> </p>
<ul class="list-unstyled"> <ul class="list-unstyled">
<li class="mb-2"> <li class="mb-2">
<i class="fas fa-envelope me-2" aria-hidden="true"></i> <i class="bi bi-envelope me-2" aria-hidden="true"></i>
Par email : <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a> Par email : <a href="mailto:projet.folliow@hotmail.com">projet.folliow@hotmail.com</a>
</li> </li>

View file

@ -98,17 +98,17 @@
<input <input
class="form-control pe-5" class="form-control pe-5"
type="password" type="password"
id="user_password" id="user_pwd"
name="user_password" name="user_pwd"
required required
> >
<button <button
class="btn position-absolute top-50 end-0 translate-middle-y me-2 p-0 border-0 bg-transparent text-muted" class="btn position-absolute top-50 end-0 translate-middle-y me-2 p-0 border-0 bg-transparent text-muted"
type="button" type="button"
onclick="togglePassword('user_password', this)" onclick="togglePassword('user_pwd', this)"
style="z-index: 10;" style="z-index: 10;"
> >
<i class="fa-solid fa-eye"></i> <i class="fa-solid fa-eye-slash"></i>
</button> </button>
</div> </div>
<div class="mt-2 small text-muted"> <div class="mt-2 small text-muted">
@ -141,7 +141,7 @@
onclick="togglePassword('pwd_confirm', this)" onclick="togglePassword('pwd_confirm', this)"
style="z-index: 10;" style="z-index: 10;"
> >
<i class="fa-solid fa-eye"></i> <i class="fa-solid fa-eye-slash"></i>
</button> </button>
</div> </div>
</div> </div>
@ -238,7 +238,7 @@
</div> </div>
<script> <script>
const pwd = document.getElementById('user_password'); const pwd = document.getElementById('user_pwd');
const rules = { const rules = {
length: { el: null, test: v => v.length >= 15 }, length: { el: null, test: v => v.length >= 15 },
@ -267,10 +267,10 @@
const icon = btn.querySelector('svg'); const icon = btn.querySelector('svg');
if (input.type === 'password') { if (input.type === 'password') {
input.type = 'text'; input.type = 'text';
icon.classList.replace('fa-eye', 'fa-eye-slash'); icon.classList.replace('fa-eye-slash', 'fa-eye');
} else { } else {
input.type = 'password'; input.type = 'password';
icon.classList.replace('fa-eye-slash', 'fa-eye'); icon.classList.replace('fa-eye', 'fa-eye-slash');
} }
} }
</script> </script>