src/Controller/SycMessagesAndPlanning.php line 68

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\FileMessage;
  4. use App\Entity\Message;
  5. use App\Entity\MessageReaction;
  6. use App\Entity\Mission;
  7. use App\Entity\WorkflowStep;
  8. use App\Entity\Campaign;
  9. use App\Enum\AdminMail;
  10. use App\Enum\Role;
  11. use App\Event\User\UserReactionEvent;
  12. use App\Form\MessageType;
  13. use App\Form\MissionParticipantDelaisType;
  14. use App\Repository\MessageReactionRepository;
  15. use App\Repository\MessageRepository;
  16. use App\Repository\MissionRepository;
  17. use App\Repository\UserRepository;
  18. use App\Repository\WorkflowStepRepository;
  19. use App\Repository\CampaignRepository;
  20. use App\Repository\FileMessageRepository;
  21. use App\Repository\MissionParticipantRepository;
  22. use App\Service\MessageService;
  23. use App\Service\NotificationService;
  24. use Doctrine\ORM\EntityManagerInterface;
  25. use Psr\Log\LoggerInterface;
  26. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  27. use Symfony\Component\Filesystem\Filesystem;
  28. use Symfony\Component\HttpFoundation\JsonResponse;
  29. use Symfony\Component\HttpFoundation\Request;
  30. use Symfony\Component\HttpFoundation\Response;
  31. use Symfony\Component\Routing\Annotation\Route;
  32. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  33. use Symfony\Component\Mime\Address;
  34. use Twig\Environment;
  35. use App\Service\GoogleStorageService;
  36. use App\Service\MissionParticipantService;
  37. use App\Service\PriceService;
  38. #[Route('/messages'name'messages')]
  39. class SycMessagesAndPlanning extends AbstractController
  40. {
  41.     public function __construct(
  42.         private Environment $twig,
  43.         private EntityManagerInterface $entityManagerInterface,
  44.         private Filesystem $filesystem,
  45.         private MessageService $messageService,
  46.         private LoggerInterface $logger,
  47.         private MessageRepository $messageRepository,
  48.         private MessageReactionRepository $messageReactionRepository,
  49.         private EventDispatcherInterface $dispatcher,
  50.         private NotificationService $notificationService,
  51.         private MissionParticipantService $missionParticipantService,
  52.         private UserRepository $userRepository,
  53.         private GoogleStorageService $googleStorageService,
  54.         private MissionParticipantRepository $missionParticipantRepository,
  55.         private PriceService $priceService
  56.     ) {
  57.     }
  58.     #[Route('/last/{lastIdMessage}-{nbMessage}'name'last')]
  59.     public function lastMessages(Request $request,FileMessageRepository $fileMessageRepository,  MissionRepository $missionRepositorystring $lastIdMessageMessageRepository $messageRepository,UserRepository $userRepository$nbMessage 10)
  60.     {
  61.         if ($this->getUser() == null) {
  62.             return new JsonResponse([
  63.                 'status' => "KO",
  64.             ], Response::HTTP_UNAUTHORIZED);
  65.         }
  66.         $unredMessage $request->query->get('unred-message');
  67.         $missionId $request->query->get('mission-id');
  68.         $currentRouteName=$request->query->get('current-route-name');
  69.         $estimatedIncome $request->query->get('estimatedIncome');
  70.         $timeZone $request->query->get('time-zone');
  71.         $dateOffSetHour floatval($request->query->get('date-offset-hour'));
  72.         $isLoadMore $request->query->get('is-load-more'); 
  73.         $lastIdMessage preg_replace("/message/"""$lastIdMessage);
  74.         $messageIdsDeleted = [] ; 
  75.         $fileMessageIdsDeleted = []; 
  76.         $messagesEditing = []; 
  77.         $messagesWithReactions = []; 
  78.        
  79.         $mission $missionRepository->findOneBy(["id" => $missionId]);
  80.         $listOfUserTyping $this->messageService->getUserTypingWithoutCurrentUser($mission);
  81.         $userTypingWithDuration $this->messageService->calculaTimeTypingOfEachUser($listOfUserTyping);
  82.         if(is_null($userTypingWithDuration)){
  83.             $userTypingWithDuration = [];
  84.         }
  85.         $message $messageRepository->findOneBy(['id' => $lastIdMessage]);
  86.         if ($mission != null) {
  87.         
  88.             if($isLoadMore == "true" || $message == null){
  89.                 $listLastMessage $messageRepository->getAllMessage($mission->getCampaign(),$nbMessage);
  90.             }
  91.             else{
  92.                 $listLastMessage =$messageRepository->findLastMessage($mission->getCampaign(), $message->getCreatedAt());
  93.                 $messageIdsDeleted $messageRepository->findIdsMessageDeleted($mission->getCampaign()) ; 
  94.                 $fileMessageIdsDeleted $fileMessageRepository->findIdsFileMessageDeleted($mission->getCampaign());
  95.                 $messagesEditing$messageRepository->findMessagesEditing($mission->getCampaign()) ; 
  96.                 $messagesWithReactions$messageRepository->findMessageWithReaction($mission->getCampaign()) ; 
  97.             }
  98.             $nbAllMessage $messageRepository->nbAllMessage($mission->getCampaign())['nb'];
  99.             
  100.          
  101.                 usort($listLastMessage, function($a$b) {
  102.                     $dateA = ($a->getCreatedAt()->getTimestamp());
  103.                     $dateB = ($b->getCreatedAt()->getTimestamp());
  104.                     return   $dateA $dateB 
  105.                 });
  106.             $missionParticipant null;
  107.             foreach ($mission->getParticipants() as $participant) {
  108.                 if ($participant->getUser()->getId() == $this->getUser()->getId()) {
  109.                     $missionParticipant $participant;
  110.                 }
  111.             }
  112.             $lastTenMessages $messageRepository->getLastTenMessages($mission->getCampaign()); 
  113.             $listIdsLastMessage $this->getIdsMessage($lastTenMessages); 
  114.             $futuresActions $this->missionParticipantService->getUniqByFutureActions($mission->getCampaign()->getId(),$this->getUser()->getId()); 
  115.             return new JsonResponse([
  116.                 "status" => "ok",
  117.                 "html" => $this->getHtmlToRenderInView(mission$missionlistLastMessage$listLastMessagetimeZone$timeZonedateOffSetHour$dateOffSetHourunredMessage$unredMessage,nbAllMessage$nbAllMessage),
  118.                 "lists_last_message_id"=>$listIdsLastMessage['message_ids'],
  119.                 "lists_last_file_message_id"=>$listIdsLastMessage['file_message_ids'],
  120.                 "planning" => $this->twig->render("mission/_planning_item.html.twig", [
  121.                     "mission" => $mission,
  122.                     "campaign" => $mission->getCampaign(),
  123.                     "userConnected" => $this->getUser(),
  124.                     "missionParticipant" => $missionParticipant,
  125.                 ]),
  126.                 "list_user_read_last_message"=>$this->userReadLastMessage($messageRepository->findOneBy(['campaign' => $mission->getCampaign()], ['createdAt' => 'DESC'])), 
  127.                 "message_deleted_ids"=> $messageIdsDeleted,
  128.                 'user_typing' => $this->getUserTypingMessage($userTypingWithDuration), 
  129.                 "file_message_deleted_ids"=> $fileMessageIdsDeleted
  130.                 "messages_editing"=>$messagesEditing,
  131.                 "messages_with_reactions"=>$this->getElementReactions($messagesWithReactions),
  132.                 "futureActions" =>  $this->getHtmlFutureActions($mission$futuresActions$currentRouteName$estimatedIncome),
  133.             ]);
  134.         }
  135.         // $this->sendEmailError('-', '-', 'L\'id de la mission est null');
  136.         return new JsonResponse(["status" => "ko"], 200);
  137.     }
  138.     #[Route('/delete/{id}'name'detele_message'methods: ['POST'])]
  139.     public function deleteMessages(Message $message)
  140.     {
  141.         if ($message->getUser()->getId() == $this->getUser()->getId() || $this->isGranted('ROLE_ADMIN')) {
  142.             $message->setIsDeleted(true);
  143.             $this->entityManagerInterface->flush();
  144.             return new JsonResponse([
  145.                 'status' => "ok"
  146.             ]);
  147.         }
  148.         return new JsonResponse(['status' => "ko"Response::HTTP_UNAUTHORIZED]);
  149.     }
  150.     #[Route('/delete/file/{id}'name'detele_file_message'methods: ['POST'])]
  151.     public function deleteFileMessages(FileMessage $fileMessageGoogleStorageService $googleStorageService)
  152.     {
  153.         if ($fileMessage->getMessages()->getUser()->getId() == $this->getUser()->getId() || $this->isGranted('ROLE_ADMIN')) {
  154.             $message $fileMessage->getMessages();
  155.             //delete file if in storage
  156.             $company $message->getCampaign()->getCompany();
  157.             $campaign $message->getCampaign();
  158.             $bucketName "company-" strtolower($company->getId());
  159.             $fileName "Campaigns/" $campaign->getId() . "/" $fileMessage->getName();
  160.             //end delete in google storage
  161.             $fileMessage->setIsDeleted(true);
  162.             $this->entityManagerInterface->flush();
  163.             $file $this->messageService->getFileMissionUrl($fileMessage->getMessages()->getMission(), $fileMessage->getName());
  164.             if ($message->getContent() == null && $fileMessage->getMessages()->getFileMessages()!=null && $this->messageService->allFileMessageIsDeleted($fileMessage->getMessages())) {
  165.                 $message->setIsDeleted(true);
  166.                 $this->entityManagerInterface->flush();
  167.             }
  168.             try {
  169.                 $this->filesystem->remove($file);
  170.             } catch (\Throwable $th) {
  171.                 $this->logger->error("can't delete file in $file");
  172.             }
  173.             $googleStorageService->deleteFile($bucketName$fileName);
  174.             return new JsonResponse([
  175.                 'status' => "ok"
  176.             ]);
  177.         }
  178.         return new JsonResponse(['status' => "ko"Response::HTTP_UNAUTHORIZED]);
  179.     }
  180.     #[Route('/emoji/toggle/{id}'name'toggle_emoji_reaction'methods: ['POST''GET'])]
  181.     public function toggleEmojiReaction(Message $messageRequest $request): JsonResponse
  182.     {
  183.         $user $this->getUser();
  184.         if ($user != null) {
  185.             $emoji $request->request->get('emoji');
  186.             $emojiId $request->request->get('emojiId');
  187.             $campaignOfMessage $message->getCampaign();
  188.             $messageReaction $this->messageReactionRepository->findReactionByUser(messageId$message->getId(), userId$user->getId(), emojiId$emojiId);
  189.             if ($messageReaction != null) {
  190.                 $message->removeMessageReaction($messageReaction[0]);
  191.                 $this->entityManagerInterface->remove($messageReaction[0]);
  192.                 $this->entityManagerInterface->flush();
  193.             } else {
  194.                 $newReaction = new MessageReaction();
  195.                 $newReaction->setEmoji($emoji);
  196.                 $newReaction->setUser($user);
  197.                 $newReaction->setEmojiId(intval($emojiId));
  198.                 $newReaction->setMessage($message);
  199.                 $message->addMessageReaction($newReaction);
  200.                 $this->entityManagerInterface->persist($newReaction);
  201.                 $this->entityManagerInterface->flush();
  202.                 $event = new UserReactionEvent($message->getUser(), $this->getUser(), $message$newReaction->getEmoji(),$campaignOfMessage);
  203.                 $this->dispatcher->dispatch($eventUserReactionEvent::NAME);
  204.             }
  205.             return new JsonResponse([
  206.                 'status' => "ok",
  207.                 'id_user' => $user->getId()
  208.             ]);
  209.         }
  210.         return new JsonResponse(['status' => "ko"Response::HTTP_UNAUTHORIZED]);
  211.     }
  212.     #[Route('/send/error'name'send_error'methods: ['POST'])]
  213.     public function sendError(Request $request)
  214.     {
  215.         $this->messageService->sendEmailError($request->request->get('xhr'), $request->request->get('type'), $request->request->get('message'));
  216.         return new JsonResponse([]);
  217.     }
  218.     #[Route('/add/{id}'name'_add'methods: ['POST'])]
  219.     public function addMessage(Request $requestMission $missionMessageRepository $messageRepository)
  220.     {
  221.         $message = new Message();
  222.         $entityManager $this->getDoctrine()->getManager();
  223.         $path 'file_message_directory';
  224.         $form $this->createForm(MessageType::class, $message);
  225.         $form->handleRequest($request);
  226.         $error_id_message $request->query->get('error_id_message'null);
  227.         $messageInsered $messageRepository->findOneBy(['id' => $error_id_message]);
  228.         if ($form->isSubmitted() && $form->isValid() && $messageInsered == null or ($path 'file_message_directory')) {
  229.             $errorMessage "";
  230.             $errorCode 200;
  231.             try {
  232.                 //$files = $form->get('fileMessages')->getData();
  233.                 $drapDrop $request->query->get('drag-drop');
  234.                 $files = !is_null($request->query->get('drag-drop')) && $request->query->get('drag-drop') == $request->files->get('file') : $form->get('fileMessages')->getData();
  235.                 if ($files != null && sizeof($files) > || !empty(preg_replace("/\s/"""$message->getContent()))) {
  236.                     foreach ($files as $file) {
  237.                         $nameSplitByDot explode('.'$file->getClientOriginalName());
  238.                         $extension $nameSplitByDot != null &&  sizeof($nameSplitByDot) > end($nameSplitByDot) : $file->guessExtension();
  239.                         $type preg_replace('/\/[a-zA-Z-_,.]*\s?/',"",$file->getMimeType());
  240.                         $nameUniqueCompany strtolower("company-" $mission->getCampaign()->getCompany()->getId());
  241.                         $destination $this->getParameter($path) . '/' $mission->getId() . '/message';
  242.                         $originalFilename pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
  243.                         $newFilename $originalFilename '-' uniqid() . '.' $extension;
  244.                         //upload file in google storage
  245.                         $this->googleStorageService->uploadFile($nameUniqueCompany$file$newFilename'Campaigns/' $mission->getCampaign()->getId());
  246.                         $fileMessage = new FileMessage();
  247.                         $fileMessage->setName($newFilename);
  248.                         $fileMessage->setIsNew(1);
  249.                         $fileMessage->setType($type);
  250.                         $message->addFileMessage($fileMessage);
  251.                     }
  252.                     $idMessage $request->query->get('id-message');
  253.                     $replyTo $request->query->get('id-reply-message');
  254.                     if ($idMessage != "") {
  255.                         $messagePersisted $messageRepository->findOneBy(['id' => $idMessage]);
  256.                         $messagePersisted->setIsModified(true);
  257.                         $messagePersisted->setContent($message->getContent(), false);
  258.                         $message $messagePersisted;
  259.                     } else {
  260.                         $message->setUser($this->getUser())
  261.                             ->setCampaign($mission->getCampaign())
  262.                             ->setMission(mission$mission)
  263.                             ->setUserListWhoRead([$this->getUser()->getId()]);
  264.                         $entityManager->persist($message);
  265.                     }
  266.                     if ($replyTo != "") {
  267.                         $replyedMessage $messageRepository->findOneBy(['id' => $replyTo]);
  268.                         $message->setReplyToWithMessage($replyedMessage);
  269.                     }
  270.                     $entityManager->flush();
  271.                     $this->messageService->sendEmailForParticipantMentionedInTchat($mission$message);
  272.                    
  273.                 }else{
  274.                     $errorMessage "Empty content";
  275.                 }
  276.             } catch (\Throwable $e) {
  277.                 $errorMessage "throwable : " $e->getMessage();
  278.                 $errorCode 500;
  279.                 $this->messageService->sendEmailError('exception'$e->getMessage(), "message : {$message->getContent()}  mission : {$mission->getId()}");
  280.             } catch (\Exception $e) {
  281.                 $errorMessage "exception : " $e->getMessage();
  282.                 $errorCode 500;
  283.                 $this->messageService->sendEmailError('error'$e->getMessage(), "message : {$message->getContent()} mission: {$mission->getId()}");
  284.             } catch (\Error $e) {
  285.                 $errorMessage "error: " $e->getMessage();
  286.                 $errorCode 500;
  287.                 $this->messageService->sendEmailError('error'$e->getMessage(), "message : {$message->getContent()} mission: {$mission->getId()}");
  288.             }
  289.             return new JsonResponse([
  290.                 'status' => $errorMessage == "" 'ok' 'ko',
  291.                 'message_id' => $message->getId(),
  292.                 'message' => $errorMessage == "" 'Enregistrer avec succes ' $errorMessage,
  293.             ], $errorCode);
  294.         }
  295.         return new JsonResponse([
  296.             'status' => 'ko',
  297.             'message_id' => $message->getId(),
  298.             'message' => 'form invalide',
  299.         ], Response::HTTP_UNAUTHORIZED);
  300.     }
  301.     
  302.     #[Route('/addaudio/{id}'name'_add_audio_file'methods: ['POST'])]
  303.     public function addAudioMessageFile(Mission $mission,Request $requestMessageRepository $messageRepository)
  304.     {
  305.         $message = new Message();
  306.         $entityManager $this->getDoctrine()->getManager();
  307.         $file $request->files->get('audio');
  308.         $nameSplitByDot explode('.'$file->getClientOriginalName());
  309.         $extension $nameSplitByDot && sizeof($nameSplitByDot) > end($nameSplitByDot) : $file->guessExtension();
  310.         $type preg_replace('/\/[a-zA-Z-_,.]*\s?/',"",$file->getMimeType());
  311.         $nameUniqueCompany strtolower("company-" $mission->getCampaign()->getCompany()->getId());
  312.         $newFilename 'audio-' uniqid() . '.' $extension;
  313.         $this->googleStorageService->uploadFile($nameUniqueCompany$file$newFilename'Campaigns/' $mission->getCampaign()->getId());
  314.         $fileMessage = new FileMessage();
  315.         $fileMessage->setName($newFilename);
  316.         $fileMessage->setIsNew(1);
  317.         $fileMessage->setType($type);
  318.         $message->addFileMessage($fileMessage);
  319.         $message->setUser($this->getUser())
  320.             ->setCampaign($mission->getCampaign())
  321.             ->setMission(mission$mission)
  322.             ->setUserListWhoRead([$this->getUser()->getId()]);
  323.         $entityManager->persist($message);
  324.         $entityManager->flush();
  325.         return new JsonResponse('ok');
  326.     }
  327.     #[Route('/planning/validation/{type}/{id}/{stepId}'name'_planning_validation'methods: ['GET'])]
  328.     public function stepValidation(string $typestring $stepIdWorkflowStepRepository $workflowStepRepositoryMission $mission)
  329.     {
  330.         return new JsonResponse([
  331.             'html' => $this->getHtmlValidationStep($type$mission$workflowStepRepository->findOneBy(['id' => $stepId]))
  332.         ]);
  333.     }
  334.       private function getHtmlValidationStep(string $typeMission $missionWorkflowStep $step)
  335.     {
  336.         return $this->twig->render('mission/_validation_step.html.twig', [
  337.             'type' => $type,
  338.             'mission' => $mission,
  339.             'step' => $step
  340.         ]);
  341.     }
  342.     private function getHtmlToRenderInView(?Mission $mission, array $listLastMessagestring $timeZonefloat $dateOffSetHourbool|null $unredMessage false,int $nbAllMessage =0)
  343.     {
  344.         if (sizeof($listLastMessage) == 0) {
  345.             return "";
  346.         }
  347.         return $this->twig->render("mission/_chat_item.html.twig", [
  348.             "messages" => $listLastMessage,
  349.             "nbAllMessage" => $nbAllMessage,
  350.             "mission" => $mission,
  351.             "unred_message" => $unredMessage,
  352.             "time_zone" => $timeZone,
  353.             "date_off_setHour" => abs($dateOffSetHour),
  354.         ]);
  355.     }
  356.     private function getHtmlFutureActions (Mission $mission, array $futuresActions, ?string $currentRouteName=null, ?string $estimatedIncome=null)
  357.     {   
  358.         $formMissionInitialTimeManually $this->createForm(MissionParticipantDelaisType::class);
  359.         return $this->twig->render("mission/Ux/_futures_actions.html.twig", [
  360.             'futurActions'=> $futuresActions
  361.             'mission'=> $mission,
  362.             'price_service' => $this->priceService,
  363.             'campaign'=> $mission->getCampaign(),
  364.             'currentRouteName'=>$currentRouteName,
  365.             'estimatedIncome'=> $this->getEstimatedIncome(),
  366.             'formMissionInitialTimeManually' => $formMissionInitialTimeManually->createView(),
  367.         ]);
  368.     }
  369.     private function getEstimatedIncome(){
  370.         if ($this->isGranted(Role::ROLE_ADMIN->value)) {
  371.             $priceCampaign $this->missionParticipantRepository->findByInitialTime();
  372.             $estimatedIncome = [];
  373.             $initialTime = [];
  374.             $price = [];
  375.             foreach ($priceCampaign as $value) {
  376.                 if (!isset($estimatedIncome[$value->getMission()->getId()])) {
  377.                     $estimatedIncome[$value->getMission()->getId()] = [];
  378.                 }
  379.                 $initialTime[$value->getMission()->getId()][] = $value->getInitialTime();
  380.                 $price[$value->getMission()->getId()][] = $value->getEstimatedIncome();
  381.             }
  382.         } elseif ($this->isGranted(Role::ROLE_SUBCONTRACTOR->value)) {
  383.             $visibleCampaign = ['orderedBy' => $this->getUser()];
  384.             $estimatedIncome $this->missionParticipantRepository->getSubcontractorForUserAndMission($this->getUser());
  385.         } else {
  386.             $estimatedIncome null;
  387.         }
  388.         return $estimatedIncome;
  389.     }
  390.     private function getIdsMessage(array $listLastMessage){
  391.         $ids = []; 
  392.         $fileIds = []; 
  393.         foreach ($listLastMessage as $key => $message) {
  394.             $ids =[...$ids$message->getId()]; 
  395.             foreach ($message->getFileMessages() as $fileMessage) {
  396.                 $fileIds =[...$fileIds$fileMessage->getId()]; 
  397.             }
  398.         }
  399.         return [
  400.             'message_ids'=>$ids
  401.             'file_message_ids'=> $fileIds
  402.         ]; 
  403.     }
  404.     private function  getUserTypingMessage(array $user_typing){
  405.         return $this->twig->render('services/messages/user_typing_message.html.twig',[
  406.             'user_typing' => $user_typing
  407.         ]);
  408.     }
  409.     private function getElementReactions(array $messages){
  410.         $listMessageWithReactions = []; 
  411.         foreach ($messages as $key => $message) {
  412.             $listMessageWithReactions = [... $listMessageWithReactions,[
  413.                  'id'=> $message->getId(), 
  414.                  'content'=> $this->messageService->getReactionsHtml($message)
  415.             ]];
  416.         }
  417.         return $listMessageWithReactions 
  418.     }
  419.     private function userReadLastMessage(?Message $message=null){
  420.         $userIds = [];
  421.         $users = []; 
  422.         if($message!=null){
  423.             $userIds $message->getUserListWhoRead();
  424.             $userIds array_diff($userIds, [$message->getUser()->getId()]);
  425.             $users $this->userRepository->findByIds($userIds);
  426.         }
  427.         return [
  428.                     'html'=>$this->twig->render('services/messages/users_who_read.html.twig',[
  429.                                 'user_list' => $users
  430.                     ]), 
  431.                     'ids'=>[...$userIds], 
  432.             ]
  433.         
  434.        ;
  435.     }
  436.     function splitChar($string$lg_max)
  437.     {
  438.         if (strlen($string) > $lg_max) {
  439.             $string substr($string0$lg_max);
  440.             $last_space strrpos($string" ");
  441.             $string substr($string0$last_space) . "...";
  442.         }
  443.         return $string;
  444.     }
  445.     #[Route('/user/istyping/{id}',name:'user_is_typing')]
  446.     public function setUserIsTyping(Campaign $campaign,CampaignRepository $campaignRepository){
  447.         
  448.         $this->messageService->postUserTypingMessage($campaign->getId());
  449.         return new JsonResponse(['status'=>'ok']);
  450.     }
  451.  
  452. }