Passed
Push — master ( f3426b...21e202 )
by Petr
03:26
created

EventService::addLinksToEvent()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 37
ccs 18
cts 18
cp 1
rs 8.439
c 0
b 0
f 0
cc 6
eloc 23
nc 6
nop 3
crap 6
1
<?php
2
3
namespace AppBundle\Service\Entity;
4
5
use AppBundle\Entity\DTO\CreateEventDTO;
6
use AppBundle\Entity\Event;
7
use AppBundle\Entity\Repository\EventRepository;
8
use AppBundle\Entity\Repository\LinkRepository;
9
use AppBundle\Entity\User;
10
use AppBundle\Exception\UnsupportedTypeException;
11
use AppBundle\Form\Event\LinksCollectionDTO;
12
use AppBundle\Response\ApiError;
13
use AppBundle\Response\ApiValidationError;
14
use AppBundle\Response\CreatedApiResponse;
15
use AppBundle\Response\EmptyApiResponse;
16
use AppBundle\Response\Infrastructure\AbstractApiResponse;
17
use AppBundle\Response\LocationApiResponse;
18
use AppBundle\Service\File\FileService;
19
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
20
use Symfony\Component\Form\FormInterface;
21
use Symfony\Component\HttpFoundation\Response;
22
use Symfony\Component\Routing\Router;
23
24
/**
25
 * @author Vehsamrak
26
 */
27
class EventService extends EntityService
28
{
29
30
    /** @var EventRepository */
31
    private $eventRepository;
32
33
    /** @var LinkRepository */
34
    private $linkRepository;
35
36
    /** @var Router */
37
    private $router;
38
39
    /** @var FileService */
40
    private $fileService;
41
42 12
    public function __construct(
43
        EventRepository $eventRepository,
44
        LinkRepository $linkRepository,
45
        Router $router,
46
        FileService $fileService
47
    ) {
48 12
        $this->eventRepository = $eventRepository;
49 12
        $this->linkRepository = $linkRepository;
50 12
        $this->router = $router;
51 12
        $this->fileService = $fileService;
52 12
    }
53
54 1
    public function createEventByForm(FormInterface $form, User $creator): AbstractApiResponse
55
    {
56
        /** @var CreateEventDTO $createEventDTO */
57 1
        $createEventDTO = $form->getData();
58
59 1
        $newEvent = new Event($createEventDTO->name, $creator, $createEventDTO->date, $createEventDTO->description);
60
61 1
        $this->eventRepository->persist($newEvent);
62
63
        try {
64 1
            $this->eventRepository->flush();
65 1
            $response = new CreatedApiResponse($this->createLocationById($newEvent->getId()));
66
        } catch (UniqueConstraintViolationException $exception) {
67
            $response = new ApiError('Event must have unique name and date.', Response::HTTP_BAD_REQUEST);
68
        }
69
70 1
        return $response;
71
    }
72
73 1
    public function editEventByForm(FormInterface $form, string $eventId): AbstractApiResponse
74
    {
75
        /** @var Event $event */
76 1
        $event = $this->eventRepository->findOneById($eventId);
77
78 1
        if (!$event) {
79
            $response = $this->createEventNotFoundErrorResult($eventId);
80
        } else {
81 1
            $eventName = $form->get('name')->getData();
82
            /** @var \DateTime $eventDate */
83 1
            $eventDate = $form->get('date')->getData();
84 1
            $eventDescription = $form->get('description')->getData();
85
86 1
            $event->setName($eventName);
87 1
            $event->setDate($eventDate);
88 1
            $event->setDescription($eventDescription);
89
90
            try {
91 1
                $this->eventRepository->flush();
92 1
                $response = new EmptyApiResponse(Response::HTTP_NO_CONTENT);
93
            } catch (UniqueConstraintViolationException $exception) {
94
                $response = new ApiError('Event must have unique name and date.', Response::HTTP_BAD_REQUEST);
95
            }
96
        }
97
98 1
        return $response;
99
    }
100
101 4
    public function addImageToEvent(string $eventId, User $executor, array $imageData = null): AbstractApiResponse
102
    {
103 4
        $event = $this->eventRepository->findOneById($eventId);
104
105 4
        if ($event) {
106 3
            if ($executor->getLogin() !== $event->getCreator()->getLogin()) {
107 1
            	$response = new ApiError('Only event creator can add images.', Response::HTTP_FORBIDDEN);
108
            } else {
109 2
                $imageName = $imageData['name'] ?: null;
110 2
                $imageContent = $imageData['content'] ?? null;
111
112 2
                if (empty($imageData) || !$imageName || !$imageContent) {
113 1
                    $response = new ApiError(
114 1
                        'Parameters are mandatory: image[name] and image[content].',
115 1
                        Response::HTTP_BAD_REQUEST
116
                    );
117
                } else {
118
                    try {
119 1
                        $imageExtension = $this->fileService->getExtensionFromBase64File($imageContent);
120 1
                        $imageName = sprintf('%s.%s', $imageName, $imageExtension);
121 1
                        $image = $this->fileService->createBase64Image($imageName, $imageContent, $event);
122
123 1
                        $imageLocation = $this->router->generate(
124 1
                            'event_image_view',
125
                            [
126 1
                                'eventId'   => $eventId,
127 1
                                'imageName' => $image->getName(),
128
                            ],
129 1
                            Router::ABSOLUTE_URL
130
                        );
131
132 1
                        $response = new LocationApiResponse(Response::HTTP_OK, $imageLocation);
133
                    } catch (UnsupportedTypeException $exception) {
134
                        $response = new ApiError(
135
                            'Only images of types png, gif and jpeg are supported.',
136 3
                            Response::HTTP_BAD_REQUEST
137
                        );
138
                    }
139
                }
140
            }
141
        } else {
142 1
            $response = $this->createEventNotFoundErrorResult($eventId);
143
        }
144
145 4
        return $response;
146
    }
147
148 3
    public function addLinksToEvent(string $eventId, User $executor, FormInterface $form): AbstractApiResponse
149
    {
150 3
        if (!$form->isValid()) {
151 1
        	return new ApiValidationError($form);
152
        }
153
154 2
        $event = $this->eventRepository->findOneById($eventId);
155
156 2
        if ($event) {
157 2
            if ($this->executorIsCreator($executor, $event)) {
158
159
                /** @var LinksCollectionDTO $linksCollectionDTO */
160 1
                $linksCollectionDTO = $form->getData();
161
162 1
                foreach ($linksCollectionDTO->links as $linkData) {
163 1
                    $linkUrl = $linkData['url'] ?? null;
164 1
                    $linkDescription = $linkData['description'] ?? null;
165 1
                    $link = $this->linkRepository->getOrCreateLink($linkUrl, $linkDescription);
166 1
                    $this->linkRepository->persist($link);
167 1
                    $event->addLink($link);
168
                }
169
170
                try {
171 1
                    $this->eventRepository->flush();
172 1
                    $response = new CreatedApiResponse($this->createLocationById($eventId));
173
                } catch (UniqueConstraintViolationException $exception) {
174 1
                    $response = new ApiError('Links must have unique url.', Response::HTTP_BAD_REQUEST);
175
                }
176
            } else {
177 2
                $response = new ApiError('Only event creator can add links.', Response::HTTP_FORBIDDEN);
178
            }
179
        } else {
180
            $response = $this->createEventNotFoundErrorResult($eventId);
181
        }
182
183 2
        return $response;
184
    }
185
186 2
    public function removeLinksFromEvent(string $eventId, string $linkId, User $executor): AbstractApiResponse
187
    {
188 2
        $event = $this->eventRepository->findOneById($eventId);
189
190 2
        if ($event) {
191 2
            if ($this->executorIsCreator($executor, $event)) {
192 1
                $link = $this->linkRepository->findOneById($linkId);
193
194 1
                if ($link) {
195 1
                    $event->removeLink($link);
196 1
                    $this->linkRepository->flush();
197 1
                    $response = new EmptyApiResponse(Response::HTTP_OK);
198
                } else {
199 1
                    $response = $this->createLinkNotFoundErrorResult($linkId);
200
                }
201
            } else {
202 2
                $response = new ApiError('Only event creator can delete links.', Response::HTTP_FORBIDDEN);
203
            }
204
        } else {
205
            $response = $this->createEventNotFoundErrorResult($eventId);
206
        }
207
208 2
        return $response;
209
    }
210
211 2
    public function createEventNotFoundErrorResult(string $eventId): ApiError
212
    {
213 2
        return new ApiError(
214 2
            sprintf('Event with id "%s" was not found.', $eventId),
215 2
            Response::HTTP_NOT_FOUND
216
        );
217
    }
218
219
    private function createLinkNotFoundErrorResult(string $linkUrl): ApiError
220
    {
221
        return new ApiError(
222
            sprintf('Link with url "%s" was not found.', $linkUrl),
223
            Response::HTTP_NOT_FOUND
224
        );
225
    }
226
227 4
    private function executorIsCreator(User $executor, Event $event): bool
228
    {
229 4
        return $executor->getLogin() === $event->getCreator()->getLogin();
230
    }
231
232 2
    private function createLocationById(string $eventId): string
233
    {
234 2
        return $this->router->generate('event_view', ['eventId' => $eventId]);
235
    }
236
}
237