This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace KI\PonthubBundle\Helper; |
||
4 | |||
5 | use Doctrine\ORM\EntityManager; |
||
6 | use Doctrine\ORM\EntityRepository; |
||
7 | use KI\PonthubBundle\Entity\Episode; |
||
8 | use KI\PonthubBundle\Entity\Game; |
||
9 | use KI\PonthubBundle\Entity\Movie; |
||
10 | use KI\PonthubBundle\Entity\Other; |
||
11 | use KI\PonthubBundle\Entity\Software; |
||
12 | |||
13 | class GlobalStatisticsHelper |
||
14 | { |
||
15 | protected $manager; |
||
16 | protected $ponthubFileRepository; |
||
17 | protected $ponthubFileUserRepository; |
||
18 | |||
19 | public function __construct(EntityManager $manager, EntityRepository $ponthubFileRepository, EntityRepository $ponthubFileUserRepository) |
||
0 ignored issues
–
show
|
|||
20 | { |
||
21 | $this->manager = $manager; |
||
22 | $this->ponthubFileRepository = $ponthubFileRepository; |
||
23 | $this->ponthubFileUserRepository = $ponthubFileUserRepository; |
||
24 | } |
||
25 | |||
26 | /** |
||
27 | * Hall of fame (histogramme) des plus gros downloaders |
||
28 | * @return array |
||
29 | */ |
||
30 | public function getGlobalDownloaders() |
||
31 | { |
||
32 | // Recherche des plus gros downloaders |
||
33 | $downloaderIds = $this->manager->createQuery('SELECT IDENTITY(e.user), SUM(f.size) AS compte |
||
34 | FROM KI\PonthubBundle\Entity\PonthubFileUser e |
||
35 | LEFT JOIN e.file f |
||
36 | GROUP BY e.user |
||
37 | ORDER BY compte DESC' |
||
38 | ) |
||
39 | ->setMaxResults(10) |
||
40 | ->getResult(); |
||
41 | |||
42 | // On regarde les détails sur chaque utilisateur |
||
43 | $downloaderCategories = []; |
||
44 | $downloaderSeries = [ |
||
45 | ['name' => 'Films', 'data' => []], |
||
46 | ['name' => 'Séries', 'data' => []], |
||
47 | ['name' => 'Jeux', 'data' => []], |
||
48 | ['name' => 'Logiciels', 'data' => []], |
||
49 | ['name' => 'Autres', 'data' => []] |
||
50 | ]; |
||
51 | |||
52 | foreach ($downloaderIds as $key => $value) { |
||
53 | $downloads = $this->ponthubFileUserRepository->findBy(['user' => $value[1]]); |
||
54 | |||
55 | $user = $downloads[0]->getUser(); |
||
56 | $downloaderCategories[] = $user->getFirstName().' '.$user->getLastName(); |
||
57 | for ($i = 0; $i < 6; $i++) { |
||
58 | $downloaderSeries[$i]['data'][] = 0; |
||
59 | } |
||
60 | |||
61 | foreach ($downloads as $download) { |
||
62 | $file = $download->getFile(); |
||
63 | $size = round($file->getSize()/(1000*1000*1000), 5); |
||
64 | |||
65 | if ($file instanceof Movie) { |
||
66 | $downloaderSeries[0]['data'][$key] += $size; |
||
67 | } |
||
68 | if ($file instanceof Episode) { |
||
69 | $downloaderSeries[1]['data'][$key] += $size; |
||
70 | } |
||
71 | if ($file instanceof Game) { |
||
72 | $downloaderSeries[3]['data'][$key] += $size; |
||
73 | } |
||
74 | if ($file instanceof Software) { |
||
75 | $downloaderSeries[4]['data'][$key] += $size; |
||
76 | } |
||
77 | if ($file instanceof Other) { |
||
78 | $downloaderSeries[5]['data'][$key] += $size; |
||
79 | } |
||
80 | } |
||
81 | } |
||
82 | |||
83 | return [ |
||
84 | 'categories' => $downloaderCategories, |
||
85 | 'series' => $downloaderSeries |
||
86 | ]; |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * Fichiers les plus téléchargés (avec drilldown) |
||
91 | * @return array |
||
92 | */ |
||
93 | public function getGlobalDownloads() |
||
94 | { |
||
95 | // Recherche des fichiers les plus téléchargés |
||
96 | $downloadSerie = [ |
||
97 | ['name' => 'Films', 'drilldown' => 1, 'y' => $this->getTotalDownloads('movie')], |
||
98 | ['name' => 'Séries', 'drilldown' => 2, 'y' => $this->getTotalDownloads('episode')], |
||
99 | ['name' => 'Jeux', 'drilldown' => 3, 'y' => $this->getTotalDownloads('game')], |
||
100 | ['name' => 'Logiciels', 'drilldown' => 4, 'y' => $this->getTotalDownloads('software')], |
||
101 | ['name' => 'Autres', 'drilldown' => 5, 'y' => $this->getTotalDownloads('other')] |
||
102 | ]; |
||
103 | |||
104 | // Tri par ordre des downloads totaux |
||
105 | $total = []; |
||
106 | foreach ($downloadSerie as $key => $row) { |
||
107 | $total[$key] = $row['y']; |
||
108 | } |
||
109 | array_multisort($total, SORT_DESC, $downloadSerie); |
||
110 | |||
111 | $downloadDrilldown = [ |
||
112 | ['name' => 'Films', 'id' => 1, 'data' => $this->getDownloads('movie')], |
||
113 | ['name' => 'Séries', 'id' => 2, 'data' => $this->getDownloads('episode')], |
||
114 | ['name' => 'Jeux', 'id' => 3, 'data' => $this->getDownloads('game')], |
||
115 | ['name' => 'Logiciels', 'id' => 4, 'data' => $this->getDownloads('software')], |
||
116 | ['name' => 'Autres', 'id' => 5, 'data' => $this->getDownloads('other')] |
||
117 | ]; |
||
118 | |||
119 | return [ |
||
120 | 'serie' => $downloadSerie, |
||
121 | 'drilldown' => $downloadDrilldown |
||
122 | ]; |
||
123 | } |
||
124 | |||
125 | /** |
||
126 | * Renvoie le nombre total de fichiers par catégorie |
||
127 | * @param string $category |
||
128 | * @return integer |
||
129 | */ |
||
130 | private function getTotalDownloads($category) { |
||
131 | $connection = $this->manager->getConnection(); |
||
132 | $statement = $connection->prepare('SELECT COUNT(*) AS compte FROM PonthubFileUser LEFT JOIN Likeable ON Likeable.id = PonthubFileUser.file_id WHERE Likeable.type = :category'); |
||
133 | $statement->bindValue('category', $category); |
||
134 | $statement->execute(); |
||
135 | $results = $statement->fetchAll(); |
||
136 | |||
137 | return (int)$results[0]['compte']; |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * Renvoie les fichiers les plus téléchargés pour une categorie |
||
142 | * @param string $category |
||
143 | * @return array |
||
144 | */ |
||
145 | private function getDownloads($category) { |
||
146 | $connection = $this->manager->getConnection(); |
||
147 | $statement = $connection->prepare('SELECT Likeable.name, COUNT(*) AS compte FROM PonthubFileUser LEFT JOIN Likeable ON Likeable.id = PonthubFileUser.file_id WHERE Likeable.type = :category GROUP BY PonthubFileUser.file_id ORDER BY compte DESC LIMIT 10'); |
||
148 | $statement->bindValue('category', $category); |
||
149 | $statement->execute(); |
||
150 | $results = $statement->fetchAll(); |
||
151 | |||
152 | $return = []; |
||
153 | foreach ($results as $result) { |
||
154 | $return[] = [$result['name'], (int)$result['compte']]; |
||
155 | } |
||
156 | return $return; |
||
157 | } |
||
158 | |||
159 | /** |
||
160 | * Répartition des fichiers dans tous le catalogue |
||
161 | * @return array |
||
162 | */ |
||
163 | public function getGlobalPonthub() |
||
164 | { |
||
165 | // Construction de la tree map résumant les fichiers dispos sur Ponthub |
||
166 | return [ |
||
167 | 'Nombre de fichiers dispos' => [ |
||
168 | 'Films' => $this->getTotal('Movie'), |
||
169 | 'Séries' => $this->getTotal('Episode'), |
||
170 | 'Jeux' => $this->getTotal('Game'), |
||
171 | 'Logiciels' => $this->getTotal('Software'), |
||
172 | 'Autres' => $this->getTotal('Other') |
||
173 | ], |
||
174 | 'Volume de fichiers (Go)' => [ |
||
175 | 'Films' => $this->getTotal('Movie', true), |
||
176 | 'Séries' => $this->getTotal('Episode', true), |
||
177 | 'Jeux' => $this->getTotal('Game', true), |
||
178 | 'Logiciels' => $this->getTotal('Software', true), |
||
179 | 'Autres' => $this->getTotal('Other', true) |
||
180 | ] |
||
181 | ]; |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * Retourne un total selon une catégorie de fichiers |
||
186 | * @param string $category |
||
187 | * @param boolean $size Si true, renvoie la taille totale, sinon le nombre total |
||
188 | * @return integer |
||
189 | */ |
||
190 | private function getTotal($category, $size = false) { |
||
191 | if ($size) { |
||
192 | $dql = 'SELECT SUM(e.size) FROM KI\PonthubBundle\Entity\\'.$category.' e'; |
||
0 ignored issues
–
show
'SELECT SUM(e.size) FROM...y\\' . $category . ' e' is used as a query on line 193. If $category can contain user-input, it is usually preferable to use a parameter placeholder like :paramName and pass the dynamic input via setParameter .
If you want to query a table by some specific user-input, instead of manually building the DQL, it is recommended to use parameter binding instead: function getUserByEmail(EntityManager $em. $email) {
return $em->createQuery("SELECT u FROM User u WHERE u.email = :email")
->setParameter('email', $email)
->getSingleResult();
}
![]() |
|||
193 | return $this->manager->createQuery($dql)->getSingleScalarResult()/(1000*1000*1000); |
||
194 | } else { |
||
195 | $dql = 'SELECT COUNT(e.id) FROM KI\PonthubBundle\Entity\\'.$category.' e'; |
||
0 ignored issues
–
show
'SELECT COUNT(e.id) FROM...y\\' . $category . ' e' is used as a query on line 196. If $category can contain user-input, it is usually preferable to use a parameter placeholder like :paramName and pass the dynamic input via setParameter .
If you want to query a table by some specific user-input, instead of manually building the DQL, it is recommended to use parameter binding instead: function getUserByEmail(EntityManager $em. $email) {
return $em->createQuery("SELECT u FROM User u WHERE u.email = :email")
->setParameter('email', $email)
->getSingleResult();
}
![]() |
|||
196 | return $this->manager->createQuery($dql)->getSingleScalarResult(); |
||
197 | } |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Histo en barres horizontales de répartition par années |
||
202 | * @return array |
||
203 | */ |
||
204 | public function getGlobalYears() |
||
205 | { |
||
206 | // Construction de l'arbre des années des films/jeux dispos |
||
207 | $dql = 'SELECT e.year, COUNT(e.id) FROM KI\PonthubBundle\Entity\Movie e GROUP BY e.year'; |
||
208 | $movieYears = $this->manager->createQuery($dql)->getResult(); |
||
209 | $dql = 'SELECT e.year, COUNT(e.id) FROM KI\PonthubBundle\Entity\Game e GROUP BY e.year'; |
||
210 | $gameYears = $this->manager->createQuery($dql)->getResult(); |
||
211 | |||
212 | $yearCategories = []; |
||
213 | $yearSeries = [ |
||
214 | ['name' => 'Films', 'data' => []], |
||
215 | ['name' => 'Jeux', 'data' => []] |
||
216 | ]; |
||
217 | |||
218 | // On rajoute l'année dans les catégories si elle n'y est pas déjà |
||
219 | View Code Duplication | foreach ($movieYears as $key => $value) { |
|
220 | if (!in_array((int)$value['year'], $yearCategories)) { |
||
221 | $yearCategories[] = $value['year']; |
||
222 | $yearSeries[0]['data'][] = 0; |
||
223 | $yearSeries[1]['data'][] = 0; |
||
224 | } |
||
225 | } |
||
226 | View Code Duplication | foreach ($gameYears as $key => $value) { |
|
227 | if (!in_array((int)$value['year'], $yearCategories)) { |
||
228 | $yearCategories[] = $value['year']; |
||
229 | $yearSeries[0]['data'][] = 0; |
||
230 | $yearSeries[1]['data'][] = 0; |
||
231 | } |
||
232 | } |
||
233 | |||
234 | // On ordonne les années |
||
235 | sort($yearCategories); |
||
236 | |||
237 | // On répartit les entrées |
||
238 | $maxPopMovie = 0; |
||
239 | $maxPopGame = 0; |
||
240 | View Code Duplication | foreach ($movieYears as $key => $value) { |
|
241 | $id = array_search((int)$value['year'], $yearCategories); |
||
242 | $yearSeries[0]['data'][$id] = -$value[1]; |
||
243 | |||
244 | if ($value[1] > $maxPopMovie) |
||
245 | $maxPopMovie = (int)$value[1]; |
||
246 | } |
||
247 | View Code Duplication | foreach ($gameYears as $key => $value) { |
|
248 | $id = array_search((int)$value['year'], $yearCategories); |
||
249 | $yearSeries[1]['data'][$id] = (int)$value[1]; |
||
250 | |||
251 | if ($value[1] > $maxPopGame) |
||
252 | $maxPopGame = (int)$value[1]; |
||
253 | } |
||
254 | |||
255 | return [ |
||
256 | 'categories' => $yearCategories, |
||
257 | 'series' => $yearSeries, |
||
258 | 'min' => -$maxPopMovie, |
||
259 | 'max' => $maxPopGame |
||
260 | ]; |
||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Timeline avec camembert par promo et moyenne |
||
265 | * @return array |
||
266 | */ |
||
267 | public function getGlobalTimeline() |
||
268 | { |
||
269 | // Timeline répartition par promos par mois |
||
270 | $dql = 'SELECT u.promo, MONTH(e.date) AS mois, SUM(f.size) AS taille |
||
271 | FROM KI\PonthubBundle\Entity\PonthubFileUser e |
||
272 | LEFT JOIN e.file f LEFT JOIN e.user u |
||
273 | WHERE u.promo = \'016\' OR u.promo = \'017\' OR u.promo = \'018\' OR u.promo = \'019\' |
||
274 | GROUP BY mois, u.promo'; |
||
275 | $results = $this->manager->createQuery($dql)->getResult(); |
||
276 | |||
277 | $timeline = [ |
||
278 | 'promo016' => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
||
279 | 'promo017' => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
||
280 | 'promo018' => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
||
281 | 'promo019' => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
||
282 | 'average' => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], |
||
283 | 'pie' => [ |
||
284 | 'promo016' => 0, |
||
285 | 'promo017' => 0, |
||
286 | 'promo018' => 0, |
||
287 | 'promo019' => 0, |
||
288 | ] |
||
289 | ]; |
||
290 | // On répartit les données dans les tableaux suivants |
||
291 | foreach ($results as $result) { |
||
292 | $size = round($result['taille']/(1000*1000*1000), 1); |
||
293 | $timeline['promo'.$result['promo']][$result['mois'] - 1] += $size; |
||
294 | $timeline['pie']['promo'.$result['promo']] += $size; |
||
295 | } |
||
296 | // On calcule les moyennes |
||
297 | for ($i = 0; $i < 12; $i++) { |
||
298 | $timeline['average'][$i] = round(($timeline['promo016'][$i] + $timeline['promo017'][$i] + $timeline['promo018'][$i] + $timeline['promo019'][$i])/4, 1); |
||
299 | } |
||
300 | return $timeline; |
||
301 | } |
||
302 | } |
||
303 |
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.