diff --git a/assets/vue/services/message.js b/assets/vue/services/message.js index f402c17b1a..3053ed7d20 100644 --- a/assets/vue/services/message.js +++ b/assets/vue/services/message.js @@ -33,17 +33,8 @@ async function deleteMessageForUser(messageId, userId) { }) } -async function checkAndUpdateMessageStatus(messageId) { - return await axios.patch(`/api/messages/${messageId}/check-and-update-status`, {}, { - headers: { - 'Content-Type': 'application/json' - } - }) -} - export const messageService = { create, countUnreadMessages, deleteMessageForUser, - checkAndUpdateMessageStatus, }; diff --git a/assets/vue/store/messageRelUserStore.js b/assets/vue/store/messageRelUserStore.js index 7f5280f9e9..4a5f545c95 100644 --- a/assets/vue/store/messageRelUserStore.js +++ b/assets/vue/store/messageRelUserStore.js @@ -16,6 +16,7 @@ export const useMessageRelUserStore = defineStore("messageRelUser", { "order[sendDate]": "desc", "receivers.read": false, "receivers.receiver": securityStore.user["@id"], + "receivers.receiverType": 1, itemsPerPage: 1, msgType: MESSAGE_TYPE_INBOX, status: 0, diff --git a/assets/vue/views/message/MessageList.vue b/assets/vue/views/message/MessageList.vue index 6ba017e57c..3aa8ddf43d 100644 --- a/assets/vue/views/message/MessageList.vue +++ b/assets/vue/views/message/MessageList.vue @@ -474,8 +474,6 @@ async function deleteMessage(message) { } } - await messageService.checkAndUpdateMessageStatus(messageId) - notification.showSuccessNotification(t("Message deleted")) await messageRelUserStore.findUnreadCount() loadMessages() diff --git a/assets/vue/views/message/MessageShow.vue b/assets/vue/views/message/MessageShow.vue index fcd0ebcf09..ca968122d6 100644 --- a/assets/vue/views/message/MessageShow.vue +++ b/assets/vue/views/message/MessageShow.vue @@ -154,6 +154,8 @@ import BaseCard from "../../components/basecomponents/BaseCard.vue" import MessageCommunicationParty from "./MessageCommunicationParty.vue" import BaseIcon from "../../components/basecomponents/BaseIcon.vue" import SectionHeader from "../../components/layout/SectionHeader.vue" +import { messageService } from "../../services/message" +import { useNotification } from "../../composables/notification" const confirm = useConfirm() const { t } = useI18n() @@ -161,7 +163,6 @@ const { t } = useI18n() const isLoadingSelect = ref(false) const store = useStore() const securityStore = useSecurityStore() -//const find = store.getters["message/find"]; const route = useRoute() const router = useRouter() const messageRelUserStore = useMessageRelUserStore() @@ -177,13 +178,12 @@ const isLoading = computed(() => store.state.message.isLoading) const item = ref(null) const myReceiver = ref(null) +const notification = useNotification() store.dispatch("message/load", id).then((responseItem) => { item.value = responseItem - myReceiver.value = [...responseItem.receiversTo, ...responseItem.receiversCc].find( - ({ receiver }) => receiver["@id"] === securityStore.user["@id"], - ) + myReceiver.value = findMyReceiver(responseItem, securityStore.user["@id"]) // Change to read. if (myReceiver.value && false === myReceiver.value.read) { @@ -193,16 +193,43 @@ store.dispatch("message/load", id).then((responseItem) => { } }) +function extractUserId(apiId) { + return apiId.split("/").pop() +} + +function findMyReceiver(message, userId) { + const receivers = [...message.receiversTo, ...message.receiversCc] + return receivers.find(({ receiver }) => receiver["@id"] === userId) +} + +async function deleteMessage(message) { + try { + const userId = extractUserId(securityStore.user["@id"]) + const messageId = extractUserId(message["@id"]) + + if (message.sender["@id"] === securityStore.user["@id"]) { + await messageService.deleteMessageForUser(messageId, userId) + } else { + const myReceiver = findMyReceiver(message, securityStore.user["@id"]) + if (myReceiver) { + await store.dispatch("messagereluser/del", myReceiver) + } + } + + notification.showSuccessNotification(t("Message deleted")) + await messageRelUserStore.findUnreadCount() + await router.push({ name: "MessageList" }) + } catch (e) { + notification.showErrorNotification(t("Error deleting message")) + } +} + function confirmDelete() { confirm.require({ header: t("Confirmation"), message: t(`Are you sure you want to delete "${item.value.title}"?`), accept: async () => { - await store.dispatch("message/del", item) - - await router.push({ - name: "MessageList", - }) + await deleteMessage(item.value) }, }) } diff --git a/src/CoreBundle/Entity/Listener/MessageStatusListener.php b/src/CoreBundle/Entity/Listener/MessageStatusListener.php new file mode 100644 index 0000000000..b00ef3d560 --- /dev/null +++ b/src/CoreBundle/Entity/Listener/MessageStatusListener.php @@ -0,0 +1,34 @@ +entityManager = $entityManager; + } + + public function postRemove(MessageRelUser $messageRelUser, LifecycleEventArgs $args): void + { + $message = $messageRelUser->getMessage(); + $remainingReceivers = $this->entityManager->getRepository(MessageRelUser::class) + ->count(['message' => $message]); + + if ($remainingReceivers === 0) { + $message->setStatus(Message::MESSAGE_STATUS_DELETED); + $this->entityManager->flush(); + } + } +} diff --git a/src/CoreBundle/Entity/Message.php b/src/CoreBundle/Entity/Message.php index 5da5a9987e..9be10bc916 100644 --- a/src/CoreBundle/Entity/Message.php +++ b/src/CoreBundle/Entity/Message.php @@ -59,13 +59,6 @@ use Symfony\Component\Validator\Constraints as Assert; output: false, processor: MessageProcessor::class, ), - new Patch( - uriTemplate: '/messages/{id}/check-and-update-status', - inputFormats: ['json' => ['application/json']], - security: "is_granted('ROLE_USER')", - output: false, - processor: MessageProcessor::class, - ), ], normalizationContext: [ 'groups' => ['message:read'], diff --git a/src/CoreBundle/Entity/MessageRelUser.php b/src/CoreBundle/Entity/MessageRelUser.php index d30b950218..fc261f6f45 100644 --- a/src/CoreBundle/Entity/MessageRelUser.php +++ b/src/CoreBundle/Entity/MessageRelUser.php @@ -9,6 +9,7 @@ namespace Chamilo\CoreBundle\Entity; use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; use ApiPlatform\Metadata\ApiFilter; use ApiPlatform\Metadata\ApiResource; +use Chamilo\CoreBundle\Entity\Listener\MessageStatusListener; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -32,6 +33,7 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Table(name: 'message_rel_user')] #[ORM\UniqueConstraint(name: 'message_receiver', columns: ['message_id', 'user_id'])] #[ORM\Entity] +#[ORM\EntityListeners([MessageStatusListener::class])] #[ApiFilter( filterClass: SearchFilter::class, properties: [ diff --git a/src/CoreBundle/Resources/config/listeners.yml b/src/CoreBundle/Resources/config/listeners.yml index c6380cfc12..33a4f07bcd 100644 --- a/src/CoreBundle/Resources/config/listeners.yml +++ b/src/CoreBundle/Resources/config/listeners.yml @@ -101,3 +101,8 @@ services: - '@translator' tags: - {name: doctrine.orm.entity_listener, entity_manager: default, lazy: true} + + Chamilo\CoreBundle\Entity\Listener\MessageStatusListener: + arguments: [ '@doctrine.orm.entity_manager' ] + tags: + - { name: doctrine.orm.entity_listener, entity_manager: default, lazy: true } diff --git a/src/CoreBundle/State/MessageProcessor.php b/src/CoreBundle/State/MessageProcessor.php index 89d7c95ef1..57a06b2134 100644 --- a/src/CoreBundle/State/MessageProcessor.php +++ b/src/CoreBundle/State/MessageProcessor.php @@ -44,10 +44,6 @@ final class MessageProcessor implements ProcessorInterface return $this->processDeleteForUser($data); } - if ($operation instanceof Patch && str_contains($operation->getUriTemplate(), 'check-and-update-status')) { - return $this->checkAndUpdateMessageStatus($data); - } - /** @var Message $message */ $message = $this->persistProcessor->process($data, $operation, $uriVariables, $context); @@ -121,22 +117,6 @@ final class MessageProcessor implements ProcessorInterface return $message; } - private function checkAndUpdateMessageStatus($data): Message - { - /** @var Message $message */ - $message = $data; - - $messageRelUserRepository = $this->entityManager->getRepository(MessageRelUser::class); - $remainingReceivers = $messageRelUserRepository->count(['message' => $message]); - - if (0 === $remainingReceivers) { - $message->setStatus(Message::MESSAGE_STATUS_DELETED); - $this->entityManager->flush(); - } - - return $message; - } - private function saveNotificationForInboxMessage(Message $message): void { $sender_info = api_get_user_info(