src/Controller/HomeController.php line 51

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Repository\ReviewFormRepository;
  4. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  5. use Symfony\Component\HttpFoundation\RequestStack;
  6. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  7. use Symfony\Component\HttpFoundation\RedirectResponse;
  8. use Symfony\Component\HttpFoundation\JsonResponse;
  9. use Symfony\Component\HttpFoundation\Response;
  10. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  11. use Symfony\Component\HttpFoundation\StreamedResponse;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  14. use Symfony\Component\Routing\Annotation\Route;
  15. use App\Repository\UsersRepository;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use DateTime;
  18. use App\Repository\QuestionRepository;
  19. use App\Repository\DimensionRepository;
  20. use App\Repository\EmployeeRepository;
  21. use App\Entity\Users;
  22. use App\Entity\ReviewForm;
  23. use App\Entity\Session;
  24. use App\Entity\Reponse;
  25. use App\Entity\Employee;
  26. class HomeController extends AbstractController
  27. {
  28.     public function __construct(
  29.         QuestionRepository $questionRepository,
  30.         DimensionRepository $dimensionRepository,
  31.         ReviewFormRepository $reviewFormRepository,
  32.         EmployeeRepository $employeeRepository,
  33.         EntityManagerInterface $em
  34.     )
  35.     {
  36.         $this->questionRepository $questionRepository;
  37.         $this->dimensionRepository $dimensionRepository;
  38.         $this->reviewFormRepository $reviewFormRepository;
  39.         $this->employeeRepository $employeeRepository;
  40.         $this->em $em;
  41.     }
  42.     // Contrôleur Symfony
  43.     #[Route(path'/'name'index')]
  44.     public function index(Request $request): Response
  45.     {
  46.         $lang $request->query->get('_locale'$request->getSession()->get('_locale''fr'));
  47.         $request->getSession()->set('_locale'$lang);
  48.         $reviewForm $this->reviewFormRepository->findFormWithDimensionsAndQuestionsByLang('8b6cf598-7f27-11ef-9d7f-1d1f43f3f908'$lang);
  49.         return $this->render('index.html.twig', [
  50.             'reviewForm' => $reviewForm
  51.         ]);
  52.     }
  53.     #[Route('/change-langage/{params}'name'change_language')]
  54.     public function changeLangage($paramsRequestStack $requestStackSessionInterface $session): Response
  55.     {
  56.         // Liste des langues valides
  57.         $validLocales = ['en''fr''nl'];
  58.         // Vérifier si la langue est valide, sinon utiliser 'en' comme langue par défaut
  59.         if (!in_array($params$validLocales)) {
  60.             $params 'en';
  61.         }
  62.         // Stocker la langue sélectionnée dans la session
  63.         $session->set('_locale'$params);
  64.         // Récupérer la requête actuelle
  65.         $request $requestStack->getCurrentRequest();
  66.         $previousUrl $request->headers->get('referer'); // URL du référent (page précédente)
  67.         return $this->redirectToRoute('index');
  68.         // Ajouter ou mettre à jour le paramètre de langue dans l'URL de la page précédente
  69.         $urlComponents parse_url($previousUrl);
  70.         parse_str($urlComponents['query'] ?? ''$query);
  71.         $query['_locale'] = $params;
  72.         $urlComponents['query'] = http_build_query($query);
  73.         // Reconstruire l'URL complète avec le paramètre de langue ajouté
  74.         $newUrl $urlComponents['scheme'] . '://' $urlComponents['host'] . ($urlComponents['path'] ?? '') . '?' $urlComponents['query'];
  75.         // Rediriger vers l'URL modifiée avec la nouvelle langue
  76.         return new RedirectResponse($newUrl);
  77.     }
  78.     #[Route(path'/form/{lang}/{formId}'name'form')]
  79.     public function form($lang$formId): Response
  80.     {
  81.         $reviewForm $this->reviewFormRepository->findFormWithDimensionsAndQuestionsByLang($formId$lang);
  82.         return $this->render('home.html.twig', [
  83.             'reviewForm' => $reviewForm
  84.         ]);
  85.     }
  86.     #[Route(path'/send-form'name'send_form')]
  87.     public function sendForm(Request $request): Response
  88.     {
  89.         $reviewId trim((string) $request->get('review'''));
  90.         $lang strtolower((string) $request->get('lang''fr'));
  91.         $review $reviewId !== ''
  92.             $this->reviewFormRepository->findFormWithDimensionsAndQuestionsByLang($reviewId$lang)
  93.             : null;
  94.         if (!$review instanceof ReviewForm) {
  95.             return new JsonResponse([
  96.                 'errors' => [
  97.                     'review' => 'Le formulaire demandé est introuvable.'
  98.                 ]
  99.             ], 404);
  100.         }
  101.         $fieldErrors $this->validateRequiredFields($request);
  102.         if (!empty($fieldErrors)) {
  103.             return new JsonResponse([
  104.                 'errors' => $fieldErrors
  105.             ], 400);
  106.         }
  107.         $responses json_decode((string) $request->get('questionData''[]'), true);
  108.         if (!is_array($responses)) {
  109.             return new JsonResponse([
  110.                 'errors' => [
  111.                     'questionData' => 'Les réponses au questionnaire sont invalides.'
  112.                 ]
  113.             ], 400);
  114.         }
  115.         $scoreError $this->validateScoreConstraints($review$responses);
  116.         if ($scoreError !== null) {
  117.             return new JsonResponse([
  118.                 'errors' => [
  119.                     'score_rule' => $scoreError
  120.                 ]
  121.             ], 400);
  122.         }
  123.         $session = new Session();
  124.         $session->setEmployee(null);
  125.         $session->setCreatedAt(new \DateTime('now'));
  126.         $session->setEmail((string) $request->get('email'));
  127.         $fullName trim(sprintf(
  128.             '%s %s',
  129.             (string) $request->get('firstName'''),
  130.             (string) $request->get('name''')
  131.         ));
  132.         $session->setName($fullName !== '' $fullName : (string) $request->get('firstName'''));
  133.         $session->setMessage($request->get('message'));
  134.         $session->setReviewForm($review);
  135.         $session->setLang($lang);
  136.         $demographics = [
  137.             'region'            => $request->get('region'),
  138.             'province'          => $request->get('province'),
  139.             'country'           => $request->get('country'),
  140.             'gender'            => $request->get('gender'),
  141.             'age_range'         => $request->get('age_range'),
  142.             'education_level'   => $request->get('education_level'),
  143.             'industry'          => $request->get('industry'),
  144.             'employment_status' => $request->get('employment_status'),
  145.             'contract_type'     => $request->get('contract_type'),
  146.             'working_time'      => $request->get('working_time'),
  147.             'work_mode'         => $request->get('work_mode'),
  148.             'commute_time'      => $request->get('commute_time'),
  149.             'work_language'     => $request->get('work_language'),
  150.             'management'        => $request->get('management'),
  151.             'health_status'     => $request->get('health_status'),
  152.             'job_level'         => $request->get('job_level'),
  153.             'sector_type'       => $request->get('sector_type'),
  154.             'org_size'          => $request->get('org_size'),
  155.             'years_experience'  => $request->get('years_experience'),
  156.             'tenure'            => $request->get('tenure'),
  157.         ];
  158.         $session->setDemographics($demographics);
  159.         $employee $this->employeeRepository->findOneBy(['email' => $request->get('email')]);
  160.         if ($employee) {
  161.             $session->setEmployee($employee);
  162.         }
  163.         $responseByQuestionId = [];
  164.         foreach ($responses as $response) {
  165.             if (!is_array($response) || !isset($response['id'])) {
  166.                 continue;
  167.             }
  168.             $responseByQuestionId[(int) $response['id']] = $response;
  169.         }
  170.         foreach ($review->getDimensions() as $dimension) {
  171.             foreach ($dimension->getQuestions() as $question) {
  172.                 $response $responseByQuestionId[$question->getId()] ?? null;
  173.                 if (!$response) {
  174.                     continue;
  175.                 }
  176.                 $reponse = new Reponse();
  177.                 $reponse->setQuestion($question);
  178.                 $reponse->setSession($session);
  179.                 $reponse->setQuantity((int)($response['score'] ?? 0));
  180.                 $reponse->setMinimalQuantity((int)($response['score_minimal'] ?? 0));
  181.                 $reponse->setDeleted(false);
  182.                 $reponse->setComment($response['comment'] ?? null);
  183.                 $this->em->persist($reponse);
  184.             }
  185.         }
  186.         $session->setStatus(1);
  187.         $this->em->persist($session);
  188.         $this->em->flush();
  189.         return new JsonResponse(['ok' => true]);
  190.     }
  191.     private function validateRequiredFields(Request $request): array
  192.     {
  193.         $requiredFields = [
  194.             'firstName' => 'Prénom',
  195.             'name' => 'Nom',
  196.             'email' => 'Email',
  197.             'region' => 'Région de résidence',
  198.             'gender' => 'Sexe',
  199.             'age_range' => 'Âge',
  200.             'education_level' => 'Niveau d’études',
  201.             'industry' => 'Secteur d’activité',
  202.             'employment_status' => 'Statut professionnel actuel',
  203.             'job_level' => 'Niveau de fonction',
  204.             'sector_type' => 'Secteur d’appartenance',
  205.             'org_size' => 'Taille de l’organisation',
  206.             'years_experience' => 'Années d’expérience professionnelle',
  207.             'tenure' => 'Ancienneté dans l’entreprise actuelle',
  208.             'working_time' => 'Temps de travail',
  209.             'work_mode' => 'Mode de travail principal',
  210.             'commute_time' => 'Temps de trajet quotidien',
  211.             'work_language' => 'Langue principale au travail',
  212.             'management' => 'Responsabilité hiérarchique',
  213.         ];
  214.         $errors = [];
  215.         foreach ($requiredFields as $field => $label) {
  216.             $value trim((string) $request->get($field''));
  217.             if ($value === '') {
  218.                 $errors[$field] = sprintf('Le champ « %s » est obligatoire.'$label);
  219.                 continue;
  220.             }
  221.             if ($field === 'email' && !filter_var($valueFILTER_VALIDATE_EMAIL)) {
  222.                 $errors[$field] = 'Veuillez saisir une adresse email valide.';
  223.             }
  224.         }
  225.         return $errors;
  226.     }
  227.     private function validateScoreConstraints(ReviewForm $review, array $responses): ?string
  228.     {
  229.         $responseByQuestionId = [];
  230.         $responsePositionByQuestionId = [];
  231.         foreach ($responses as $position => $response) {
  232.             if (!is_array($response) || !isset($response['id'])) {
  233.                 continue;
  234.             }
  235.             $questionId = (int) $response['id'];
  236.             $responseByQuestionId[$questionId] = $response;
  237.             $responsePositionByQuestionId[$questionId] = $position;
  238.         }
  239.         $dimensions $review->getDimensions()->toArray();
  240.         usort($dimensions, static function ($left$right) {
  241.             return ($left->getSorting() ?? 0) <=> ($right->getSorting() ?? 0);
  242.         });
  243.         foreach ($dimensions as $dimension) {
  244.             $questions $dimension->getQuestions()->toArray();
  245.             $questionCount count($questions);
  246.             if ($questionCount || $questionCount !== 0) {
  247.                 return sprintf('La structure de la dimension "%s" est invalide.'$dimension->getName());
  248.             }
  249.             usort($questions, static function ($left$right) use ($responsePositionByQuestionId) {
  250.                 $leftPosition $responsePositionByQuestionId[$left->getId()] ?? PHP_INT_MAX;
  251.                 $rightPosition $responsePositionByQuestionId[$right->getId()] ?? PHP_INT_MAX;
  252.                 if ($leftPosition === $rightPosition) {
  253.                     return ($left->getId() ?? 0) <=> ($right->getId() ?? 0);
  254.                 }
  255.                 return $leftPosition <=> $rightPosition;
  256.             });
  257.             for ($index 0$index $questionCount$index += 3) {
  258.                 $groupQuestions array_slice($questions$index3);
  259.                 if (count($groupQuestions) < 3) {
  260.                     return sprintf('Les réponses de la dimension "%s" sont incomplètes.'$dimension->getName());
  261.                 }
  262.                 $checks = [
  263.                     'score' => [
  264.                         'label' => 'score actuel',
  265.                         'subScores' => [],
  266.                         'globalScore' => null,
  267.                     ],
  268.                     'score_minimal' => [
  269.                         'label' => 'score souhaité',
  270.                         'subScores' => [],
  271.                         'globalScore' => null,
  272.                     ],
  273.                 ];
  274.                 foreach ($checks as $field => &$check) {
  275.                     $subScores = [];
  276.                     $globalScore null;
  277.                     foreach ($groupQuestions as $groupIndex => $question) {
  278.                         $response $responseByQuestionId[$question->getId()] ?? null;
  279.                         $value is_array($response) ? ($response[$field] ?? null) : null;
  280.                         if ($value === null || $value === '') {
  281.                             return sprintf('Les réponses de la dimension "%s" sont incomplètes.'$dimension->getName());
  282.                         }
  283.                         $score = (int) $value;
  284.                         if ($groupIndex 2) {
  285.                             $subScores[] = $score;
  286.                         } else {
  287.                             $globalScore $score;
  288.                         }
  289.                     }
  290.                     if (count($subScores) < || $globalScore === null) {
  291.                         return sprintf('Les réponses de la dimension "%s" sont incomplètes.'$dimension->getName());
  292.                     }
  293.                     $min min($subScores);
  294.                     $max max($subScores);
  295.                     if (($min === $max && $globalScore !== $min) || ($min !== $max && ($globalScore $min || $globalScore $max))) {
  296.                         if ($min === $max) {
  297.                             return sprintf(
  298.                                 'Le %s de la dimension "%s" doit être égal à %d.',
  299.                                 $check['label'],
  300.                                 $dimension->getName(),
  301.                                 $min
  302.                             );
  303.                         }
  304.                         return sprintf(
  305.                             'Le %s de la dimension "%s" doit être compris entre %d et %d.',
  306.                             $check['label'],
  307.                             $dimension->getName(),
  308.                             $min,
  309.                             $max
  310.                         );
  311.                     }
  312.                 }
  313.                 unset($check);
  314.             }
  315.         }
  316.         return null;
  317.     }
  318. }