Paaxio 1.0
Plateforme de streaming musical - SAE IUT Bayonne
Chargement...
Recherche...
Aucune correspondance
controller_utilisateur.class.php
Aller à la documentation de ce fichier.
1<?php
2
27{
34 public function __construct(\Twig\Environment $twig, \Twig\Loader\FilesystemLoader $loader)
35 {
36 parent::__construct($loader, $twig);
37 }
38
48 public function signin()
49 {
50 if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
51 $this->show405();
52 return;
53 }
54
55 header('Content-Type: application/json');
56
57 $post = $this->getPost();
58 $email = trim($post['email'] ?? '');
59 $password = $post['password'] ?? '';
60
61 // Validation via la classe Validator
62 $signinRules = [
63 'email' => [
64 'obligatoire' => true,
65 'type' => 'string',
66 'format' => FILTER_VALIDATE_EMAIL
67 ],
68 'password' => [
69 'obligatoire' => true,
70 'type' => 'string',
71 ]
72 ];
73
74 $validator = new Validator($signinRules);
75 $signinData = [
76 'email' => $email,
77 'password' => $password
78 ];
79
80 if (!$validator->valider($signinData)) {
81 echo json_encode([
82 'success' => false,
83 'message' => implode(' ', $validator->getMessagesErreurs())
84 ]);
85 return;
86 }
87
88 try {
89 $utilisateurDAO = new UtilisateurDAO($this->getPDO());
90 $utilisateur = $utilisateurDAO->find($email);
91
92 if (!$utilisateur) {
93 echo json_encode([
94 'success' => false,
95 'message' => 'Adresse e-mail ou mot de passe incorrect.'
96 ]);
97 return;
98 }
99
100 $hashedPassword = $utilisateur->getMotDePasseUtilisateur();
101
102 if (!password_verify($password, $hashedPassword)) {
103 echo json_encode([
104 'success' => false,
105 'message' => 'Adresse e-mail ou mot de passe incorrect.'
106 ]);
107 return;
108 }
109
110 $statut = $utilisateur->getStatutUtilisateur();
111 // Vérification que le compte est actif
112 if ($statut && $statut !== StatutUtilisateur::Actif) {
113 echo json_encode([
114 'success' => false,
115 'message' => 'Votre compte est ' . ($statut === StatutUtilisateur::Suspendu ? 'suspendu' : 'supprimé') . '.'
116 ]);
117 return;
118 }
119
120 // Connexion réussie : initialisation de la session
121 $_SESSION['user_email'] = $utilisateur->getEmailUtilisateur();
122 $_SESSION['user_pseudo'] = $utilisateur->getPseudoUtilisateur();
123 $_SESSION['user_role'] = $utilisateur->getRoleUtilisateur()?->getRoleEnum();
124 $_SESSION['user_photo'] = $utilisateur->geturlPhotoUtilisateur();
125 $_SESSION['user_logged_in'] = true;
126
127 // Réponse de succès
128 echo json_encode([
129 'success' => true,
130 'message' => 'Connexion réussie!',
131 'user' => [
132 'email' => $utilisateur->getEmailUtilisateur(),
133 'pseudo' => $utilisateur->getPseudoUtilisateur()
134 ]
135 ]);
136 } catch (Exception $e) {
137 header('Content-Type: application/json');
138 echo json_encode([
139 'success' => false,
140 'message' => 'Une erreur est survenue lors de la connexion. Veuillez réessayer plus tard (' . $e->getMessage() . ').'
141 ]);
142 }
143 }
144
156 public function signup()
157 {
158
159 if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
160 $this->show405();
161 return;
162 }
163
164 header('Content-Type: application/json');
165
166 $post = $this->getPost() ?? [];
167
168 // Types de profils autorisés
169 $allowedTypes = [
170 'artiste' => 'artiste',
171 'auditeur' => 'auditeur',
172 'producteur' => 'producteur'
173 ];
174
175 $userType = strtolower(trim($post['type'] ?? ''));
176 $nom = trim($post['nom'] ?? '');
177 $pseudo = trim($post['pseudo'] ?? '');
178 $description = trim($post['description'] ?? '');
179 $website = trim($post['website'] ?? '');
180 $email = strtolower(trim($post['email'] ?? ''));
181 $birthdate = trim($post['birthdate'] ?? '');
182 $password = $post['password'] ?? '';
183 $passwordRepeat = $post['password_repeat'] ?? '';
184 $genreId = isset($post['genre_id']) ? (int)$post['genre_id'] : null;
185
186 $errors = [];
187
188 // Validation préalable du type d'utilisateur (non dans les règles Validator)
189 if (!array_key_exists($userType, $allowedTypes)) {
190 $errors[] = 'Le type de profil sélectionné est invalide.';
191 }
192
193 // Règles de validation des données pour l'inscription
194 $signupRules = [
195 'nom' => [
196 'obligatoire' => true,
197 'type' => 'string',
198 'longueur_min' => 1,
199 'longueur_max' => 255
200 ],
201 'pseudo' => [
202 'obligatoire' => true,
203 'type' => 'string',
204 'longueur_min' => 3,
205 'longueur_max' => 50,
206 'pseudo_format' => true
207 ],
208 'description' => [
209 'obligatoire' => true,
210 'type' => 'string',
211 'longueur_min' => 10,
212 'longueur_max' => 1000
213 ],
214 'website' => [
215 'obligatoire' => false,
216 'format' => FILTER_VALIDATE_URL
217 ],
218 'email' => [
219 'obligatoire' => true,
220 'type' => 'string',
221 'longueur_min' => 5,
222 'longueur_max' => 320,
223 'format' => FILTER_VALIDATE_EMAIL
224 ],
225 'birthdate' => [
226 'obligatoire' => true,
227 'type' => 'string',
228 'age_minimum' => 13
229 ],
230 'password' => [
231 'obligatoire' => true,
232 'type' => 'string',
233 'longueur_min' => 8,
234 'longueur_max' => 128,
235 'mot_de_passe_fort' => true
236 ]
237 ];
238
239 $signupData = [
240 'nom' => $nom,
241 'pseudo' => $pseudo,
242 'description' => $description,
243 'website' => $website,
244 'email' => $email,
245 'birthdate' => $birthdate,
246 'password' => $password
247 ];
248
249 $validator = new Validator($signupRules);
250 if (!$validator->valider($signupData)) {
251 $errors = array_merge($errors, $validator->getMessagesErreurs());
252 }
253
254 // Vérification supplémentaire : confirmation du mot de passe
255 if ($password !== $passwordRepeat) {
256 $errors[] = 'Les mots de passe ne correspondent pas.';
257 }
258
259 // Pour les artistes/producteurs, vérifier la sélection d'un genre
260 if ($userType != 'auditeur') {
261 if (!$genreId) {
262 $errors[] = 'Veuillez sélectionner un genre musical.';
263 } else {
264 $genreDao = new GenreDAO($this->getPDO());
265 try {
266 $genre = $genreDao->find((int)$genreId);
267 } catch (Exception $e) {
268 $genre = null;
269 }
270 if (!$genre) {
271 $errors[] = 'Le genre sélectionné est invalide.';
272 }
273 }
274 }
275
276 // Vérification unicité de l'email et du pseudo
277 $utilisateurDAO = new UtilisateurDAO($this->getPDO());
278
279 if ($email !== '' && $utilisateurDAO->existsByEmail($email)) {
280 $errors[] = 'Un compte existe déjà avec cette adresse e-mail.';
281 }
282
283 if ($pseudo !== '' && $utilisateurDAO->existsByPseudo($pseudo)) {
284 $errors[] = 'Ce nom ou pseudonyme est déjà utilisé.';
285 }
286
287 if (!empty($errors)) {
288 echo json_encode([
289 'success' => false,
290 'message' => implode(' ', $errors)
291 ]);
292 return;
293 }
294
295 // Analyse de la date de naissance
296 $birthDateTime = DateTime::createFromFormat('Y-m-d', $birthdate);
297
298 $roleDao = new RoleDAO($this->getPDO());
299 $role = $roleDao->findByType($allowedTypes[$userType]);
300
301 if (!$role) {
302 echo json_encode([
303 'success' => false,
304 'message' => 'Impossible de déterminer le rôle à attribuer à ce compte.'
305 ]);
306 return;
307 }
308
309 $hashedPassword = password_hash($password, PASSWORD_ARGON2ID);
310 $createdAt = (new DateTime())->format('Y-m-d H:i:s');
311 $pdo = $this->getPDO();
312
313 try {
314 $utilisateur = new Utilisateur();
315 // Affectation des différents attributs de l'utilisateur
316 $utilisateur->setEmailUtilisateur($email);
317 $utilisateur->setNomUtilisateur($nom);
318 $utilisateur->setPseudoUtilisateur($pseudo);
319 $utilisateur->setMotDePasseUtilisateur($hashedPassword);
320 $dateNaissance = !empty($birthdate) ? DateTime::createFromFormat('Y-m-d', $birthdate) : null;
321 $utilisateur->setDateDeNaissanceUtilisateur($dateNaissance);
322 $utilisateur->setDateInscriptionUtilisateur(DateTime::createFromFormat('Y-m-d H:i:s', $createdAt));
323 $utilisateur->setStatutUtilisateur(\StatutUtilisateur::Actif);
324 $utilisateur->setGenreUtilisateur(isset($genre) ? $genre : null);
325 $utilisateur->setEstAbonnee(false);
326 $utilisateur->setDescriptionUtilisateur($description ?? null);
327 $utilisateur->setSiteWebUtilisateur((isset($website) && $website !== '') ? $website : null);
328 $utilisateur->setStatutAbonnement(\StatutAbonnement::Inactif);
329 $utilisateur->setDateDebutAbonnement(null);
330 $utilisateur->setDateFinAbonnement(null);
331 $utilisateur->setPointsDeRenommeeArtiste(null);
332 $utilisateur->setNbAbonnesArtiste(null);
333 $utilisateur->seturlPhotoUtilisateur(null);
334 $utilisateur->setRoleUtilisateur($role);
335
336 $creationReussie = $utilisateurDAO->create($utilisateur);
337
338 if ($creationReussie) {
339
340 $emailSender = new Email($this->getTwig());
341 $emailSender->sendWelcomeEmail(
342 $utilisateur->getEmailUtilisateur(),
343 $utilisateur->getPseudoUtilisateur(),
344 $userType
345 );
346
347 echo json_encode([
348 'success' => true,
349 'message' => 'Votre compte a été créé! Vérifiez vos e-mails pour confirmer votre inscription.',
350 'user' => [
351 'email' => $utilisateur->getEmailUtilisateur(),
352 'pseudo' => $utilisateur->getPseudoUtilisateur(),
353 'type' => $userType
354 ]
355 ]);
356 } else {
357 echo json_encode([
358 'success' => false,
359 'message' => 'Impossible de créer votre compte pour le moment.'
360 ]);
361 }
362 } catch (Exception $e) {
363 echo json_encode([
364 'success' => false,
365 'message' => 'Impossible de créer votre compte pour le moment (' . $e->getMessage() . ').'
366 ]);
367 }
368 }
369
385 public function inscription()
386 {
387 // On vérifie que l'utilisateur courant est bien un administrateur
388 $this->requireRole(RoleEnum::Admin);
389
390 $error = null;
391
392 if ($_SERVER['REQUEST_METHOD'] === 'POST') {
393 $pseudo = trim($_POST['pseudo'] ?? '');
394 $email = trim($_POST['email'] ?? '');
395 $password = $_POST['mdp'] ?? '';
396 $roleType = $_POST['role'] ?? 'auditeur';
397
398 $pdo = $this->getPDO();
399 $utilisateurDAO = new UtilisateurDAO($pdo);
400
401 // Vérification si l'e-mail ou le pseudo existe déjà
402 if ($utilisateurDAO->existsByEmail($email)) {
403 $error = "Cet email est déjà utilisé.";
404 } elseif ($utilisateurDAO->existsByPseudo($pseudo)) {
405 $error = "Ce pseudo est déjà pris.";
406 } else {
407 try {
408 $roleDao = new RoleDAO($pdo);
409 $role = $roleDao->findByType($roleType);
410
411 if ($role) {
412 $user = new Utilisateur();
413 $user->setPseudoUtilisateur($pseudo);
414 $user->setNomUtilisateur($pseudo);
415 $user->setEmailUtilisateur($email);
416 $user->setMotDePasseUtilisateur(password_hash($password, PASSWORD_ARGON2ID));
417 $user->setRoleUtilisateur($role);
418
419 $user->setDateInscriptionUtilisateur(new DateTime());
420 $user->setDateDeNaissanceUtilisateur(new DateTime('2000-01-01'));
421
422 $user->setStatutUtilisateur(\StatutUtilisateur::Actif);
423 $user->setEstAbonnee(false);
424 $user->setStatutAbonnement(\StatutAbonnement::Inactif);
425
426 $user->setGenreUtilisateur(null);
427 $user->setDescriptionUtilisateur("Compte créé par admin");
428 $user->setSiteWebUtilisateur(null);
429 $user->seturlPhotoUtilisateur(null);
430 $user->setDateDebutAbonnement(null);
431 $user->setDateFinAbonnement(null);
432 $user->setPointsDeRenommeeArtiste(0);
433 $user->setNbAbonnesArtiste(0);
434
435 if ($utilisateurDAO->create($user)) {
436 $this->redirectTo('admin', 'afficher', ['success' => 1]);
437 exit();
438 } else {
439 $error = "Erreur lors de la création en base de données.";
440 }
441 } else {
442 $error = "Rôle introuvable.";
443 }
444 } catch (Exception $e) {
445 $error = "Erreur système: " . $e->getMessage();
446 }
447 }
448 }
449
450 $template = $this->getTwig()->load('utilisateur_ajout.html.twig');
451 echo $template->render([
452 'page' => ['title' => 'Ajouter Utilisateur'],
453 'session' => $_SESSION,
454 'error' => $error
455 ]);
456 }
457
466 public function logout()
467 {
468 $_SESSION = [];
469 if (ini_get("session.use_cookies")) {
470 $params = session_get_cookie_params();
471 setcookie(
472 session_name(),
473 '',
474 time() - 42000,
475 $params["path"],
476 $params["domain"],
477 $params["secure"],
478 $params["httponly"]
479 );
480 }
481 session_destroy();
482
483 // Redirection vers la page d'accueil (controller=home, method=afficher)
484 $this->redirectTo('home', 'afficher');
485 }
486
496 public function afficherMesLikes()
497 {
498 // Vérification de la connexion de l'utilisateur
499 $this->requireAuth();
500
501 $emailUtilisateur = $_SESSION['user_email'] ?? null;
502
503 // DAO : récupération des chansons likées par l'utilisateur courant
504 $managerLike = new ChansonDAO($this->getPdo());
505 $chansonsLikees = $managerLike->findChansonsLikees($emailUtilisateur);
506
507 // Marquer toutes les chansons chargées comme étant likées
508 foreach ($chansonsLikees as $chanson) {
509 $chanson->setIsLiked(true);
510 }
511
512 // Création d'un "album virtuel" pour la page d'affichage
513 $albumVirtuel = (object) [
514 "getTitreAlbum" => function () {
515 return "Chansons Likées";
516 },
517 "getUrlImageAlbum" => function () {
518 return "public/assets/like_default.png";
519 },
520 "getArtisteAlbum" => function () {
521 return "Moi";
522 },
523 "getDateSortieAlbum" => function () {
524 return null;
525 },
526 ];
527
528 // Chargement du template Twig et affichage
529 $template = $this->getTwig()->load('chanson_album.html.twig');
530
531 echo $template->render([
532 'page' => [
533 'title' => "Chansons likées",
534 'name' => "musique_likee",
535 'description' => "Chansons likées par l'utilisateur"
536 ],
537 'album' => $albumVirtuel,
538 'chansons' => $chansonsLikees
539 ]);
540 }
541
550 public function afficherProfilArtiste()
551 {
552 // Récupération du pseudo dans la query string
553 $pseudo = $_GET['pseudo'] ?? null;
554
555 if (!$pseudo) {
556 $this->redirectTo('home', 'afficher');
557 }
558
559 $utilisateurDAO = new UtilisateurDAO($this->getPDO());
560 $albumDAO = new AlbumDAO($this->getPDO());
561
562 // Recherche de l'artiste via son pseudo
563 $utilisateur = $utilisateurDAO->findByPseudo($pseudo);
564
565 // Vérification de l'abonnement si connecté
566 $estAbonneAArtiste = false;
567 if (isset($_SESSION['user_email'])) {
568 $estAbonneAArtiste = $utilisateurDAO->estAbonneAArtiste($_SESSION['user_email'], $utilisateur->getEmailUtilisateur());
569 }
570
571 if (!$utilisateur) {
572 $this->redirectTo('home', 'afficher');
573 }
574
575 // Récupération des albums de cet artiste par son e-mail
576 $emailArtiste = $utilisateur->getEmailUtilisateur();
577
578 $albums = $albumDAO->findAllByArtistEmail($emailArtiste);
579
580 $template = $this->getTwig()->load('artiste_profil.html.twig');
581 echo $template->render([
582 'session' => $_SESSION,
583 'utilisateur' => $utilisateur,
584 'albums' => $albums,
585 'estAbonneAArtiste' => $estAbonneAArtiste
586 ]);
587 }
588
597 public function suivreArtiste()
598 {
599 header('Content-Type: application/json');
600
601 // Vérification de la connexion
602 if (!isset($_SESSION['user_email'])) {
603 echo json_encode(['success' => false, 'message' => 'Non connecté']);
604 return;
605 }
606
607 $emailArtiste = $_POST['emailArtiste'] ?? null;
608 $emailAbonne = $_SESSION['user_email'];
609
610 // --- SÉCURITÉ : Empêcher l'auto-abonnement ---
611 if ($emailAbonne === $emailArtiste) {
612 echo json_encode([
613 'success' => false,
614 'message' => 'Vous ne pouvez pas vous abonner à votre propre profil.'
615 ]);
616 return;
617 }
618
619 // Traitement de l'abonnement/désabonnement
620 if ($emailArtiste) {
621 $dao = new UtilisateurDAO($this->getPDO());
622 $result = $dao->basculerAbonnement($emailAbonne, $emailArtiste);
623
624 $increment = ($result === 'followed') ? 1 : -1;
625 $dao->updateNbAbonnes($emailArtiste, $increment);
626
627 $artisteAJour = $dao->find($emailArtiste);
628 $nouveauNombre = $artisteAJour ? $artisteAJour->getNbAbonnesArtiste() : 0;
629
630 echo json_encode([
631 'success' => true,
632 'action' => $result,
633 'newText' => ($result === 'followed') ? 'Abonné(e)' : 'S\'abonner',
634 'nbAbonnes' => $nouveauNombre
635 ]);
636 } else {
637 echo json_encode(['success' => false, 'message' => 'Email artiste manquant']);
638 }
639 }
640
649 public function afficherMotDePasseOublie()
650 {
651 $template = $this->getTwig()->load('forgot_password.html.twig');
652 echo $template->render([
653 'page' => [
654 'title' => 'Mot de passe oublié - Paaxio',
655 'name' => 'forgot_password',
656 'description' => 'Réinitialiser votre mot de passe Paaxio'
657 ],
658 'session' => $_SESSION
659 ]);
660 }
661
676 public function demanderReinitialisation()
677 {
678
679 if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
680 $this->show405();
681 return;
682 }
683
684 header('Content-Type: application/json');
685
686 $post = $this->getPost();
687 $email = strtolower(trim($post['email'] ?? ''));
688
689 // Validation de l'email
690 $rules = [
691 'email' => [
692 'obligatoire' => true,
693 'type' => 'string',
694 'format' => FILTER_VALIDATE_EMAIL
695 ]
696 ];
697
698 $validator = new Validator($rules);
699 if (!$validator->valider(['email' => $email])) {
700 echo json_encode([
701 'success' => false,
702 'message' => 'Veuillez fournir une adresse email valide.'
703 ]);
704 return;
705 }
706
707 try {
708 $utilisateurDAO = new UtilisateurDAO($this->getPDO());
709 $utilisateur = $utilisateurDAO->find($email);
710
711 // Message de succès identique dans tous les cas (sécurité)
712 $messageSucces = 'Si cette adresse email est associée à un compte, vous recevrez un email de réinitialisation dans quelques instants.';
713
714 // Si l'utilisateur n'existe pas, on retourne quand même un succès
715 // pour éviter l'énumération des adresses email
716 if (!$utilisateur) {
717 echo json_encode([
718 'success' => true,
719 'message' => $messageSucces
720 ]);
721 return;
722 }
723
724 // Vérification que le compte est actif
725 $statut = $utilisateur->getStatutUtilisateur();
726 if ($statut && $statut !== StatutUtilisateur::Actif) {
727 echo json_encode([
728 'success' => true,
729 'message' => $messageSucces
730 ]);
731 return;
732 }
733
734 // Création du token de réinitialisation
735 $tokenDAO = new PasswordResetTokenDAO($this->getPDO());
736 $token = $tokenDAO->create($email);
737
738 if (!$token) {
739 echo json_encode([
740 'success' => false,
741 'message' => 'Une erreur est survenue. Veuillez réessayer plus tard.'
742 ]);
743 return;
744 }
745
746 // Envoi de l'email de réinitialisation
747 $emailSender = new Email($this->getTwig());
748 $emailSender->sendPasswordResetEmail(
749 $utilisateur->getEmailUtilisateur(),
750 $utilisateur->getPseudoUtilisateur(),
751 $token->getToken()
752 );
753
754 echo json_encode([
755 'success' => true,
756 'message' => $messageSucces
757 ]);
758 } catch (Exception $e) {
759 error_log('Erreur réinitialisation mot de passe: ' . $e->getMessage());
760 echo json_encode([
761 'success' => false,
762 'message' => 'Une erreur est survenue. Veuillez réessayer plus tard.'
763 ]);
764 }
765 }
766
776 public function resetPassword()
777 {
778 $get = $this->getGet();
779 $tokenValue = $get['token'] ?? '';
780
781 if (empty($tokenValue)) {
782 $this->afficherErreurToken('Lien de réinitialisation invalide.');
783 return;
784 }
785
786 try {
787 $tokenDAO = new PasswordResetTokenDAO($this->getPDO());
788 $token = $tokenDAO->findValidToken($tokenValue);
789
790 if (!$token) {
791 $this->afficherErreurToken('Ce lien de réinitialisation est invalide ou a expiré. Veuillez faire une nouvelle demande.');
792 return;
793 }
794
795 // Récupérer les informations de l'utilisateur
796 $utilisateurDAO = new UtilisateurDAO($this->getPDO());
797 $utilisateur = $utilisateurDAO->find($token->getEmailUtilisateur());
798
799 $template = $this->getTwig()->load('reset_password.html.twig');
800 echo $template->render([
801 'page' => [
802 'title' => 'Nouveau mot de passe - Paaxio',
803 'name' => 'reset_password',
804 'description' => 'Définir un nouveau mot de passe pour votre compte Paaxio'
805 ],
806 'session' => $_SESSION,
807 'token' => $tokenValue,
808 'pseudo' => $utilisateur ? $utilisateur->getPseudoUtilisateur() : ''
809 ]);
810 } catch (Exception $e) {
811 error_log('Erreur affichage reset password: ' . $e->getMessage());
812 $this->afficherErreurToken('Une erreur est survenue. Veuillez réessayer.');
813 }
814 }
815
827 public function traiterReinitialisation()
828 {
829
830 if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
831 $this->show405();
832 return;
833 }
834
835 header('Content-Type: application/json');
836
837 $post = $this->getPost();
838 $tokenValue = trim($post['token'] ?? '');
839 $password = $post['password'] ?? '';
840 $passwordRepeat = $post['password_repeat'] ?? '';
841
842 // Validation des données
843 $errors = [];
844
845 if (empty($tokenValue)) {
846 $errors[] = 'Token de réinitialisation manquant.';
847 }
848
849 // Règles de validation du mot de passe
850 $passwordRules = [
851 'password' => [
852 'obligatoire' => true,
853 'type' => 'string',
854 'longueur_min' => 8,
855 'longueur_max' => 128,
856 'mot_de_passe_fort' => true
857 ]
858 ];
859
860 $validator = new Validator($passwordRules);
861 if (!$validator->valider(['password' => $password])) {
862 $errors = array_merge($errors, $validator->getMessagesErreurs());
863 }
864
865 // Vérification de la confirmation du mot de passe
866 if ($password !== $passwordRepeat) {
867 $errors[] = 'Les mots de passe ne correspondent pas.';
868 }
869
870 if (!empty($errors)) {
871 echo json_encode([
872 'success' => false,
873 'message' => implode(' ', $errors)
874 ]);
875 return;
876 }
877
878 try {
879 $tokenDAO = new PasswordResetTokenDAO($this->getPDO());
880 $token = $tokenDAO->findValidToken($tokenValue);
881
882 if (!$token) {
883 echo json_encode([
884 'success' => false,
885 'message' => 'Ce lien de réinitialisation est invalide ou a expiré. Veuillez faire une nouvelle demande.'
886 ]);
887 return;
888 }
889
890 // Mettre à jour le mot de passe
891 $updateResult = $tokenDAO->updatePassword($token->getEmailUtilisateur(), $password);
892
893 if (!$updateResult) {
894 echo json_encode([
895 'success' => false,
896 'message' => 'Une erreur est survenue lors de la mise à jour du mot de passe.'
897 ]);
898 return;
899 }
900
901 // Marquer le token comme utilisé
902 $tokenDAO->markAsUsed($tokenValue);
903
904 // Invalider tous les autres tokens de cet utilisateur
905 $tokenDAO->invalidateTokensForUser($token->getEmailUtilisateur());
906
907 echo json_encode([
908 'success' => true,
909 'message' => 'Votre mot de passe a été réinitialisé avec succès. Vous pouvez maintenant vous connecter.'
910 ]);
911 } catch (Exception $e) {
912 error_log('Erreur traitement réinitialisation: ' . $e->getMessage());
913 echo json_encode([
914 'success' => false,
915 'message' => 'Une erreur est survenue. Veuillez réessayer plus tard.'
916 ]);
917 }
918 }
919
920
921
931 private function afficherErreurToken(string $message): void
932 {
933 $template = $this->getTwig()->load('reset_password_error.html.twig');
934 echo $template->render([
935 'page' => [
936 'title' => 'Lien expiré - Paaxio',
937 'name' => 'reset_password_error',
938 'description' => 'Lien de réinitialisation invalide'
939 ],
940 'session' => $_SESSION,
941 'error_message' => $message
942 ]);
943 }
944
954 public function afficherGestionProfil(){
955 // Vérifier si l'utilisateur est connecté
956 if (!isset($_SESSION['user_email'])) {
957 $this->redirectTo('home', 'afficher');
958 }
959
960 $uDAO = new UtilisateurDAO($this->getPDO());
961 $user = $uDAO->find($_SESSION['user_email']);
962
963 // Préparation de la date pour l'input HTML5 (format YYYY-MM-DD)
964 $dateNaissance = "";
965 if ($user && $user->getDateDeNaissanceUtilisateur()) {
966 $dateNaissance = $user->getDateDeNaissanceUtilisateur()->format('Y-m-d');
967 }
968
969 $template = $this->getTwig()->load('utilisateur_gestion_profil.html.twig');
970 echo $template->render([
971 'page' => [
972 'title' => "Gestion du Profil",
973 'name' => "gestion_profil"
974 ],
975 'user' => $user,
976 'dateNaissance' => $dateNaissance,
977 'session' => $_SESSION
978 ]);
979 }
980
990 public function enregistrerProfil()
991 {
992 // Sécurité : vérifier la session et la méthode POST
993 if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_SESSION['user_email'])) {
994 $this->redirectTo('home', 'afficher');
995 }
996
997 $uDAO = new UtilisateurDAO($this->getPDO());
998 $emailActuel = $_SESSION['user_email']; //Pour récupérer l'ancien email
999 $user = $uDAO->find($emailActuel);
1000
1001 if (!$user) {
1002 $this->redirectTo('home', 'afficher');
1003 }
1004
1005 // Mise à jour des champs textuels
1006 $user->setPseudoUtilisateur($_POST['pseudo'] ?? $user->getPseudoUtilisateur());
1007 $user->setDescriptionUtilisateur($_POST['description'] ?? $user->getDescriptionUtilisateur());
1008 $user->setNomUtilisateur($_POST['nom'] ?? $user->getNomUtilisateur());
1009 $user->setEmailUtilisateur($_POST['email'] ?? $user->getEmailUtilisateur());
1010
1011 // Gestion de la date de naissance
1012 $birthdate = $_POST['birthdate'] ?? '';
1013 if (!empty($birthdate)) {
1014 try {
1015 $dateObj = new DateTime($birthdate);
1016 // Vérification de sécurité : année supérieure à 1920
1017 if ($dateObj->format('Y') > 1920) {
1018 $user->setDateDeNaissanceUtilisateur($dateObj);
1019 }
1020 } catch (Exception $e) {
1021 // En cas d'erreur de format, on ne change rien
1022 }
1023 }
1024
1025 // Gestion du genre
1026 if (isset($_POST['genre_id'])) {
1027 $genreDAO = new GenreDAO($this->getPDO());
1028 $genre = $genreDAO->find((int)$_POST['genre_id']);
1029 if ($genre) {
1030 $user->setGenreUtilisateur($genre);
1031 }
1032 }
1033
1034 // Gestion du téléversement de la photo de profil
1035 if (isset($_FILES['photo']) && $_FILES['photo']['error'] === UPLOAD_ERR_OK) {
1036 $uploadDir = 'assets/images/profile_pictures/';
1037
1038 if (!is_dir($uploadDir)) {
1039 mkdir($uploadDir, 0777, true);
1040 }
1041
1042 $extension = pathinfo($_FILES['photo']['name'], PATHINFO_EXTENSION);
1043 $nomFichier = 'profile_' . uniqid() . '.' . $extension;
1044 $cheminCible = $uploadDir . $nomFichier;
1045
1046 if (move_uploaded_file($_FILES['photo']['tmp_name'], $cheminCible)) {
1047 $anciennePhoto = $user->geturlPhotoUtilisateur();
1048 // Supprimer l'ancienne photo si elle existe y no es la default
1049 if ($anciennePhoto && strpos($anciennePhoto, 'default.png') === false && file_exists($anciennePhoto)) {
1050 @unlink($anciennePhoto);
1051 }
1052 $user->seturlPhotoUtilisateur($cheminCible);
1053 }
1054 }
1055
1056 //Persistance des modifications
1057 if ($uDAO->update($user, $emailActuel)) {
1058 // Mettre à jour la session
1059 $_SESSION['user_pseudo'] = $user->getPseudoUtilisateur();
1060 $_SESSION['user_photo'] = $user->geturlPhotoUtilisateur();
1061
1062 // Redirection avec message de succès
1063 $_SESSION['user_email'] = $user->getEmailUtilisateur();
1064
1065 // Redirection avec message de succès
1066 $this->redirectTo('utilisateur', 'afficherGestionProfil', ['success' => 1]);
1067 }
1068 }
1069
1075 public function afficherSecurite()
1076 {
1077 if (!isset($_SESSION['user_email'])) {
1078 $this->redirectTo('home', 'afficher');
1079 }
1080
1081 $template = $this->getTwig()->load('utilisateur_securite.html.twig');
1082 echo $template->render([
1083 'page' => ['title' => "Sécurité - Paaxio", 'name' => "securite"],
1084 'session' => $_SESSION
1085 ]);
1086 }
1087
1097 public function modifierMotDePasse()
1098 {
1099 if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_SESSION['user_email'])) {
1100 $this->redirectTo('home', 'afficher');
1101 }
1102
1103 $uDAO = new UtilisateurDAO($this->getPDO());
1104 $user = $uDAO->find($_SESSION['user_email']);
1105
1106 // Clause de garde : vérifier si l'utilisateur existe toujours en base
1107 if (!$user) {
1108 $this->redirectTo('home', 'afficher');
1109 }
1110
1111 $actuel = $_POST['ancien_mdp'] ?? '';
1112 $nouveau = $_POST['nouveau_mdp'] ?? '';
1113 $repeter = $_POST['repeter_mdp'] ?? '';
1114
1115 // Vérifier le mot de passe actuel
1116 if (!password_verify($actuel, $user->getMotDePasseUtilisateur())) {
1117 $this->redirectTo('utilisateur', 'afficherSecurite', ['error' => 'actuel']);
1118 }
1119
1120 // Vérifier la correspondance des deux nouveaux mots de passe
1121 if ($nouveau !== $repeter) {
1122 $this->redirectTo('utilisateur', 'afficherSecurite', ['error' => 'match']);
1123 }
1124
1125 // Vérifier la force du mot de passe (Regex)
1126 $regex = '/^(?=.*[a-zA-Z])(?=.*[0-9!@#$%^&*(),.?":{}|<>]).{10,}$/';
1127 if (!preg_match($regex, $nouveau)) {
1128 $this->redirectTo('utilisateur', 'afficherSecurite', ['error' => 'force']);
1129 }
1130
1131 // Hachage avec ARGON2ID et mise à jour
1132 $user->setMotDePasseUtilisateur(password_hash($nouveau, PASSWORD_ARGON2ID));
1133
1134 if ($uDAO->update($user)) {
1135 // Déconnexion forcée après changement réussi pour obliger la reconnexion
1136 session_destroy();
1137 $this->redirectTo('home', 'afficher', ['success_psw' => 1]);
1138 } else {
1139 $this->redirectTo('utilisateur', 'afficherSecurite', ['error' => 'db']);
1140 }
1141 }
1142
1151 public function supprimerCompte()
1152 {
1153 if (!isset($_SESSION['user_email'])) {
1154 $this->redirectTo('home', 'afficher');
1155 }
1156
1157 $uDAO = new UtilisateurDAO($this->getPDO());
1158
1159 // Suppression en base de données
1160 if ($uDAO->delete($_SESSION['user_email'])) {
1161 // Destruction de la session
1162 session_destroy();
1163 $this->redirectTo('home', 'afficher', ['account_deleted' => 1]);
1164 } else {
1165 $this->redirectTo('utilisateur', 'afficherSecurite', ['error' => 'delete_fail']);
1166 }
1167 }
1168
1177 public function afficherAbonnement()
1178 {
1179 if (!isset($_SESSION['user_email'])) {
1180 $this->redirectTo('home', 'afficher');
1181 }
1182
1183 $uDAO = new UtilisateurDAO($this->getPDO());
1184 $user = $uDAO->find($_SESSION['user_email']);
1185
1186 $template = $this->getTwig()->load('utilisateur_abonnement.html.twig');
1187 echo $template->render([
1188 'page' => ['title' => "Abonnement - Paaxio", 'name' => "abonnement"],
1189 'user' => $user,
1190 'session' => $_SESSION
1191 ]);
1192 }
1193
1194}
Contrôleur dédié à la gestion des utilisateurs.
afficherMotDePasseOublie()
Affiche le formulaire de mot de passe oublié.
modifierMotDePasse()
Traite la modification du mot de passe avec vérifications de sécurité.
demanderReinitialisation()
Traite la demande de réinitialisation de mot de passe.
afficherGestionProfil()
Affiche la page de gestion du profil de l'utilisateur connecté.
afficherErreurToken(string $message)
Affiche une page d'erreur pour les tokens invalides.
afficherProfilArtiste()
Affiche le profil public d'un artiste.
signup()
Gère l'inscription d'un nouvel utilisateur.
supprimerCompte()
Supprime définitivement le compte de l'utilisateur connecté.
logout()
Déconnecte l'utilisateur et détruit la session.
__construct(\Twig\Environment $twig, \Twig\Loader\FilesystemLoader $loader)
Constructeur du contrôleur utilisateur.
resetPassword()
Affiche le formulaire de réinitialisation de mot de passe.
inscription()
Gère la création d'un nouvel utilisateur par l'administrateur.
traiterReinitialisation()
Traite la réinitialisation du mot de passe.
afficherSecurite()
Affiche la page de sécurité (modification du mot de passe).
afficherAbonnement()
Affiche la page de gestion de l'abonnement.
afficherMesLikes()
Affiche la page des chansons aimées (likées) par l'utilisateur connecté.
enregistrerProfil()
Traite et enregistre les modifications du profil utilisateur.
suivreArtiste()
Gère l'abonnement/désabonnement à un artiste via une requête AJAX.
signin()
Gère la connexion (authentification) d'un utilisateur.
Classe de base pour tous les contrôleurs de l'application.
getPost()
Récupère les données POST.
Twig Environment $twig
requireRole($requiredRole)
Exige que l'utilisateur ait un rôle spécifique.
show405()
Affiche une erreur 405 Méthode non autorisée.
redirectTo(string $controller, string $method, array $params=[])
Redirige vers un contrôleur et une méthode donnés.
getGet()
Récupère les données GET.
requireAuth(string $controller='', string $method='', array $params=[])
Exige que l'utilisateur soit authentifié.
Twig Loader FilesystemLoader $loader
getPDO()
Récupère la connexion PDO.
getTwig()
Récupère l'environnement Twig.
Classe de gestion des emails pour Paaxio Utilise PHPMailer pour l'envoi d'emails via SMTP.
Data Access Object pour les tokens de réinitialisation de mot de passe.
Permet de valider des données selon des règles spécifiées.
$genreDAO
Definition include.php:329