Test Failed
Push — master ( 9e6cf9...d006e3 )
by Petr
04:08
created

EventController::viewImageAction()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 0
cts 0
cp 0
rs 9.3142
c 0
b 0
f 0
cc 3
eloc 13
nc 3
nop 2
crap 12
1
<?php
2
3
namespace AppBundle\Controller;
4
5
use AppBundle\Controller\Infrastructure\RestController;
6
use AppBundle\Entity\DTO\CreateEventDTO;
7
use AppBundle\Entity\Event;
8
use AppBundle\Entity\Repository\EventRepository;
9
use AppBundle\Exception\UnsupportedTypeException;
10
use AppBundle\Response\ApiError;
11
use AppBundle\Response\CollectionApiResponse;
12
use AppBundle\Response\CreatedApiResponse;
13
use AppBundle\Response\EmptyApiResponse;
14
use AppBundle\Response\LocationApiResponse;
15
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
16
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
17
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
18
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
19
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
20
use Symfony\Component\Form\Extension\Core\Type\DateType;
21
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
22
use Symfony\Component\Form\Extension\Core\Type\TextType;
23
use Symfony\Component\Form\FormBuilder;
24
use Symfony\Component\Form\FormError;
25
use Symfony\Component\Form\FormInterface;
26
use Symfony\Component\HttpFoundation\Request;
27
use Symfony\Component\HttpFoundation\Response;
28
use AppBundle\Response\ApiResponse;
29
30
/**
31
 * @Route("event")
32
 * @author Vehsamrak
33
 */
34
class EventController extends RestController
35
{
36
37
    /**
38
     * Find events by name part
39
     * @Route("s/like/{searchString}/{limit}/{offset}", name="events_find_like")
40
     * @Method("GET")
41
     * @ApiDoc(
42
     *     section="Event",
43
     *     statusCodes={
44
     *         200="OK",
45
     *     }
46
     * )
47
     * @param string $searchString Search string
48
     * @param int $limit Limit results. Default is 50
49 4
     * @param int $offset Starting serial number of result collection. Default is 0
50
     */
51 4
    public function findLikeAction($searchString = null, $limit = null, $offset = null)
52 4
    {
53 4
        $eventRepository = $this->get('rockparade.event_repository');
54
        $events = $eventRepository->findLike($searchString);
55 4
        $total = $events->count();
56 4
57
        $limit = (int) filter_var($limit, FILTER_VALIDATE_INT);
58 4
        $offset = (int) filter_var($offset, FILTER_VALIDATE_INT);
59 2
60
        if ($limit || $offset) {
61
            $events = $events->slice($offset, $limit ?: null);
62 4
        }
63
64 4
        $response = new CollectionApiResponse(
65
            $events,
66
            Response::HTTP_OK,
67
            $total,
68
            $limit,
69
            $offset
70 4
        );
71
72
        return $this->respond($response);
73
    }
74
75
    /**
76
     * List all events
77
     * @Route("s/{limit}/{offset}", name="events_list")
78
     * @Method("GET")
79
     * @ApiDoc(
80
     *     section="Event",
81
     *     statusCodes={
82
     *         200="OK",
83
     *     }
84
     * )
85
     * @param int $limit Limit results. Default is 50
86 1
     * @param int $offset Starting serial number of result collection. Default is 0
87
     */
88 1
    public function listAction($limit = null, $offset = null): Response
89 1
    {
90 1
        return $this->respond(
91
            $this->createCollectionResponse(
92
                $this->get('rockparade.event_repository'),
93
                $limit,
94
                $offset
95
            )
96
        );
97
    }
98
99
    /**
100
     * View event by id
101
     * @Route("/{eventId}", name="event_view")
102
     * @Method("GET")
103
     * @ApiDoc(
104
     *     section="Event",
105
     *     statusCodes={
106
     *         200="Event was found",
107
     *         404="Event with given id was not found",
108
     *     }
109
     * )
110 3
     * @param string $eventId event id
111
     */
112 View Code Duplication
    public function viewAction(string $eventId): Response
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113 3
    {
114 3
        /** @var EventRepository $eventRepository */
115
        $eventRepository = $this->get('rockparade.event_repository');
116 3
        $event = $eventRepository->findOneById($eventId);
117 2
118
        if ($event) {
119 1
            $response = new ApiResponse($event, Response::HTTP_OK);
120
        } else {
121
            $response = $this->createEventNotFoundErrorResult($eventId);
122 3
        }
123
124
        return $this->respond($response);
125
    }
126
127
    /**
128
     * Create new event
129
     * @Route("")
130
     * @Method("POST")
131
     * @Security("has_role('ROLE_USER')")
132
     * @ApiDoc(
133
     *     section="Event",
134
     *     requirements={
135
     *         {
136
     *             "name"="name",
137
     *             "dataType"="string",
138
     *             "requirement"="true",
139
     *             "description"="event name"
140
     *         },
141
     *         {
142
     *             "name"="date",
143
     *             "dataType"="date (dd-MM-yyyy HH:mm)",
144
     *             "requirement"="true",
145
     *             "description"="event date"
146
     *         },
147
     *         {
148
     *             "name"="description",
149
     *             "dataType"="text",
150
     *             "requirement"="true",
151
     *             "description"="event description"
152
     *         },
153
     *     },
154
     *     statusCodes={
155
     *         201="New event was created. Link to new resource in header 'Location'",
156
     *         400="Validation error",
157
     *     }
158 2
     * )
159
     */
160 2
    public function createAction(Request $request): Response
161 2
    {
162
        $form = $this->createEventCreationForm();
163 2
        $this->processForm($request, $form);
164 1
165
        if ($form->isValid()) {
166
            $newEvent = $this->createEventByForm($form);
167 1
168 1
            /** @var EventRepository $eventRepository */
169
            $eventRepository = $this->get('rockparade.event_repository');
170
            $eventRepository->persist($newEvent);
171 1
172 1
            try {
173
                $eventRepository->flush();
174
                $response = new CreatedApiResponse($this->createLocationById($newEvent->getId()));
175 1
            } catch (UniqueConstraintViolationException $exception) {
176
                $form->addError(new FormError('Event must have unique name and date.'));
177
                $response = new ApiError($this->getFormErrors($form), Response::HTTP_BAD_REQUEST);
178
            }
179 1
180
        } else {
181
            $response = new ApiError($this->getFormErrors($form), Response::HTTP_BAD_REQUEST);
182 2
        }
183
184
        return $this->respond($response);
185
    }
186
187
    /**
188
     * Edit event
189
     * @Route("/{eventId}", name="event_edit")
190
     * @Method("PUT")
191
     * @Security("has_role('ROLE_USER')")
192
     * @ApiDoc(
193
     *     section="Event",
194
     *     requirements={
195
     *         {
196
     *             "name"="name",
197
     *             "dataType"="string",
198
     *             "requirement"="true",
199
     *             "description"="event name"
200
     *         },
201
     *         {
202
     *             "name"="date",
203
     *             "dataType"="date (dd-MM-yyyy HH:mm)",
204
     *             "requirement"="true",
205
     *             "description"="event date"
206
     *         },
207
     *         {
208
     *             "name"="description",
209
     *             "dataType"="string",
210
     *             "requirement"="true",
211
     *             "description"="event description"
212
     *         },
213
     *     },
214
     *     statusCodes={
215
     *         204="Event was edited with new data",
216
     *         400="Validation error",
217
     *         404="Event with given id was not found",
218
     *     }
219
     * )
220 2
     * @param string $eventId event id
221
     */
222 2
    public function editAction(Request $request, string $eventId): Response
223 2
    {
224
        $form = $this->createEventCreationForm();
225 2
        $this->processForm($request, $form);
226
227 1
        if ($form->isValid()) {
228
            /** @var EventRepository $eventRepository */
229 1
            $eventRepository = $this->get('rockparade.event_repository');
230
            /** @var Event $event */
231 1
            $event = $eventRepository->findOneById($eventId);
232
233
            if (!$event) {
234 1
                $response = $this->createEventNotFoundErrorResult($eventId);
235
            } else {
236 1
                $eventName = $form->get('name')->getData();
237 1
                /** @var \DateTime $eventDate */
238
                $eventDate = $form->get('date')->getData();
239 1
                $eventDescription = $form->get('description')->getData();
240 1
241 1
                $event->setName($eventName);
242
                $event->setDate($eventDate);
243
                $event->setDescription($eventDescription);
244 1
245 1
                try {
246
                    $eventRepository->flush();
247 1
                    $response = new EmptyApiResponse(Response::HTTP_NO_CONTENT);
248
                } catch (UniqueConstraintViolationException $exception) {
249
                    $response = new ApiError(['Event must have unique name and date.'], Response::HTTP_BAD_REQUEST);
250
                }
251
            }
252 1
253
        } else {
254
            $response = new ApiError($this->getFormErrors($form), Response::HTTP_BAD_REQUEST);
255 2
        }
256
257
        return $this->respond($response);
258
    }
259
260
    /**
261
     * Delete event
262
     * @Route("/{eventId}", name="event_delete")
263
     * @Method("DELETE")
264
     * @Security("has_role('ROLE_USER')")
265
     * @ApiDoc(
266
     *     section="Event",
267
     *     statusCodes={
268
     *         204="Event was deleted",
269
     *         404="Event with given id was not found",
270
     *     }
271
     * )
272 1
     * @param string $eventId event id
273
     */
274 View Code Duplication
    public function deleteEvent(string $eventId): Response
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275 1
    {
276 1
        /** @var EventRepository $eventRepository */
277
        $eventRepository = $this->get('rockparade.event_repository');
278 1
        $event = $eventRepository->findOneById($eventId);
279 1
280 1
        if ($event) {
281
            $eventRepository->remove($event);
282 1
            $eventRepository->flush();
283
284
            $response = new EmptyApiResponse(Response::HTTP_NO_CONTENT);
285
        } else {
286
            $response = $this->createEventNotFoundErrorResult($eventId);
287
        }
288 1
289
        return $this->respond($response);
290
    }
291 1
292
    /**
293 1
     * Add image to event
294 1
     * @Route("/{eventId}/image", name="event_image_add")
295 1
     * @Method("POST")
296
     * @Security("has_role('ROLE_USER')")
297
     * @ApiDoc(
298
     *     section="Event",
299 4
     *     statusCodes={
300
     *         404="Event with given id was not found",
301
     *     }
302 4
     * )
303 4
     * @param string $eventId event id
304 4
     */
305 4
    public function addImageAction(Request $request, string $eventId): Response
306 4
    {
307
        /** @var EventRepository $eventRepository */
308 4
        $eventRepository = $this->get('rockparade.event_repository');
309
        $event = $eventRepository->findOneById($eventId);
310
311
        if ($event) {
312 4
            $image = $request->get('image');
313
314 4
            $imageName = $image['name'] ?: null;
315
            $imageContent = $image['content'] ?? null;
316
317 1
            if (!$image || !$imageName || !$imageContent) {
318
                $response = new ApiError(
319 1
                    'Parameters are mandatory: image[name] and image[content].',
320
                    Response::HTTP_BAD_REQUEST
321
                );
322 1
            } else {
323
                try {
324
                    $imageExtensionChecker = $this->get('rockparade.image_extension_checker');
325 1
                    $imageExtension = $imageExtensionChecker->getExtensionFromBase64File($imageContent);
326 1
                    $imageName = sprintf('%s.%s', $imageName, $imageExtension);
327
328 1
                    $imageLocation = $this->generateUrl(
329
                        'event_image_view',
330
                        [
331
                            'eventId'   => $eventId,
332
                            'imageName' => $imageName,
333
                        ]
334
                    );
335
336
                    $fileService = $this->get('rockparade.file_service');
337
                    $fileService->createBase64Image($imageName, $imageContent, $event);
338
339
                    $response = new LocationApiResponse(Response::HTTP_OK, $imageLocation);
340
                } catch (UnsupportedTypeException $exception) {
341
                    $response = new ApiError(
342
                        'Only images of types png, gif and jpeg are supported.',
343
                        Response::HTTP_BAD_REQUEST
344
                    );
345
                }
346
            }
347
        } else {
348
            $response = $this->createEventNotFoundErrorResult($eventId);
349
        }
350
351
        return $this->respond($response);
352
    }
353
354
    /**
355
     * Get event image
356
     * @Route("/{eventId}/image/{imageName}", name="event_image_view")
357
     * @Method("GET")
358
     * @ApiDoc(
359
     *     section="Event",
360
     *     statusCodes={
361
     *         404="Event with given id was not found",
362
     *         404="Image with given name was not found",
363
     *     }
364
     * )
365
     * @param string $eventId event id
366
     * @param string $imageName image name
367
     */
368
    public function viewImageAction(string $eventId, string $imageName): Response
369
    {
370
        /** @var EventRepository $eventRepository */
371
        $eventRepository = $this->get('rockparade.event_repository');
372
        $event = $eventRepository->findOneById($eventId);
373
374
        if ($event) {
375
            $image = $event->getImageWithName($imageName);
376
            $apiResponseFactory = $this->get('rockparade.api_response_factory');
377
378
            if ($image) {
379
                $response = $apiResponseFactory->createResponse($image);
380
            } else {
381
                $response = $apiResponseFactory->createNotFoundResponse();
382
            }
383
        } else {
384
            $response = $this->createEventNotFoundErrorResult($eventId);
385
        }
386
387
        return $this->respond($response);
388
    }
389
390
    private function createEventNotFoundErrorResult(string $eventId): ApiError
391
    {
392
        return new ApiError(
393
            sprintf('Event with id "%s" was not found.', $eventId),
394
            Response::HTTP_NOT_FOUND
395
        );
396
    }
397
398
    private function createEventCreationForm(): FormInterface
399
    {
400
        /** @var FormBuilder $formBuilder */
401
        $formBuilder = $this->createFormBuilder(new CreateEventDTO());
402
        $formBuilder->add('name', TextType::class);
403
        $formBuilder->add(
404
            'date',
405
            DateType::class,
406
            [
407
                'widget' => 'single_text',
408
                'format' => 'yyyy-MM-dd HH:mm',
409
            ]
410
        );
411
        $formBuilder->add('description', TextareaType::class);
412
413
        return $formBuilder->getForm();
414
    }
415
416
    private function createLocationById(string $eventId): string
417
    {
418
        return $this->generateUrl('event_view', ['eventId' => $eventId]);
419
    }
420
421
    private function createEventByForm(FormInterface $form): Event
422
    {
423
        /** @var CreateEventDTO $createEventDTO */
424
        $createEventDTO = $form->getData();
425
        $creator = $this->getUser();
426
427
        return new Event($createEventDTO->name, $creator, $createEventDTO->date, $createEventDTO->description);
0 ignored issues
show
Documentation introduced by
$creator is of type null|object, but the function expects a object<AppBundle\Entity\User>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
428
    }
429
}
430