Passed
Push — master ( eabfa3...2db6fa )
by Petr
04:00
created

BandController::createMemberAction()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 40
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 4.0466

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 18
cts 21
cp 0.8571
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 28
nc 4
nop 2
crap 4.0466
1
<?php
2
3
namespace AppBundle\Controller;
4
5
use AppBundle\Entity\Band;
6
use AppBundle\Entity\BandMember;
7
use AppBundle\Entity\Repository\BandRepository;
8
use AppBundle\Entity\User;
9
use AppBundle\Form\Ambassador\AmbassadorFormType;
10
use AppBundle\Form\Ambassador\AmbassadorMemberFormType;
11
use AppBundle\Form\Ambassador\BandFormType;
12
use AppBundle\Response\ApiValidationError;
13
use AppBundle\Response\CreatedApiResponse;
14
use AppBundle\Response\EmptyApiResponse;
15
use AppBundle\Response\Infrastructure\AbstractApiResponse;
16
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
17
use AppBundle\Controller\Infrastructure\RestController;
18
use AppBundle\Response\ApiError;
19
use AppBundle\Response\ApiResponse;
20
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
21
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
22
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
23
use Symfony\Component\Form\FormInterface;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\HttpFoundation\Response;
26
use Symfony\Component\Validator\Constraints as Assert;
27
28
/**
29
 * @author Vehsamrak
30
 * @Route("band")
31
 */
32
class BandController extends RestController
33
{
34
35
    /**
36
     * List all registered bands
37
     * @Route("s/{limit}/{offset}", name="bands_list")
38
     * @Method("GET")
39
     * @ApiDoc(
40
     *     section="Band",
41
     *     statusCodes={
42
     *         200="OK",
43
     *     }
44
     * )
45
     * @param int $limit Limit results. Default is 50
46
     * @param int $offset Starting serial number of result collection. Default is 0
47
     */
48 2
    public function listAction($limit = null, $offset = null): Response
49
    {
50 2
        return $this->listEntities($this->get('rockparade.band_repository'), $limit, $offset);
51
    }
52
53
    /**
54
     * View band by name
55
     * @Route("/{id}", name="band_view")
56
     * @Method("GET")
57
     * @ApiDoc(
58
     *     section="Band",
59
     *     statusCodes={
60
     *         200="Band was found",
61
     *         404="Band with given name was not found",
62
     *     }
63
     * )
64
     * @param string $id band name
65
     */
66 3
    public function viewAction(string $id): Response
67
    {
68 3
        return $this->viewEntity($this->get('rockparade.band_repository'), $id);
69
    }
70
71
    /**
72
     * Create new band
73
     * @Route("", name="band_create")
74
     * @Method("POST")
75
     * @Security("has_role('ROLE_USER')")
76
     * @ApiDoc(
77
     *     section="Band",
78
     *     requirements={
79
     *         {
80
     *             "name"="name",
81
     *             "dataType"="string",
82
     *             "requirement"="true",
83
     *             "description"="band name"
84
     *         },
85
     *         {
86
     *             "name"="description",
87
     *             "dataType"="string",
88
     *             "requirement"="true",
89
     *             "description"="band description"
90
     *         },
91
     *         {
92
     *             "name"="members",
93
     *             "dataType"="array",
94
     *             "requirement"="false",
95
     *             "description"="logins and short descriptions of band musicians"
96
     *         },
97
     *     },
98
     *     statusCodes={
99
     *         201="New band was created. Link to new resource provided in header 'Location'",
100
     *         400="Validation error",
101
     *     }
102
     * )
103
     */
104 2 View Code Duplication
    public function createAction(Request $request): 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...
105
    {
106 2
        $form = $this->createAndProcessForm($request, BandFormType::class);
107
108 2
        $apiResponseFactory = $this->get('rockparade.api_response_factory');
109 2
        $response = $apiResponseFactory->createResponse(
110 2
            $this->createApiOperation($request),
111
            $form,
112 2
            $this->getUser(),
113 2
            Band::class
114
        );
115
116 2
        return $this->respond($response);
117
    }
118
119
    /**
120
     * Edit band
121
     * @Route("/{bandName}", name="band_edit")
122
     * @Method("PUT")
123
     * @Security("has_role('ROLE_USER')")
124
     * @ApiDoc(
125
     *     section="Band",
126
     *     requirements={
127
     *         {
128
     *             "name"="name",
129
     *             "dataType"="string",
130
     *             "requirement"="true",
131
     *             "description"="band name"
132
     *         },
133
     *         {
134
     *             "name"="description",
135
     *             "dataType"="string",
136
     *             "requirement"="true",
137
     *             "description"="band description"
138
     *         },
139
     *         {
140
     *             "name"="users",
141
     *             "dataType"="array",
142
     *             "requirement"="true",
143
     *             "description"="logins of band musicians"
144
     *         },
145
     *     },
146
     *     statusCodes={
147
     *         204="Band was edited with new data",
148
     *         400="Validation error",
149
     *     }
150
     * )
151
     * @param string $bandName band name
152
     */
153 2
    public function editAction(Request $request, string $bandName): Response
154
    {
155
        /** @var BandRepository $bandRepository */
156 2
        $bandRepository = $this->get('rockparade.band_repository');
157
        /** @var Band $band */
158 2
        $band = $bandRepository->findOneByName($bandName);
159
160 2
        $form = $this->createForm(AmbassadorFormType::class);
161 2
        $this->processForm($request, $form);
162 2
        $form = $this->get('rockparade.band')->processFormAndUpdateBand($form, $band, $this->getUser());
163
164 2
        return $this->respond($this->createResponseFromUpdateForm($form));
165
    }
166
167
    /**
168
     * List all band members
169
     * @Route("/{bandName}/members", name="band_members")
170
     * @Method("GET")
171
     * @ApiDoc(
172
     *     section="Band",
173
     *     statusCodes={
174
     *         200="OK",
175
     *         404="Band was not found",
176
     *     }
177
     * )
178
     */
179 4 View Code Duplication
    public function listMembersAction(string $bandName): 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...
180
    {
181 4
        $bandRepository = $this->get('rockparade.band_repository');
182 4
        $band = $bandRepository->findOneByName($bandName);
183
184 4
        if (!$band) {
185
            $response = $this->createEntityNotFoundResponse(Band::class, $bandName);
186
        } else {
187 4
            $response = new ApiResponse($band->getMembers(), Response::HTTP_OK);
188
        }
189
190 4
        return $this->respond($response);
191
    }
192
193
    /**
194
     * Add member to band
195
     * @Route("/{bandName}/members", name="band_member_create")
196
     * @Method("POST")
197
     * @Security("has_role('ROLE_USER')")
198
     * @ApiDoc(
199
     *     section="Band",
200
     *     requirements={
201
     *         {
202
     *             "name"="login",
203
     *             "dataType"="string",
204
     *             "requirement"="true",
205
     *             "description"="user login"
206
     *         },
207
     *         {
208
     *             "name"="short_description",
209
     *             "dataType"="string",
210
     *             "requirement"="true",
211
     *             "description"="short description of musicians role in band"
212
     *         },
213
     *         {
214
     *             "name"="description",
215
     *             "dataType"="string",
216
     *             "requirement"="false",
217
     *             "description"="long description of musician"
218
     *         },
219
     *     },
220
     *     statusCodes={
221
     *         200="Member was added to the band",
222
     *         400="Validation error",
223
     *     }
224
     * )
225
     * @param string $bandName band name
226
     */
227 1
    public function createMemberAction(Request $request, string $bandName): Response
228
    {
229 1
        $form = $this->createForm(AmbassadorMemberFormType::class);
230 1
        $this->processForm($request, $form);
231
232 1
        if ($form->isValid()) {
233 1
            $bandRepository = $this->get('rockparade.band_repository');
234 1
            $band = $bandRepository->findOneByName($bandName);
235
236 1
            if (!$band) {
237
                $response = $this->createEntityNotFoundResponse(Band::class, $bandName);
238
            } else {
239 1
                $newUserLogin = $form->get('login')->getData();
240 1
                $newUser = $this->get('rockparade.user_repository')->findOneByLogin($newUserLogin);
241
242 1
                if (!$newUser) {
243
                    $response = $this->createEntityNotFoundResponse(User::class, $newUserLogin);
244
                } else {
245 1
                    $bandMemberRepository = $this->get('rockparade.band_member_repository');
246 1
                    $shortDescription = (string) $form->get('short_description')->getData();
247 1
                    $description = (string) $form->get('description')->getData();
248 1
                    $bandMember = $bandMemberRepository->getOrCreateByBandAndUser(
249
                        $band,
250
                        $newUser,
251
                        $shortDescription,
252
                        $description
253
                    );
254
255 1
                    $band->addMember($bandMember);
256 1
                    $bandRepository->flush();
257
258 1
                    $response = new EmptyApiResponse(Response::HTTP_OK);
259
                }
260
            }
261
        } else {
262
            $response = new ApiValidationError($form);
263
        }
264
265 1
        return $this->respond($response);
266
    }
267
268
    /**
269
     * Delete member from band
270
     * @Route("/{bandName}/member/{userLogin}", name="band_member_delete")
271
     * @Method("DELETE")
272
     * @Security("has_role('ROLE_USER')")
273
     * @ApiDoc(
274
     *     section="Band",
275
     *     statusCodes={
276
     *         204="Member was deleted from the band",
277
     *         404="Band or user was not found",
278
     *     }
279
     * )
280
     * @param string $bandName band name
281
     * @param string $userLogin member login
282
     */
283 1
    public function deleteMemberAction(string $bandName, string $userLogin)
284
    {
285 1
        $bandRepository = $this->get('rockparade.band_repository');
286 1
        $band = $bandRepository->findOneByName($bandName);
287
288 1
        if ($band) {
289 1
            $userRepository = $this->get('rockparade.user_repository');
290 1
            $user = $userRepository->findOneByLogin($userLogin);
291
292 1
            if ($user) {
293 1
                $bandMemberRepository = $this->get('rockparade.band_member_repository');
294 1
                $bandMember = $bandMemberRepository->findByBandAndUser($band, $user);
295
296 1
                if ($bandMember) {
297 1
                    $band->removeMember($bandMember);
298 1
                    $bandRepository->flush();
299
300 1
                    $response = new EmptyApiResponse(Response::HTTP_NO_CONTENT);
301
                } else {
302 1
                    $response = $this->createEntityNotFoundResponse(BandMember::class, $userLogin);
303
                }
304
            } else {
305 1
                $response = $this->createEntityNotFoundResponse(User::class, $userLogin);
306
            }
307
        } else {
308
            $response = $this->createEntityNotFoundResponse(Band::class, $bandName);
309
        }
310
311 1
        return $this->respond($response);
312
    }
313
    
314
    /**
315
     * Update band member
316
     * @Route("/{bandName}/member", name="band_member_update")
317
     * @Method("PUT")
318
     * @Security("has_role('ROLE_USER')")
319
     * @ApiDoc(
320
     *     section="Band",
321
     *     requirements={
322
     *         {
323
     *             "name"="login",
324
     *             "dataType"="string",
325
     *             "requirement"="true",
326
     *             "description"="login of musician"
327
     *         },
328
     *         {
329
     *             "name"="short_description",
330
     *             "dataType"="string",
331
     *             "requirement"="true",
332
     *             "description"="short description of role in band"
333
     *         },
334
     *         {
335
     *             "name"="description",
336
     *             "dataType"="string",
337
     *             "requirement"="false",
338
     *             "description"="long description of musician"
339
     *         },
340
     *     },
341
     *     statusCodes={
342
     *         204="Band member was successfully updated",
343
     *         404="Band or user was not found",
344
     *     }
345
     * )
346
     * @param string $bandName band name
347
     * @param string $userLogin member login
0 ignored issues
show
Bug introduced by
There is no parameter named $userLogin. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
348
     */
349 1
    public function updateMemberAction(Request $request, string $bandName)
350
    {
351 1
        $bandRepository = $this->get('rockparade.band_repository');
352 1
        $band = $bandRepository->findOneByName($bandName);
353
354 1
        if ($band) {
355 1
            $userLogin = $request->get('login');
356 1
            $userRepository = $this->get('rockparade.user_repository');
357 1
            $user = $userRepository->findOneByLogin($userLogin);
358
359 1
            if ($user) {
360 1
                $bandMemberRepository = $this->get('rockparade.band_member_repository');
361 1
                $bandMember = $bandMemberRepository->findByBandAndUser($band, $user);
362
                
363 1
                if ($bandMember) {
364 1
                    $form = $this->createForm(AmbassadorMemberFormType::class);
365 1
                    $this->processForm($request, $form);
366 1
                    $form = $this->get('rockparade.band')->processFormAndUpdateBandMember($form, $bandMember);
367
                    
368 1
                    $bandRepository->flush();
369
370 1
                    $response = $this->createResponseFromUpdateForm($form);
371
                } else {
372 1
                    $response = $this->createEntityNotFoundResponse(BandMember::class, $userLogin);
373
                }
374
            } else {
375 1
                $response = $this->createEntityNotFoundResponse(User::class, $userLogin);
376
            }
377
        } else {
378
            $response = $this->createEntityNotFoundResponse(Band::class, $bandName);
379
        }
380
381 1
        return $this->respond($response);
382
    }
383
384
    /**
385
     * @return ApiError|CreatedApiResponse|EmptyApiResponse
386
     */
387 3
    private function createResponseFromUpdateForm(FormInterface $form): AbstractApiResponse
388
    {
389 3
        if ($form->isValid()) {
390 2
            return new EmptyApiResponse(Response::HTTP_NO_CONTENT);
391
        } else {
392 1
            return new ApiValidationError($form);
393
        }
394
    }
395
}
396