Completed
Pull Request — master (#158)
by Adrien
02:03
created

DefaultController::indexAction()   B

Complexity

Conditions 8
Paths 10

Size

Total Lines 61
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 61
rs 7.0047
c 0
b 0
f 0
cc 8
eloc 36
nc 10
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Badger\Bundle\GameBundle\Controller;
4
5
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
6
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
7
use Symfony\Component\HttpFoundation\JsonResponse;
8
use Symfony\Component\HttpFoundation\Request;
9
use Symfony\Component\HttpFoundation\Response;
10
11
/**
12
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
13
 */
14
class DefaultController extends Controller
15
{
16
    /**
17
     * @Route("/", name="homepage")
18
     */
19
    public function indexAction()
20
    {
21
        $mostUnlockedBadges = [];
22
        $badgeChampions = [];
23
        $userBadgeCompletions = [];
24
        $userTags = $this->getUser()->getTags()->toArray();
25
26
        // Put default tag first
27
        usort($userTags, function ($a, $b)
28
        {
29
            if ($a->isDefault()) {
30
                return -1;
31
            } else if($b->isDefault()) {
32
                return 1;
33
            }
34
        });
35
36
        // Get most unlocked badges & champions per tag
37
        foreach ($userTags as $tag) {
38
            $month = date('m');
39
            $year = date('Y');
40
            $currentUserIsChampion = false;
41
42
            $mostUnlockedBadges[$tag->getCode()] = $this->get('badger.game.repository.badge_completion')
43
                ->getMostUnlockedBadgesForMonth($month, $year, $tag, 5);
44
45
            $maxBadgeCompletions = $this->get('badger.game.repository.badge_completion')
46
                ->getTopNumberOfUnlocksForMonth($month, $year, $tag);
47
48
            $champions = $this->get('badger.user.repository.user')
49
                ->getMonthlyBadgeChampions($month, $year, $tag, $maxBadgeCompletions);
50
51
            foreach ($champions as $champion) {
52
                if ($champion['user']->getId() === $this->getUser()->getId()) {
53
                    $currentUserIsChampion = true;
54
                }
55
56
                $badgeChampions[$tag->getCode()][$champion['badgeCompletions']][] = $champion['user'];
57
            }
58
59
            if (!$currentUserIsChampion) {
60
                $userCompletions = $this->get('badger.game.repository.badge_completion')
61
                    ->getTopNumberOfUnlocksForMonth($month, $year, $tag, $this->getUser());
62
63
                if (!empty($userCompletions)) {
64
                    $userBadgeCompletions[$tag->getCode()] = current($userCompletions)['nbCompletions'];
65
                }
66
            }
67
68
        }
69
70
        $newMembers = $this->get('badger.user.repository.user')->getNewUsersForMonth($month, $year);
0 ignored issues
show
Bug introduced by
The variable $month does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $year does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
71
72
        return $this->render('@Game/home.html.twig', [
73
            'newMembers'           => $newMembers,
74
            'mostUnlockedBadges'   => $mostUnlockedBadges,
75
            'userTags'             => $userTags,
76
            'badgeChampions'       => $badgeChampions,
77
            'userBadgeCompletions' => $userBadgeCompletions
78
        ]);
79
    }
80
81
    /**
82
     * @Route("/users", name="users")
83
     */
84
    public function usersAction()
85
    {
86
        $users = $this->getDoctrine()->getRepository('UserBundle:User')->findAll();
87
88
        return $this->render('@Game/users.html.twig', [
89
            'users' => $users
90
        ]);
91
    }
92
93
    /**
94
     * @Route("/admin", name="admin")
95
     */
96
    public function adminAction()
97
    {
98
        return $this->render('@Game/base-admin.html.twig');
99
    }
100
101
    /**
102
     * @Route("/user/{username}", name="userprofile")
103
     * @param string $username
104
     *
105
     * @return Response
106
     */
107
    public function userProfileAction($username)
108
    {
109
        $user = $this->getDoctrine()->getRepository('UserBundle:User')->findOneBy([
110
            'username' => $username
111
        ]);
112
113
        $badgeCompletions = [];
114
115
        if ($user) {
116
            $badgeCompletions = $this->get('badger.game.repository.badge_completion')->findBy([
117
                'user' => $user, 'pending' => '0'
118
            ]);
119
120
            foreach ($badgeCompletions as $key => $badgeCompletion) {
121
                if (!$this->get('security.authorization_checker')->isGranted('view', $badgeCompletion->getBadge())) {
122
                    unset($badgeCompletions[$key]);
123
                }
124
            }
125
        }
126
127
        $displayedTags = $user->getTags();
128
129
        foreach ($displayedTags as $key => $userTag) {
130
            if (!$this->get('security.authorization_checker')->isGranted('view', $userTag)) {
131
                unset($displayedTags[$key]);
132
            }
133
        }
134
135
        return $this->render('@Game/user-profile.html.twig', [
136
            'user'             => $user,
137
            'badgeCompletions' => $badgeCompletions
138
        ]);
139
    }
140
141
    /**
142
     * @Route("/badge/{id}", name="viewbadge")
143
     * @param $id
144
     *
145
     * @return Response
146
     */
147
    public function badgeViewAction($id)
148
    {
149
        $badge = $this->get('badger.game.repository.badge')->findOneBy([
150
            'id' => $id
151
        ]);
152
153
        if (null === $badge || !$this->get('security.authorization_checker')->isGranted('view', $badge)) {
154
            throw $this->createNotFoundException();
155
        }
156
157
        $badgeCompletions = $this->get('badger.game.repository.badge_completion')->findBy([
158
            'badge' => $badge,
159
            'pending' => '0'
160
        ]);
161
162
        $isUnlocked = false;
163
        $isClaimed = false;
164
165
        $userCompletion = $this->get('badger.game.repository.badge_completion')->findOneBy([
166
            'user' => $this->getUser(),
167
            'badge' => $badge
168
        ]);
169
170
        if (null !== $userCompletion) {
171
            $isClaimed = $userCompletion->isPending();
172
            $isUnlocked = !$userCompletion->isPending();
173
        }
174
175
        return $this->render('@Game/view-badge.html.twig', [
176
            'badge'            => $badge,
177
            'badgeCompletions' => $badgeCompletions,
178
            'isUnlocked'       => $isUnlocked,
179
            'isClaimed'        => $isClaimed
180
        ]);
181
    }
182
183
    /**
184
     * @Route("/claim/badge/{id}", name="claimbadge")
185
     * @param int $id
186
     *
187
     * @return JsonResponse
188
     */
189
    public function claimBadgeAction($id)
190
    {
191
        $user = $this->getUser();
192
        $badge = $this->get('badger.game.repository.badge')->find($id);
193
194
        if (null === $badge) {
195
            return new JsonResponse('No badge with this id.', 400);
196
        }
197
198
        if (!$this->get('security.authorization_checker')->isGranted('view', $badge)) {
199
            return new JsonResponse('No badge with this id.', 400);
200
        }
201
202
        $claimedBadge = $this->get('badger.game.repository.badge_completion')->findOneBy([
203
            'user' => $user,
204
            'badge' => $badge
205
        ]);
206
207
        if (null !== $claimedBadge) {
208
            return new JsonResponse('This badge is already claimed.', 400);
209
        }
210
211
        $badgeCompletionFactory = $this->get('badger.game.badge_completion.factory');
212
        $badgeCompletion = $badgeCompletionFactory->create($user, $badge);
213
214
        $this->get('badger.game.saver.badge_completion')->save($badgeCompletion);
215
216
        return new JsonResponse();
217
    }
218
219
    /**
220
     * @Route("/claim/step/{id}", name="claimstep")
221
     * @param int $id
222
     *
223
     * @return JsonResponse
224
     */
225 View Code Duplication
    public function claimStepAction($id)
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...
226
    {
227
        $user = $this->getUser();
228
        $step = $this->get('badger.game.repository.adventure_step')->find($id);
229
230
        if (null === $step) {
231
            return new JsonResponse('No step with this id.', 404);
232
        }
233
234
        if (!$this->get('security.authorization_checker')->isGranted('view', $step->getAdventure())) {
235
            return new JsonResponse('No step with this id.', 404);
236
        }
237
238
        $stepCompletion = $this->get('badger.game.repository.adventure_step_completion')->findOneBy([
239
            'user' => $user,
240
            'step' => $step
241
        ]);
242
243
        if (null !== $stepCompletion) {
244
            return new JsonResponse('This step is already claimed.', 400);
245
        }
246
247
        $stepCompletionFactory = $this->get('badger.game.adventure_step_completion.factory');
248
        $stepCompletion = $stepCompletionFactory->create($user, $step);
249
250
        $this->get('badger.game.saver.adventure_step_completion')->save($stepCompletion);
251
252
        return new JsonResponse();
253
    }
254
255
    /**
256
     * @Route("/claim/quest/{id}", name="claimquest")
257
     * @param int $id
258
     *
259
     * @return JsonResponse
260
     */
261 View Code Duplication
    public function claimQuestAction($id)
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...
262
    {
263
        $user = $this->getUser();
264
        $quest = $this->get('badger.game.repository.quest')->find($id);
265
266
        if (null === $quest) {
267
            return new JsonResponse('No quest with this id.', 400);
268
        }
269
270
        if (!$this->get('security.authorization_checker')->isGranted('view', $quest)) {
271
            return new JsonResponse('No quest with this id.', 400);
272
        }
273
274
        $questCompletion = $this->get('badger.game.repository.quest_completion')->findOneBy([
275
            'user' => $user,
276
            'quest' => $quest
277
        ]);
278
279
        if (null !== $questCompletion) {
280
            return new JsonResponse('This quest is already claimed.', 400);
281
        }
282
283
        $questCompletionFactory = $this->get('badger.game.quest_completion.factory');
284
        $questCompletion = $questCompletionFactory->create($user, $quest);
285
286
        $this->get('badger.game.saver.quest_completion')->save($questCompletion);
287
288
        return new JsonResponse();
289
    }
290
291
    /**
292
     * @Route("/badges", name="badges")
293
     *
294
     * @return Response
295
     */
296
    public function badgeListAction()
297
    {
298
        $user = $this->getUser();
299
        $userTags = $user->getTags();
300
301
        $unlockedBadgeIds = $this->get('badger.game.repository.badge_completion')
302
            ->getCompletionBadgesByUser($user, false);
303
304
        $claimedBadgeIds = $this->get('badger.game.repository.badge_completion')
305
            ->getCompletionBadgesByUser($user, true);
306
307
        return $this->render('@Game/badges.html.twig', [
308
            'tags' => $userTags,
309
            'unlockedBadgesIds' => $unlockedBadgeIds,
310
            'claimedBadgeIds' => $claimedBadgeIds
311
        ]);
312
    }
313
314
    /**
315
     * @Route("/quests", name="quests")
316
     * @param Request $request
317
     *
318
     * @return Response
319
     */
320
    public function questListAction(Request $request)
321
    {
322
        $user = $this->getUser();
323
        $status = $request->get('status', 'available');
324
325
        $questRepository = $this->get('badger.game.repository.quest');
326
        $completionRepository = $this->get('badger.game.repository.quest_completion');
327
328
        $availableQuests = $questRepository->getAvailableQuestsForUser($user);
329
        $questCompletions = $completionRepository->findBy(['user' => $user, 'pending' => 0]);
330
        $claimedQuestIds = $this->get('badger.game.repository.quest_completion')
331
            ->getQuestIdsClaimedByUser($user);
332
333
        return $this->render('@Game/quests.html.twig', [
334
            'availableQuests'      => $availableQuests,
335
            'questCompletions'     => $questCompletions,
336
            'countAvailableQuests' => count($availableQuests),
337
            'countCompletedQuests' => count($questCompletions),
338
            'claimedQuestIds'      => $claimedQuestIds,
339
            'status'               => $status
340
        ]);
341
    }
342
343
    /**
344
     * @Route("/adventures", name="adventures")
345
     *
346
     * @return Response
347
     */
348
    public function adventureListAction()
349
    {
350
        $user = $this->getUser();
351
352
        $availableAdventures = $this->get('badger.game.repository.adventure')
353
            ->getAvailableAdventuresForUser($user);
354
355
        $completedAdventures = $this->get('badger.game.repository.adventure')
356
            ->getCompletedAdventuresForUser($user);
357
358
        $completedStepsByAdventure = $this->get('badger.game.repository.adventure_step_completion')
359
            ->userCompletedSteps($user);
360
361
        foreach ($availableAdventures as $adventure) {
362
            $adventure->completed = '0';
363
364
            foreach ($completedStepsByAdventure as $data) {
365
                if ($adventure->getId() === $data['adventure']->getId()) {
366
                    $adventure->completed = $data['completions'];
367
                }
368
            }
369
        }
370
371
        return $this->render('@Game/adventures.html.twig', [
372
            'availableAdventures' => $availableAdventures,
373
            'completedAdventures' => $completedAdventures
374
        ]);
375
    }
376
377
    /**
378
     * @Route("/adventures/{id}", name="viewadventure")
379
     *
380
     * @param int $id
381
     *
382
     * @return Response
383
     */
384
    public function adventureViewAction($id)
385
    {
386
        $user = $this->getUser();
387
        $adventure = $this->get('badger.game.repository.adventure')
388
            ->find($id);
389
390
        $completedSteps = $this->get('badger.game.repository.adventure_step_completion')
391
            ->userAdventureCompletedSteps($user, $adventure);
392
393
        $claimedSteps = $this->get('badger.game.repository.adventure_step_completion')
394
            ->userAdventureClaimedSteps($user, $adventure);
395
396
        $progression = count($completedSteps) * 100 / count($adventure->getSteps());
397
398
        $totalStep = count($adventure->getSteps());
399
        $isAdventureComplete = count($completedSteps) === $totalStep;
400
401
        return $this->render('@Game/view-adventure.html.twig', [
402
            'adventure' => $adventure,
403
            'completedSteps' => $completedSteps,
404
            'claimedSteps' => $claimedSteps,
405
            'progression' => $progression,
406
            'isAdventureComplete' => $isAdventureComplete
407
        ]);
408
    }
409
410
    /**
411
     * @Route("/leaderboard", name="leaderboard")
412
     *
413
     * @return Response
414
     */
415
    public function leaderboardAction()
416
    {
417
        $users = $this->getDoctrine()->getRepository('UserBundle:User')->getSortedUserByUnlockedBadges();
418
419
        return $this->render('@Game/leaderboard.html.twig', [
420
            'users' => $users
421
        ]);
422
    }
423
424
    /**
425
     * @Route("/search/users", name="search_users")
426
     * @param Request $request
427
     *
428
     * @return JsonResponse
429
     */
430
    public function searchUsersAction(Request $request)
431
    {
432
        $token = $request->get('token');
433
434
        if ('' === trim($token)) {
435
            $users = $this->get('badger.user.repository.user')->findAll();
436
            $results = [];
437
438
            foreach ($users as $user) {
439
                $results[] = [
440
                    'username' => $user->getUsername(),
441
                    'profilePicture' => $user->getProfilePicture()
442
                ];
443
            }
444
445
            return new JsonResponse($results);
446
        }
447
448
        $results = $this->get('badger.user.repository.elastic.user')->findUser($token);
449
450
        return new JsonResponse($results);
451
    }
452
}
453