<?php
namespace App\Controller;
use App\DTO\UserDTO;
use App\Entity\ActiviteUser;
use App\Entity\Diplome;
use App\Entity\Enum\EnglishLevel;
use App\Entity\Enum\SkillLevel;
use App\Entity\Experience;
use App\Entity\Skill;
use App\Entity\Society;
use App\Entity\User;
use App\Form\FreelanceRegisterFormType;
use App\Form\RegistrationFormType;
use App\Form\ResetPasswordRequestFormType;
use App\Form\SocietyRegisterFormType;
use App\Security\AppAuthenticator;
use App\Security\EmailVerifier;
use App\Service\Upload\AvatarUploader;
use App\Service\Upload\PDFUploader;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Proxies\__CG__\App\Entity\Diplome as AppEntityDiplome;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
class AuthController extends AbstractController
{
/**
* @var EmailVerifier
*/
private $emailVerifier;
public function __construct(
EmailVerifier $emailVerifier
) {
$this->emailVerifier = $emailVerifier;
}
/**
* @Route("/api/user", name="api_user", methods={"GET"})
* @IsGranted("ROLE_USER")
*/
public function getUserInfo(): JsonResponse
{
$user = $this->getUser();
dd($user);
return $this->json([
'id' => $user->getId(),
'email' => $user->getEmail(),
]);
}
/**
* @Route("/inscription", name="register_freelance")
* @param Request $request
* @param UserPasswordHasherInterface $userPasswordHasher
* @param EntityManagerInterface $entityManager
* @param UserAuthenticatorInterface $authenticator
* @param AppAuthenticator $formAuthenticator
* @return Response|null
* @throws Exception
*/
public function registerFreelance(
Request $request,
UserPasswordHasherInterface $userPasswordHasher,
EntityManagerInterface $entityManager,
UserAuthenticatorInterface $authenticator,
AppAuthenticator $formAuthenticator
): ?Response {
$user = new User();
$user->setCreatedAt(new DateTime());
$user->setRoles(['ROLE_FREELANCE']);
$user->setType('freelance');
$user->setPhone('');
$user->setFirstname('');
$user->setLastname('');
$form = $this->createForm(FreelanceRegisterFormType::class, $user);
$form->handleRequest($request);
$isErrorEmail = false;
if ($form->isSubmitted() && $form->isValid()) {
// $recaptchaToken = $form->get('recaptchaToken')->getData();
// if (!$this->verifyRecaptcha($recaptchaToken)) {
// $this->addFlash('error', 'reCAPTCHA a détecté une activité suspecte.');
// return $this->redirectToRoute('register_freelance');
// }
$user->setPassword($userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
));
$entityManager->persist($user);
$entityManager->flush();
$activiteUser = new ActiviteUser(
"Inscription par mail",
$user
);
$entityManager->persist($activiteUser);
$entityManager->flush();
try {
$this->sendConfirmation($user);
$this->addFlash('email_validation_send', true);
return $authenticator->authenticateUser($user, $formAuthenticator, $request);
} catch (Exception $e) {
return $authenticator->authenticateUser($user, $formAuthenticator, $request);
}
}
return $this->render('auth/register_freelance_new.html.twig', [
'form' => $form->createView(),
'is_error_mail' => $isErrorEmail
]);
}
private function verifyRecaptcha(string $recaptchaToken): bool
{
$secretKey = $this->getParameter('google_recaptcha_secret_key');
$response = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret=' . $secretKey . '&response=' . $recaptchaToken);
$data = json_decode($response, true);
return $data['success'] && $data['score'] > 0.5;
}
/**
* @Route("/inscription", name="register")
*/
public function register(
Request $request,
UserPasswordHasherInterface $userPasswordHasher,
EntityManagerInterface $entityManager,
UserAuthenticatorInterface $authenticator,
AppAuthenticator $formAuthenticator
): ?Response {
if ($this->getUser()) {
$user = $this->getUser();
$route = $user->isAdmin() ? 'admin_dashboard' : 'homepage';
return $this->redirectToRoute($route);
}
$user = new User();
$user->setCreatedAt(new DateTime());
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$form['email']->addError(new FormError('Veuillez saisir un email valide'));
$user->setPassword($userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
));
$role = $user->isFreelance() ? "ROLE_FREELANCE" : "ROLE_SOCIETY";
$user->setRoles(["ROLE_USER", $role]);
$entityManager->persist($user);
$entityManager->flush();
$this->sendConfirmation($user);
$this->addFlash('email_validation_send', true);
return $authenticator->authenticateUser($user, $formAuthenticator, $request);
}
return $this->render('auth/register.html.twig', ['registrationForm' => $form->createView()]);
}
/**
* @Route("/inscription-entreprise", name="register_society")
*/
public function registerSociety(
Request $request,
UserPasswordHasherInterface $userPasswordHasher,
EntityManagerInterface $entityManager,
UserAuthenticatorInterface $authenticator,
AppAuthenticator $formAuthenticator
): ?Response {
$user = new User();
$form = $this->createForm(SocietyRegisterFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setCreatedAt(new DateTime());
$user->setRoles(['ROLE_SOCIETY']);
$user->setType('society');
$user->setPhone($form->get('phone')->getData());
$user->setPassword($userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
));
$society = new Society();
$society->setName($form->get('name')->getData());
$society->setType($form->get('typeSociete')->getData());
$society->setCa(0);
$society->setAdress('');
$society->setVille('');
$society->setDescription('');
$society->setPhone('');
$society->setNbMission($form->get('nb_mission')->getData());
$society->setPostIntercontrat($form->get('post_intercontrat')->getData());
$user->setPhone($form->get('phone')->getData());
$society->setUser($user);
$entityManager->persist($user);
$entityManager->persist($society);
$entityManager->flush();
$society->updateSlug();
$entityManager->persist($society);
$entityManager->flush();
// $this->sendConfirmation($user);
// $this->addFlash('email_validation_send', true);
/* @changeLog 2022-11-03 [FIX] (Anthony) Mise en place d'une redirection après inscription compte entreprise */
$this->addFlash('success', 'Votre compte entreprise a été créé avec succès, notre équipe va vous contacter rapidement pour la validation de votre compte.');
return $this->redirectToRoute('login');
}
return $this->render('auth/register_society_new.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/verify/resend", name="resend_verification")
*/
public function resendVerificationEmail(Request $request): Response
{
if ($this->getUser()) {
$this->sendConfirmation($this->getUser());
return $this->redirectToRoute('dashboard');
}
return $this->redirectToRoute('homepage');
}
private function sendConfirmation(UserInterface $user)
{
$this->emailVerifier->sendEmailConfirmation(
'verify_email',
$user,
(new TemplatedEmail())
->from(new Address('ne-pas-repondre@workdispo.com', 'workdispo.com'))
->to($user->getEmail())->subject('Veuillez confirmer votre email')
->htmlTemplate('emails/confirmation_email.html.twig')
);
}
/**
* @Route("/verify/email", name="verify_email")
*/
public function verifyUserEmail(Request $request): Response
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
// validate email confirmation link, sets User::isVerified=true and persists
try {
$this->emailVerifier->handleEmailConfirmation($request, $this->getUser());
} catch (VerifyEmailExceptionInterface $exception) {
$this->addFlash('verify_email_error', $exception->getReason());
return $this->redirectToRoute('register');
}
// return $this->redirectToRoute('dashboard');
return $this->redirectToRoute('dashboard');
}
/**
* @Route("/connexion", name="login")
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
/** @var User $user */
$user = $this->getUser();
$route = $user->isAdmin() ? 'admin_dashboard' : 'homepage';
return $this->redirectToRoute($route);
}
$resetForm = $this->createForm(ResetPasswordRequestFormType::class);
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('auth/login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
'resetForm' => $resetForm->createView(),
]);
}
/**
* @Route("/deconnexion", name="logout")
*/
public function logout(): Response
{
return $this->redirectToRoute('homepage');
}
/**
* @Route("/api/register", name="api_register", methods={"POST"})
*/
public function apiRegister(
Request $request,
UserPasswordHasherInterface $passwordHasher,
EntityManagerInterface $entityManager,
SerializerInterface $serializer,
ValidatorInterface $validator,
JWTTokenManagerInterface $jwtManager
): JsonResponse {
$data = $request->getContent();
// Désérialiser les données JSON en DTO
$userDTO = $serializer->deserialize($data, UserDTO::class, 'json');
// Valider les données du DTO
$errors = $validator->validate($userDTO);
$errorMessages = [];
if (count($errors) > 0) {
foreach ($errors as $error) {
$errorMessages[] = $error->getMessage();
}
}
// Vérifier si l'email existe déjà
if ($entityManager->getRepository(User::class)->findOneBy(['email' => $userDTO->email])) {
$errorMessages[] = 'Cet email est déjà utilisé.';
}
// S'il y a des erreurs, on les retourne sous forme d'un tableau
if (!empty($errorMessages)) {
return new JsonResponse(['errors' => $errorMessages], Response::HTTP_BAD_REQUEST);
}
// Création de l'utilisateur
$user = new User();
$user->setCreatedAt(new DateTime());
$user->setRoles(['ROLE_FREELANCE']);
$user->setType('freelance');
$user->setPhone('');
$user->setFirstname('');
$user->setLastname('');
$user->setEmail($userDTO->email);
$user->setPassword($passwordHasher->hashPassword($user, $userDTO->password));
$entityManager->persist($user);
$entityManager->flush();
// Génération du token JWT
$token = $jwtManager->create($user);
return new JsonResponse([
'message' => 'Inscription réussie.',
'token' => $token
], Response::HTTP_CREATED);
}
/**
* @Route("/api/checkProfile", name="api_check_profile", methods={"GET"})
* @IsGranted("ROLE_FREELANCE")
*/
public function checkProfile(Request $request): JsonResponse
{
$user = $this->getUser();
$profile = $user->hasProfile();
if (!$profile) {
return new JsonResponse(['message' => 'Profil non renseigné.'], Response::HTTP_BAD_REQUEST);
}
return new JsonResponse(['message' => 'Profil renseigné.'], Response::HTTP_OK);
}
/**
* @Route("/api/checkProfileFinished", name="api_check_profile_finished", methods={"GET"})
* @IsGranted("ROLE_FREELANCE")
*/
public function checkProfileFinished(Request $request): JsonResponse
{
$user = $this->getUser();
$profile = $user->hasProfile();
if (!$profile) {
return new JsonResponse(['message' => 'Profil non renseigné.'], Response::HTTP_BAD_REQUEST);
}
$finished = $user->getUniqueProfile()->getFinished();
if ($finished === 0 || $finished === false) {
return new JsonResponse(['message' => 'Profil non terminé.'], Response::HTTP_BAD_REQUEST);
}
return new JsonResponse(['message' => 'Profil terminé.'], Response::HTTP_OK);
}
/**
* @Route("/api/complete_before", name="complete_resume_profile_before_api", methods={"POST"})
* @IsGranted("ROLE_FREELANCE")
*/
public function completeResumeBeforeApi(
Request $request,
EntityManagerInterface $entityManager,
PDFUploader $pdfUploader,
AvatarUploader $avatarUploader,
SessionInterface $session
): Response {
/* @var User $user */
$user = $this->getUser();
$profile = $user->getUniqueProfile();
// REDIRECT IF COMPLETE
if ($profile->getTitle()) {
return $this->json(['message' => 'Profil déjà renseigné.'], Response::HTTP_BAD_REQUEST);
}
$profile->setContrats(null);
$profile->setIsVisible(true);
$isNew = false;
if (!$profile->getId()) {
$isNew = true;
$profile->setUrl($profile->getName());
}
$jsonData = $session->get('generated_content', null);
$cvFile = $session->get('cv_file');
$profile->setCvname($cvFile);
$profile->setCvFile($cvFile);
$profile->setCdi('Non');
$profile->setDisponibility('Immédiate');
$data = json_decode($jsonData, true);
// dd($data['Compétences']);
if (!empty($data['Compétences'])) {
foreach ($data['Compétences'] as $competence => $levelName) {
$newCompetence = new Skill();
$newCompetence->setName($competence);
// Utilisation de SkillLevel::LIST pour convertir le nom du niveau en entier
$level = is_string($levelName) && isset(SkillLevel::LIST[$levelName])
? SkillLevel::LIST[$levelName]
: SkillLevel::BEGINNER;
// Par défaut 'Débutant' si le niveau n'est pas trouvé
$newCompetence->setLevel($level);
$profile->addSkill($newCompetence);
}
}
(!empty($data['tjm']) && $data['tjm'] != '') ? $profile->setCost((int)$data['tjm']) : $profile->setCost(0);
(!empty($data['region']) && $data['region'] != '') ? $profile->setMobility([$data['region']]) : $profile->setMobility(["Toute la France"]);
(!empty($data['anglais'])) ? $profile->setEnglishLevel($data['anglais']) : $profile->setEnglishLevel(EnglishLevel::NOTION);
// !empty($data['legalStatus']) ? $profile->setLegalStatus($data['legalStatus']) : $profile->setLegalStatus(LegalStatus::RELFEXION);
!empty($data['legalStatus']) && $data['legalStatus'] !== "En réflexion" ? $profile->setLegalStatus($data['legalStatus']) : $profile->setLegalStatus('');
(!empty($data['année_experience'])) ? $profile->setExperienceNumber($data['année_experience']) : $profile->setExperienceNumber('N/A');
(!empty($data['cp_ville'])) ? $profile->setLocation($data['cp_ville']) : $profile->setLocation('N/A');
(!empty($data['Poste'])) ? $profile->setTitle($data['Poste']) : $profile->setTitle('N/A');
(!empty($data['nom'])) ? $profile->setName($data['nom']) : $profile->setName('Anonyme');
(!empty($data['prenom'])) ? $profile->setFirstname($data['prenom']) : $profile->setFirstname('Anonyme');
if (isset($data['diplômes'])) {
$diplomeData = $data['diplômes'];
} else {
$diplomeData = null; // Ou définir une valeur par défaut appropriée
}
// dd($diplomeData);
if (!empty($diplomeData)) {
$newDiplome = new Diplome();
if (array_values($diplomeData) !== $diplomeData) {
$newDiplome->setTitle($diplomeData['title'])
->setUniversity($diplomeData['university'] ?? '')
->setLevel($diplomeData['level'] ?? '');
if (isset($diplomeData['obtentionYear']) && is_numeric($diplomeData['obtentionYear'])) {
$obtentionYear = (int)$diplomeData['obtentionYear'];
error_log('Obtention Year: ' . $obtentionYear);
$newDiplome->setObtentionYear($obtentionYear);
}
$profile->addDiplome($newDiplome);
} else {
foreach ($diplomeData as $diplome) {
$newDiplome->setTitle($diplome['title'])
->setUniversity($diplome['university'] ?? '')
->setLevel($diplome['level'] ?? '');
if (isset($diplome['obtentionYear']) && is_numeric($diplome['obtentionYear'])) {
$obtentionYear = (int)$diplome['obtentionYear'];
error_log('Obtention Year: ' . $obtentionYear);
$newDiplome->setObtentionYear($obtentionYear);
}
$profile->addDiplome($newDiplome);
}
}
}
$profile->setPhone(empty(json_decode($jsonData, true)['telephone'] ?? 'N/A') ?? $profile->setPhone('Non spécifié'));
if (isset($data['experience'])) {
$experienceData = $data['experience'];
} else {
$experienceData = null; // Ou définir une valeur par défaut appropriée
}
if (!empty($experienceData)) {
if (isset($experienceData['title'])) {
// Single $experienceDataapeta object, handle it directly
$experienceData = [$experienceData];
}
// Process the JSON data and add experiences to the profile
foreach ($experienceData as $experience) {
$newExperience = new Experience();
$newExperience->setEmployer($experience['employer'] ?? '');
// Set end_at to the last day of the current year if empty
if (empty($experience['end_at'])) {
$currentYear = date('Y');
$endAt = new \DateTime("$currentYear-12-31");
} else {
try {
$endAt = new \DateTime($experience['end_at']);
} catch (\Exception $e) {
// Handle invalid date format by setting a default date
$endAt = new \DateTime("$currentYear-12-31");
}
}
$newExperience->setEndAt($endAt);
if (isset($experience['environment_tech'])) {
if (is_array($experience['environment_tech'])) {
$environmentTech = implode(', ', $experience['environment_tech']);
} else {
$environmentTech = $experience['environment_tech'];
}
} else {
$environmentTech = ''; // Valeur par défaut si 'environment_tech' n'existe pas
}
if (isset($experience['missions'])) {
if (is_array($experience['missions'])) {
// Convertir le tableau en chaîne de caractères avec des sauts de ligne
$missions = implode("\n", $experience['missions']);
} else {
// Vérifier si 'missions' est déjà une chaîne de caractères
$missions = $experience['missions'];
}
} else {
// Définir une valeur par défaut si 'missions' n'existe pas
$missions = '';
}
try {
$startAt = isset($experience['start_at']) ? new \DateTime($experience['start_at']) : new \DateTime();
} catch (\Exception $e) {
// Utiliser une date par défaut ou gérer l'erreur
$startAt = new \DateTime(); // Date actuelle ou une autre valeur par défaut
}
$newExperience->setEnvironment($environmentTech)
->setMissions($missions)
->setStartAt($startAt);
// Assurez-vous que 'title' est toujours une chaîne de caractères
$title = $experience['title'] ?? '';
if (!is_string($title)) {
$title = '';
}
$newExperience->setTitle($title);
$profile->addExperience($newExperience);
}
}
// Vérifier si la clé 'certifications' existe
if (isset($data['certifications'])) {
$certificationData = $data['certifications'];
} else {
$certificationData = null; // Ou définir une valeur par défaut appropriée
}
if (isset($data['anglais'])) {
$anglais = $data['anglais'];
// Mapper des valeurs possibles aux niveaux de la classe
$levelMapping = [
'notions' => EnglishLevel::NOTION,
'technique' => EnglishLevel::TECHNIQUE,
'courant' => EnglishLevel::COURANT,
];
$englishLevel = $levelMapping[strtolower($anglais)] ?? EnglishLevel::NOTION; // Niveau par défaut
// dd($englishLevel);
$profile->setEnglishLevel($englishLevel);
}
if (!empty($certificationData)) {
foreach ($certificationData as $certification) {
$newCertification = new Certification();
$newCertification->setTitle($certification['title'] ?? '')
->setEtablissement($certification['etablissement'] ?? '');
// Vérification et conversion de l'année d'obtention
if (isset($certification['obtention_year']) && is_numeric($certification['obtention_year'])) {
$obtentionYear = (int)$certification['obtention_year'];
error_log('Obtention Year: ' . $obtentionYear);
$newCertification->setObtentionYear($obtentionYear);
} else {
// Définir une valeur par défaut appropriée ou gérer l'erreur
error_log('Invalid Obtention Year: ' . (isset($certification['obtention_year']) ? $certification['obtention_year'] : 'not set'));
$newCertification->setObtentionYear(0);
}
$profile->addCertification($newCertification);
}
}
// Vérifier si la clé 'certifications' existe
if (isset($data['présentation'])) {
$presentationData = $data['présentation'];
} else {
$presentationData = null; // Ou définir une valeur par défaut appropriée
}
if (!empty($presentationData)) {
$profile->setAbout($presentationData);
}
if (isset($data['url_Linkedin'])) {
$linkedInData = $data['url_Linkedin'];
} else {
$linkedInData = null; // Ou définir une valeur par défaut appropriée
}
if (!empty($linkedInData)) {
$profile->setLinkedin($linkedInData);
}
$profile->setFinished(false);
$profile->setProfileType(0);
// dump($jsonData);
// dd($profile);
$entityManager->flush();
if (empty($user->getFirstname())) {
$user->setFirstname($profile->getFirstname());
$entityManager->persist($user);
}
if (empty($user->getLastname())) {
$user->setLastname($profile->getName());
$entityManager->persist($user);
}
$profile->updateSlug();
$entityManager->persist($profile);
$entityManager->flush();
return $this->json(['message' => 'Profile updated successfully']);
}
/**
* @Route("/api/getProfile", name="api_get_profile", methods={"GET"})
* @IsGranted("ROLE_FREELANCE")
*/
public function getProfile(Request $request, EntityManagerInterface $entityManager): JsonResponse
{
$user = $this->getUser();
$profile = $user->getUniqueProfile();
if (!$profile) {
return new JsonResponse(['message' => 'Profil non renseigné.'], Response::HTTP_BAD_REQUEST);
}
$serializer = $this->container->get('serializer');
$data = $serializer->serialize($profile, 'json', [
'circular_reference_handler' => function ($object) {
return $object->getId(); // ou retourne une propriété unique de ton objet
},
]);
return new JsonResponse(['data' => json_decode($data)], Response::HTTP_OK);
}
}