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 |
|
|
|
|
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 |
|
|
|
|
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 |
|
|
|
|
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
|
|
|
|
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.