|
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) |
|
|
|
|
|
|
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'; |
|
|
|
|
|
|
193
|
|
|
return $this->manager->createQuery($dql)->getSingleScalarResult()/(1000*1000*1000); |
|
194
|
|
|
} else { |
|
195
|
|
|
$dql = 'SELECT COUNT(e.id) FROM KI\PonthubBundle\Entity\\'.$category.' e'; |
|
|
|
|
|
|
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
EntityManagermight 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
EntityManageris closed. Any other code which depends on the same instance of theEntityManagerduring 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.