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, |
|
|
|
|
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
|
|
|
|
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.