Passed
Pull Request — master (#5695)
by
unknown
07:17
created

MessageProcessor::process()   B

Complexity

Conditions 10
Paths 12

Size

Total Lines 44
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 10
eloc 24
nc 12
nop 4
dl 0
loc 44
rs 7.6666
c 3
b 0
f 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\State;
8
9
use ApiPlatform\Metadata\DeleteOperationInterface;
10
use ApiPlatform\Metadata\Operation;
11
use ApiPlatform\Metadata\Patch;
12
use ApiPlatform\Metadata\Post;
13
use ApiPlatform\State\ProcessorInterface;
14
use Chamilo\CoreBundle\Entity\Message;
15
use Chamilo\CoreBundle\Entity\MessageAttachment;
16
use Chamilo\CoreBundle\Entity\MessageRelUser;
17
use Chamilo\CoreBundle\Repository\ResourceNodeRepository;
18
use Doctrine\ORM\EntityManagerInterface;
19
use Notification;
20
use Symfony\Bundle\SecurityBundle\Security;
21
use Symfony\Component\HttpFoundation\RequestStack;
22
use Vich\UploaderBundle\Storage\FlysystemStorage;
23
24
final class MessageProcessor implements ProcessorInterface
25
{
26
    public function __construct(
27
        private readonly ProcessorInterface $persistProcessor,
28
        private readonly ProcessorInterface $removeProcessor,
29
        private readonly FlysystemStorage $storage,
30
        private readonly EntityManagerInterface $entityManager,
31
        private readonly ResourceNodeRepository $resourceNodeRepository,
32
        private readonly Security $security,
33
        private readonly RequestStack $requestStack
34
    ) {}
35
36
    public function process($data, Operation $operation, array $uriVariables = [], array $context = [])
37
    {
38
        if ($operation instanceof DeleteOperationInterface) {
39
            return $this->removeProcessor->process($data, $operation, $uriVariables, $context);
40
        }
41
42
        if ($operation instanceof Patch && str_contains($operation->getUriTemplate(), 'delete-for-user')) {
43
            return $this->processDeleteForUser($data);
44
        }
45
46
        if ($operation instanceof Patch && str_contains($operation->getUriTemplate(), 'check-and-update-status')) {
47
            return $this->checkAndUpdateMessageStatus($data);
48
        }
49
50
        /** @var Message $message */
51
        $message = $this->persistProcessor->process($data, $operation, $uriVariables, $context);
52
53
        foreach ($message->getAttachments() as $attachment) {
54
            $attachment->resourceNode->addResourceFile(
55
                $attachment->getResourceFileToAttach()
56
            );
57
58
            foreach ($message->getReceivers() as $receiver) {
59
                $attachment->addUserLink($receiver->getReceiver());
60
            }
61
        }
62
63
        $user = $this->security->getUser();
64
        if (!$user) {
65
            throw new \LogicException('User not found.');
66
        }
67
        $messageRelUser = new MessageRelUser();
68
        $messageRelUser->setMessage($message);
69
        $messageRelUser->setReceiver($user);
70
        $messageRelUser->setReceiverType(MessageRelUser::TYPE_SENDER);
71
        $this->entityManager->persist($messageRelUser);
72
73
        if ($message->getMsgType() === Message::MESSAGE_TYPE_INBOX) {
74
            $this->saveNotificationForInboxMessage($message);
75
        }
76
77
        $this->entityManager->flush();
78
79
        return $message;
80
    }
81
82
    private function processDeleteForUser($data): Message
83
    {
84
        /** @var Message $message */
85
        $message = $data;
86
87
        $request = $this->requestStack->getCurrentRequest();
88
        if (!$request) {
89
            throw new \LogicException('Cannot get current request');
90
        }
91
92
        $requestData = json_decode($request->getContent(), true);
93
        if (!isset($requestData['userId'])) {
94
            throw new \InvalidArgumentException('The field userId is required.');
95
        }
96
97
        $userId = $requestData['userId'];
98
        $messageRelUserRepository = $this->entityManager->getRepository(MessageRelUser::class);
99
        $messageRelUser = $messageRelUserRepository->findOneBy([
100
            'message' => $message,
101
            'receiver' => $userId,
102
        ]);
103
104
        if ($messageRelUser) {
105
            $this->entityManager->remove($messageRelUser);
106
            $this->entityManager->flush();
107
        }
108
109
        return $message;
110
    }
111
112
    private function checkAndUpdateMessageStatus($data): Message
113
    {
114
        /** @var Message $message */
115
        $message = $data;
116
117
        $messageRelUserRepository = $this->entityManager->getRepository(MessageRelUser::class);
118
        $remainingReceivers = $messageRelUserRepository->count(['message' => $message]);
119
120
        if ($remainingReceivers === 0) {
121
            $message->setStatus(Message::MESSAGE_STATUS_SENDER_DELETED);
122
            $this->entityManager->flush();
123
        }
124
125
        return $message;
126
    }
127
128
    private function saveNotificationForInboxMessage(Message $message): void
129
    {
130
        $sender_info = api_get_user_info(
131
            $message->getSender()->getId()
132
        );
133
134
        $userIdList = $message
135
            ->getReceivers()
136
            ->map(fn (MessageRelUser $messageRelUser): int => $messageRelUser->getReceiver()->getId())
137
            ->getValues()
138
        ;
139
140
        $attachmentList = [];
141
142
        /** @var MessageAttachment $messageAttachment */
143
        foreach ($message->getAttachments() as $messageAttachment) {
144
            $stream = $this->resourceNodeRepository->getResourceNodeFileStream(
145
                $messageAttachment->resourceNode
146
            );
147
148
            $attachmentList[] = [
149
                'stream' => $stream,
150
                'filename' => $messageAttachment->getFilename(),
151
            ];
152
        }
153
154
        (new Notification())
155
            ->saveNotification(
156
                $message->getId(),
157
                Notification::NOTIFICATION_TYPE_MESSAGE,
158
                $userIdList,
159
                $message->getTitle(),
160
                $message->getContent(),
161
                $sender_info,
162
                $attachmentList,
163
            )
164
        ;
165
    }
166
}
167