src/Controller/WidgetSatisfactionClientController.php line 281

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Event;
  4. use App\Entity\EventRegistration;
  5. use App\Entity\SatisfactionClientAnswer;
  6. use App\Entity\SatisfactionClientSurvey;
  7. use App\Entity\SatisfactionClientSurveyResponse;
  8. use App\Repository\AccountingFirmRepository;
  9. use App\Repository\AuthorizedDomainRepository;
  10. use App\Repository\CollaboratorRepository;
  11. use App\Repository\EventRepository;
  12. use App\Repository\SatisfactionClientQuestionRepository;
  13. use App\Repository\SatisfactionClientSurveyRepository;
  14. use App\Repository\SatisfactionClientSurveyResponseRepository;
  15. use App\Services\WidgetMailing;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use Qferrer\Mjml\Twig\MjmlExtension;
  18. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  19. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  20. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  21. use Symfony\Component\HttpFoundation\JsonResponse;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  24. use Symfony\Component\HttpKernel\KernelInterface;
  25. use Symfony\Component\Mailer\MailerInterface;
  26. use Symfony\Component\Mime\Email;
  27. use Symfony\Component\Routing\Annotation\Route;
  28. use Twig\Environment;
  29. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  30. use Symfony\Component\HttpFoundation\Response;
  31. class WidgetSatisfactionClientController extends AbstractController
  32. {
  33.     protected MjmlExtension $mjmlRenderer;
  34.     protected Environment $twig;
  35.     private MailerInterface $mailer;
  36.     public function __construct(MailerInterface $mailerMjmlExtension $mjmlRendererEnvironment $twig)
  37.     {
  38.         $this->mailer $mailer;
  39.         $this->mjmlRenderer $mjmlRenderer;
  40.         $this->twig $twig;
  41.     }
  42.     #[Route('/check-satisfaction-client'name'w_satsifaction_client_check')]
  43.     public function ctrl_checkSatisfactionClient(Request $requestAccountingFirmRepository $repositorystring $prefix null): JsonResponse
  44.     {
  45.         $token $request->query->get('token');
  46.         $host $request->get('host');
  47.         if ($token && $host) {
  48.             $accountingFirm $repository->findOneBy(['satisfactionToken' => $token]);
  49.             $isAuthorized false;
  50.             if ($accountingFirm && in_array($host$accountingFirm->getListAuthorizedDomains())) {
  51.                 $isAuthorized true;
  52.             }
  53.             $url $isAuthorized $accountingFirm->getSatisfactionWidgetUrl() : null;
  54.         } else {
  55.             $accountingFirm $repository->findOneBy(['host' => $host]);
  56.             $url $accountingFirm $prefix $this->generateUrl('w_satisfaction_client_get') : null;
  57.         }
  58.         return $this->json($url);
  59.     }
  60.    #[Route('/widget-satisfaction-client'name'w_satisfaction_client_get')]
  61.    public function ctrl_widgetSatisfactionClient(
  62.         Request $request,
  63.         AccountingFirmRepository $repository,
  64.         AuthorizedDomainRepository $domains,
  65.         SatisfactionClientSurveyRepository $surveyRepository,
  66.         SatisfactionClientSurveyResponseRepository $responseRepository,
  67.         CollaboratorRepository $collaboratorRepository,
  68.         ParameterBagInterface $params
  69.     ) {
  70.         $token $request->query->get('token');
  71.         $host $request->get('host');
  72.         $surveyId $request->query->get('surveyId');
  73.         $tokenClient $request->query->get('tokenClient');
  74.         $tokenCollaborators $request->query->get('tokenCollaborators');
  75.         $collaboratorTokens $tokenCollaborators === "preview"
  76.             ? ["preview"]
  77.             : explode(','$tokenCollaborators);
  78.         if ($host != "preview") {
  79.             $accountingFirm $repository->findOneBy(['host' => $host]);
  80.             if (is_null($accountingFirm)) {
  81.                 $domains $domains->findBy(['name' => $host]);
  82.                 if (empty($domains)) {
  83.                     throw new NotFoundHttpException('Domaine non autorisé');
  84.                 }
  85.                 foreach ($domains as $dom) {
  86.                     $tmp_ac $dom->getAccountingFirm();
  87.                     if ($tmp_ac->getSatisfactionToken() == $token) {
  88.                         $accountingFirm $tmp_ac;
  89.                         break;
  90.                     }
  91.                 }
  92.             }
  93.             if (is_null($accountingFirm)) {
  94.                 throw new NotFoundHttpException('Cabinet non trouvé');
  95.             }
  96.         }
  97.         $survey $surveyRepository->find($surveyId);
  98.         if (!$survey || $survey->getAccountingFirm()->getId() !== $accountingFirm->getId()) {
  99.             throw new NotFoundHttpException('Enquête non trouvé');
  100.         }
  101.         if($collaboratorTokens[0] != "preview") {
  102.             foreach ($collaboratorTokens as $tokenCollaborator) {
  103.                 $collaborator $collaboratorRepository->findOneBy(['token' => $tokenCollaborator]);
  104.                 if (!$collaborator || !$survey->getCollaborators()->contains($collaborator)) {
  105.                     throw new NotFoundHttpException('Collaborateur non autorisé');
  106.                 }
  107.             }
  108.         }
  109.         if($tokenClient != "preview" && $collaboratorTokens[0] != "preview") {
  110.             foreach ($collaboratorTokens as $tokenCollaborator) {
  111.                 $existingResponse $responseRepository->findBySurveyAndTokens($survey$tokenClient$tokenCollaborator);
  112.                 if ($existingResponse) {
  113.                     return $this->render('widget_satisfaction_client/already_responded.twig', [
  114.                         'accountingFirm' => $accountingFirm
  115.                     ]);
  116.                 }
  117.             }
  118.         }
  119.         if($tokenClient != "preview" && $collaboratorTokens[0] != "preview") {
  120.             return $this->render('widget_satisfaction_client/content.html.twig', [
  121.                 'accountingFirm' => $accountingFirm,
  122.                 'survey' => $survey,
  123.                 'tokenClient' => $tokenClient,
  124.                 'tokenCollaborators' => $collaboratorTokens,
  125.                 'serverUrl' => $params->get('domain_widget_satisfaction_client'),
  126.                 'domainWidget' => $_ENV['DOMAIN_WIDGET_SATISFACTION_CLIENT'],
  127.             ]);
  128.         } else {
  129.             return $this->render('widget_satisfaction_client/preview.html.twig', [
  130.                 'accountingFirm' => $accountingFirm,
  131.                 'survey' => $survey,
  132.                 'tokenClient' => $tokenClient,
  133.                 'tokenCollaborators' => $collaboratorTokens,
  134.                 'serverUrl' => $params->get('domain_widget_satisfaction_client'),
  135.                 'domainWidget' => $_ENV['DOMAIN_WIDGET_SATISFACTION_CLIENT'],
  136.             ]);
  137.         }
  138.     }
  139.     #[Route('/submit'name'w_submit_satisfaction_survey'methods: ['POST'])]
  140.     public function submit(
  141.         Request $request,
  142.         SatisfactionClientSurveyRepository $surveyRepository,
  143.         SatisfactionClientQuestionRepository $questionRepository,
  144.         EntityManagerInterface $em,
  145.         SatisfactionClientSurveyResponseRepository $responseRepository
  146.     ): JsonResponse {
  147.         try {
  148.             $data json_decode($request->getContent(), true);
  149.             if (!$data) {
  150.                 return new JsonResponse(['error' => 'Invalid JSON data'], Response::HTTP_BAD_REQUEST);
  151.             }
  152.             $requiredFields = ['surveyId''tokenClient''tokenCollaborators''answers'];
  153.             foreach ($requiredFields as $field) {
  154.                 if (!isset($data[$field])) {
  155.                     return new JsonResponse(['error' => "Missing required field: $field"], Response::HTTP_BAD_REQUEST);
  156.                 }
  157.             }
  158.             $survey $surveyRepository->find($data['surveyId']);
  159.             if (!$survey) {
  160.                 return new JsonResponse(['error' => 'Survey not found'], Response::HTTP_NOT_FOUND);
  161.             }
  162.            $collaboratorTokens is_array($data['tokenCollaborators'])
  163.                                 ? $data['tokenCollaborators']
  164.                                 : array_filter(explode(','$data['tokenCollaborators']));
  165.             foreach ($collaboratorTokens as $tokenCollaborator) {
  166.                 $existingResponse $responseRepository->findBySurveyAndTokens($survey$data['tokenClient'], $tokenCollaborator);
  167.                 if ($existingResponse) {
  168.                     return new JsonResponse(
  169.                         ['error' => 'You have already responded to this survey for collaborator: ' $tokenCollaborator],
  170.                         Response::HTTP_CONFLICT
  171.                     );
  172.                 }
  173.             }
  174.             foreach ($collaboratorTokens as $tokenCollaborator) {
  175.                     $surveyResponse = new SatisfactionClientSurveyResponse();
  176.                     $surveyResponse->setSurvey($survey);
  177.                     $surveyResponse->setAnsweredAt(new \DateTime());
  178.                 foreach ($data['answers'] as $answerData) {
  179.                     if (!isset($answerData['questionId'])) {
  180.                         continue;
  181.                     }
  182.                     $question $questionRepository->find($answerData['questionId']);
  183.                     if (!$question || $question->getSurvey()->getId() !== $survey->getId()) {
  184.                         continue;
  185.                     }
  186.                     $answer = new SatisfactionClientAnswer();
  187.                     $answer->setQuestion($question);
  188.                     $answer->setSurveyResponse($surveyResponse);
  189.                     $answer->setTokenClient($data['tokenClient']);
  190.                     $answer->setTokenCollaborator($tokenCollaborator);
  191.                     if (isset($answerData['rating']) && $answerData['rating'] !== null) {
  192.                         $answer->setRating((int)$answerData['rating']);
  193.                     }
  194.                     if (isset($answerData['textAnswer'])) {
  195.                         $answer->setTextAnswer($answerData['textAnswer']);
  196.                     } elseif ($question->isMandatoryFreeText()) {
  197.                         return new JsonResponse(
  198.                             ['error' => 'Text answer is required for question: ' $question->getId()],
  199.                             Response::HTTP_BAD_REQUEST
  200.                         );
  201.                     }
  202.                     $em->persist($answer);
  203.                     $surveyResponse->addAnswer($answer);
  204.                 }
  205.                 $em->persist($surveyResponse);
  206.             }
  207.             $em->flush();
  208.             return new JsonResponse([
  209.                 'success' => true,
  210.                 'message' => 'Survey responses saved successfully for all collaborators',
  211.                 'responsesCount' => count($surveyResponse->getAnswers())
  212.             ]);
  213.         } catch (\Exception $e) {
  214.             return new JsonResponse([
  215.                 'error' => 'An error occurred while saving responses',
  216.                 'details' => $e->getMessage()
  217.             ], Response::HTTP_INTERNAL_SERVER_ERROR);
  218.         }
  219.     }
  220.     //récupère le js qui intègre le widget
  221.     #[Route('/embed'name'w_satisfaction_client_embed')]
  222.     public function embed()
  223.     {
  224.         $root $this->getParameter('kernel.project_dir');
  225.         $path $root '/public/widgets/widget_satisfaction_client/widget_satisfaction_client.js';
  226.         return new BinaryFileResponse($path);
  227.     }
  228.     #[Route('/{filename}.{format}'name'w_event_files')]
  229.     public function widget_files(string $filenamestring $format)
  230.     {
  231.         $allowed = array('png''jpg''jpeg''gif''js''svg''eot''ttf''woff');
  232.         if (in_array($format$allowed)) {
  233.             $root $this->getParameter('kernel.project_dir');
  234.             $path $root '/public/widget_event/' $filename '.' $format;
  235.             return new BinaryFileResponse($path);
  236.         }
  237.         return false;
  238.     }
  239.     //récupérer image, fichier,... (on verra plus tard ça)
  240.     #[Route('/cover-file/{id}'name'w_satisfaction_client_files_cover')]
  241.     public function widget_files_vich(Event $eventKernelInterface $kernel)
  242.     {
  243.         $filename $event->getCoverImage();
  244.         if (!$filename) {
  245.             throw $this->createNotFoundException("Aucun fichier associé à cet événement.");
  246.         }
  247.         // Exemple avec VichUploaderBundle qui stocke dans public/uploads/event_covers/
  248.         $filePath $kernel->getProjectDir() . '/upload/events/' $filename;
  249.         if (!file_exists($filePath)) {
  250.             throw $this->createNotFoundException("Le fichier n'existe pas.");
  251.         }
  252.         return (new BinaryFileResponse($filePath))
  253.             ->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE$filename);
  254.     }
  255.     #[Route('/widget-satisfaction-client-send-form'name'widget_satisfaction_client_send_form'methods: ['POST''OPTIONS'])]
  256.     public function sendForm(
  257.         Request $request,
  258.         EntityManagerInterface $em,
  259.         AccountingFirmRepository $repository,
  260.         SatisfactionClientSurveyRepository $surveyRepository,
  261.         SatisfactionClientQuestionRepository $questionRepository
  262.     ): JsonResponse {
  263.         $data json_decode($request->getContent(), true);
  264.         if (json_last_error() !== JSON_ERROR_NONE) {
  265.             return new JsonResponse(['message' => 'Invalid JSON'], JsonResponse::HTTP_BAD_REQUEST);
  266.         }
  267.         $accountingFirm $repository->findOneById($data['cabinetId'] ?? null);
  268.         if (!$accountingFirm) {
  269.             return new JsonResponse(['message' => 'Cabinet introuvable'], JsonResponse::HTTP_NOT_FOUND);
  270.         }
  271.         $survey $surveyRepository->findByAccountingFirm($accountingFirm);
  272.         if (!$survey) {
  273.             return new JsonResponse(['message' => 'Aucune enquête satisfaction active trouvée'], JsonResponse::HTTP_NOT_FOUND);
  274.         }
  275.         if (!isset($data['answers']) || !is_array($data['answers'])) {
  276.             return new JsonResponse(['message' => 'Aucune réponse transmise'], JsonResponse::HTTP_BAD_REQUEST);
  277.         }
  278.         $surveyResponse = new SatisfactionClientSurveyResponse();
  279.         $surveyResponse->setSurvey($survey);
  280.         foreach ($data['answers'] as $answerData) {
  281.             if (!isset($answerData['questionId'])) {
  282.                 continue;
  283.             }
  284.             $question $questionRepository->find($answerData['questionId']);
  285.             if (!$question || $question->getSurvey()->getId() !== $survey->getId()) {
  286.                 continue;
  287.             }
  288.             $answer = new SatisfactionClientAnswer();
  289.             $answer->setQuestion($question)
  290.                 ->setSurveyResponse($surveyResponse);
  291.             if ($question->isMandatoryFreeText()) {
  292.                 $answer->setTextAnswer($answerData['textAnswer'] ?? '');
  293.             } else {
  294.                 $rating $answerData['rating'] ?? null;
  295.                 if ($rating >= && $rating <= 5) {
  296.                     $answer->setRating($rating);
  297.                 }
  298.             }
  299.             $surveyResponse->addAnswer($answer);
  300.         }
  301.         $em->persist($surveyResponse);
  302.         $em->flush();
  303.         return new JsonResponse([
  304.             'message' => "Merci pour votre participation. Vos retours sont précieux et seront attentivement étudiés par notre équipe."
  305.         ], JsonResponse::HTTP_OK);
  306.     }
  307. }