src/Controller/API/MessageController.php line 360

Open in your IDE?
  1. <?php
  2. namespace App\Controller\API;
  3. use App\Entity\Campaign;
  4. use App\Entity\DiscussionGroup;
  5. use App\Entity\FileMessage;
  6. use App\Entity\Message;
  7. use App\Entity\MessageReaction;
  8. use App\Entity\Mission;
  9. use App\Entity\User;
  10. use App\Event\Chat\GroupedMessageSentEvent;
  11. use App\Event\Chat\MessageSentEvent;
  12. use App\Event\User\UserReactionEvent;
  13. use App\Form\MessageType;
  14. use App\Repository\DiscussionGroupRepository;
  15. use App\Repository\MessageReactionRepository;
  16. use App\Repository\MessageRepository;
  17. use App\Repository\UserRepository;
  18. use App\Service\CampaignApiService;
  19. use App\Service\ChatService;
  20. use App\Service\DeviceService;
  21. use Doctrine\ORM\EntityManagerInterface;
  22. use FOS\RestBundle\Controller\Annotations as Rest;
  23. use Nelmio\ApiDocBundle\Annotation\Model;
  24. use OpenApi\Attributes as OA;
  25. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  26. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  27. use Symfony\Component\HttpFoundation\JsonResponse;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\HttpFoundation\Response;
  30. use App\Service\GoogleStorageService;
  31. use App\Service\MessageService;
  32. use App\Service\MissionApiService;
  33. use App\Service\MissionParticipantService;
  34. use App\Service\WorkflowStepService;
  35. use Psr\Log\LoggerInterface;
  36. use Symfony\Component\Mercure\HubInterface;
  37. use Symfony\Component\Mercure\Update;
  38. use Symfony\Component\Serializer\SerializerInterface;
  39. use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
  40. class MessageController extends AbstractController
  41. {
  42.     
  43.     
  44.     public function __construct(
  45.         private EntityManagerInterface $entityManager
  46.         private GoogleStorageService $googleStorageService,
  47.         private MessageService $messageService,
  48.         private LoggerInterface $logger,
  49.         private MessageReactionRepository $messageReactionRepository,
  50.         private EventDispatcherInterface $dispatcher
  51.         private HubInterface $hub
  52.         private SerializerInterface $serializer
  53.         private ChatService $chatService
  54.         private DiscussionGroupRepository $discussionGroupRepository,
  55.     ){}
  56.     /**
  57.      * Add a message to a campaign
  58.      *
  59.      * @param Campaign $campaign
  60.      * @param Request $request
  61.      * @param EntityManagerInterface $entityManager
  62.      * @return Message|\Symfony\Component\Form\FormInterface
  63.      */
  64.     #[Rest\Post('/api/v2/campaigns/{id}/messages')]
  65.     #[Rest\View(statusCodeResponse::HTTP_CREATEDserializerGroups: ['message_write'])]
  66.     #[OA\Tag(name'Campaigns')]
  67.     #[OA\Parameter(
  68.         name'content',
  69.         description'The message\'s content',
  70.         in'query',
  71.         requiredtrue,
  72.         schema: new OA\Schema(type'string'),
  73.     )]
  74.     #[OA\Response(
  75.         responseResponse::HTTP_CREATED,
  76.         description'The message has been created',
  77.         content: new OA\JsonContent(
  78.             type'array',
  79.             items: new OA\Items(ref: new Model(typeMessage::class, groups: ['message_write']))
  80.         )
  81.     )]
  82.     #[OA\Response(
  83.         responseResponse::HTTP_BAD_REQUEST,
  84.         description'The form is invalid and contains errors',
  85.         content: new OA\JsonContent(
  86.             type'array',
  87.             items: new OA\Items(properties: [
  88.                 new OA\Property(property'code'type'integer'),
  89.                 new OA\Property(property'message'type'string'),
  90.                 new OA\Property(property'errors'type'array'items: new OA\Items(properties: [
  91.                     new OA\Property(property'children'type'array'items: new OA\Items(properties: [])),
  92.                 ])),
  93.             ], type'object')
  94.         )
  95.     )]
  96.     #[OA\Response(
  97.         responseResponse::HTTP_UNAUTHORIZED,
  98.         description'Unauthorized - the user isn\'t logged in',
  99.         content: new OA\JsonContent(
  100.             type'array',
  101.             items: new OA\Items(properties: [
  102.                 new OA\Property(property'code'type'integer'),
  103.                 new OA\Property(property'message'type'string'),
  104.             ], type'object')
  105.         )
  106.     )]
  107.     #[OA\Response(
  108.         responseResponse::HTTP_NOT_FOUND,
  109.         description'The campaign doesn\'t exists',
  110.     )]
  111.     public function postMessage(Mission $missionRequest $request,DeviceService $deviceService,  EventDispatcherInterface $dispatcherEntityManagerInterface $entityManagerDiscussionGroupRepository $discussionGroupRepository)
  112.     {
  113.         
  114.         $group $discussionGroupRepository->findOneBy(['id'=>$request->query->get('groupId')]);
  115.         $platform $deviceService->getPlatformAndVersion$request->headers->get('User-Agent')); 
  116.         $message = (new Message())
  117.             ->setUser($this->getUser())
  118.             ->setCampaign($mission->getCampaign())
  119.             ->setMission($mission)
  120.             ->setPlatform$platform)
  121.             ->setUserListWhoRead([$this->getUser()->getId()])
  122.             ->setDiscussionGroup($group);
  123.             ;
  124.         $form $this->createForm(MessageType::class, $message, ['csrf_protection' => false]);
  125.         $form->handleRequest($request);
  126.         if ($form->isSubmitted()) {
  127.             $path 'file_message_directory';
  128.             $idMessageToEdit $request->query->get('id-edit-message') ;
  129.             $idMessageToReply  $request->query->get('id-reply-message');
  130.             $dateOffSetHour $request->query->get('time-zone'0);
  131.             
  132.             $files = []; 
  133.             $newMessage $this->messageService->addMessage($mission$message,$files$idMessageToReply$idMessageToEdit$path);
  134.          
  135.             $renderPlanning $this->chatService->getHtmlToRenderPlanning($mission);
  136.             $typeMessage $idMessageToEdit != "" && $idMessageToEdit!=null 'update''insert';
  137.             
  138.     
  139.             $this->chatService->publishMessageNotificationCampaignHashed(
  140.                 $mission->getId(),
  141.                 [
  142.                 'message'=>$this->serializer->normalize($newMessagenull, [AbstractNormalizer::GROUPS => ['message_read']]),
  143.                 'html'=>$this->chatService->getHtmlToRenderInViewForLastMessage($mission,$newMessage,$dateOffSetHour),
  144.                 'type'=>$typeMessage,
  145.                 'planning' => $renderPlanning,
  146.                 'currentUser' => $this->getUser()->getId(),
  147.                 
  148.             ], $group);
  149.             $this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
  150.                     "message" => "",
  151.                     'idMission' => $mission->getId(),
  152.                     'group' => !is_null($group) ? $group->getId() : "",
  153.                     'type' => 'message-unread'
  154.                 ]);
  155.     
  156.             $files $form->get('fileMessages')->getData();
  157.             foreach ($files as $file) {
  158.                 $newMessage = new Message();
  159.                 $newMessage->setUser($this->getUser())
  160.                     ->setCampaign($mission->getCampaign())
  161.                     ->setMission($mission)
  162.                     ->setPlatform$platform)
  163.                     ->setUserListWhoRead([$this->getUser()->getId()]);
  164.                 
  165.                 if (!is_null($group)) {
  166.                     $newMessage->setDiscussionGroup($group);
  167.                 }
  168.     
  169.     
  170.                 $nameSplitByDot explode('.'$file->getClientOriginalName());
  171.                 $extension sizeof($nameSplitByDot) > end($nameSplitByDot) : $file->guessExtension();
  172.                 $type preg_replace('/\/[a-zA-Z-_,.]*\s?/',"",$file->getMimeType());
  173.                 $nameUniqueCompany strtolower("company-" $mission->getCampaign()->getCompany()->getId());
  174.                 $originalFilename pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
  175.                 $newFilename $originalFilename '-' uniqid() . '.' $extension;
  176.                 //upload file in google storage
  177.                 $this->googleStorageService->uploadFile($nameUniqueCompany$file$newFilename'Campaigns/' $mission->getCampaign()->getId());
  178.                 $fileMessage = new FileMessage();
  179.                 $fileMessage->setName($newFilename);
  180.                 $fileMessage->setIsNew(1);
  181.                 $fileMessage->setType($type);
  182.                 $fileMessage->setIsNotInfected(true); 
  183.                 $newMessage->addFileMessage($fileMessage);
  184.                 $this->entityManager->persist($newMessage);
  185.                 
  186.                 $userWhoReadMessage $this->messageService->getBullUsersWhoReadMessage($newMessage); 
  187.                 
  188.                 $newMessage->setUserListWhoReadApi($userWhoReadMessage); 
  189.                 $this->messageService->sendEmailForParticipantMentionedInTchat($mission$newMessage);
  190.     
  191.                 $renderPlanning $this->chatService->getHtmlToRenderPlanning($mission);
  192.                
  193.                 $this->chatService->publishMessageNotificationCampaignHashed(
  194.                     $mission->getId(),
  195.                     [
  196.                         'message' => $this->serializer->normalize($newMessagenull, [AbstractNormalizer::GROUPS => ['message_read']]),
  197.                         'html' => $this->chatService->getHtmlToRenderInViewForLastMessage($mission$newMessage$dateOffSetHour),
  198.                         'type' => 'insert',
  199.                         'planning' => $renderPlanning,
  200.                         'currentUser' => $this->getUser()->getId(),
  201.                     ],
  202.                     $group
  203.                 );
  204.     
  205.                 $this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
  206.                     "message" => "",
  207.                     'idMission' => $mission->getId(),
  208.                     'group' => !is_null($group) ? $group->getId() : "",
  209.                     'type' => 'message-unread'
  210.                 ]);
  211.     
  212.                 $this->entityManager->flush();
  213.                     
  214.             }   
  215.             return  $newMessage ;
  216.             
  217.         } else {
  218.             return $form;
  219.         }
  220.         
  221.     }
  222.     #[Rest\Get('/api/v2/message/public/discussion/{id}')]
  223.     #[Rest\View(serializerGroups: ['message_read'])]
  224.     #[OA\Response(
  225.         response200,
  226.         description'Get all the details about a mission',
  227.         content: new OA\JsonContent(
  228.             type'array',
  229.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['message_read']))
  230.         )
  231.     )]
  232.     #[OA\Response(
  233.         response401,
  234.         description'Unauthorized - the user isn\'t logged in',
  235.         content: new OA\JsonContent(
  236.             type'array',
  237.             items: new OA\Items(properties: [
  238.                 new OA\Property(property'code'type'integer'),
  239.                 new OA\Property(property'message'type'string'),
  240.             ], type'object')
  241.         )
  242.     )]
  243.     #[OA\Response(
  244.         response404,
  245.         description'The mission with id doesn\'t exists',
  246.     )]
  247.     public function getListDiscussionGroupe(Mission $missionDiscussionGroupRepository $discussionGroupRepositoryMessageService $messageService)
  248.     {   
  249.         $nbrMessageUreadInGroup $messageService->getNumberMessageUnread($missionnull);
  250.         $additionnedDiscussion = new DiscussionGroup(); 
  251.         $additionnedDiscussion->setId('group');
  252.         $additionnedDiscussion->setName('Groupe');
  253.         $additionnedDiscussion->setNbrUnreadMessage($nbrMessageUreadInGroup);
  254.         $additionnedDiscussion->setCampaign($mission->getCampaign());
  255.         $discussionGroupe $discussionGroupRepository->getAllDiscussionGroup($mission->getCampaign());
  256.         
  257.         foreach ($discussionGroupe as $key => $group) {
  258.              $nbrMessageUread $messageService->getNumberMessageUnread($mission$group);
  259.              $group->setNbrUnreadMessage($nbrMessageUread); 
  260.         }
  261.         return [ $additionnedDiscussion,...$discussionGroupe];
  262.     }
  263.     #[Rest\POST('/api/v2/message/toggle-pinned/{id}')]
  264.     #[Rest\View(serializerGroups: ['message_read'])]
  265.     #[OA\Response(
  266.         response200,
  267.         description'Get all the details about a mission',
  268.         content: new OA\JsonContent(
  269.             type'array',
  270.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['message_read']))
  271.         )
  272.     )]
  273.     #[OA\Response(
  274.         response401,
  275.         description'Unauthorized - the user isn\'t logged in',
  276.         content: new OA\JsonContent(
  277.             type'array',
  278.             items: new OA\Items(properties: [
  279.                 new OA\Property(property'code'type'integer'),
  280.                 new OA\Property(property'message'type'string'),
  281.             ], type'object')
  282.         )
  283.     )]
  284.     #[OA\Response(
  285.         response404,
  286.         description'The mission with id doesn\'t exists',
  287.     )]
  288.     public function toggleMessagePinned(Message $message)
  289.     {   
  290.          $userAlreadyPinnedAMessage false
  291.          $currentUser $this->getUser(); 
  292.          foreach ($message->getPinnedByUsers() as $user) {
  293.                 if($user->getId() == $currentUser->getId()){
  294.                      $userAlreadyPinnedAMessage true
  295.                      break;
  296.                 }
  297.          }
  298.          $userAlreadyPinnedAMessage $message->removePinnedByUser$currentUser) :  $message->addPinnedByUser$currentUser);;
  299.          $this->entityManager->flush();
  300.          $this->chatService->publishOnMessagePinned($message); 
  301.           return $message
  302.     }
  303.     #[Rest\Get('/api/v2/message/pinned/{id}/{idGroup}')]
  304.     #[Rest\View(serializerGroups: ['message_read'])]
  305.     #[OA\Response(
  306.         response200,
  307.         description'Get all the details about a mission',
  308.         content: new OA\JsonContent(
  309.             type'array',
  310.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['message_read']))
  311.         )
  312.     )]
  313.     #[OA\Response(
  314.         response401,
  315.         description'Unauthorized - the user isn\'t logged in',
  316.         content: new OA\JsonContent(
  317.             type'array',
  318.             items: new OA\Items(properties: [
  319.                 new OA\Property(property'code'type'integer'),
  320.                 new OA\Property(property'message'type'string'),
  321.             ], type'object')
  322.         )
  323.     )]
  324.     #[OA\Response(
  325.         response404,
  326.         description'The mission with id doesn\'t exists',
  327.     )]
  328.     public function getAllMessagePinned(Mission $mission,string $idGroupMissionApiService $missionApiService,  MessageService $messageServiceMessageRepository $messageRepository,string $page ="0"string $loadMore "0")
  329.     {   
  330.        
  331.  
  332.            $group $idGroup =='group' null $this->discussionGroupRepository->findOneBy(['id'=>$idGroup]);
  333.            $messages $messageRepository->pinnedMessage($mission->getCampaign(), $group$this->getUser()) ;
  334.            usort($messages, function($a$b) {
  335.                     $dateA $a->getCreatedAt()->getTimestamp();
  336.                     $dateB $b->getCreatedAt()->getTimestamp();
  337.                     return   $dateA $dateB 
  338.             });
  339.            $messages $this->addAddionalData($messages,$mission) ; 
  340.         
  341.           return $messages
  342.     }
  343.     #[Rest\Get('/api/v2/message/discussion/{idGroup}/{id}/{page}')]
  344.     #[Rest\View(serializerGroups: ['message_read'])]
  345.     #[OA\Response(
  346.         response200,
  347.         description'Get all the details about a mission',
  348.         content: new OA\JsonContent(
  349.             type'array',
  350.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['message_read']))
  351.         )
  352.     )]
  353.     #[OA\Response(
  354.         response401,
  355.         description'Unauthorized - the user isn\'t logged in',
  356.         content: new OA\JsonContent(
  357.             type'array',
  358.             items: new OA\Items(properties: [
  359.                 new OA\Property(property'code'type'integer'),
  360.                 new OA\Property(property'message'type'string'),
  361.             ], type'object')
  362.         )
  363.     )]
  364.     #[OA\Response(
  365.         response404,
  366.         description'The mission with id doesn\'t exists',
  367.     )]
  368.     public function getAllMessageInGroup(Mission $missionMissionApiService $missionApiService,  MessageService $messageServiceMessageRepository $messageRepositorystring $idGroup,string $page ="0"string $loadMore "0")
  369.     {   
  370.        
  371.            $fileMessage= [];
  372.            $group $idGroup =='group' null $this->discussionGroupRepository->findOneBy(['id'=>$idGroup]);
  373.            $nbrElementPerPage 10;   
  374.            $initialPage $page
  375.           
  376.           $maxPage 5
  377.           $listMessageUnread= [];
  378.           $messages=[];
  379.           $i=0;
  380.           
  381.           while($i<$maxPage){
  382.                 $limite $page == 'all' ?  null :  intval($page) * $nbrElementPerPage
  383.                 $messages $messageRepository->getAllMessage($mission->getCampaign(), $limite$group);
  384.                 if($initialPage == 'all' || intval($initialPage) > || count($messages) == 0){
  385.                     break; 
  386.                 }
  387.                 $listMessageUnread $this->getMessageUnread($messages);
  388.                 if( count($messages) > count($listMessageUnread)){
  389.                      break;
  390.                 }
  391.                 $page++;
  392.                 $i++;
  393.           }
  394.           foreach ($mission->getCampaign()->getFileMissions() as $file) {
  395.                 $nameOfFileinBucket "Campaigns/{$mission->getCampaign()->getId()}/{$file->getName()}";
  396.                 $nameOfBucket "company-{$mission->getCampaign()->getCompany()->getId()}";
  397.                 $fileMessage= [...$fileMessage, [
  398.                     'id'=>$file->getId(), 
  399.                     'name'=>$file->getName(), 
  400.                     'link'=>$this->googleStorageService->getUrlBucket(strtolower($nameOfBucket),$nameOfFileinBucket),
  401.                 ]];
  402.             }
  403.         
  404.            $nbrMessages $messageRepository->nbAllMessage($mission->getCampaign(),$group)['nb'];
  405.            usort($messages, function($a$b) {
  406.                     $dateA $a->getCreatedAt()->getTimestamp();
  407.                     $dateB $b->getCreatedAt()->getTimestamp();
  408.                     return   $dateA $dateB 
  409.             });
  410.             $tempMessages = [];
  411.             foreach ($messages as $message) {
  412.                  if($message->getContent() != null || ($message->getContent()==null && $this->haveFileNotDeleted($message))){
  413.                      $tempMessages = [...$tempMessages$message];
  414.                  }
  415.             }
  416.            $idLastMessageUnred sizeof($listMessageUnread) != end($listMessageUnread)->getId() : null;
  417.            $messageService->marqueAllInMissionMessageReadWithGroup($mission$this->getUser(), $group );
  418.            $messages $this->addAddionalData($tempMessages,$mission$idLastMessageUnred) ; 
  419.            
  420.           return [
  421.                         'messages'=> $messages,
  422.                         'initialBrief'=> $mission->getCampaign()->getBrief(),
  423.                         'nbrMessages'=> $nbrMessages,
  424.                         'idLastMessageUread'=>$idLastMessageUnred,
  425.                         'fileMessage'=> $fileMessage,
  426.                         'page'=>$page,
  427.                         'user_typing'=>[...$this->messageService->calculaTimeTypingOfEachUser($this->messageService->getUserTypingWithoutCurrentUser($mission))]
  428.                     ]
  429.                 ;
  430.     }
  431.      
  432.     public function getMessageUnread(array $messages)
  433.     {
  434.             $currentUserId $this->getUser()->getId(); 
  435.             $listMessageUnread = []; 
  436.             foreach ($messages as $message) {
  437.                 $userIds  array_map(function($item){
  438.                      if($item instanceof User ){
  439.                          return $item->getId(); 
  440.                      }
  441.                      return $item
  442.                  }, $message->getUserListWhoRead());
  443.                 
  444.                  if(!in_array($currentUserId$userIds)){
  445.                     $listMessageUnread[] =  $message
  446.                  }
  447.             }
  448.         return  $listMessageUnread
  449.     }    
  450. private function haveFileNotDeleted(Message $message){
  451.          
  452.         foreach ($message->getFileMessages() as $fileMessage) {
  453.               if($fileMessage->getIsDeleted() != true){
  454.                 return true
  455.               }
  456.         }
  457.         return false
  458.    }
  459.     #[Rest\Get('/api/v2/message/public/{id}/{page}')]
  460.     #[Rest\View(serializerGroups: ['message_read'])]
  461.     #[OA\Response(
  462.         response200,
  463.         description'Get all the details about a mission',
  464.         content: new OA\JsonContent(
  465.             type'array',
  466.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['message_read']))
  467.         )
  468.     )]
  469.     #[OA\Response(
  470.         response401,
  471.         description'Unauthorized - the user isn\'t logged in',
  472.         content: new OA\JsonContent(
  473.             type'array',
  474.             items: new OA\Items(properties: [
  475.                 new OA\Property(property'code'type'integer'),
  476.                 new OA\Property(property'message'type'string'),
  477.             ], type'object')
  478.         )
  479.     )]
  480.     #[OA\Response(
  481.         response404,
  482.         description'The mission with id doesn\'t exists',
  483.     )]
  484.     public function getPublicMessage(Mission $missionMissionApiService $missionApiService,  MessageService $messageServiceMessageRepository $messageRepository,string $page ="0"string $loadMore "0")
  485.     {   
  486.            $userSetPicture=[];
  487.            $messageService->marqueAllInMissionMessageRead($mission$this->getUser());
  488.            $fileMessage=[];
  489.           
  490.            if($page == 'all'){
  491.               $messages $messageRepository->finMessageByCampaign($mission->getCampaign()) ;
  492.               foreach ($mission->getCampaign()->getFileMissions() as $file) {
  493.                     $nameOfFileinBucket "Campaigns/{$mission->getCampaign()->getId()}/{$file->getName()}";
  494.                     $nameOfBucket "company-{$mission->getCampaign()->getCompany()->getId()}";
  495.                      $fileMessage= [...$fileMessage, [
  496.                         'id'=>$file->getId(), 
  497.                         'name'=>$file->getName(), 
  498.                         'link'=>$this->googleStorageService->getUrlBucket(strtolower($nameOfBucket),$nameOfFileinBucket),
  499.                      ]];
  500.               }
  501.               
  502.            }
  503.            else{
  504.               $messages $messageRepository->getAllMessage($mission->getCampaign(), $page 10) ;
  505.            }
  506.            usort($messages, function($a$b) {
  507.                     $dateA $a->getCreatedAt()->getTimestamp();
  508.                     $dateB $b->getCreatedAt()->getTimestamp();
  509.                     return   $dateA $dateB 
  510.             });
  511.            $messages $this->addAddionalData($messages,$mission) ; 
  512.            
  513.         return [ 
  514.                     'messages'=> $messages,
  515.                     'initialBrief'=> $mission->getCampaign()->getBrief(),
  516.                     'fileMessage'=> $fileMessage,
  517.                     'user_typing'=>[...$this->messageService->calculaTimeTypingOfEachUser($this->messageService->getUserTypingWithoutCurrentUser($mission))],
  518.                     
  519.                 ];
  520.     }
  521.     #[Rest\get('/api/v2/message/campaign-state/{id}')]
  522.     #[Rest\View(serializerGroups: ['mission_list','mission_read','step_write','message_read'])]
  523.     #[OA\Response(
  524.         response200,
  525.         description'Returns all the missions for the authenticated user',
  526.         content: new OA\JsonContent(
  527.             type'array',
  528.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list','message_read','mission_read','step_write']))
  529.         )
  530.     )]
  531.     
  532.     public function campaignState(Mission $mission,MissionParticipantService $missionParticipantServiceWorkflowStepService $workflowStepService,CampaignApiService $campaignApiService,  MissionApiService $missionApiService){
  533.          
  534.         $stateCampaign $missionApiService->getCampaignState($mission->getCampaign()); 
  535.         $notification $this->getNotification($mission$stateCampaign$this->getUser()); 
  536.         $step $workflowStepService->getWorkflowActiveStepBy($mission);
  537.         $responsables $campaignApiService->getWorkflowActiveStepByCampaing($mission->getCampaign());
  538.         $participants =[];
  539.         $listMissionParticipants $missionParticipantService->getParticipants($mission->getCampaign());
  540.         
  541.         $userAlreadyIn = [];
  542.         foreach ($listMissionParticipants as $user) {
  543.                 if($user->getId() != $this->getUser()->getId() && !in_array($user->getId(), $userAlreadyIn)){
  544.                         $participants=[...$participants,[
  545.                             'user'=>[
  546.                                 'id'=> $user->getId(), 
  547.                                 'firstname'=> $user->getFirstname(),
  548.                                 'lastname'=> $user->getLastname(),
  549.                                 'fullname'=>$user->getFullname(), 
  550.                                 'pictureName'=>$user->getPictureName(),
  551.                                 'identifier'=>$user->getIdentifier(), 
  552.                             ]                            
  553.                         ]
  554.                     ] ;
  555.                     $userAlreadyIn =[... $userAlreadyIn$user->getId()]; 
  556.                 }
  557.          }
  558.         return new JsonResponse([
  559.             'state'=>$stateCampaign
  560.             'notifications'=> $notification
  561.             'step'=> $step,
  562.             'future_actions' => $missionParticipantService->getUniqByFutureActions($mission->getCampaign()->getId(),$this->getUser()->getId()),
  563.             'participants'=>  $participants
  564.             'subcontractors_not_evaluate'=>$campaignApiService->getSubcontractorNoEstimatedIncome($mission->getCampaign()),
  565.             'responsable_step'=> $responsables
  566.             'user_typing'=>[...$this->messageService->calculaTimeTypingOfEachUser($this->messageService->getUserTypingWithoutCurrentUser($mission))],
  567.         ]);
  568.     }
  569.     #[Rest\Post('/api/v2/campaigns/delete/filemessages/{id}')]
  570.     #[OA\Response(
  571.         response200,
  572.         description'Returns all the missions for the authenticated user',
  573.         content: new OA\JsonContent(
  574.             type'array',
  575.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  576.         )
  577.     )]
  578.     public function deleteFilMessage(FileMessage $fileMessage)
  579.     {   
  580.         $message $fileMessage->getMessages();
  581.         //delete file if in storage
  582.         $company $message->getCampaign()->getCompany();
  583.         $campaign $message->getCampaign();
  584.         $bucketName "company-" strtolower($company->getId());
  585.         $fileName "Campaigns/" $campaign->getId() . "/" $fileMessage->getName();
  586.         //end delete in google storage
  587.         $fileMessage->setIsDeleted(true); 
  588.         $this->entityManager->flush();
  589.         $file $this->messageService->getFileMissionUrl($fileMessage->getMessages()->getMission(), $fileMessage->getName());
  590.         if ($message->getContent() == null && sizeof($fileMessage->getMessages()->getFileMessages()) == 0) {
  591.             $message->setIsDeleted(true);
  592.             $this->entityManager->flush();
  593.         }
  594.         try {
  595.             $this->filesystem->remove($file);
  596.         } catch (\Throwable $th) {
  597.             $this->logger->error("can't delete file in $file");
  598.         }
  599.         $this->googleStorageService->deleteFile($bucketName$fileName);
  600.             $mission $message->getMission();
  601.             $renderContent $this->chatService->getHtmlContentToRenderInViewForLastMessage($mission,$message,0);
  602.             $this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
  603.                         "message" => "",
  604.                         'idMission' => $message->getMission()->getId(),
  605.                         'group' => $message->getDiscussionGroup(),
  606.                         'type' => 'message-unread'
  607.                     ]);
  608.             
  609.             $this->chatService->publishMessageNotificationCampaignHashed($mission->getId(),[
  610.                 'message'=>$this->serializer->normalize($messagenull, [AbstractNormalizer::GROUPS => ['message_read']],),
  611.                 'html'=>$renderContent,
  612.                 'type'=>'update',
  613.             ]);
  614.         return new JsonResponse([
  615.             'status'=>'ok'
  616.         ]);
  617.     }
  618.     #[Rest\Get('/api/v2/message/un-read-message-per-discussion/{id}')]
  619.     #[OA\Response(
  620.         response200,
  621.         description'Returns all the missions for the authenticated user',
  622.         content: new OA\JsonContent(
  623.             type'array',
  624.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  625.         )
  626.     )]
  627.     
  628.     public function getMessageUnreadPerDiscussion(Mission $missionDiscussionGroupRepository $discussionGroupRepositoryMessageService $messageService)
  629.     {   
  630.         $temp=[
  631.             [
  632.                 'id'=> 'group',
  633.                 'nbrMessageUnread'=>$messageService->getNumberMessageUnread($missionnull)
  634.             ]
  635.         ];
  636.         $discussionGroupe $discussionGroupRepository->getAllDiscussionGroup($mission->getCampaign()); 
  637.         foreach ($discussionGroupe as $key => $group) {
  638.             $discussion=[
  639.                 'id'=> $group->getId(),
  640.                 'nbrMessageUnread'=>$messageService->getNumberMessageUnread($mission$group)
  641.             ] ;
  642.             $temp=[...$temp,$discussion];
  643.         }
  644.        
  645.         return new JsonResponse($temp);
  646.     }
  647.     #[Rest\Post('/api/v2/campaigns/delete/messages/{id}')]
  648.     #[OA\Response(
  649.         response200,
  650.         description'Returns all the missions for the authenticated user',
  651.         content: new OA\JsonContent(
  652.             type'array',
  653.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  654.         )
  655.     )]
  656.     
  657.     public function deleteMessage(Message $message)
  658.     {   
  659.         $message->setIsDeleted(true);
  660.         $this->entityManager->flush();
  661.         $this->chatService->publishMessageNotificationCampaignHashed($message->getMission()->getId(),['message'=>$message->getId(),'type'=>'deleted'],$message->getDiscussionGroup());
  662.          $this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
  663.                     "message" => "",
  664.                     'idMission' => $message->getMission()->getId(),
  665.                     'group' => $message->getDiscussionGroup(),
  666.                     'type' => 'message-unread'
  667.                 ]);
  668.         return new JsonResponse([
  669.             'status'=>'ok'
  670.         ]);
  671.     }
  672.  
  673.     #[Rest\Post('/api/v2/message/emoji/{id}')]
  674.     #[OA\Response(
  675.         response200,
  676.         description'Returns all the missions for the authenticated user',
  677.         content: new OA\JsonContent(
  678.             type'array',
  679.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  680.         )
  681.     )]
  682.     
  683.     public function addEmoji(Request $requestMessage $message)
  684.     {  
  685.             $emoji $request->request->get('smiley');
  686.             $emojiId $request->request->get('id');
  687.             $campaignOfMessage $message->getCampaign();
  688.             $user $this->getUser();
  689.             $messageReaction $this->messageReactionRepository->findReactionByUser(messageId$message->getId(), userId$user->getId(), emojiId$emojiId);
  690.             if ($messageReaction != null) {
  691.                 $message->removeMessageReaction($messageReaction[0]);
  692.                 $this->entityManager->remove($messageReaction[0]);
  693.                 $this->entityManager->flush();
  694.             } else {
  695.                 $newReaction = new MessageReaction();
  696.                 $newReaction->setEmoji($emoji);
  697.                 $newReaction->setUser($user);
  698.                 $newReaction->setEmojiId(intval($emojiId));
  699.                 $newReaction->setMessage($message);
  700.                 $message->addMessageReaction($newReaction);
  701.                 $this->entityManager->persist($newReaction);
  702.                 $this->entityManager->flush();
  703.                 $event = new UserReactionEvent($message->getUser(), $this->getUser(), $message$newReaction->getEmoji(),$campaignOfMessage);
  704.                 $this->dispatcher->dispatch($eventUserReactionEvent::NAME);
  705.             }
  706.             $mission $message->getMission();
  707.             $renderContent $this->chatService->getHtmlContentToRenderInViewForLastMessage($mission,$message,0);
  708.            
  709.             $this->chatService->publishMessageNotificationCampaignHashed($mission->getId(),[
  710.                 'message'=>$this->serializer->normalize($messagenull, [AbstractNormalizer::GROUPS => ['message_read']],),
  711.                 'html'=>$renderContent,
  712.                 'type'=>'update',
  713.             ]);
  714.         return new JsonResponse(['status'=>$emoji]); 
  715.     }
  716.     #[Rest\Post('/api/v2/messages/user/isTyping/{id}')]
  717.     #[OA\Response(
  718.         response200,
  719.         description'Returns all the missions for the authenticated user',
  720.         content: new OA\JsonContent(
  721.             type'array',
  722.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  723.         )
  724.     )]
  725.     
  726.     public function userStartTyping(Mission $mission,Request $request)
  727.     {   
  728.         
  729.          
  730.         $groupId $request->query->get('groupId');
  731.         $group null;
  732.         if (!empty($groupId) && !is_null($groupId)) {
  733.             $group $this->discussionGroupRepository->findOneBy(['id'=>$groupId]);
  734.         }
  735.         $user $this->getUser();
  736.         $this->chatService->publishMessageNotificationCampaignHashed($mission->getId(),[
  737.                 'message'=>"",
  738.                 'type'=>'isTyping',
  739.                 'currentUser' => $user->getId(),
  740.                 'missionIds'=>array_map(function($item){
  741.                     return  $item->getId(); 
  742.                  }, $mission->getCampaign()->getMissions()->toArray()),
  743.                 'typingRender' => $this->chatService->userTyping($user),
  744.                 'user'=> $this->serializer->normalize($usernull, [AbstractNormalizer::GROUPS => ['message_read']])
  745.             ],$group);
  746.         return new JsonResponse([
  747.             'status'=> 'ok',
  748.         ]);
  749.     }
  750.     #[Rest\Post('/api/v2/messages/user/isStopTyping/{id}')]
  751.     #[OA\Response(
  752.         response200,
  753.         description'Returns all the missions for the authenticated user',
  754.         content: new OA\JsonContent(
  755.             type'array',
  756.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  757.         )
  758.     )]
  759.     
  760.     public function useFinichedTyping(Mission $mission,Request $request)
  761.     {   
  762.         
  763.         $groupId $request->query->get('groupId');
  764.         $group null;
  765.         if (!empty($groupId) && !is_null($groupId)) {
  766.             $group $this->discussionGroupRepository->findOneBy(['id'=>$groupId]);
  767.         }
  768.         $user $this->getUser();
  769.         $this->chatService->publishMessageNotificationCampaignHashed($mission->getId(),[
  770.                 'message'=>"",
  771.                 'type'=>'isStopTyping',
  772.                 'currentUser' => $user->getId(),
  773.                 'user'=> $this->serializer->normalize($usernull, [AbstractNormalizer::GROUPS => ['message_read']])
  774.             ],$group);
  775.         return new JsonResponse([
  776.             'status'=>'ok'
  777.         ]);
  778.     }
  779.     #[Rest\Post('/api/v2/messages/add/discussion/{id}')]
  780.     #[OA\Response(
  781.         response200,
  782.         description'Returns all the missions for the authenticated user',
  783.         content: new OA\JsonContent(
  784.             type'array',
  785.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  786.         )
  787.     )]
  788.     
  789.     public function newDiscussionGroup(Request $request,Campaign $campaignUserRepository $userRepository)
  790.     {   
  791.             $nameDiscussion $request->request->get('newNameDiscussionGroup'null); 
  792.             $userIds $request->request->get('userIdsSelected'); 
  793.             $discussionGroup = new DiscussionGroup(); 
  794.             
  795.             $discussionGroup->setName($nameDiscussion);
  796.             $discussionGroup->setCreatedBy($this->getUser());
  797.             $discussionGroup->setCampaign($campaign);
  798.             $discussionGroup->addUser($this->getUser());
  799.           
  800.         
  801.             foreach ($userIds as $key => $userId) {
  802.                 $user $userRepository->findOneBy(['id'=>$userId]); 
  803.                 if($user instanceof User){
  804.                     $discussionGroup->addUser($user); 
  805.                     if($this->getUser()->getId() != $user->getId()){
  806.                         $event = new GroupedMessageSentEvent($discussionGroup,$user);
  807.                         $this->dispatcher->dispatch($eventGroupedMessageSentEvent::NAME);
  808.                     }
  809.                 }
  810.             }
  811.             $this->entityManager->persist($discussionGroup); 
  812.             $this->entityManager->flush(); 
  813.             $this->chatService->publishOnDiscussionGroupUpdate('add',$discussionGroup); 
  814.             $this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
  815.                 "message" => "",
  816.                 'idMission' => $campaign->getMissions()->first()->getId(),
  817.                 'group' => !is_null($discussionGroup) ? $discussionGroup->getId() : "",
  818.                 'type' => 'message-unread'
  819.             ]);
  820.         return new JsonResponse([
  821.             'status'=>'ok'
  822.         ]);
  823.     }
  824.     #[Rest\Post('/api/v2/messages/delete/discussion/{id}')]
  825.     #[Rest\View(serializerGroups: ['message_read'])]
  826.     #[OA\Response(
  827.         response200,
  828.         description'Returns all the missions for the authenticated user',
  829.         content: new OA\JsonContent(
  830.             type'array',
  831.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  832.         )
  833.     )]
  834.     
  835.     public function deleteDiscussionGroup(Request $requestDiscussionGroup $discussionGroup)
  836.     {   
  837.         
  838.         $message null;
  839.         foreach ($discussionGroup->getMessages() as $message) {
  840.             $message->setIsDeleted(true);
  841.             $this->entityManager->persist($message);
  842.             $this->entityManager->flush();
  843.         }
  844.         $discussionGroup->setDeleted(true);
  845.         $this->entityManager->persist($discussionGroup);
  846.         $this->entityManager->flush();
  847.         if ( null != $message ) {
  848.          $this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
  849.                     "message" => "",
  850.                     'idMission' => $message->getMission()->getId(),
  851.                     'group' => $discussionGroup,
  852.                     'type' => 'message-unread'
  853.                 ]);
  854.         }
  855.         $this->chatService->publishOnDiscussionGroupUpdate('delete',$discussionGroup); 
  856.      
  857.         return  $discussionGroup;
  858.     }
  859.     #[Rest\Post('/api/v2/messages/discussion/{id}')]
  860.     #[Rest\View(serializerGroups: ['message_read'])]
  861.     #[OA\Response(
  862.         response200,
  863.         description'Returns all the missions for the authenticated user',
  864.         content: new OA\JsonContent(
  865.             type'array',
  866.             items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  867.         )
  868.     )]
  869.     
  870.     public function editDiscussionGroup(Request $requestDiscussionGroup $discussionGroupUserRepository $userRepository)
  871.     {   
  872.         
  873.         $nameDiscussion $request->request->get('newNameDiscussionGroup'null); 
  874.         $userIds $request->request->get('userIdsSelected'); 
  875.         
  876.   
  877.         foreach ($discussionGroup->getUsers() as  $user) {
  878.                 $discussionGroup->removeUser($user);
  879.         }
  880.         if( $nameDiscussion != null){
  881.              $discussionGroup->setName($nameDiscussion); 
  882.         }
  883.         if($userIds!=null){
  884.             foreach ($userIds as $key => $userId) {
  885.                 $user $userRepository->findOneBy(['id'=>$userId]); 
  886.                 if($user instanceof User){
  887.                     $discussionGroup->addUser($user); 
  888.                 }
  889.             }
  890.         }
  891.     
  892.         $this->entityManager->flush(); 
  893.         $this->chatService->publishOnDiscussionGroupUpdate('edit',$discussionGroup); 
  894.      
  895.         return  $discussionGroup;
  896.     }
  897.     #[Rest\Post('/api/v2/message/marque-to-be-read/{id}')]
  898.     #[OA\Response(
  899.        response200,
  900.        description'Returns all the missions for the authenticated user',
  901.        content: new OA\JsonContent(
  902.            type'array',
  903.            items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  904.        )
  905.    )]
  906.    public function marqueUserToReadMessage(Message $message){
  907.         $userWhoReadMessage $message->getUserListWhoRead(); 
  908.         if(!in_array($this->getUser()->getId(),$userWhoReadMessage)){
  909.              $message->setUserListWhoRead([...$message->getUserListWhoRead(), $this->getUser()->getId()]); 
  910.              $this->entityManager->flush(); 
  911.         }
  912.         $this->chatService->publishUserReadMessage($message); 
  913.          $this->chatService->publishMessageNotificationCampaignHashed(
  914.             $message->getCampaign()->getMissions()->first()->getId(),
  915.             [
  916.                 'message' => $this->serializer->normalize($messagenull, [AbstractNormalizer::GROUPS => ['message_read']]),
  917.                 'type' => "userWhoRead",
  918.                 'userId' => $this->getUser()->getId(),
  919.             ],
  920.             $message?->getDiscussionGroup()
  921.         );
  922.         return new JsonResponse([
  923.             'status'=>'ok'
  924.         ]);
  925.    }
  926.    #[Rest\Post('/api/v2/message/user-enter-in-discussion/{id}')]
  927.    #[OA\Response(
  928.       response200,
  929.       description'Returns all the missions for the authenticated user',
  930.       content: new OA\JsonContent(
  931.           type'array',
  932.           items: new OA\Items(ref: new Model(typeMission::class, groups: ['mission_list']))
  933.       )
  934.   )]
  935.   public function onUserEnterInDiscussion(Message $message){
  936.       
  937.        $this->chatService->publishUserEnterInDiscussion($message); 
  938.        return new JsonResponse([
  939.            'status'=>'ok'
  940.        ]);
  941.   }
  942.     public function addAddionlDataForOneMessage($message$mission){
  943.                 // $userWhoReadMessage = $this->messageService->getBullUsersWhoReadMessageByIds($message, $nextMessage); 
  944.                 // $message->setUserListWhoRead($userWhoReadMessage); 
  945.                 foreach ($message->getFileMessages() as $fileMessage) {
  946.                     if($fileMessage->isIsNew()){
  947.                         $nameOfFileinBucket "Campaigns/{$mission->getCampaign()->getId()}/{$fileMessage->getName()}";
  948.                         $nameOfBucket "company-{$mission->getCampaign()->getCompany()->getId()}";
  949.                         $link $this->googleStorageService->getUrlBucket(strtolower($nameOfBucket),$nameOfFileinBucket);;
  950.                     }
  951.                     else{
  952.                         $link "{$this->getParameter('back_website_url')}/{$this->messageService->getFileMissionUrl$mission$fileMessage->getName())}";
  953.                     } 
  954.                     $fileMessage->setName("$link;=;{$fileMessage->getName()}");
  955.                 }
  956.                 $reactions $message->getMessageReactions(); 
  957.                 
  958.                 $message->setReactionListApi($this->formateReactionList($reactions)); 
  959.     }
  960.     public function addAddionalData(Array $messagesMission $mission$idLastMessageUread=null){
  961.         foreach ($messages as $key => $message) {
  962.                 $nextMessage =  sizeof($messages) - != $key  $messages[$key 1] : null 
  963.                 $userWhoReadMessage $this->messageService->getBullUsersWhoReadMessageByIds($message$nextMessage); 
  964.                 $message->setUserListWhoRead($userWhoReadMessage); 
  965.                 if($idLastMessageUread != null && $idLastMessageUread == $message->getId()){
  966.                     $message->setLastMessageUread($idLastMessageUread);
  967.                 }
  968.                 // foreach ($message->getFileMessages() as $fileMessage) {
  969.                 //     if($fileMessage->isIsNew()){
  970.                 //         $nameOfFileinBucket = "Campaigns/{$mission->getCampaign()->getId()}/{$fileMessage->getName()}";
  971.                 //         $nameOfBucket = "company-{$mission->getCampaign()->getCompany()->getId()}";
  972.                 //         $link = $this->googleStorageService->getUrlBucket(strtolower($nameOfBucket),$nameOfFileinBucket);;
  973.                 //     }
  974.                 //     else{
  975.                 //         $link = "{$this->getParameter('back_website_url')}/{$this->messageService->getFileMissionUrl( $mission, $fileMessage->getName())}";
  976.                 //     } 
  977.                 //     $fileMessage->setName("$link;=;{$fileMessage->getName()}");
  978.                 // }
  979.                
  980.         }
  981.         return $messages;
  982.     }
  983.     public function formateReactionList($reactions){
  984.         $newReactionType =[]; 
  985.         foreach ($reactions as $key => $reaction) {
  986.             $newReactionType = [... $newReactionType, [
  987.                 'id'=> $reaction->getId(), 
  988.                 'emojy'=> $reaction->getEmoji()
  989.             ]];
  990.         }
  991.         return $newReactionType
  992.     }
  993.     private function getNotification(Mission $mission,Array $stateCampaignUser $user){
  994.         $state $stateCampaign['state']; 
  995.         switch (true) {
  996.             case  in_array('ROLE_SUBCONTRACTOR'$user->getRoles()): {
  997.                 if($state == "waiting_resend"){
  998.                     return "Mission en attente de resoumission au client"
  999.                 }
  1000.                 if($state == "waiting_validation"){
  1001.                     return "Le client a été notifié pour valider votre proposition"
  1002.                 }
  1003.             }
  1004.             
  1005.             default:
  1006.                return ""
  1007.         }
  1008.     }
  1009. }