Commit a5d404c2b9743fcd541561a591ff7d35f7498736
1 parent
828525a8
Exists in
master
and in
1 other branch
Grosse refactorisation et simplification de la logique des stats
(UsersController => StatsTable) v4.106.6-3.7.9
Showing
8 changed files
with
185 additions
and
183 deletions
Show diff stats
CHANGES.txt
... | ... | @@ -134,6 +134,10 @@ Outre ces changements, voici d'autres changements importants : |
134 | 134 | ======= CHANGES ======= |
135 | 135 | |
136 | 136 | ------- |
137 | +24/10/2020 v4.106.6-3.7.9 | |
138 | + - (i) Grosse refactorisation et simplification de la logique des stats (UsersController => StatsTable) | |
139 | + | |
140 | +------- | |
137 | 141 | 23/10/2020 v4.106.5-3.7.9 |
138 | 142 | - (b) Bugfix tests (ajout Stats en fixture) |
139 | 143 | - (e) Ajout d'un champs "description" à toutes les tables qui en manquent | ... | ... |
README.md
... | ... | @@ -42,8 +42,8 @@ Logiciel testé et validé sur les configurations suivantes : |
42 | 42 | |
43 | 43 | -------------------------------------------------------------------------------------------- |
44 | 44 | |
45 | -Date: 23/10/2020 | |
46 | -Version: 4.106.5-3.7.9 | |
45 | +Date: 24/10/2020 | |
46 | +Version: 4.106.6-3.7.9 | |
47 | 47 | |
48 | 48 | |
49 | 49 | HISTORIQUE DES CHANGEMENTS DE VERSION : voir le fichier CHANGES.txt (ou la page web /pages/changes) | ... | ... |
src/Controller/StatsController.php
... | ... | @@ -98,8 +98,10 @@ class StatsController extends AppController |
98 | 98 | * @return \Cake\Http\Response|null Redirects to index. |
99 | 99 | * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. |
100 | 100 | */ |
101 | - public function delete($id = null) | |
101 | + public function delete($year=null,$user_id=null) | |
102 | + //public function delete($id = null) | |
102 | 103 | { |
104 | + $id = [$year,$user_id]; | |
103 | 105 | $this->request->allowMethod(['post', 'delete']); |
104 | 106 | $stat = $this->Stats->get($id); |
105 | 107 | if ($this->Stats->delete($stat)) { | ... | ... |
src/Controller/UsersController.php
... | ... | @@ -208,7 +208,8 @@ class UsersController extends AppController |
208 | 208 | ] |
209 | 209 | */ |
210 | 210 | |
211 | - $this->_updateStatsForCurrentUserOnLogin(); | |
211 | + $this->statsUpdateForCurrentUserWhen(null, 'sur login'); | |
212 | + //$this->statsUpdateForCurrentUserOnLogin(); | |
212 | 213 | //exit; |
213 | 214 | |
214 | 215 | // On va maintenant à la page qui etait demandée |
... | ... | @@ -223,7 +224,8 @@ class UsersController extends AppController |
223 | 224 | public function logout() { |
224 | 225 | //debug("LOGOUT !"); |
225 | 226 | //debug($this->u); |
226 | - $this->_updateStatsForCurrentUserOnLogout(); | |
227 | + $this->statsUpdateForCurrentUserWhen(null,'sur logout'); | |
228 | + //$this->statsUpdateForCurrentUserOnLogout(); | |
227 | 229 | //$this->Flash->success('You are now logged out.'); |
228 | 230 | return $this->redirect($this->LdapAuth->logout()); |
229 | 231 | // Puis ça va sur /users/login |
... | ... | @@ -270,183 +272,15 @@ class UsersController extends AppController |
270 | 272 | } |
271 | 273 | |
272 | 274 | |
273 | - /* | |
274 | - * Mise à jour des stats pour ce user (et pour l'année courante) au moment du login | |
275 | - * => on enregistre son heure de connexion | |
276 | - * => on incrémente le nombre de connexions | |
277 | - */ | |
278 | - public function _updateStatsForCurrentUserOnLogin($user_infos = null) { | |
279 | - | |
280 | - $user_id = $this->_getCurrentUserEntityFromSession($user_infos)->id; | |
281 | - //debug($user); | |
282 | - | |
283 | - $now = new FrozenTime(); | |
284 | - //debug($last_login_time); | |
285 | - $year = $now->format('yy'); | |
286 | - //debug($year); | |
287 | - | |
288 | - // On recup la Stat du user courant | |
289 | - $table_stats = $this->Users->Stats; | |
290 | - $stat_id = [$year,$user_id]; | |
291 | - $current_user_stat = null; | |
292 | - try { | |
293 | - // Si un enregistrement existe pour ce user (et cette année) => on le récupère | |
294 | - $current_user_stat = $table_stats->get($stat_id); | |
295 | - //debug("exists"); | |
296 | - //$current_user_stat->last_logout_time = null; | |
297 | - } catch (\Cake\Datasource\Exception\RecordNotFoundException $e) { | |
298 | - //echo 'Exception reçue : ', $e->getMessage(), "\n"; | |
299 | - // Pas d'enregistrement pour ce user (et cette année) => on le crée | |
300 | - //debug("new"); | |
301 | - /* | |
302 | - $stat = [ | |
303 | - //['year','user_id'] => [$year,$user->id], | |
304 | - //'(year,user_id)' => [$year,$user->id], | |
305 | - 'year' => $year, | |
306 | - 'user_id' => $user->id, | |
307 | - 'last_login_time' => $last_login_time, | |
308 | - ]; | |
309 | - debug($stat); | |
310 | - */ | |
311 | - //$stat_entity = $table_stats->newEntity($stat); | |
312 | - $current_user_stat = $table_stats->newEntity(); | |
313 | - $current_user_stat->year = $year; | |
314 | - $current_user_stat->user_id = $user_id; | |
315 | - } | |
316 | - $last_login_time = $current_user_stat->last_login_time; | |
317 | - $last_logout_time = $current_user_stat->last_logout_time; | |
318 | - | |
319 | - /* | |
320 | - * Check le cas où le logout n'a pas été enregistré | |
321 | - * (le user n'a pas fait logout, ça s'est fait tout seul par timeout) | |
322 | - * => Dans ce cas, on ajoute à la durée totale le dernier temps de connexion last_connex_dur | |
323 | - */ | |
324 | - if ($last_logout_time < $last_login_time) { | |
325 | - $last_connex_dur = $current_user_stat->last_connex_dur; | |
326 | - /* | |
327 | - * (Optimisation): Si la dernière session a été très courte (<10s), on ne le comptabilise pas | |
328 | - * => on décrémente le nb de connexions (passées) | |
329 | - */ | |
330 | - if ($current_user_stat->connex_nb>0 && $last_connex_dur<10) | |
331 | - $current_user_stat->connex_nb--; | |
332 | - else | |
333 | - $current_user_stat->connex_dur_tot += $last_connex_dur; | |
334 | - } | |
335 | - | |
336 | - // On met à jour le champs last_login_time, RAZ last_connex_dur, et incrémente le nb de connexions | |
337 | - $current_user_stat->last_login_time = $now; | |
338 | - $current_user_stat->last_connex_dur = 0; | |
339 | - // et 1 NOUVELLE connexion de plus, 1 ! | |
340 | - $current_user_stat->connex_nb++; | |
341 | - //debug($current_user_stat); | |
342 | - // On sauvegarde en table | |
343 | - if (! $table_stats->save($current_user_stat)) { | |
344 | - echo "Impossible de sauvegarder une stat sur login !"; | |
345 | - debug($current_user_stat->getErrors()); | |
346 | - debug($current_user_stat); | |
347 | - exit; | |
348 | - } | |
349 | - /* | |
350 | - $query = $table_stats->findById($stat_id); | |
351 | - if ($query->isEmpty()) { | |
352 | - debug("no"); | |
353 | - // record doesn't exist | |
354 | - } | |
355 | - else { | |
356 | - debug("yes"); | |
357 | - } | |
358 | - */ | |
359 | - } // _updateStatsForCurrentUserOnLogin() | |
360 | - | |
361 | 275 | /* |
362 | - * Mise à jour des stats pour ce user (et pour l'année courante) durant la session, à chaque action | |
363 | - * => on met à jour son temps de connexion | |
276 | + * Mise à jour des stats pour le user courant ($user_infos) (et pour l'année courante) | |
277 | + * au moment de l'événement $event_name | |
364 | 278 | */ |
365 | - public function updateStatsForCurrentUserDuringSession($session_user = null) { | |
366 | - | |
367 | - //debug("ici"); | |
368 | - //exit; | |
369 | - // Current user | |
370 | - //$user_id = $this->u->id; | |
371 | - //debug($session_user); | |
372 | - $user_id = $this->_getCurrentUserEntityFromSession($session_user)->id; | |
373 | - //debug($user_id); | |
374 | - | |
375 | - // On récupère la Stat de ce user | |
376 | - $now = new FrozenTime(); | |
377 | - //debug($last_login_time); | |
378 | - $year = $now->format('yy'); | |
379 | - //debug($year); | |
380 | - $table_stats = $this->Users->Stats; | |
381 | - $stat_id = [$year,$user_id]; | |
382 | - //debug($stat_id); | |
383 | - $current_user_stat = $table_stats->get($stat_id); | |
384 | - | |
385 | - // On met à jour le temps de connexion | |
386 | - $connex_duration = $now->diff($current_user_stat->last_login_time); | |
387 | - //debug($connex_duration); | |
388 | - //exit; | |
389 | - $current_user_stat->last_connex_dur = $connex_duration->h*3600 + $connex_duration->i*60 + $connex_duration->s; | |
390 | - //debug($current_user_stat->last_connex_dur); | |
391 | - | |
392 | - // On sauvegarde en table | |
393 | - if (! $table_stats->save($current_user_stat)) { | |
394 | - echo "Impossible de sauvegarder une stat durant la session !"; | |
395 | - debug($current_user_stat->getErrors()); | |
396 | - debug($current_user_stat); | |
397 | - exit; | |
398 | - } | |
399 | - | |
400 | - } // updateStatsForCurrentUserDuringSession() | |
401 | - | |
402 | - /* | |
403 | - * Mise à jour des stats pour ce user (et pour l'année courante) au moment du logout | |
404 | - * => on enregistre son heure de dé-connexion | |
405 | - * => on calcule son temps de connexion et on l'ajoute au champ qui totalise le temps de connexion : connex_dur_tot | |
406 | - */ | |
407 | - private function _updateStatsForCurrentUserOnLogout() { | |
408 | - | |
409 | - // Current user | |
410 | - $user_id = $this->u->id; | |
411 | - | |
412 | - $last_logout_time = new FrozenTime(); | |
413 | - //debug($last_login_time); | |
414 | - $year = $last_logout_time->format('yy'); | |
415 | - //debug($year); | |
416 | - | |
417 | - // On récup la stat de ce user (pour cette année) | |
418 | - // Normalement, elle doit exister puisque il y a déjà eu login ! | |
419 | - // TODO: Cas particulier où le login se fait le 31 décembre, et le logout l'année suivante => BUG !!! | |
420 | - $table_stats = $this->Users->Stats; | |
421 | - $stat_id = [$year,$user_id]; | |
422 | - $current_user_stat = $table_stats->get($stat_id); | |
423 | - $last_login_time = $current_user_stat->last_login_time; | |
424 | - | |
425 | - // 1) On met à jour le champ last_logout_time | |
426 | - $current_user_stat->last_logout_time = $last_logout_time; | |
427 | - | |
428 | - // 2) On met à jour le temps de connexion total (cumulé) | |
429 | - // - on calcule le temps de connexion | |
430 | - $connex_duration = $last_logout_time->diff($last_login_time); | |
431 | - $connex_duration = $connex_duration->h*3600 + $connex_duration->i*60 + $connex_duration->s; | |
432 | - //debug($last_login_time); | |
433 | - //debug($last_logout_time); | |
434 | - //debug($connex_dur_totation); | |
435 | - // - on cumule ce temps au temps total | |
436 | - //debug($current_user_stat->connex_dur_tot); | |
437 | - //debug($connex_dur_totation); | |
438 | - $current_user_stat->connex_dur_tot += $connex_duration; | |
439 | - //debug($current_user_stat->connex_dur_tot); | |
440 | - | |
441 | - // On sauvegarde en table | |
442 | - if (! $table_stats->save($current_user_stat)) { | |
443 | - echo "Impossible de sauvegarder une stat sur logout !"; | |
444 | - debug($current_user_stat->getErrors()); | |
445 | - debug($current_user_stat); | |
446 | - exit; | |
447 | - } | |
448 | - } // _updateStatsForCurrentUserOnLogout() | |
449 | - | |
279 | + public function statsUpdateForCurrentUserWhen($session_user=null, $event_name) { | |
280 | + $user_id = ($event_name=='sur logout') ? $this->u->id : $this->_getCurrentUserEntityFromSession($session_user)->id; | |
281 | + //debug($user); | |
282 | + $this->Users->Stats->updateForUserWhen($user_id, $event_name); | |
283 | + } | |
450 | 284 | |
451 | 285 | |
452 | 286 | /** | ... | ... |
src/Model/Table/StatsTable.php
... | ... | @@ -5,6 +5,7 @@ use Cake\ORM\Query; |
5 | 5 | use Cake\ORM\RulesChecker; |
6 | 6 | use Cake\ORM\Table; |
7 | 7 | use Cake\Validation\Validator; |
8 | +use Cake\I18n\FrozenTime; | |
8 | 9 | |
9 | 10 | /** |
10 | 11 | * Stats Model |
... | ... | @@ -96,4 +97,147 @@ class StatsTable extends Table |
96 | 97 | |
97 | 98 | return $rules; |
98 | 99 | } |
100 | + | |
101 | + | |
102 | + private function getEntityForUser($user_id, $now) { | |
103 | + //$now = new FrozenTime(); | |
104 | + //debug($last_login_time); | |
105 | + $year = $now->format('yy'); | |
106 | + //debug($year); | |
107 | + | |
108 | + // On recup la Stat du user courant | |
109 | + //$table_stats = $this->Users->Stats; | |
110 | + $table_stats = $this; | |
111 | + $stat_id = [$year,$user_id]; | |
112 | + $current_user_stat = null; | |
113 | + try { | |
114 | + // Si un enregistrement existe pour ce user (et cette année) => on le récupère | |
115 | + $current_user_stat = $table_stats->get($stat_id); | |
116 | + //debug("exists"); | |
117 | + //$current_user_stat->last_logout_time = null; | |
118 | + } catch (\Cake\Datasource\Exception\RecordNotFoundException $e) { | |
119 | + //echo 'Exception reçue : ', $e->getMessage(), "\n"; | |
120 | + // Pas d'enregistrement pour ce user (et cette année) => on le crée | |
121 | + //debug("new"); | |
122 | + /* | |
123 | + $stat = [ | |
124 | + //['year','user_id'] => [$year,$user->id], | |
125 | + //'(year,user_id)' => [$year,$user->id], | |
126 | + 'year' => $year, | |
127 | + 'user_id' => $user->id, | |
128 | + 'last_login_time' => $last_login_time, | |
129 | + ]; | |
130 | + debug($stat); | |
131 | + */ | |
132 | + //$stat_entity = $table_stats->newEntity($stat); | |
133 | + $current_user_stat = $table_stats->newEntity(); | |
134 | + $current_user_stat->year = $year; | |
135 | + $current_user_stat->user_id = $user_id; | |
136 | + } | |
137 | + return $current_user_stat; | |
138 | + } | |
139 | + | |
140 | + private function saveStat($stat, $event_name) { | |
141 | + if (! $this->save($stat)) { | |
142 | + echo "Impossible de sauvegarder une stat $event_name !"; | |
143 | + debug($stat->getErrors()); | |
144 | + debug($stat); | |
145 | + exit; | |
146 | + } | |
147 | + } | |
148 | + | |
149 | + /* | |
150 | + * Mise à jour des stats pour le user courant (et pour l'année courante) | |
151 | + * au moment de l'événement $event_name qui peut être de 3 types : | |
152 | + * - 'sur login' | |
153 | + * - 'durant la session' | |
154 | + * - 'sur logout' | |
155 | + */ | |
156 | + public function updateForUserWhen($user_id, $event_name) { | |
157 | + | |
158 | + // 1) Get (or create) stat for user $user_id | |
159 | + $now = new FrozenTime(); | |
160 | + $current_user_stat = $this->getEntityForUser($user_id, $now); | |
161 | + | |
162 | + // 2) TT selon event $event_name | |
163 | + | |
164 | + /* | |
165 | + * - au LOGIN ( == 'sur login') | |
166 | + * | |
167 | + * => on enregistre son heure de connexion | |
168 | + * => on incrémente le nombre de connexions | |
169 | + * | |
170 | + */ | |
171 | + if ($event_name == 'sur login') { | |
172 | + $last_login_time = $current_user_stat->last_login_time; | |
173 | + $last_logout_time = $current_user_stat->last_logout_time; | |
174 | + /* | |
175 | + * Check le cas où le logout n'a pas été enregistré | |
176 | + * (le user n'a pas fait logout, ça s'est fait tout seul par timeout) | |
177 | + * => Dans ce cas, on ajoute à la durée totale le dernier temps de connexion last_connex_dur | |
178 | + */ | |
179 | + if ($last_logout_time < $last_login_time) { | |
180 | + $last_connex_dur = $current_user_stat->last_connex_dur; | |
181 | + /* | |
182 | + * (Optimisation): Si la dernière session a été très courte (<20s), on ne le comptabilise pas | |
183 | + * => on décrémente le nb de connexions (passées) | |
184 | + */ | |
185 | + if ($current_user_stat->connex_nb>0 && $last_connex_dur<20) | |
186 | + $current_user_stat->connex_nb--; | |
187 | + else | |
188 | + $current_user_stat->connex_dur_tot += $last_connex_dur; | |
189 | + } | |
190 | + // On met à jour le champs last_login_time, RAZ last_connex_dur, et incrémente le nb de connexions | |
191 | + $current_user_stat->last_login_time = $now; | |
192 | + $current_user_stat->last_connex_dur = 0; | |
193 | + // et 1 NOUVELLE connexion de plus, 1 ! | |
194 | + $current_user_stat->connex_nb++; | |
195 | + } | |
196 | + | |
197 | + /* | |
198 | + * - PENDANT la session (à chaque action) ( == 'durant la session') | |
199 | + * | |
200 | + * => on met à jour son temps de connexion | |
201 | + * | |
202 | + */ | |
203 | + elseif ($event_name == 'durant la session') { | |
204 | + // On met à jour le temps de connexion | |
205 | + $connex_duration = $now->diff($current_user_stat->last_login_time); | |
206 | + //debug($connex_duration); | |
207 | + //exit; | |
208 | + $current_user_stat->last_connex_dur = $connex_duration->h*3600 + $connex_duration->i*60 + $connex_duration->s; | |
209 | + //debug($current_user_stat->last_connex_dur); | |
210 | + } | |
211 | + | |
212 | + /* | |
213 | + * - au LOGOUT ( == 'sur logout') | |
214 | + * | |
215 | + * => on enregistre son heure de dé-connexion | |
216 | + * => on calcule son temps de connexion et on l'ajoute au champ qui totalise le temps de connexion : connex_dur_tot | |
217 | + * | |
218 | + */ | |
219 | + else { | |
220 | + $last_login_time = $current_user_stat->last_login_time; | |
221 | + // 1) On met à jour le champ last_logout_time | |
222 | + $current_user_stat->last_logout_time = $now; | |
223 | + // 2) On met à jour le temps de connexion total (cumulé) | |
224 | + // - on calcule le temps de connexion | |
225 | + $connex_duration = $now->diff($last_login_time); | |
226 | + $connex_duration = $connex_duration->h*3600 + $connex_duration->i*60 + $connex_duration->s; | |
227 | + //debug($last_login_time); | |
228 | + //debug($last_logout_time); | |
229 | + //debug($connex_dur_totation); | |
230 | + // - on cumule ce temps au temps total | |
231 | + //debug($current_user_stat->connex_dur_tot); | |
232 | + //debug($connex_dur_totation); | |
233 | + $current_user_stat->connex_dur_tot += $connex_duration; | |
234 | + //debug($current_user_stat->connex_dur_tot); | |
235 | + } | |
236 | + | |
237 | + // 3) On sauvegarde en table | |
238 | + $this->saveStat($current_user_stat, $event_name); | |
239 | + | |
240 | + } // updateForUserWhen() | |
241 | + | |
242 | + | |
99 | 243 | } | ... | ... |
src/Routing/Filter/SessionTimeoutFilter.php
... | ... | @@ -34,8 +34,9 @@ class SessionTimeoutFilter extends DispatcherFilter |
34 | 34 | //debug("iciii2"); |
35 | 35 | |
36 | 36 | // Sinon, on met à jour les stats de connexion |
37 | + (new UsersController())->statsUpdateForCurrentUserWhen($session_user, 'durant la session'); | |
38 | + //(new UsersController())->statsUpdateForCurrentUserDuringSession($session_user); | |
37 | 39 | //(new UsersController())->updateStatsForCurrentUserDuringSession(); |
38 | - (new UsersController())->updateStatsForCurrentUserDuringSession($session_user); | |
39 | 40 | //exit; |
40 | 41 | |
41 | 42 | ... | ... |
src/Template/Stats/index.ctp
... | ... | @@ -20,17 +20,34 @@ function getHourMnSecForDuration($duration_sec) { |
20 | 20 | } |
21 | 21 | |
22 | 22 | |
23 | -echo "<b>Temps de connexion moyen (sur tous les utilisateurs et toutes les années) : </b>"; | |
23 | +// Moyenne générale pour le nombre de connexions et le temps de connexion | |
24 | + | |
24 | 25 | $connex_nb_tot = 0; |
25 | 26 | $connex_dur_tot_tot = 0; |
26 | 27 | foreach ($stats as $stat) { |
27 | 28 | $connex_nb_tot += $stat->connex_nb; |
28 | 29 | $connex_dur_tot_tot += $stat->connex_dur_tot; |
29 | 30 | } |
31 | +$connex_nb_year_avg = $connex_nb_tot / $stats->count(); | |
30 | 32 | $connex_dur_tot_avg = round($connex_dur_tot_tot / $connex_nb_tot); |
31 | 33 | //$connex_dur_tot_avg = intdiv($connex_dur_tot_tot , $connex_nb_tot); |
32 | 34 | //echo $connex_dur_tot_avg; |
33 | 35 | list($h,$m,$s) = getHourMnSecForDuration($connex_dur_tot_avg); |
36 | + | |
37 | +//TODO: corriger ce calcul qui est faux (il faut ramener au nombre de mois effectifs de toutes les années incomplètes, assez compliqué...) | |
38 | +echo '<br>'; | |
39 | +echo "<b>Nombre moyen de connexions d'un utilisateur par an (sur tous les utilisateurs et toutes les années) (approximatif si années incomplètes) : </b>"; | |
40 | +echo round($connex_nb_year_avg, 0); | |
41 | + | |
42 | +//TODO: corriger ce calcul qui est faux (il faut ramener au nombre de mois effectifs de toutes les années incomplètes, assez compliqué...) | |
43 | +/* | |
44 | +echo '<br>'; | |
45 | +echo "<b>Nombre moyen de connexions d'un utilisateur par mois (sur tous les utilisateurs et toutes les années) : </b>"; | |
46 | +echo round($connex_nb_year_avg/12, 1); | |
47 | +*/ | |
48 | + | |
49 | +echo '<br>'; | |
50 | +echo "<b>Temps de connexion moyen d'un utilisateur (sur tous les utilisateurs et toutes les années) : </b>"; | |
34 | 51 | echo "$h h $m mn $s sec"; |
35 | 52 | echo "<br>";echo "<br>"; |
36 | 53 | ... | ... |
tests/TestCase/Controller/General.php
... | ... | @@ -443,7 +443,7 @@ class General extends TestCase { |
443 | 443 | ]; |
444 | 444 | $this->session($authType); |
445 | 445 | //$this->request->getSession()->write($authType); |
446 | - (new UsersController())->_updateStatsForCurrentUserOnLogin($user['Auth']['User']); | |
446 | + (new UsersController())->statsUpdateForCurrentUserOnLogin($user['Auth']['User']); | |
447 | 447 | |
448 | 448 | |
449 | 449 | } | ... | ... |