Completed
Push — master ( a0eba1...9ea362 )
by Petr
02:57
created

EventService   B

Complexity

Total Complexity 28

Size/Duplication

Total Lines 221
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Test Coverage

Coverage 97.73%

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 16
dl 0
loc 221
ccs 86
cts 88
cp 0.9773
rs 8.4614
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
B createEventByForm() 0 24 2
B editEventByForm() 0 29 3
C addImageToEvent() 0 46 8
B addLinksToEvent() 0 38 6
B removeLinksFromEvent() 0 26 4
A createEventNotFoundErrorResult() 0 7 1
A createLinkNotFoundErrorResult() 0 7 1
A executorIsCreator() 0 4 1
A createLocationById() 0 4 1
1
<?php
2
3
namespace AppBundle\Service\Entity;
4
5
use AppBundle\Entity\Event;
6
use AppBundle\Entity\Link;
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\EventFormType;
12
use AppBundle\Form\Event\LinksCollectionFormType;
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 EventFormType $createEventDTO */
58 1
        $createEventDTO = $form->getData();
59
        $eventDate = new \DateTime($createEventDTO->date);
60 1
        $newEvent = new Event(
61
            $createEventDTO->name,
62 1
            $creator,
63
            $eventDate,
64
            $createEventDTO->description,
65 1
            $createEventDTO->place
66 1
        );
67
68
        $this->eventRepository->persist($newEvent);
69
70
        try {
71 1
            $this->eventRepository->flush();
72
            $response = new CreatedApiResponse($this->createLocationById($newEvent->getId()));
73
        } catch (UniqueConstraintViolationException $exception) {
74 1
            $response = new ApiError('Event must have unique name and date.', Response::HTTP_BAD_REQUEST);
75
        }
76
77 1
        return $response;
78
    }
79 1
80
    public function editEventByForm(FormInterface $form, string $eventId): AbstractApiResponse
81
    {
82 1
        /** @var Event $event */
83
        $event = $this->eventRepository->findOneById($eventId);
84 1
85 1
        if (!$event) {
86
            $response = $this->createEventNotFoundErrorResult($eventId);
87 1
        } else {
88 1
            $eventName = $form->get('name')->getData();
89 1
            /** @var \DateTime $eventDate */
90
            $eventDate = new \DateTime($form->get('date')->getData());
91
            $eventDescription = $form->get('description')->getData();
92 1
            $eventPlace = $form->get('place')->getData();
93 1
94
            $event->setName($eventName);
95
            $event->setDate($eventDate);
96
            $event->setDescription($eventDescription);
97
            $event->setPlace($eventPlace);
98
99 1
            try {
100
                $this->eventRepository->flush();
101
                $response = new EmptyApiResponse(Response::HTTP_NO_CONTENT);
102 4
            } catch (UniqueConstraintViolationException $exception) {
103
                $response = new ApiError('Event must have unique name and date.', Response::HTTP_BAD_REQUEST);
104 4
            }
105
        }
106 4
107 3
        return $response;
108 1
    }
109
110 2
    public function addImageToEvent(string $eventId, User $executor, array $imageData = null): AbstractApiResponse
111 2
    {
112
        $event = $this->eventRepository->findOneById($eventId);
113 2
114 1
        if ($event) {
115 1
            if ($executor->getLogin() !== $event->getCreator()->getLogin()) {
116 1
            	$response = new ApiError('Only event creator can add images.', Response::HTTP_FORBIDDEN);
117
            } else {
118
                $imageName = $imageData['name'] ?: null;
119
                $imageContent = $imageData['content'] ?? null;
120 1
121 1
                if (empty($imageData) || !$imageName || !$imageContent) {
122 1
                    $response = new ApiError(
123
                        'Parameters are mandatory: image[name] and image[content].',
124 1
                        Response::HTTP_BAD_REQUEST
125 1
                    );
126
                } else {
127 1
                    try {
128 1
                        $imageExtension = $this->fileService->getExtensionFromBase64File($imageContent);
129
                        $imageName = sprintf('%s.%s', $imageName, $imageExtension);
130 1
                        $image = $this->fileService->createBase64Image($imageName, $imageContent, $event);
131
132
                        $imageLocation = $this->router->generate(
133 1
                            'event_image_view',
134
                            [
135
                                'id'   => $eventId,
136
                                'imageName' => $image->getName(),
137 3
                            ],
138
                            Router::ABSOLUTE_URL
139
                        );
140
141
                        $response = new LocationApiResponse(Response::HTTP_OK, $imageLocation);
142
                    } catch (UnsupportedTypeException $exception) {
143 1
                        $response = new ApiError(
144
                            'Only images of types png, gif and jpeg are supported.',
145
                            Response::HTTP_BAD_REQUEST
146 4
                        );
147
                    }
148
                }
149 3
            }
150
        } else {
151 3
            $response = $this->createEventNotFoundErrorResult($eventId);
152 1
        }
153
154
        return $response;
155
    }
156 2
157
    public function addLinksToEvent(string $eventId, User $executor, FormInterface $form): AbstractApiResponse
158 2
    {
159 2
        if (!$form->isValid()) {
160
        	return new ApiValidationError($form);
161
        }
162 1
163
        /** @var Event $event */
164 1
        $event = $this->eventRepository->findOneById($eventId);
165 1
166 1
        if ($event) {
167 1
            if ($this->executorIsCreator($executor, $event)) {
168 1
169 1
                /** @var LinksCollectionFormType $linksCollectionDTO */
170
                $linksCollectionDTO = $form->getData();
171
172
                foreach ($linksCollectionDTO->links as $linkData) {
173 1
                    $linkUrl = $linkData['url'] ?? null;
174 1
                    $linkDescription = $linkData['description'] ?? null;
175
                    $link = $this->linkRepository->getOrCreateLink($linkUrl, $linkDescription);
176 1
                    $this->linkRepository->persist($link);
177
                    $event->addLink($link);
178
                }
179 2
180
                try {
181
                    $this->eventRepository->flush();
182
                    $response = new CreatedApiResponse($this->createLocationById($eventId));
183
                } catch (UniqueConstraintViolationException $exception) {
184
                    $response = new ApiError('Links must have unique url.', Response::HTTP_BAD_REQUEST);
185 2
                }
186
            } else {
187
                $response = new ApiError('Only event creator can add links.', Response::HTTP_FORBIDDEN);
188 2
            }
189
        } else {
190
            $response = $this->createEventNotFoundErrorResult($eventId);
191 2
        }
192
193 2
        return $response;
194 2
    }
195
196 1
    public function removeLinksFromEvent(string $eventId, string $linkId, User $executor): AbstractApiResponse
197
    {
198 1
        /** @var Event $event */
199 1
        $event = $this->eventRepository->findOneById($eventId);
200 1
201 1
        if ($event) {
202
            if ($this->executorIsCreator($executor, $event)) {
203 1
                /** @var Link $link */
204
                $link = $this->linkRepository->findOneById($linkId);
205
206 2
                if ($link) {
207
                    $event->removeLink($link);
208
                    $this->linkRepository->flush();
209
                    $response = new EmptyApiResponse(Response::HTTP_OK);
210
                } else {
211
                    $response = $this->createLinkNotFoundErrorResult($linkId);
212 2
                }
213
            } else {
214
                $response = new ApiError('Only event creator can delete links.', Response::HTTP_FORBIDDEN);
215 1
            }
216
        } else {
217 1
            $response = $this->createEventNotFoundErrorResult($eventId);
218 1
        }
219 1
220
        return $response;
221
    }
222
223
    public function createEventNotFoundErrorResult(string $eventId): ApiError
224
    {
225
        return new ApiError(
226
            sprintf('Event with id "%s" was not found.', $eventId),
227
            Response::HTTP_NOT_FOUND
228
        );
229
    }
230
231 4
    private function createLinkNotFoundErrorResult(string $linkUrl): ApiError
232
    {
233 4
        return new ApiError(
234
            sprintf('Link with url "%s" was not found.', $linkUrl),
235
            Response::HTTP_NOT_FOUND
236 2
        );
237
    }
238 2
239
    private function executorIsCreator(User $executor, Event $event): bool
240
    {
241
        return $executor->getLogin() === $event->getCreator()->getLogin();
242
    }
243
244
    private function createLocationById(string $eventId): string
245
    {
246
        return $this->router->generate('event_view', ['id' => $eventId]);
247
    }
248
}
249