[SPIP] v3.2.1-->v3.2.3
[lhc/web/www.git] / www / plugins-dist / statistiques / genie / popularites.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2019 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 /**
14 * Gestion du calcul des popularités (cron)
15 *
16 * @plugin Statistiques pour SPIP
17 * @license GNU/GPL
18 * @package SPIP\Statistiques\Genie
19 **/
20
21 if (!defined("_ECRIRE_INC_VERSION")) {
22 return;
23 }
24
25
26 /**
27 * Calcule des coefficients de popularité en fonction de l'intervalle
28 * écoulé depuis le précédent calcul
29 *
30 * Popularite, modele logarithmique
31 *
32 * @param int $duree Intervalle écoulé depuis le précédent calcul
33 * @return array {
34 * @type float $a Coefficient d'amortissement
35 * @type float $b Constante multiplicative
36 * }
37 **/
38 function genie_popularite_constantes($duree) {
39 // duree de demi-vie d'une visite dans le calcul de la popularite (en jours)
40 $demivie = 0.5;
41 // periode de reference en jours
42 $periode = 1;
43 // $a est le coefficient d'amortissement depuis la derniere mesure
44 $a = pow(2, -$duree / ($demivie * 24 * 3600));
45 // $b est la constante multiplicative permettant d'avoir
46 // une visite par jour (periode de reference) = un point de popularite
47 // (en regime stationnaire)
48 // or, magie des maths, ca vaut log(2) * duree journee/demi-vie
49 // si la demi-vie n'est pas trop proche de la seconde ;)
50 $b = log(2) * $periode / $demivie;
51
52 return array($a, $b);
53 }
54
55 /**
56 * Cron de calcul des popularités des articles
57 *
58 * @uses genie_popularite_constantes()
59 *
60 * @param int $t
61 * Timestamp de la dernière exécution de cette tâche
62 * @return int
63 * Positif si la tâche a été terminée, négatif pour réexécuter cette tâche
64 **/
65 function genie_popularites_dist($t) {
66
67 // Si c'est le premier appel, ne pas calculer
68 $t = $GLOBALS['meta']['date_popularites'];
69 ecrire_meta('date_popularites', time());
70
71 if (!$t) {
72 return 1;
73 }
74
75 $duree = time() - $t;
76 list($a, $b) = genie_popularite_constantes($duree);
77
78 // du passe, faisons table (SQL) rase
79 sql_update('spip_articles', array('maj' => 'maj', 'popularite' => "popularite * $a"), 'popularite>1');
80
81 // enregistrer les metas...
82 $row = sql_fetsel('MAX(popularite) AS max, SUM(popularite) AS tot', "spip_articles");
83 ecrire_meta("popularite_max", $row['max']);
84 ecrire_meta("popularite_total", $row['tot']);
85
86
87 // Une fois par jour purger les referers du jour ; qui deviennent
88 // donc ceux de la veille ; au passage on stocke une date_statistiques
89 // dans spip_meta - cela permet au code d'etre "reentrant", ie ce cron
90 // peut etre appele par deux bases SPIP ne partageant pas le meme
91 // _DIR_TMP, sans tout casser...
92
93 $aujourdhui = date("Y-m-d");
94 if (($d = $GLOBALS['meta']['date_statistiques']) != $aujourdhui) {
95 spip_log("Popularite: purger referer depuis $d");
96 ecrire_meta('date_statistiques', $aujourdhui);
97 if (strncmp($GLOBALS['connexions'][0]['type'], 'sqlite', 6) == 0) {
98 spip_query("UPDATE spip_referers SET visites_veille=visites_jour, visites_jour=0");
99 } else
100 // version 3 fois plus rapide, mais en 2 requetes
101 #spip_query("ALTER TABLE spip_referers CHANGE visites_jour visites_veille INT( 10 ) UNSIGNED NOT NULL DEFAULT '0',CHANGE visites_veille visites_jour INT( 10 ) UNSIGNED NOT NULL DEFAULT '0'");
102 #spip_query("UPDATE spip_referers SET visites_jour=0");
103 // version 4 fois plus rapide que la premiere, en une seule requete
104 // ATTENTION : peut poser probleme cf https://core.spip.net/issues/2505
105 {
106 sql_alter("TABLE spip_referers DROP visites_veille,
107 CHANGE visites_jour visites_veille INT(10) UNSIGNED NOT NULL DEFAULT '0',
108 ADD visites_jour INT(10) UNSIGNED NOT NULL DEFAULT '0'");
109 }
110 }
111
112 // et c'est fini pour cette fois-ci
113 return 1;
114
115 }