Passed
Push — master ( 6444d8...6b2101 )
by Petr
03:48
created

EventService::addImageToEvent()   C

Complexity

Conditions 8
Paths 16

Size

Total Lines 46
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8

Importance

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