<?php
namespace App\Controller\API;
use App\Entity\Campaign;
use App\Entity\DiscussionGroup;
use App\Entity\FileMessage;
use App\Entity\Message;
use App\Entity\MessageReaction;
use App\Entity\Mission;
use App\Entity\User;
use App\Event\Chat\GroupedMessageSentEvent;
use App\Event\Chat\MessageSentEvent;
use App\Event\User\UserReactionEvent;
use App\Form\MessageType;
use App\Repository\DiscussionGroupRepository;
use App\Repository\MessageReactionRepository;
use App\Repository\MessageRepository;
use App\Repository\UserRepository;
use App\Service\CampaignApiService;
use App\Service\ChatService;
use Doctrine\ORM\EntityManagerInterface;
use FOS\RestBundle\Controller\Annotations as Rest;
use Nelmio\ApiDocBundle\Annotation\Model;
use OpenApi\Attributes as OA;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Service\GoogleStorageService;
use App\Service\MessageService;
use App\Service\MissionApiService;
use App\Service\MissionParticipantService;
use App\Service\WorkflowStepService;
use Psr\Log\LoggerInterface;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
class MessageController extends AbstractController
{
public function __construct(
private EntityManagerInterface $entityManager,
private GoogleStorageService $googleStorageService,
private MessageService $messageService,
private LoggerInterface $logger,
private MessageReactionRepository $messageReactionRepository,
private EventDispatcherInterface $dispatcher,
private HubInterface $hub,
private SerializerInterface $serializer,
private ChatService $chatService,
private DiscussionGroupRepository $discussionGroupRepository,
){}
/**
* Add a message to a campaign
*
* @param Campaign $campaign
* @param Request $request
* @param EntityManagerInterface $entityManager
* @return Message|\Symfony\Component\Form\FormInterface
*/
#[Rest\Post('/api/v2/campaigns/{id}/messages')]
#[Rest\View(statusCode: Response::HTTP_CREATED, serializerGroups: ['message_write'])]
#[OA\Tag(name: 'Campaigns')]
#[OA\Parameter(
name: 'content',
description: 'The message\'s content',
in: 'query',
required: true,
schema: new OA\Schema(type: 'string'),
)]
#[OA\Response(
response: Response::HTTP_CREATED,
description: 'The message has been created',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Message::class, groups: ['message_write']))
)
)]
#[OA\Response(
response: Response::HTTP_BAD_REQUEST,
description: 'The form is invalid and contains errors',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(properties: [
new OA\Property(property: 'code', type: 'integer'),
new OA\Property(property: 'message', type: 'string'),
new OA\Property(property: 'errors', type: 'array', items: new OA\Items(properties: [
new OA\Property(property: 'children', type: 'array', items: new OA\Items(properties: [])),
])),
], type: 'object')
)
)]
#[OA\Response(
response: Response::HTTP_UNAUTHORIZED,
description: 'Unauthorized - the user isn\'t logged in',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(properties: [
new OA\Property(property: 'code', type: 'integer'),
new OA\Property(property: 'message', type: 'string'),
], type: 'object')
)
)]
#[OA\Response(
response: Response::HTTP_NOT_FOUND,
description: 'The campaign doesn\'t exists',
)]
public function postMessage(Mission $mission, Request $request,EventDispatcherInterface $dispatcher, EntityManagerInterface $entityManager, DiscussionGroupRepository $discussionGroupRepository)
{
$group = $discussionGroupRepository->findOneBy(['id'=>$request->query->get('groupId')]);
$message = (new Message())
->setUser($this->getUser())
->setCampaign($mission->getCampaign())
->setMission($mission)
->setUserListWhoRead([$this->getUser()->getId()])
->setDiscussionGroup($group);
;
$form = $this->createForm(MessageType::class, $message, ['csrf_protection' => false]);
$form->handleRequest($request);
if ($form->isSubmitted()) {
$path = 'file_message_directory';
$idMessageToEdit = $request->query->get('id-edit-message') ;
$idMessageToReply = $request->query->get('id-reply-message');
$dateOffSetHour = $request->query->get('time-zone', 0);
$files = [];
$newMessage = $this->messageService->addMessage($mission, $message,$files, $idMessageToReply, $idMessageToEdit, $path);
$renderPlanning = $this->chatService->getHtmlToRenderPlanning($mission);
$typeMessage = $idMessageToEdit != "" && $idMessageToEdit!=null ? 'update': 'insert';
$this->chatService->publishMessageNotificationCampaign(
$mission->getId(),
[
'message'=>$this->serializer->normalize($newMessage, null, [AbstractNormalizer::GROUPS => ['message_read']]),
'html'=>$this->chatService->getHtmlToRenderInViewForLastMessage($mission,$newMessage,$dateOffSetHour),
'type'=>$typeMessage,
'planning' => $renderPlanning,
'currentUser' => $this->getUser()->getId(),
], $group);
$this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
"message" => "",
'idMission' => $mission->getId(),
'group' => !is_null($group) ? $group->getId() : "",
'type' => 'message-unread'
]);
$files = $form->get('fileMessages')->getData();
foreach ($files as $file) {
$newMessage = new Message();
$newMessage->setUser($this->getUser())
->setCampaign($mission->getCampaign())
->setMission($mission)
->setUserListWhoRead([$this->getUser()->getId()]);
if (!is_null($group)) {
$newMessage->setDiscussionGroup($group);
}
$nameSplitByDot = explode('.', $file->getClientOriginalName());
$extension = sizeof($nameSplitByDot) > 1 ? end($nameSplitByDot) : $file->guessExtension();
$type = preg_replace('/\/[a-zA-Z-_,.]*\s?/',"",$file->getMimeType());
$nameUniqueCompany = strtolower("company-" . $mission->getCampaign()->getCompany()->getId());
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$newFilename = $originalFilename . '-' . uniqid() . '.' . $extension;
//upload file in google storage
$this->googleStorageService->uploadFile($nameUniqueCompany, $file, $newFilename, 'Campaigns/' . $mission->getCampaign()->getId());
$fileMessage = new FileMessage();
$fileMessage->setName($newFilename);
$fileMessage->setIsNew(1);
$fileMessage->setType($type);
$fileMessage->setIsNotInfected(true);
$newMessage->addFileMessage($fileMessage);
$this->entityManager->persist($newMessage);
$this->messageService->sendEmailForParticipantMentionedInTchat($mission, $newMessage);
$renderPlanning = $this->chatService->getHtmlToRenderPlanning($mission);
$this->chatService->publishMessageNotificationCampaign(
$mission->getId(),
[
'message' => $this->serializer->normalize($newMessage, null, [AbstractNormalizer::GROUPS => ['message_read']]),
'html' => $this->chatService->getHtmlToRenderInViewForLastMessage($mission, $newMessage, $dateOffSetHour),
'type' => 'insert',
'planning' => $renderPlanning,
'currentUser' => $this->getUser()->getId(),
],
$group
);
$this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
"message" => "",
'idMission' => $mission->getId(),
'group' => !is_null($group) ? $group->getId() : "",
'type' => 'message-unread'
]);
$this->entityManager->flush();
}
return $newMessage ;
} else {
return $form;
}
}
#[Rest\Get('/api/v2/message/public/discussion/{id}')]
#[Rest\View(serializerGroups: ['message_read'])]
#[OA\Response(
response: 200,
description: 'Get all the details about a mission',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['message_read']))
)
)]
#[OA\Response(
response: 401,
description: 'Unauthorized - the user isn\'t logged in',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(properties: [
new OA\Property(property: 'code', type: 'integer'),
new OA\Property(property: 'message', type: 'string'),
], type: 'object')
)
)]
#[OA\Response(
response: 404,
description: 'The mission with id doesn\'t exists',
)]
public function getListDiscussionGroupe(Mission $mission, DiscussionGroupRepository $discussionGroupRepository, MessageService $messageService)
{
$nbrMessageUreadInGroup = $messageService->getNumberMessageUnread($mission, null);
$additionnedDiscussion = new DiscussionGroup();
$additionnedDiscussion->setId('group');
$additionnedDiscussion->setName('Groupe');
$additionnedDiscussion->setNbrUnreadMessage($nbrMessageUreadInGroup);
$additionnedDiscussion->setCampaign($mission->getCampaign());
$discussionGroupe = $discussionGroupRepository->getAllDiscussionGroup($mission->getCampaign());
foreach ($discussionGroupe as $key => $group) {
$nbrMessageUread = $messageService->getNumberMessageUnread($mission, $group);
$group->setNbrUnreadMessage($nbrMessageUread);
}
return [ $additionnedDiscussion,...$discussionGroupe];
}
#[Rest\POST('/api/v2/message/toggle-pinned/{id}')]
#[Rest\View(serializerGroups: ['message_read'])]
#[OA\Response(
response: 200,
description: 'Get all the details about a mission',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['message_read']))
)
)]
#[OA\Response(
response: 401,
description: 'Unauthorized - the user isn\'t logged in',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(properties: [
new OA\Property(property: 'code', type: 'integer'),
new OA\Property(property: 'message', type: 'string'),
], type: 'object')
)
)]
#[OA\Response(
response: 404,
description: 'The mission with id doesn\'t exists',
)]
public function toggleMessagePinned(Message $message)
{
$userAlreadyPinnedAMessage = false;
$currentUser = $this->getUser();
foreach ($message->getPinnedByUsers() as $user) {
if($user->getId() == $currentUser->getId()){
$userAlreadyPinnedAMessage = true;
break;
}
}
$userAlreadyPinnedAMessage ? $message->removePinnedByUser( $currentUser) : $message->addPinnedByUser( $currentUser);;
$this->entityManager->flush();
$this->chatService->publishOnMessagePinned($message);
return $message;
}
#[Rest\Get('/api/v2/message/pinned/{id}/{idGroup}')]
#[Rest\View(serializerGroups: ['message_read'])]
#[OA\Response(
response: 200,
description: 'Get all the details about a mission',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['message_read']))
)
)]
#[OA\Response(
response: 401,
description: 'Unauthorized - the user isn\'t logged in',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(properties: [
new OA\Property(property: 'code', type: 'integer'),
new OA\Property(property: 'message', type: 'string'),
], type: 'object')
)
)]
#[OA\Response(
response: 404,
description: 'The mission with id doesn\'t exists',
)]
public function getAllMessagePinned(Mission $mission,string $idGroup, MissionApiService $missionApiService, MessageService $messageService, MessageRepository $messageRepository,string $page ="0", string $loadMore = "0")
{
$group = $idGroup =='group' ? null : $this->discussionGroupRepository->findOneBy(['id'=>$idGroup]);
$messages = $messageRepository->pinnedMessage($mission->getCampaign(), $group, $this->getUser()) ;
usort($messages, function($a, $b) {
$dateA = $a->getCreatedAt()->getTimestamp();
$dateB = $b->getCreatedAt()->getTimestamp();
return $dateA - $dateB ;
});
$messages = $this->addAddionalData($messages,$mission) ;
return $messages;
}
#[Rest\Get('/api/v2/message/discussion/{idGroup}/{id}/{page}')]
#[Rest\View(serializerGroups: ['message_read'])]
#[OA\Response(
response: 200,
description: 'Get all the details about a mission',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['message_read']))
)
)]
#[OA\Response(
response: 401,
description: 'Unauthorized - the user isn\'t logged in',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(properties: [
new OA\Property(property: 'code', type: 'integer'),
new OA\Property(property: 'message', type: 'string'),
], type: 'object')
)
)]
#[OA\Response(
response: 404,
description: 'The mission with id doesn\'t exists',
)]
public function getAllMessageInGroup(Mission $mission, MissionApiService $missionApiService, MessageService $messageService, MessageRepository $messageRepository, string $idGroup,string $page ="0", string $loadMore = "0")
{
$fileMessage= [];
$group = $idGroup =='group' ? null : $this->discussionGroupRepository->findOneBy(['id'=>$idGroup]);
$nbrElementPerPage = 10;
$initialPage = $page;
$maxPage = 5;
$listMessageUnread= [];
$messages=[];
$i=0;
while($i<$maxPage){
$limite = $page == 'all' ? null : intval($page) * $nbrElementPerPage;
$messages = $messageRepository->getAllMessage($mission->getCampaign(), $limite, $group);
if($initialPage == 'all' || intval($initialPage) > 1 || count($messages) == 0){
break;
}
$listMessageUnread = $this->getMessageUnread($messages);
if( count($messages) > count($listMessageUnread)){
break;
}
$page++;
$i++;
}
foreach ($mission->getCampaign()->getFileMissions() as $file) {
$nameOfFileinBucket = "Campaigns/{$mission->getCampaign()->getId()}/{$file->getName()}";
$nameOfBucket = "company-{$mission->getCampaign()->getCompany()->getId()}";
$fileMessage= [...$fileMessage, [
'id'=>$file->getId(),
'name'=>$file->getName(),
'link'=>$this->googleStorageService->getUrlBucket(strtolower($nameOfBucket),$nameOfFileinBucket),
]];
}
$nbrMessages = $messageRepository->nbAllMessage($mission->getCampaign(),$group)['nb'];
usort($messages, function($a, $b) {
$dateA = $a->getCreatedAt()->getTimestamp();
$dateB = $b->getCreatedAt()->getTimestamp();
return $dateA - $dateB ;
});
$tempMessages = [];
foreach ($messages as $message) {
if($message->getContent() != null || ($message->getContent()==null && $this->haveFileNotDeleted($message))){
$tempMessages = [...$tempMessages, $message];
}
}
$idLastMessageUnred = sizeof($listMessageUnread) != 0 ? end($listMessageUnread)->getId() : null;
$messages = $this->addAddionalData($tempMessages,$mission, $idLastMessageUnred) ;
$messageService->marqueAllInMissionMessageReadWithGroup($mission, $this->getUser(), $group );
return [
'messages'=> $messages,
'initialBrief'=> $mission->getCampaign()->getBrief(),
'nbrMessages'=> $nbrMessages,
'idLastMessageUread'=>$idLastMessageUnred,
'fileMessage'=> $fileMessage,
'page'=>$page,
'user_typing'=>[...$this->messageService->calculaTimeTypingOfEachUser($this->messageService->getUserTypingWithoutCurrentUser($mission))]
]
;
}
public function getMessageUnread(array $messages)
{
$currentUserId = $this->getUser()->getId();
$listMessageUnread = [];
foreach ($messages as $message) {
$userIds = array_map(function($item){
if($item instanceof User ){
return $item->getId();
}
return $item;
}, $message->getUserListWhoRead());
if(!in_array($currentUserId, $userIds)){
$listMessageUnread[] = $message;
}
}
return $listMessageUnread;
}
private function haveFileNotDeleted(Message $message){
foreach ($message->getFileMessages() as $fileMessage) {
if($fileMessage->getIsDeleted() != true){
return true;
}
}
return false;
}
#[Rest\Get('/api/v2/message/public/{id}/{page}')]
#[Rest\View(serializerGroups: ['message_read'])]
#[OA\Response(
response: 200,
description: 'Get all the details about a mission',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['message_read']))
)
)]
#[OA\Response(
response: 401,
description: 'Unauthorized - the user isn\'t logged in',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(properties: [
new OA\Property(property: 'code', type: 'integer'),
new OA\Property(property: 'message', type: 'string'),
], type: 'object')
)
)]
#[OA\Response(
response: 404,
description: 'The mission with id doesn\'t exists',
)]
public function getPublicMessage(Mission $mission, MissionApiService $missionApiService, MessageService $messageService, MessageRepository $messageRepository,string $page ="0", string $loadMore = "0")
{
$userSetPicture=[];
$messageService->marqueAllInMissionMessageRead($mission, $this->getUser());
$fileMessage=[];
if($page == 'all'){
$messages = $messageRepository->finMessageByCampaign($mission->getCampaign()) ;
foreach ($mission->getCampaign()->getFileMissions() as $file) {
$nameOfFileinBucket = "Campaigns/{$mission->getCampaign()->getId()}/{$file->getName()}";
$nameOfBucket = "company-{$mission->getCampaign()->getCompany()->getId()}";
$fileMessage= [...$fileMessage, [
'id'=>$file->getId(),
'name'=>$file->getName(),
'link'=>$this->googleStorageService->getUrlBucket(strtolower($nameOfBucket),$nameOfFileinBucket),
]];
}
}
else{
$messages = $messageRepository->getAllMessage($mission->getCampaign(), $page * 10) ;
}
usort($messages, function($a, $b) {
$dateA = $a->getCreatedAt()->getTimestamp();
$dateB = $b->getCreatedAt()->getTimestamp();
return $dateA - $dateB ;
});
$messages = $this->addAddionalData($messages,$mission) ;
return [
'messages'=> $messages,
'initialBrief'=> $mission->getCampaign()->getBrief(),
'fileMessage'=> $fileMessage,
'user_typing'=>[...$this->messageService->calculaTimeTypingOfEachUser($this->messageService->getUserTypingWithoutCurrentUser($mission))],
];
}
#[Rest\get('/api/v2/message/campaign-state/{id}')]
#[Rest\View(serializerGroups: ['mission_list','mission_read','step_write','message_read'])]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list','message_read','mission_read','step_write']))
)
)]
public function campaignState(Mission $mission,MissionParticipantService $missionParticipantService, WorkflowStepService $workflowStepService,CampaignApiService $campaignApiService, MissionApiService $missionApiService){
$stateCampaign = $missionApiService->getCampaignState($mission->getCampaign());
$notification = $this->getNotification($mission, $stateCampaign, $this->getUser());
$step = $workflowStepService->getWorkflowActiveStepBy($mission);
$responsables = $campaignApiService->getWorkflowActiveStepByCampaing($mission->getCampaign());
$participants =[];
$listMissionParticipants = $missionParticipantService->getParticipants($mission->getCampaign());
$userAlreadyIn = [];
foreach ($listMissionParticipants as $user) {
if($user->getId() != $this->getUser()->getId() && !in_array($user->getId(), $userAlreadyIn)){
$participants=[...$participants,[
'user'=>[
'id'=> $user->getId(),
'firstname'=> $user->getFirstname(),
'lastname'=> $user->getLastname(),
'fullname'=>$user->getFullname(),
'pictureName'=>$user->getPictureName(),
'identifier'=>$user->getIdentifier(),
]
]
] ;
$userAlreadyIn =[... $userAlreadyIn, $user->getId()];
}
}
return new JsonResponse([
'state'=>$stateCampaign,
'notifications'=> $notification,
'step'=> $step,
'future_actions' => $missionParticipantService->getUniqByFutureActions($mission->getCampaign()->getId(),$this->getUser()->getId()),
'participants'=> $participants,
'subcontractors_not_evaluate'=>$campaignApiService->getSubcontractorNoEstimatedIncome($mission->getCampaign()),
'responsable_step'=> $responsables,
'user_typing'=>[...$this->messageService->calculaTimeTypingOfEachUser($this->messageService->getUserTypingWithoutCurrentUser($mission))],
]);
}
#[Rest\Post('/api/v2/campaigns/delete/filemessages/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function deleteFilMessage(FileMessage $fileMessage)
{
$message = $fileMessage->getMessages();
//delete file if in storage
$company = $message->getCampaign()->getCompany();
$campaign = $message->getCampaign();
$bucketName = "company-" . strtolower($company->getId());
$fileName = "Campaigns/" . $campaign->getId() . "/" . $fileMessage->getName();
//end delete in google storage
$fileMessage->setIsDeleted(true);
$this->entityManager->flush();
$file = $this->messageService->getFileMissionUrl($fileMessage->getMessages()->getMission(), $fileMessage->getName());
if ($message->getContent() == null && sizeof($fileMessage->getMessages()->getFileMessages()) == 0) {
$message->setIsDeleted(true);
$this->entityManager->flush();
}
try {
$this->filesystem->remove($file);
} catch (\Throwable $th) {
$this->logger->error("can't delete file in $file");
}
$this->googleStorageService->deleteFile($bucketName, $fileName);
$mission = $message->getMission();
$renderContent = $this->chatService->getHtmlContentToRenderInViewForLastMessage($mission,$message,0);
$this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
"message" => "",
'idMission' => $message->getMission()->getId(),
'group' => $message->getDiscussionGroup(),
'type' => 'message-unread'
]);
$this->chatService->publishMessageNotificationCampaign($mission->getId(),[
'message'=>$this->serializer->normalize($message, null, [AbstractNormalizer::GROUPS => ['message_read']],),
'html'=>$renderContent,
'type'=>'update',
]);
return new JsonResponse([
'status'=>'ok'
]);
}
#[Rest\Get('/api/v2/message/un-read-message-per-discussion/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function getMessageUnreadPerDiscussion(Mission $mission, DiscussionGroupRepository $discussionGroupRepository, MessageService $messageService)
{
$temp=[
[
'id'=> 'group',
'nbrMessageUnread'=>$messageService->getNumberMessageUnread($mission, null)
]
];
$discussionGroupe = $discussionGroupRepository->getAllDiscussionGroup($mission->getCampaign());
foreach ($discussionGroupe as $key => $group) {
$discussion=[
'id'=> $group->getId(),
'nbrMessageUnread'=>$messageService->getNumberMessageUnread($mission, $group)
] ;
$temp=[...$temp,$discussion];
}
return new JsonResponse($temp);
}
#[Rest\Post('/api/v2/campaigns/delete/messages/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function deleteMessage(Message $message)
{
$message->setIsDeleted(true);
$this->entityManager->flush();
$this->chatService->publishMessageNotificationCampaign($message->getMission()->getId(),['message'=>$message->getId(),'type'=>'deleted'],$message->getDiscussionGroup());
$this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
"message" => "",
'idMission' => $message->getMission()->getId(),
'group' => $message->getDiscussionGroup(),
'type' => 'message-unread'
]);
return new JsonResponse([
'status'=>'ok'
]);
}
#[Rest\Post('/api/v2/message/emoji/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function addEmoji(Request $request, Message $message)
{
$emoji = $request->request->get('smiley');
$emojiId = $request->request->get('id');
$campaignOfMessage = $message->getCampaign();
$user = $this->getUser();
$messageReaction = $this->messageReactionRepository->findReactionByUser(messageId: $message->getId(), userId: $user->getId(), emojiId: $emojiId);
if ($messageReaction != null) {
$message->removeMessageReaction($messageReaction[0]);
$this->entityManager->remove($messageReaction[0]);
$this->entityManager->flush();
} else {
$newReaction = new MessageReaction();
$newReaction->setEmoji($emoji);
$newReaction->setUser($user);
$newReaction->setEmojiId(intval($emojiId));
$newReaction->setMessage($message);
$message->addMessageReaction($newReaction);
$this->entityManager->persist($newReaction);
$this->entityManager->flush();
$event = new UserReactionEvent($message->getUser(), $this->getUser(), $message, $newReaction->getEmoji(),$campaignOfMessage);
$this->dispatcher->dispatch($event, UserReactionEvent::NAME);
}
$mission = $message->getMission();
$renderContent = $this->chatService->getHtmlContentToRenderInViewForLastMessage($mission,$message,0);
$this->chatService->publishMessageNotificationCampaign($mission->getId(),[
'message'=>$this->serializer->normalize($message, null, [AbstractNormalizer::GROUPS => ['message_read']],),
'html'=>$renderContent,
'type'=>'update',
]);
return new JsonResponse(['status'=>$emoji]);
}
#[Rest\Post('/api/v2/messages/user/isTyping/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function userStartTyping(Mission $mission,Request $request)
{
$groupId = $request->query->get('groupId');
$group = null;
if (!empty($groupId) && !is_null($groupId)) {
$group = $this->discussionGroupRepository->findOneBy(['id'=>$groupId]);
}
$user = $this->getUser();
$this->chatService->publishMessageNotificationCampaign($mission->getId(),[
'message'=>"",
'type'=>'isTyping',
'currentUser' => $user->getId(),
'missionIds'=>array_map(function($item){
return $item->getId();
}, $mission->getCampaign()->getMissions()->toArray()),
'typingRender' => $this->chatService->userTyping($user),
'user'=> $this->serializer->normalize($user, null, [AbstractNormalizer::GROUPS => ['message_read']])
],$group);
return new JsonResponse([
'status'=> 'ok',
]);
}
#[Rest\Post('/api/v2/messages/user/isStopTyping/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function useFinichedTyping(Mission $mission,Request $request)
{
$groupId = $request->query->get('groupId');
$group = null;
if (!empty($groupId) && !is_null($groupId)) {
$group = $this->discussionGroupRepository->findOneBy(['id'=>$groupId]);
}
$user = $this->getUser();
$this->chatService->publishMessageNotificationCampaign($mission->getId(),[
'message'=>"",
'type'=>'isStopTyping',
'currentUser' => $user->getId(),
'user'=> $this->serializer->normalize($user, null, [AbstractNormalizer::GROUPS => ['message_read']])
],$group);
return new JsonResponse([
'status'=>'ok'
]);
}
#[Rest\Post('/api/v2/messages/add/discussion/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function newDiscussionGroup(Request $request,Campaign $campaign, UserRepository $userRepository)
{
$nameDiscussion = $request->request->get('newNameDiscussionGroup', null);
$userIds = $request->request->get('userIdsSelected');
$discussionGroup = new DiscussionGroup();
$discussionGroup->setName($nameDiscussion);
$discussionGroup->setCreatedBy($this->getUser());
$discussionGroup->setCampaign($campaign);
$discussionGroup->addUser($this->getUser());
foreach ($userIds as $key => $userId) {
$user = $userRepository->findOneBy(['id'=>$userId]);
if($user instanceof User){
$discussionGroup->addUser($user);
if($this->getUser()->getId() != $user->getId()){
$event = new GroupedMessageSentEvent($discussionGroup,$user);
$this->dispatcher->dispatch($event, GroupedMessageSentEvent::NAME);
}
}
}
$this->entityManager->persist($discussionGroup);
$this->entityManager->flush();
$this->chatService->publishOnDiscussionGroupUpdate('add',$discussionGroup);
$this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
"message" => "",
'idMission' => $campaign->getMissions()->first()->getId(),
'group' => !is_null($discussionGroup) ? $discussionGroup->getId() : "",
'type' => 'message-unread'
]);
return new JsonResponse([
'status'=>'ok'
]);
}
#[Rest\Post('/api/v2/messages/delete/discussion/{id}')]
#[Rest\View(serializerGroups: ['message_read'])]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function deleteDiscussionGroup(Request $request, DiscussionGroup $discussionGroup)
{
$message = null;
foreach ($discussionGroup->getMessages() as $message) {
$message->setIsDeleted(true);
$this->entityManager->persist($message);
$this->entityManager->flush();
}
$discussionGroup->setDeleted(true);
$this->entityManager->persist($discussionGroup);
$this->entityManager->flush();
if ( null != $message ) {
$this->chatService->publishNotificationMessageUnread("message-send-end-not-read", [
"message" => "",
'idMission' => $message->getMission()->getId(),
'group' => $discussionGroup,
'type' => 'message-unread'
]);
}
$this->chatService->publishOnDiscussionGroupUpdate('delete',$discussionGroup);
return $discussionGroup;
}
#[Rest\Post('/api/v2/messages/discussion/{id}')]
#[Rest\View(serializerGroups: ['message_read'])]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function editDiscussionGroup(Request $request, DiscussionGroup $discussionGroup, UserRepository $userRepository)
{
$nameDiscussion = $request->request->get('newNameDiscussionGroup', null);
$userIds = $request->request->get('userIdsSelected');
foreach ($discussionGroup->getUsers() as $user) {
$discussionGroup->removeUser($user);
}
if( $nameDiscussion != null){
$discussionGroup->setName($nameDiscussion);
}
if($userIds!=null){
foreach ($userIds as $key => $userId) {
$user = $userRepository->findOneBy(['id'=>$userId]);
if($user instanceof User){
$discussionGroup->addUser($user);
}
}
}
$this->entityManager->flush();
$this->chatService->publishOnDiscussionGroupUpdate('edit',$discussionGroup);
return $discussionGroup;
}
#[Rest\Post('/api/v2/message/marque-to-be-read/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function marqueUserToReadMessage(Message $message){
$userWhoReadMessage = $message->getUserListWhoRead();
if(!in_array($this->getUser()->getId(),$userWhoReadMessage)){
$message->setUserListWhoRead([...$message->getUserListWhoRead(), $this->getUser()->getId()]);
$this->entityManager->flush();
}
$this->chatService->publishUserReadMessage($message);
$this->chatService->publishMessageNotificationCampaign(
$message->getCampaign()->getMissions()->first()->getId(),
[
'message' => $this->serializer->normalize($message, null, [AbstractNormalizer::GROUPS => ['message_read']]),
'type' => "userWhoRead",
'userId' => $this->getUser()->getId(),
],
$message?->getDiscussionGroup()
);
return new JsonResponse([
'status'=>'ok'
]);
}
#[Rest\Post('/api/v2/message/user-enter-in-discussion/{id}')]
#[OA\Response(
response: 200,
description: 'Returns all the missions for the authenticated user',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: Mission::class, groups: ['mission_list']))
)
)]
public function onUserEnterInDiscussion(Message $message){
$this->chatService->publishUserEnterInDiscussion($message);
return new JsonResponse([
'status'=>'ok'
]);
}
public function addAddionlDataForOneMessage($message, $mission){
// $userWhoReadMessage = $this->messageService->getBullUsersWhoReadMessage($message, $nextMessage);
// $message->setUserListWhoRead($userWhoReadMessage);
foreach ($message->getFileMessages() as $fileMessage) {
if($fileMessage->isIsNew()){
$nameOfFileinBucket = "Campaigns/{$mission->getCampaign()->getId()}/{$fileMessage->getName()}";
$nameOfBucket = "company-{$mission->getCampaign()->getCompany()->getId()}";
$link = $this->googleStorageService->getUrlBucket(strtolower($nameOfBucket),$nameOfFileinBucket);;
}
else{
$link = "{$this->getParameter('back_website_url')}/{$this->messageService->getFileMissionUrl( $mission, $fileMessage->getName())}";
}
$fileMessage->setName("$link;=;{$fileMessage->getName()}");
}
$reactions = $message->getMessageReactions();
$message->setReactionListApi($this->formateReactionList($reactions));
}
public function addAddionalData(Array $messages, Mission $mission, $idLastMessageUread=null){
foreach ($messages as $key => $message) {
$nextMessage = sizeof($messages) - 1 != $key ? $messages[$key + 1] : null ;
$userWhoReadMessage = $this->messageService->getBullUsersWhoReadMessage($message, $nextMessage);
$message->setUserListWhoRead($userWhoReadMessage);
if($idLastMessageUread != null && $idLastMessageUread == $message->getId()){
$message->setLastMessageUread($idLastMessageUread);
}
// foreach ($message->getFileMessages() as $fileMessage) {
// if($fileMessage->isIsNew()){
// $nameOfFileinBucket = "Campaigns/{$mission->getCampaign()->getId()}/{$fileMessage->getName()}";
// $nameOfBucket = "company-{$mission->getCampaign()->getCompany()->getId()}";
// $link = $this->googleStorageService->getUrlBucket(strtolower($nameOfBucket),$nameOfFileinBucket);;
// }
// else{
// $link = "{$this->getParameter('back_website_url')}/{$this->messageService->getFileMissionUrl( $mission, $fileMessage->getName())}";
// }
// $fileMessage->setName("$link;=;{$fileMessage->getName()}");
// }
}
return $messages;
}
public function formateReactionList($reactions){
$newReactionType =[];
foreach ($reactions as $key => $reaction) {
$newReactionType = [... $newReactionType, [
'id'=> $reaction->getId(),
'emojy'=> $reaction->getEmoji()
]];
}
return $newReactionType;
}
private function getNotification(Mission $mission,Array $stateCampaign, User $user){
$state = $stateCampaign['state'];
switch (true) {
case in_array('ROLE_SUBCONTRACTOR', $user->getRoles()): {
if($state == "waiting_resend"){
return "Mission en attente de resoumission au client";
}
if($state == "waiting_validation"){
return "Le client a été notifié pour valider votre proposition";
}
}
default:
return "";
}
}
}