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) |
|
|
|
|
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
|
|
|
|
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:If that code throws an exception and the
EntityManager
is closed. Any other code which depends on the same instance of theEntityManager
during this request will fail.On the other hand, if you instead inject the
ManagerRegistry
, thegetManager()
method guarantees that you will always get a usable manager instance.