diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..95a9d20 --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/php/public/css/profil.css b/php/public/css/profil.css new file mode 100644 index 0000000..f8603eb --- /dev/null +++ b/php/public/css/profil.css @@ -0,0 +1,122 @@ +/* profil.css */ +.profiles-container { + display: flex; + flex-wrap: wrap; + justify-content: space-around; + gap: 20px; + padding: 0; + list-style: none; +} + +.profile { + width: calc(50% - 20px); /* Ajustez la largeur si nécessaire pour correspondre au design */ + border: 1px solid #ccc; /* Bordure comme dans l'image */ + border-radius: 10px; + overflow: hidden; + background: #fff; + margin-bottom: 20px; + display: flex; + align-items: center; /* Alignement vertical */ +} + +.profile-image-container { + padding: 10px; + display: flex; + align-items: center; + justify-content: center; + background: #f0f0f0; + flex-shrink: 0; /* Empêche le conteneur de rétrécir */ +} + +.profile-image-container img { + width: 100px; + height: 100px; + border-radius: 50%; +} + +.profile-details { + padding: 10px; + flex-grow: 1; /* Permet à ce div de prendre l'espace restant */ +} + +.profile-details p { + margin: 5px 0; + font-weight: bold; /* Texte en gras comme dans l'image */ +} + +.profile-details .job-title { + color: #007bff; + font-size: 0.85em; +} + +.profile-details a { + display: block; /* Prend toute la largeur du conteneur */ + background: #007bff; + color: #fff; + padding: 5px 15px; + text-decoration: none; + border-radius: 5px; + font-size: 14px; + margin-top: 10px; /* Espace au-dessus du lien */ + text-align: center; /* Centre le texte dans le lien */ +} + +.profile-details a:hover { + background: #0056b3; +} + + + +/* profil.css */ +.pagination { + display: flex; + padding-left: 0; + list-style: none; + border-radius: 0.25rem; +} + +.page-link { + position: relative; + display: block; + padding: 0.5rem 0.75rem; + margin-left: -1px; + line-height: 1.25; + color: #007bff; + background-color: #fff; + border: 1px solid #dee2e6; +} + +.page-link:hover { + color: #0056b3; + text-decoration: none; + background-color: #e9ecef; + border-color: #dee2e6; +} + +.page-item:first-child .page-link { + margin-left: 0; + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.page-item:last-child .page-link { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} + +.page-item.active .page-link { + z-index: 1; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + cursor: auto; + background-color: #fff; + border-color: #dee2e6; +} + + diff --git a/php/src/controleur/FrontControleur.php b/php/src/controleur/FrontControleur.php index bbb91e4..f93cbff 100755 --- a/php/src/controleur/FrontControleur.php +++ b/php/src/controleur/FrontControleur.php @@ -18,14 +18,19 @@ class FrontControleur global $twig; session_start(); - + if($_SESSION["utilisateur"]){ + $twig->addGlobal('nom', $_SESSION["utilisateur"]->getNom()); + $twig->addGlobal('prenom', $_SESSION["utilisateur"]->getPrenom()); + $twig->addGlobal('role', $_SESSION["utilisateur"]->getRole()); + $twig->addGlobal('id', $_SESSION["utilisateur"]->getId()); + } $router = new AltoRouter(); $router->setBasePath('/SAE_2A_FA-Reseau_ALICA/php'); - $router->map('GET', '/', 'UtilisateurControleur'); + $router->map('GET|POST', '/', 'UtilisateurControleur'); - $router->map('GET','/[a:action]?','UtilisateurControleur'); + $router->map('GET|POST','/[a:action]?','UtilisateurControleur'); $router->map('POST','/[a:action]?','UtilisateurControleur'); diff --git a/php/src/controleur/UtilisateurControleur.php b/php/src/controleur/UtilisateurControleur.php index a1a3b23..e99a20d 100755 --- a/php/src/controleur/UtilisateurControleur.php +++ b/php/src/controleur/UtilisateurControleur.php @@ -7,18 +7,17 @@ use App\gateway\ImageSaver; use App\metier\Alumni; use App\modele\OffreModele; use App\modele\UtilisateurModele; +use Exception; class UtilisateurControleur { - public function __construct() - { - } public function connection() { global $twig; - $dVueErreur = []; // Tableau pour stocker les erreurs, le cas échéant + + $dVueErreur = []; $userModel = new UtilisateurModele(); if (isset($_POST['email'], $_POST['password'])) { @@ -29,8 +28,8 @@ class UtilisateurControleur if ($utilisateur instanceof Alumni) { $_SESSION['utilisateur'] = $utilisateur; - header('Location: accueil'); - exit(); + echo $twig->render('accueil.html'); + return; } else { $dVueErreur[] = "L'adresse email ou le mot de passe est incorrect."; } @@ -42,7 +41,7 @@ class UtilisateurControleur { global $twig; - $dVueErreur = []; // Tableau pour stocker les erreurs, le cas échéant + $dVueErreur = []; $userModel = new UtilisateurModele(); if (isset($_POST['firstname'],$_POST['name'], $_POST['email'], $_POST['password'])) { @@ -51,23 +50,25 @@ class UtilisateurControleur $email = Validation::nettoyerString($_POST['email']); $motDePasse = Validation::nettoyerString($_POST['password']); $hash = password_hash($motDePasse, PASSWORD_DEFAULT); + try { + // verification que l'email est valide et unique : + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + $dVueErreur[] = "L'adresse email n'est pas valide ou est déjà utilisée."; + } else { + $utilisateur = $userModel->getUtilisateurByEmail($email); + if ($utilisateur instanceof Alumni) { + $dVueErreur[] = "L'adresse email est déjà utilisée."; + } + } + $nouvelUtilisateur = $userModel->inscription($prenom, $nom, $email, $hash); - // verification que l'email est valide et unique : - if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { - $dVueErreur[] = "L'adresse email n'est pas valide ou est déjà utilisée."; - } else { - $utilisateur = $userModel->getUtilisateurByEmail($email); - if ($utilisateur instanceof Alumni) { - $dVueErreur[] = "L'adresse email est déjà utilisée."; + if ($nouvelUtilisateur instanceof Alumni) { + echo $twig->render('inscription_success.html'); + exit(); } } - $nouvelUtilisateur = $userModel->inscription($prenom,$nom,$email, $hash); - - if ($nouvelUtilisateur instanceof Alumni) { - echo $twig->render('inscription_success.html'); - exit(); - } else { - $dVueErreur[] = "L'inscription a échoué, veuillez réessayer."; + catch (Exception $e) { + $dVueErreur[] = "L'inscription a échoué, veuillez réessayer."; } } echo $twig->render('inscription.html', ['dVueErreur' => $dVueErreur]); @@ -78,19 +79,13 @@ class UtilisateurControleur global $twig; // Ajout d'un var_dump pour déboguer if (isset($_SESSION['utilisateur']) && $_SESSION['utilisateur'] instanceof Alumni) { - $prenom = $_SESSION['utilisateur']->getPrenom(); - $nom = $_SESSION['utilisateur']->getNom(); - $id = $_SESSION['utilisateur']->getId(); - } - else{ - $prenom = null; - $nom = null; - $id = null; - } $userModel = new UtilisateurModele(); $evenements=$userModel->getEvenement(); //aller sur la page d'accueil avec le nom et prenom de l'utilisateur - echo $twig->render('accueil.html', ['prenom' => $prenom, 'nom' => $nom, 'id' => $id,"eventsList"=>$evenements]); + echo $twig->render('accueil.html', ['evenements' => $evenements]); + } else { + echo $twig->render('accueil.html'); + } } public function consulterProfilLimite() @@ -350,4 +345,33 @@ class UtilisateurControleur global $twig; echo $twig->render('evenement.html', ['evenements' => $evenements]); } + + public function getProfilByPage(?array $params) + { + + global $twig; + $dVueErreur = []; // Tableau pour stocker les erreurs, le cas échéant + $userModel = new UtilisateurModele(); + $nbParPage = 10; + $nombreTotalPages = ceil(($userModel->getNbTotalPages())/$nbParPage); + if (isset($params['id'] ) && $params['id'] != null) { + $page = Validation::validerIntPossitif($params['id']); + try{ + $profils = $userModel->getProfilByPage($page, $nbParPage); + if (isset($profils)) { + echo $twig->render('profil.html', [ + 'profils' => $profils, + 'nombreTotalPages' => $nombreTotalPages, + 'page' => $page] + ); + } + }catch (Exception $e){ + $dVueErreur[] = "Aucun profil n'a été trouvé."; + echo $twig->render('erreur.html', ['dVueErreur' => $dVueErreur]); + } + } else { + $dVueErreur[] = "La page n'existe pas."; + echo $twig->render('erreur.html', ['dVueErreur' => $dVueErreur]); + } + } } \ No newline at end of file diff --git a/php/src/gateway/AlumniGateway.php b/php/src/gateway/AlumniGateway.php index ab84401..eaa8c6e 100644 --- a/php/src/gateway/AlumniGateway.php +++ b/php/src/gateway/AlumniGateway.php @@ -12,11 +12,13 @@ class AlumniGateway /** * @param $con */ - public function __construct(Connection $con){ + public function __construct(Connection $con) + { $this->con = $con; } - public function insert(string $email, string $motDePasse, string $role){ + public function insert(string $email, string $motDePasse, string $role) + { $query = 'INSERT INTO Alumni (mail, mdp, role) VALUES (:mail, :mdp, :role)'; return $this->con->executeQuery($query, array( ':mail' => array($email, PDO::PARAM_STR), @@ -26,15 +28,16 @@ class AlumniGateway } - public function updateMotDePasse(int $id, string $password){ - $query='UPDATE Alumni SET motDePasse=:new WHERE id=:i'; + public function updateMotDePasse(int $id, string $password) + { + $query = 'UPDATE Alumni SET motDePasse=:new WHERE id=:i'; $this->con->executeQuery($query, array( ':i' => array($id, PDO::PARAM_INT), ':new' => array($password, PDO::PARAM_STR) )); } - public function ObtenirById(int $id) : array + public function ObtenirById(int $id): array { $query = 'SELECT * FROM Alumni WHERE id=:i'; $this->con->executeQuery($query, array( @@ -43,8 +46,9 @@ class AlumniGateway return $this->con->getResults(); } - public function findByEmail(string $email){ - $query = 'SELECT Alumni.id, Alumni.mail, Alumni.mdp, Alumni.role, Profil.nom, Profil.prenom + public function findByEmail(string $email) + { + $query = 'SELECT Alumni.id, Alumni.mail, Alumni.mdp, Alumni.role, Profil.nom, Profil.prenom FROM Alumni LEFT JOIN Profil ON Alumni.id = Profil.alumni WHERE Alumni.mail = :e'; @@ -55,8 +59,9 @@ class AlumniGateway } - public function getAll(){ - $query='SELECT * FROM Alumni'; + public function getAll() + { + $query = 'SELECT * FROM Alumni'; $this->con->executeQuery($query); return $this->con->getResults(); } @@ -70,4 +75,6 @@ class AlumniGateway $res = $this->con->getResults(); return $res[0]['id']; } -} \ No newline at end of file + + +} diff --git a/php/src/gateway/OffreGateway.php b/php/src/gateway/OffreGateway.php index 1664bc9..a0e1bb2 100755 --- a/php/src/gateway/OffreGateway.php +++ b/php/src/gateway/OffreGateway.php @@ -128,6 +128,13 @@ class OffreGateway return $this->con->getResults(); } + public function getNbTotalPages() + { + $query = 'SELECT COUNT(*) FROM Profil'; + $this->con->executeQuery($query, array()); + $res = $this->con->getResults(); + return intval($res[0]['COUNT(*)']); + } } \ No newline at end of file diff --git a/php/src/gateway/ProfilGateway.php b/php/src/gateway/ProfilGateway.php index 3673b68..a0afb77 100644 --- a/php/src/gateway/ProfilGateway.php +++ b/php/src/gateway/ProfilGateway.php @@ -33,4 +33,16 @@ class ProfilGateway )); return $this->con->getResults(); } + + public function userByPage(int $page, int $nbParPage) + { + $start = ($page - 1) * $nbParPage; // Calcul de l'index de départ pour LIMIT + $start = max(0, $start); // Si $start est négatif, on met 0 (pas de page -1) + $query = 'SELECT * FROM Profil LIMIT :start, :nbParPage'; + $this->con->executeQuery($query, array( + ':start' => array($start, PDO::PARAM_INT), + ':nbParPage' => array($nbParPage, PDO::PARAM_INT), + )); + return $this->con->getResults(); + } } \ No newline at end of file diff --git a/php/src/metier/Alumni.php b/php/src/metier/Alumni.php index f132ab2..610b752 100644 --- a/php/src/metier/Alumni.php +++ b/php/src/metier/Alumni.php @@ -34,7 +34,7 @@ class Alumni{ $this->email = $email; $this->motDePasse = $motDePasse; $this->role = $role; - $this->profil = new Profil($nom, $prenom, $email, "","", "", ""); + $this->profil = new Profil($nom, $prenom, $email, "","", "", "",""); } /** diff --git a/php/src/metier/Profil.php b/php/src/metier/Profil.php index 8fef2ee..9bd0f06 100644 --- a/php/src/metier/Profil.php +++ b/php/src/metier/Profil.php @@ -19,6 +19,7 @@ class Profil */ private string $nom; + /** * @var string Prenom */ @@ -28,6 +29,8 @@ class Profil /** * @var string Url linkedin */ + //image can be null + private ?string $image; private string $linkedinUrl; /** @@ -48,11 +51,12 @@ class Profil * @param string $githubUrl * @param string $portfolioUrl */ - public function __construct(string $nom, string $prenom, string $email, string $cv, string $linkedinUrl, string $githubUrl, string $portfolioUrl) + public function __construct(string $nom, string $prenom, string $email, ?string $image,string $cv, string $linkedinUrl, string $githubUrl, string $portfolioUrl) { $this->nom = $nom; $this->prenom = $prenom; + $this->image = $image; $this->email = $email; $this->cv = $cv; $this->linkedinUrl = $linkedinUrl; @@ -61,6 +65,11 @@ class Profil } + + public function getImage(): ?string + { + return $this->image ?? 'logo.png'; + } public function getCv(): string { return $this->cv; diff --git a/php/src/modele/UtilisateurModele.php b/php/src/modele/UtilisateurModele.php index deabaaf..022f7f2 100755 --- a/php/src/modele/UtilisateurModele.php +++ b/php/src/modele/UtilisateurModele.php @@ -8,6 +8,7 @@ use App\metier\Evenement; use App\metier\Alumni; use App\gateway\AlumniGateway; use App\gateway\ProfilGateway; +use App\metier\Profil; use App\metier\Offre; class UtilisateurModele @@ -30,10 +31,10 @@ class UtilisateurModele * @return Alumni */ - public function connection(string $email, string $mdp) : ? Alumni - { - $con = new Connection(DB_HOST,DB_USER,DB_PASS); - $gate = new AlumniGateway($con); + public function connection(string $email, string $mdp): ?Alumni + { + $con = new Connection(DB_HOST, DB_USER, DB_PASS); + $gate = new AlumniGateway($con); // Récupation de l'utilisateur avec l'email $utilisateur = $gate->findByEmail($email); @@ -50,7 +51,7 @@ class UtilisateurModele // L'utilisateur n'existe pas, renvoyez null return null; } - } + } /** * @description s'inscrire @@ -60,41 +61,41 @@ class UtilisateurModele * @return \Alumni chargé */ - public function inscription(string $prenom, string $nom,string $email, string $hashpassword):? Alumni - { - $role = "Membre"; - $con = new Connection(DB_HOST,DB_USER,DB_PASS); - $gate = new AlumniGateway($con); - $profilGate = new ProfilGateway($con); - // Insérez le nouvel utilisateur dans la base de données en utilisant AlumniGateway - if ($gate->insert($email, $hashpassword, $role)) { - $id = $gate->getID($email); - if($profilGate->insert($id,$nom, $prenom,$email)){ - // L'insertion a réussi, retournez le nouvel utilisateur - $nouvelUtilisateur = new Alumni($id,$email, $hashpassword, $role,$nom,$prenom); - return $nouvelUtilisateur; - } - return null; - } else { - // L'insertion a échoué, renvoyez un utilisateur vide pour indiquer l'échec - return null; - } - } - - public function getUtilisateurByEmail(string $email) - { - $con = new Connection(DB_HOST,DB_USER,DB_PASS); - $gate = new AlumniGateway($con); - // Récupérez l'utilisateur avec l'email donné en utilisant AlumniGateway - $utilisateur = $gate->findByEmail($email); - if ($utilisateur instanceof Alumni) { - // L'utilisateur existe, retournez-le - return $utilisateur; - } else { - // L'utilisateur n'existe pas, renvoyez null - return null; - } - } + public function inscription(string $prenom, string $nom, string $email, string $hashpassword): ?Alumni + { + $role = "Membre"; + $con = new Connection(DB_HOST, DB_USER, DB_PASS); + $gate = new AlumniGateway($con); + $profilGate = new ProfilGateway($con); + // Insérez le nouvel utilisateur dans la base de données en utilisant AlumniGateway + if ($gate->insert($email, $hashpassword, $role)) { + $id = $gate->getID($email); + if ($profilGate->insert($id, $nom, $prenom, $email)) { + // L'insertion a réussi, retournez le nouvel utilisateur + $nouvelUtilisateur = new Alumni($id, $email, $hashpassword, $role, $nom, $prenom); + return $nouvelUtilisateur; + } + return null; + } else { + // L'insertion a échoué, renvoyez un utilisateur vide pour indiquer l'échec + return null; + } + } + + public function getUtilisateurByEmail(string $email) + { + $con = new Connection(DB_HOST, DB_USER, DB_PASS); + $gate = new AlumniGateway($con); + // Récupérez l'utilisateur avec l'email donné en utilisant AlumniGateway + $utilisateur = $gate->findByEmail($email); + if ($utilisateur instanceof Alumni) { + // L'utilisateur existe, retournez-le + return $utilisateur; + } else { + // L'utilisateur n'existe pas, renvoyez null + return null; + } + } public function getEvenement() : array { @@ -104,8 +105,7 @@ class UtilisateurModele $evenement = array(); - foreach($data as $row) - { + foreach ($data as $row) { $evenement[] = new Evenement( $row['id'], $row['organisateur'], @@ -185,6 +185,32 @@ class UtilisateurModele return $evenement; } + public function getProfilByPage(string $page, int $nbParPage) + { + $page = max(1, intval($page)); + $con = new Connection(DB_HOST, DB_USER, DB_PASS); + $gate = new ProfilGateway($con); + $data = $gate->userByPage($page, $nbParPage); + if(isset($data)){ + //Création d'une liste d'objets utilisateurs + $profils = array(); + foreach ($data as $row) { + $profils[] = new Profil( + $row['nom'], + $row['prenom'], + $row['email'], + $row['image'] ?? null, + $row['cv'] ?? '', + $row['linkedinURL'] ?? '', + $row['githubURL'] ?? '', + $row['portfolioURL'] ?? '' + ); + } + return $profils; + } + return null; + } + public function getOfferFromId(int $id) : ?Offre { @@ -264,5 +290,10 @@ class UtilisateurModele return $offers; } + public function getNbTotalPages() + { + return $this->offreGw->getNbTotalPages(); + } + } \ No newline at end of file diff --git a/php/templates/menu.html b/php/templates/menu.html index 7e48b0e..a771142 100644 --- a/php/templates/menu.html +++ b/php/templates/menu.html @@ -21,6 +21,7 @@ +