1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Badger\Bundle\GameBundle\Controller; |
4
|
|
|
|
5
|
|
|
use Badger\Bundle\GameBundle\Event\BadgeUnlockEvent; |
6
|
|
|
use Badger\Bundle\GameBundle\GameEvents; |
7
|
|
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
8
|
|
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller; |
9
|
|
|
use Symfony\Component\HttpFoundation\JsonResponse; |
10
|
|
|
use Symfony\Component\HttpFoundation\Request; |
11
|
|
|
use Symfony\Component\HttpFoundation\Response; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* @license http://opensource.org/licenses/MIT The MIT License (MIT) |
15
|
|
|
*/ |
16
|
|
|
class DefaultController extends Controller |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* @Route("/", name="homepage") |
20
|
|
|
*/ |
21
|
|
|
public function indexAction() |
22
|
|
|
{ |
23
|
|
|
$mostUnlockedBadges = []; |
24
|
|
|
$badgeChampions = []; |
25
|
|
|
$userBadgeCompletions = []; |
26
|
|
|
$userTags = $this->getUser()->getTags()->toArray(); |
27
|
|
|
$date = new \DateTime(); |
28
|
|
|
|
29
|
|
|
// Put default tag first |
30
|
|
|
usort($userTags, function ($a, $b) { |
31
|
|
|
if ($a->isDefault()) { |
32
|
|
|
return -1; |
33
|
|
|
} elseif ($b->isDefault()) { |
34
|
|
|
return 1; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
return 0; |
38
|
|
|
}); |
39
|
|
|
|
40
|
|
|
// Get most unlocked badges & champions per tag |
41
|
|
|
foreach ($userTags as $tag) { |
42
|
|
|
$currentUserIsChampion = false; |
43
|
|
|
|
44
|
|
|
$mostUnlockedBadges[$tag->getCode()] = $this->get('badger.game.repository.badge_completion') |
45
|
|
|
->getMostUnlockedBadgesForDate($date, $tag, 5); |
46
|
|
|
|
47
|
|
|
$maxBadgeCompletions = $this->get('badger.game.repository.badge_completion') |
48
|
|
|
->getTopNumberOfUnlocksForDate($date, $tag); |
49
|
|
|
|
50
|
|
|
$champions = $this->get('badger.user.repository.user') |
51
|
|
|
->getMonthlyBadgeChampions($date, $tag, $maxBadgeCompletions); |
52
|
|
|
|
53
|
|
|
foreach ($champions as $champion) { |
54
|
|
|
if ($champion['user']->getId() === $this->getUser()->getId()) { |
55
|
|
|
$currentUserIsChampion = true; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
$badgeChampions[$tag->getCode()][$champion['badgeCompletions']][] = $champion['user']; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
if (!$currentUserIsChampion) { |
62
|
|
|
$userCompletions = $this->get('badger.game.repository.badge_completion') |
63
|
|
|
->getTopNumberOfUnlocksForDate($date, $tag, $this->getUser()); |
64
|
|
|
|
65
|
|
|
if (!empty($userCompletions)) { |
66
|
|
|
$userBadgeCompletions[$tag->getCode()] = current($userCompletions)['nbCompletions']; |
67
|
|
|
} |
68
|
|
|
} |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
$newMembers = $this->get('badger.user.repository.user')->getNewUsersForMonth($date); |
72
|
|
|
|
73
|
|
|
return $this->render('@Game/home.html.twig', [ |
74
|
|
|
'newMembers' => $newMembers, |
75
|
|
|
'mostUnlockedBadges' => $mostUnlockedBadges, |
76
|
|
|
'userTags' => $userTags, |
77
|
|
|
'badgeChampions' => $badgeChampions, |
78
|
|
|
'userBadgeCompletions' => $userBadgeCompletions |
79
|
|
|
]); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* @Route("/users", name="users") |
84
|
|
|
*/ |
85
|
|
|
public function usersAction() |
86
|
|
|
{ |
87
|
|
|
$users = $this->getDoctrine()->getRepository('UserBundle:User')->findAll(); |
88
|
|
|
|
89
|
|
|
return $this->render('@Game/users.html.twig', [ |
90
|
|
|
'users' => $users |
91
|
|
|
]); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @Route("/admin", name="admin") |
96
|
|
|
*/ |
97
|
|
|
public function adminAction() |
98
|
|
|
{ |
99
|
|
|
return $this->render('@Game/base-admin.html.twig'); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* @Route("/user/{username}", name="userprofile") |
104
|
|
|
* @param string $username |
105
|
|
|
* |
106
|
|
|
* @return Response |
107
|
|
|
*/ |
108
|
|
|
public function userProfileAction($username) |
109
|
|
|
{ |
110
|
|
|
$user = $this->getDoctrine()->getRepository('UserBundle:User')->findOneBy([ |
111
|
|
|
'username' => $username |
112
|
|
|
]); |
113
|
|
|
|
114
|
|
|
$badgeCompletions = []; |
115
|
|
|
|
116
|
|
|
if ($user) { |
117
|
|
|
$badgeCompletions = $this->get('badger.game.repository.badge_completion')->findBy([ |
118
|
|
|
'user' => $user, 'pending' => '0' |
119
|
|
|
]); |
120
|
|
|
|
121
|
|
|
foreach ($badgeCompletions as $key => $badgeCompletion) { |
122
|
|
|
if (!$this->get('security.authorization_checker')->isGranted('view', $badgeCompletion->getBadge())) { |
123
|
|
|
unset($badgeCompletions[$key]); |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
$displayedTags = $user->getTags(); |
129
|
|
|
|
130
|
|
|
foreach ($displayedTags as $key => $userTag) { |
131
|
|
|
if (!$this->get('security.authorization_checker')->isGranted('view', $userTag)) { |
132
|
|
|
unset($displayedTags[$key]); |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
return $this->render('@Game/user-profile.html.twig', [ |
137
|
|
|
'user' => $user, |
138
|
|
|
'badgeCompletions' => $badgeCompletions |
139
|
|
|
]); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* @Route("/badge/{id}", name="viewbadge") |
144
|
|
|
* @param $id |
145
|
|
|
* |
146
|
|
|
* @return Response |
147
|
|
|
*/ |
148
|
|
|
public function badgeViewAction($id) |
149
|
|
|
{ |
150
|
|
|
$badge = $this->get('badger.game.repository.badge')->findOneBy([ |
151
|
|
|
'id' => $id |
152
|
|
|
]); |
153
|
|
|
|
154
|
|
|
if (null === $badge || !$this->get('security.authorization_checker')->isGranted('view', $badge)) { |
155
|
|
|
throw $this->createNotFoundException(); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
$badgeCompletions = $this->get('badger.game.repository.badge_completion')->findBy([ |
159
|
|
|
'badge' => $badge, |
160
|
|
|
'pending' => '0' |
161
|
|
|
]); |
162
|
|
|
|
163
|
|
|
$isUnlocked = false; |
164
|
|
|
$isClaimed = false; |
165
|
|
|
|
166
|
|
|
$userCompletion = $this->get('badger.game.repository.badge_completion')->findOneBy([ |
167
|
|
|
'user' => $this->getUser(), |
168
|
|
|
'badge' => $badge |
169
|
|
|
]); |
170
|
|
|
|
171
|
|
|
if (null !== $userCompletion) { |
172
|
|
|
$isClaimed = $userCompletion->isPending(); |
173
|
|
|
$isUnlocked = !$userCompletion->isPending(); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
return $this->render('@Game/view-badge.html.twig', [ |
177
|
|
|
'badge' => $badge, |
178
|
|
|
'badgeCompletions' => $badgeCompletions, |
179
|
|
|
'isUnlocked' => $isUnlocked, |
180
|
|
|
'isClaimed' => $isClaimed |
181
|
|
|
]); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* @Route("/claim/badge/{id}", name="claimbadge") |
186
|
|
|
* @param int $id |
187
|
|
|
* |
188
|
|
|
* @return JsonResponse |
189
|
|
|
*/ |
190
|
|
|
public function claimBadgeAction($id) |
191
|
|
|
{ |
192
|
|
|
$user = $this->getUser(); |
193
|
|
|
$badge = $this->get('badger.game.repository.badge')->find($id); |
194
|
|
|
|
195
|
|
|
if (null === $badge) { |
196
|
|
|
return new JsonResponse('No badge with this id.', 400); |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
if (!$this->get('security.authorization_checker')->isGranted('view', $badge)) { |
200
|
|
|
return new JsonResponse('No badge with this id.', 400); |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
$claimedBadge = $this->get('badger.game.repository.badge_completion')->findOneBy([ |
204
|
|
|
'user' => $user, |
205
|
|
|
'badge' => $badge |
206
|
|
|
]); |
207
|
|
|
|
208
|
|
|
if (null !== $claimedBadge) { |
209
|
|
|
return new JsonResponse('This badge is already claimed.', 400); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
$badgeCompletionFactory = $this->get('badger.game.badge_completion.factory'); |
213
|
|
|
$badgeCompletion = $badgeCompletionFactory->create($user, $badge); |
214
|
|
|
|
215
|
|
|
$this->get('badger.game.saver.badge_completion')->save($badgeCompletion); |
216
|
|
|
|
217
|
|
|
$event = new BadgeUnlockEvent($badgeCompletion); |
218
|
|
|
$this->get('event_dispatcher')->dispatch(GameEvents::BADGE_HAS_BEEN_CLAIMED, $event); |
219
|
|
|
|
220
|
|
|
return new JsonResponse(); |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* @Route("/claim/step/{id}", name="claimstep") |
225
|
|
|
* @param int $id |
226
|
|
|
* |
227
|
|
|
* @return JsonResponse |
228
|
|
|
*/ |
229
|
|
View Code Duplication |
public function claimStepAction($id) |
|
|
|
|
230
|
|
|
{ |
231
|
|
|
$user = $this->getUser(); |
232
|
|
|
$step = $this->get('badger.game.repository.adventure_step')->find($id); |
233
|
|
|
|
234
|
|
|
if (null === $step) { |
235
|
|
|
return new JsonResponse('No step with this id.', 404); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
if (!$this->get('security.authorization_checker')->isGranted('view', $step->getAdventure())) { |
239
|
|
|
return new JsonResponse('No step with this id.', 404); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
$stepCompletion = $this->get('badger.game.repository.adventure_step_completion')->findOneBy([ |
243
|
|
|
'user' => $user, |
244
|
|
|
'step' => $step |
245
|
|
|
]); |
246
|
|
|
|
247
|
|
|
if (null !== $stepCompletion) { |
248
|
|
|
return new JsonResponse('This step is already claimed.', 400); |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
$stepCompletionFactory = $this->get('badger.game.adventure_step_completion.factory'); |
252
|
|
|
$stepCompletion = $stepCompletionFactory->create($user, $step); |
253
|
|
|
|
254
|
|
|
$this->get('badger.game.saver.adventure_step_completion')->save($stepCompletion); |
255
|
|
|
|
256
|
|
|
return new JsonResponse(); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @Route("/claim/quest/{id}", name="claimquest") |
261
|
|
|
* @param int $id |
262
|
|
|
* |
263
|
|
|
* @return JsonResponse |
264
|
|
|
*/ |
265
|
|
View Code Duplication |
public function claimQuestAction($id) |
|
|
|
|
266
|
|
|
{ |
267
|
|
|
$user = $this->getUser(); |
268
|
|
|
$quest = $this->get('badger.game.repository.quest')->find($id); |
269
|
|
|
|
270
|
|
|
if (null === $quest) { |
271
|
|
|
return new JsonResponse('No quest with this id.', 400); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
if (!$this->get('security.authorization_checker')->isGranted('view', $quest)) { |
275
|
|
|
return new JsonResponse('No quest with this id.', 400); |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
$questCompletion = $this->get('badger.game.repository.quest_completion')->findOneBy([ |
279
|
|
|
'user' => $user, |
280
|
|
|
'quest' => $quest |
281
|
|
|
]); |
282
|
|
|
|
283
|
|
|
if (null !== $questCompletion) { |
284
|
|
|
return new JsonResponse('This quest is already claimed.', 400); |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
$questCompletionFactory = $this->get('badger.game.quest_completion.factory'); |
288
|
|
|
$questCompletion = $questCompletionFactory->create($user, $quest); |
289
|
|
|
|
290
|
|
|
$this->get('badger.game.saver.quest_completion')->save($questCompletion); |
291
|
|
|
|
292
|
|
|
return new JsonResponse(); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* @Route("/badges", name="badges") |
297
|
|
|
* |
298
|
|
|
* @return Response |
299
|
|
|
*/ |
300
|
|
|
public function badgeListAction() |
301
|
|
|
{ |
302
|
|
|
$user = $this->getUser(); |
303
|
|
|
$userTags = $user->getTags(); |
304
|
|
|
|
305
|
|
|
$unlockedBadgeIds = $this->get('badger.game.repository.badge_completion') |
306
|
|
|
->getCompletionBadgesByUser($user, false); |
307
|
|
|
|
308
|
|
|
$claimedBadgeIds = $this->get('badger.game.repository.badge_completion') |
309
|
|
|
->getCompletionBadgesByUser($user, true); |
310
|
|
|
|
311
|
|
|
return $this->render('@Game/badges.html.twig', [ |
312
|
|
|
'tags' => $userTags, |
313
|
|
|
'unlockedBadgesIds' => $unlockedBadgeIds, |
314
|
|
|
'claimedBadgeIds' => $claimedBadgeIds |
315
|
|
|
]); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
/** |
319
|
|
|
* @Route("/quests", name="quests") |
320
|
|
|
* @param Request $request |
321
|
|
|
* |
322
|
|
|
* @return Response |
323
|
|
|
*/ |
324
|
|
|
public function questListAction(Request $request) |
325
|
|
|
{ |
326
|
|
|
$user = $this->getUser(); |
327
|
|
|
$status = $request->get('status', 'available'); |
328
|
|
|
|
329
|
|
|
$questRepository = $this->get('badger.game.repository.quest'); |
330
|
|
|
$completionRepository = $this->get('badger.game.repository.quest_completion'); |
331
|
|
|
|
332
|
|
|
$availableQuests = $questRepository->getAvailableQuestsForUser($user); |
333
|
|
|
$questCompletions = $completionRepository->findBy(['user' => $user, 'pending' => 0]); |
334
|
|
|
$claimedQuestIds = $this->get('badger.game.repository.quest_completion') |
335
|
|
|
->getQuestIdsClaimedByUser($user); |
336
|
|
|
|
337
|
|
|
return $this->render('@Game/quests.html.twig', [ |
338
|
|
|
'availableQuests' => $availableQuests, |
339
|
|
|
'questCompletions' => $questCompletions, |
340
|
|
|
'countAvailableQuests' => count($availableQuests), |
341
|
|
|
'countCompletedQuests' => count($questCompletions), |
342
|
|
|
'claimedQuestIds' => $claimedQuestIds, |
343
|
|
|
'status' => $status |
344
|
|
|
]); |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* @Route("/adventures", name="adventures") |
349
|
|
|
* |
350
|
|
|
* @return Response |
351
|
|
|
*/ |
352
|
|
|
public function adventureListAction() |
353
|
|
|
{ |
354
|
|
|
$user = $this->getUser(); |
355
|
|
|
|
356
|
|
|
$availableAdventures = $this->get('badger.game.repository.adventure') |
357
|
|
|
->getAvailableAdventuresForUser($user); |
358
|
|
|
|
359
|
|
|
$completedAdventures = $this->get('badger.game.repository.adventure') |
360
|
|
|
->getCompletedAdventuresForUser($user); |
361
|
|
|
|
362
|
|
|
$completedStepsByAdventure = $this->get('badger.game.repository.adventure_step_completion') |
363
|
|
|
->userCompletedSteps($user); |
364
|
|
|
|
365
|
|
|
foreach ($availableAdventures as $adventure) { |
366
|
|
|
$adventure->completed = '0'; |
367
|
|
|
|
368
|
|
|
foreach ($completedStepsByAdventure as $data) { |
369
|
|
|
if ($adventure->getId() === $data['adventure']->getId()) { |
370
|
|
|
$adventure->completed = $data['completions']; |
371
|
|
|
} |
372
|
|
|
} |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
return $this->render('@Game/adventures.html.twig', [ |
376
|
|
|
'availableAdventures' => $availableAdventures, |
377
|
|
|
'completedAdventures' => $completedAdventures |
378
|
|
|
]); |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
/** |
382
|
|
|
* @Route("/adventures/{id}", name="viewadventure") |
383
|
|
|
* |
384
|
|
|
* @param int $id |
385
|
|
|
* |
386
|
|
|
* @return Response |
387
|
|
|
*/ |
388
|
|
|
public function adventureViewAction($id) |
389
|
|
|
{ |
390
|
|
|
$user = $this->getUser(); |
391
|
|
|
$adventure = $this->get('badger.game.repository.adventure') |
392
|
|
|
->find($id); |
393
|
|
|
|
394
|
|
|
$completedSteps = $this->get('badger.game.repository.adventure_step_completion') |
395
|
|
|
->userAdventureCompletedSteps($user, $adventure); |
396
|
|
|
|
397
|
|
|
$claimedSteps = $this->get('badger.game.repository.adventure_step_completion') |
398
|
|
|
->userAdventureClaimedSteps($user, $adventure); |
399
|
|
|
|
400
|
|
|
$progression = count($completedSteps) * 100 / count($adventure->getSteps()); |
401
|
|
|
|
402
|
|
|
$totalStep = count($adventure->getSteps()); |
403
|
|
|
$isAdventureComplete = count($completedSteps) === $totalStep; |
404
|
|
|
|
405
|
|
|
return $this->render('@Game/view-adventure.html.twig', [ |
406
|
|
|
'adventure' => $adventure, |
407
|
|
|
'completedSteps' => $completedSteps, |
408
|
|
|
'claimedSteps' => $claimedSteps, |
409
|
|
|
'progression' => $progression, |
410
|
|
|
'isAdventureComplete' => $isAdventureComplete |
411
|
|
|
]); |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
/** |
415
|
|
|
* @Route("/leaderboard", name="leaderboard") |
416
|
|
|
* |
417
|
|
|
* @return Response |
418
|
|
|
*/ |
419
|
|
|
public function leaderboardAction() |
420
|
|
|
{ |
421
|
|
|
$user = $this->getUser(); |
422
|
|
|
$tags = $user->getTags(); |
423
|
|
|
$championsPerTag = []; |
424
|
|
|
|
425
|
|
|
foreach ($tags as $tag) { |
426
|
|
|
$championsPerTag[$tag->getCode()] = []; |
427
|
|
|
$topNumbers = $this->get('badger.game.repository.badge_completion')->getTopNumberOfUnlocks($tag); |
428
|
|
|
$champions = $this->get('badger.user.repository.user')->getBadgeChampions($tag, $topNumbers); |
429
|
|
|
|
430
|
|
|
foreach ($champions as $champion) { |
431
|
|
|
$championsPerTag[$tag->getCode()][$champion['badgeCompletions']][] = $champion['user']; |
432
|
|
|
} |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
return $this->render('@Game/leaderboard.html.twig', [ |
436
|
|
|
'tags' => $tags, |
437
|
|
|
'championsPerTag' => $championsPerTag, |
438
|
|
|
]); |
439
|
|
|
} |
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* @Route("/search/users", name="search_users") |
443
|
|
|
* @param Request $request |
444
|
|
|
* |
445
|
|
|
* @return JsonResponse |
446
|
|
|
*/ |
447
|
|
|
public function searchUsersAction(Request $request) |
448
|
|
|
{ |
449
|
|
|
$token = $request->get('token'); |
450
|
|
|
|
451
|
|
|
if ('' === trim($token)) { |
452
|
|
|
$users = $this->get('badger.user.repository.user')->findAll(); |
453
|
|
|
$results = []; |
454
|
|
|
|
455
|
|
|
foreach ($users as $user) { |
456
|
|
|
$results[] = [ |
457
|
|
|
'username' => $user->getUsername(), |
458
|
|
|
'profilePicture' => $user->getProfilePicture() |
459
|
|
|
]; |
460
|
|
|
} |
461
|
|
|
|
462
|
|
|
return new JsonResponse($results); |
463
|
|
|
} |
464
|
|
|
|
465
|
|
|
$results = $this->get('badger.user.repository.elastic.user')->findUser($token); |
466
|
|
|
|
467
|
|
|
return new JsonResponse($results); |
468
|
|
|
} |
469
|
|
|
} |
470
|
|
|
|
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.