AchievementCheckListener::loadUser()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace KI\UserBundle\Listener;
4
5
use Doctrine\ORM\EntityManager;
6
use KI\UserBundle\Entity\Achievement;
7
use KI\UserBundle\Entity\AchievementUser;
8
use KI\UserBundle\Entity\User;
9
use KI\UserBundle\Event\AchievementCheckEvent;
10
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
11
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
12
13
class AchievementCheckListener
14
{
15
    protected $manager;
16
    protected $tokenStorage;
17
    protected $authorizationChecker;
18
19
    // L'utilisateur qui tente d'obtenir l'achievement
20
    protected $user;
21
22
    // Liste des achievements unlockés actuellement (identifiants seulement)
23
    protected $achievements = [];
24
25
    public function __construct(EntityManager $manager, TokenStorage $tokenStorage, AuthorizationChecker $authorizationChecker)
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...
26
    {
27
        $this->manager = $manager;
28
        $this->tokenStorage = $tokenStorage;
29
        $this->authorizationChecker = $authorizationChecker;
30
31
        $token = $this->tokenStorage->getToken();
32
        $this->user = $token === null ? null : $token->getUser();
33
34
        if ($this->user !== null) {
35
            $this->loadUser($this->user);
36
        }
37
    }
38
39
    private function loadUser(User $user)
40
    {
41
        $this->user = $user;
42
        $repoAU = $this->manager->getRepository('KIUserBundle:AchievementUser');
43
        $response = $repoAU->findByUser($this->user);
44
45
        foreach ($response as $achievementUser) {
46
            $this->achievements[] = $achievementUser->getAchievement()->getIdA();
47
        }
48
    }
49
50
    // Check si un achievement donné est accompli, si oui envoie une notification
51
    public function check(AchievementCheckEvent $event)
52
    {
53
        // On vérifie tout d'abord si l'achievement concerné n'est pas déjà reçu
54
        $achievement = $event->getAchievement();
55
56
        // On peut préciser l'user pour les routes sans authentification
57
        if ($event->getUser() !== null) {
58
            $this->loadUser($event->getUser());
59
        }
60
        if (!$this->user instanceof User
61
            || in_array($achievement->getIdA(), $this->achievements)
62
        )
63
            return false;
64
65
        // Sinon, on lance le check associé
66
        $check = false;
67
        $method = 'check' . $achievement->getIdA();
68
        if (method_exists($this, $method))
69
            $check = $this->$method();
70
71
        // Si le check est bon
72
        if (!$check)
73
            return false;
74
75
        // On ajoute l'achievement
76
        $achievementUser = new AchievementUser();
77
        $repoA = $this->manager->getRepository('KIUserBundle:Achievement');
78
        $achievementUser->setAchievement($repoA->findOneByAchievement($achievement->getIdA()));
79
        $achievementUser->setUser($this->user);
80
        $achievementUser->setDate(time());
81
        $achievementUser->setSeen(false);
82
        $this->manager->persist($achievementUser);
83
        $this->achievements[] = $achievement->getIdA();
84
85
        // Achievements basés sur le nombre d'achievements
86 View Code Duplication
        if (count($this->achievements) >= 10) {
87
            $achievementCheck = new AchievementCheckEvent(Achievement::UNLOCKER);
88
            $this->check($achievementCheck);
89
        }
90
91
        $total = count(Achievement::getConstants());
92 View Code Duplication
        if (count($this->achievements) >= $total * 0.5) {
93
            $achievementCheck = new AchievementCheckEvent(Achievement::CRAZY_UNLOCKER);
94
            $this->check($achievementCheck);
95
        }
96 View Code Duplication
        if (count($this->achievements) >= $total * 0.9) {
97
            $achievementCheck = new AchievementCheckEvent(Achievement::TOTAL_UNLOCKER);
98
            $this->check($achievementCheck);
99
        }
100
101
        $this->manager->flush();
102
        return true;
103
    }
104
105
    // Calcule le nombre de points de l'utilisateur
106
    public function points()
107
    {
108
        $points = 0;
109
        $factor = 1;
110
111
        // On regarde quels achievements sont locked et on en profite pour
112
        // calculer le nombre de points de l'utilisateur obtenus par les
113
        // achievements
114
        foreach ($this->achievements as $achievement) {
115
            $achievement = new Achievement($achievement);
116 View Code Duplication
            if (gettype($achievement->points()) == 'integer') {
117
                $points += $achievement->points();
118
            } else if ($achievement->points() == '+10%') {
119
                $factor += 0.1;
120
            } else if ($achievement->points() == '+15%') {
121
                $factor += 0.15;
122
            } else if ($achievement->points() == '+75%') {
123
                $factor += 0.75;
124
            }
125
        }
126
        return ceil($factor * $points);
127
    }
128
129
    // Fonctions de check correspondant aux divers achievements
130
    // Attention, ne pas changer les IDs des achievements à la légère !!!
131
    // Les checks qui retournent true sont en fait assez simples :
132
    // L'achievement associé est donc du type "faire ça action au moins une fois"
133
134
    // Ponts inside
135
    // Se logger sur le site
136
    public function check0()
137
    {
138
        return true;
139
    }
140
141
    // Fouilleur
142
    // Faire le tour du site
143
    public function check5()
144
    {
145
        return true;
146
    }
147
148
    // Photogénique
149
    // Changer la photo de son profil
150
    public function check10()
151
    {
152
        return true;
153
    }
154
155
    // Travailleur
156
    // Choisir ses cours
157
    public function check20()
158
    {
159
        return true;
160
    }
161
162
    // Autobiographie
163
    // Remplir ses infos (chambre, téléphone, département, origine, nationalité...)
164
    public function check30()
165
    {
166
        return !empty($this->user->getDepartment()) && !empty($this->user->getPromo()) && !empty($this->user->getLocation()) && !empty($this->user->getNationality()) && !empty($this->user->getPhone()) && !empty($this->user->getOrigin());
167
    }
168
169
    // Remplir ses infos étendues (stages, projets...)
170
    //public function check4() { return true; }
171
172
    // Smart
173
    // Synchroniser le calendrier avec son téléphone
174
    public function check40()
175
    {
176
        return true;
177
    }
178
179
    // Connecté
180
    // Installer l'application mobile
181
    //public function check6() { return true; }
182
183
    // Downloader
184
    // Télécharger un fichier sur Ponthub
185
    public function check50()
186
    {
187
        return true;
188
    }
189
190
    // Super Downloader
191
    // Télécharger plus de 100Go sur Ponthub
192
    public function check60()
193
    {
194
        return $this->totalPontHubSize() > (100 * 1024 * 1024 * 1024);
195
    }
196
197
    // Ultimate Downloader
198
    // Télécharger plus de 500Go sur Ponthub
199
    public function check70()
200
    {
201
        return $this->totalPontHubSize() > (500 * 1024 * 1024 * 1024);
202
    }
203
204
    private function totalPontHubSize()
205
    {
206
        return $this->manager->createQuery('SELECT SUM(file.size)
207
        FROM KIPonthubBundle:PonthubFileUser pfu,
208
        KIPonthubBundle:PonthubFile file
209
        WHERE pfu.user = :user
210
        AND pfu.file = file')
211
            ->setParameter('user', $this->user)
212
            ->getSingleScalarResult();
213
    }
214
215
    // Will be there !
216
    // Participer à un event
217
    public function check80()
218
    {
219
        return true;
220
    }
221
222
    // Pookie
223
    // Uploader un fichier d'annale
224
    public function check90()
225
    {
226
        return true;
227
    }
228
229
    // Spirit
230
    // Être membre d'un club
231
    public function check100()
232
    {
233
        $repo = $this->manager->getRepository('KIUserBundle:ClubUser');
234
        $return = $repo->findBy(['user' => $this->user]);
235
        return count($return) > 0;
236
    }
237
238
    // Nouvelliste
239
    // Écrire une news pour un club
240
    public function check110()
241
    {
242
        return true;
243
    }
244
245
    // Organisateur
246
    // Créer un event pour un club
247
    public function check120()
248
    {
249
        return true;
250
    }
251
252
    // Ruiné
253
    // Avoir un solde foyer négatif
254 View Code Duplication
    public function check130()
255
    {
256
        // On enlève l'achievement opposé (solde positif)
257
        $repoA = $this->manager->getRepository('KIUserBundle:Achievement');
258
        $oAchievement = $repoA->findOneByAchievement(Achievement::FOYER_BIS);
259
260
        $repoAU = $this->manager->getRepository('KIUserBundle:AchievementUser');
261
        $achievementUsers = $repoAU->findBy(['achievement' => $oAchievement, 'user' => $this->user]);
262
263
        if (count($achievementUsers) == 1) {
264
            $this->manager->remove($achievementUsers[0]);
265
            $this->manager->flush();
266
        }
267
        return true;
268
    }
269
270
    // Ruiné
271
    // Avoir un solde foyer positif
272 View Code Duplication
    public function check140()
273
    {
274
        // On enlève l'achievement opposé (solde positif)
275
        $repoA = $this->manager->getRepository('KIUserBundle:Achievement');
276
        $oAchievement = $repoA->findOneByAchievement(Achievement::FOYER);
277
278
        $repoAU = $this->manager->getRepository('KIUserBundle:AchievementUser');
279
        $achievementUsers = $repoAU->findBy(['achievement' => $oAchievement, 'user' => $this->user]);
280
281
        if (count($achievementUsers) == 1) {
282
            $this->manager->remove($achievementUsers[0]);
283
            $this->manager->flush();
284
        }
285
        return true;
286
    }
287
288
    // Non, ce n'était pas "password1234"
289
    // Oublier son mot de passe
290
    public function check150()
291
    {
292
        return true;
293
    }
294
295
    // The Game
296
    // Jouer à La Réponse D
297
    public function check153()
298
    {
299
        return true;
300
    }
301
302
    // Puceau, pas puceau
303
    // Réussir 100% sur la promo d'en dessous dans La Réponse D
304
    public function check154()
305
    {
306
        return true;
307
    }
308
309
    // Connaisseur
310
    // Réussir un 100% sur sa promo dans La Réponse D
311
    public function check155()
312
    {
313
        return true;
314
    }
315
316
    // Bientôt vieux cons
317
    // Réussir un 100% sur la promo d'au dessus dans La Réponse D
318
    public function check156()
319
    {
320
        return true;
321
    }
322
323
    // JRP'1747
324
    // Réussir un 100% en mode hardcore sur une promo de vieux dans La Réponse D
325
    public function check157()
326
    {
327
        return true;
328
    }
329
330
    // H3LLLP UPON SA BEUG!!!!
331
    // Reporter un bug
332
    public function check160()
333
    {
334
        return true;
335
    }
336
337
    // Technophobe
338
    // Contacter le KI pour un dépannage matériel/logiciel
339
    public function check170()
340
    {
341
        return true;
342
    }
343
344
    // KIen
345
    // Faire partie du KI
346
    public function check180()
347
    {
348
        $repo = $this->manager->getRepository('KIUserBundle:Club');
349
        $club = $repo->findOneBySlug('ki');
350
        $repo = $this->manager->getRepository('KIUserBundle:ClubUser');
351
        $return = $repo->findBy(['user' => $this->user, 'club' => $club]);
352
        return count($return) == 1;
353
    }
354
355
    // Appelez-moi Dieu
356
    // Être admin
357
    public function check190()
358
    {
359
        return $this->authorizationChecker->isGranted('ROLE_ADMIN');
360
    }
361
362
    // Unlocker
363
    // Compléter 10 achievements
364
    public function check200()
365
    {
366
        return true;
367
    }
368
369
    // Crazy Unlocker
370
    // Compléter 50% des achievements
371
    public function check210()
372
    {
373
        return true;
374
    }
375
376
    // Total Unlocker
377
    // Compléter 90% des achievements
378
    public function check220()
379
    {
380
        return true;
381
    }
382
}
383