FacegameHelper::endGame()   C
last analyzed

Complexity

Conditions 15
Paths 9

Size

Total Lines 39

Duplication

Lines 12
Ratio 30.77 %

Importance

Changes 0
Metric Value
dl 12
loc 39
rs 5.9166
c 0
b 0
f 0
cc 15
nc 9
nop 3

How to fix   Complexity   

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 KI\UserBundle\Helper;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\EntityRepository;
7
use KI\UserBundle\Entity\Achievement;
8
use KI\UserBundle\Entity\Facegame;
9
use KI\UserBundle\Event\AchievementCheckEvent;
10
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
11
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
12
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
13
14
15
// Valide les formulaires pour une entité et affiche la réponse à la demande
16
class FacegameHelper
17
{
18
    protected $manager;
19
    protected $repository;
20
    protected $dispatcher;
21
    protected $tokenStorage;
22
23
    public function __construct(
24
        EntityManager            $manager,
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $manager. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
25
        EntityRepository         $repository,
26
        EventDispatcherInterface $dispatcher,
27
        TokenStorageInterface    $tokenStorage
28
    )
29
    {
30
        $this->manager      = $manager;
31
        $this->repository   = $repository;
32
        $this->dispatcher   = $dispatcher;
33
        $this->tokenStorage = $tokenStorage;
34
    }
35
36
    /**
37
     *  On remplit la listUsers selon les paramètres rentrés
38
     *  Chaque array contient les noms proposés, une image et la position de la proposition correcte
39
     *  @param  Facegame $game La partie à populer
40
     *  @return bool Si la partie est possible ou non (assez d'élève dans la promo)
41
     */
42
    public function fillUserList(Facegame $facegame)
43
    {
44
        $hardcore = $facegame->getHardcore();
45
        $promo    = $facegame->getPromo();
46
        $player   = $facegame->getUser();
47
        $list     = $facegame->getListUsers();
48
49
        if ($hardcore) {
50
            $defaultTraits = ['department', 'promo', 'location', 'origin', 'nationality'];
51
            $nbTraits      = count($defaultTraits);
52
        }
53
54
        $users = $promo !== null ? $this->repository->findByPromo($promo) : $this->repository->findAll();
55
56
        $countUsers = count($users);
57
        if ($countUsers < 5) {
58
            return false;
59
        }
60
61
        // Gestion du nombre de questions possibles
62
        $nbQuestions = min(10, $countUsers/2 - 1);
63
        $nbPropositions = 3;
64
65
        while (count($list) < $nbQuestions) {
66
            $tempList = [];
67
            $ids      = [];
68
69
            $tempList['firstPart'] = count($list) < $nbQuestions/2;
70
71
            if ($hardcore) {
72
                // Si la promo est déjà établie on ne va pas la demander comme carac
73
                do {
74
                    $trait = $defaultTraits[rand(0, $nbTraits - 1)];
75
                } while ($promo !== null && $trait == 'promo');
76
77
                $tempList['trait'] = $trait;
78
                $userTraits = [];
79
            }
80
81
            // La réponse est décidée aléatoirement
82
            $tempList['answer'] = rand(0, $nbPropositions - 1);
83
84
            for ($i = 0; $i < $nbPropositions; $i++) {
85
                // On vérifie que l'user existe, qu'il a une image de profil,
86
                // qu'on ne propose pas le nom de la personne ayant lancé le test
87
                // et qu'on ne propose pas 2 fois la même caractéristique
88
                do {
89
                    // On vérifie qu'on ne propose pas deux fois le même nom
90
                    do {
91
                        $tempId = rand(0, $countUsers - 1);
92
                    } while (in_array($tempId, $ids));
93
94
                    $ids[] = $tempId;
95
                    $user  = $users[$tempId];
96
97
                    if ($hardcore) {
98
                        $method    = 'get'.ucfirst($trait);
99
                        $tempTrait = $user->$method();
100
                    }
101
                }
102
                while (!isset($user)
103
                    || $user->getImage() === null
104
                    || $user->getPromo() === null
105
                    || $user->getUsername() == $player->getUsername()
106
                    || $hardcore
107
                    && ($tempTrait === null || in_array($tempTrait, $userTraits, true))
108
                );
109
110
                $tempList[$i]['name'] = $user->getFirstName().' '.$user->getLastName();
111
                $tempList[$i]['picture'] = $user->getImage()->getWebPath();
112
113
                if ($hardcore) {
114
                    $userTraits[] = $tempTrait;
115
                    $tempList[$i]['trait'] = $tempTrait;
116
                }
117
            }
118
            $list[] = $tempList;
119
        }
120
        $facegame->setListUsers($list);
121
        return true;
122
    }
123
124
    /**
125
     * Finit un jeu
126
     * @param Facegame $game     La partie à résoudre
127
     * @param integer  $wrongAnswers Le nombre de mauvaises réponses
128
     */
129
    public function endGame(Facegame $game, $wrongAnswers, $duration)
130
    {
131
        if (!empty($game->getDuration())) {
132
            throw new BadRequestHttpException('Jeu déjà fini');
133
        }
134
135
        $game->setWrongAnswers($wrongAnswers);
136
        $game->setDuration($duration);
137
        $this->manager->flush();
138
139
        $achievementCheck = new AchievementCheckEvent(Achievement::GAME_PLAY);
140
        $this->dispatcher->dispatch('upont.achievement', $achievementCheck);
141
142
        $promoUser = (int)$this->tokenStorage->getToken()->getUser()->getPromo();
143
        $promoGame = (int)$game->getPromo();
144
145
        if ($wrongAnswers == 0 && $promoGame == $promoUser - 1 && $duration < 60 * 1000) {
146
147
            $achievementCheck = new AchievementCheckEvent(Achievement::GAME_BEFORE);
148
            $this->dispatcher->dispatch('upont.achievement', $achievementCheck);
149
150
        } else if ($wrongAnswers == 0 && $promoGame == $promoUser && $duration < 60 * 1000) {
151
152
            $achievementCheck = new AchievementCheckEvent(Achievement::GAME_SELF);
153
            $this->dispatcher->dispatch('upont.achievement', $achievementCheck);
154
155 View Code Duplication
        } else if ($wrongAnswers == 0 && $promoGame == $promoUser + 1 && $duration < 60 * 1000) {
156
157
            $achievementCheck = new AchievementCheckEvent(Achievement::GAME_NEXT);
158
            $this->dispatcher->dispatch('upont.achievement', $achievementCheck);
159
160
        }
161 View Code Duplication
        if ($wrongAnswers == 0 && $promoGame < $promoUser && $game->getHardcore() && $duration < 60 * 1000) {
162
163
            $achievementCheck = new AchievementCheckEvent(Achievement::GAME_OLD);
164
            $this->dispatcher->dispatch('upont.achievement', $achievementCheck);
165
166
        }
167
    }
168
}
169