source: spip-zone/_plugins_/stats_data/stats_data_fonctions.php @ 109316

Last change on this file since 109316 was 109316, checked in by booz@…, 16 months ago

séparer les moteurs de recherche, les réseaux sociaux, les recherches internes

File size: 10.0 KB
Line 
1<?php
2
3include_spip('genie/popularites'); // ?
4function genie_popularites($t) {
5
6        // Si c'est le premier appel, ne pas calculer
7        $t = $GLOBALS['meta']['date_popularites'];
8        ecrire_meta('date_popularites', time());
9
10        if (!$t) {
11                return 1;
12        }
13
14        $duree = time() - $t;
15        list($a, $b) = genie_popularite_constantes($duree);
16
17        // du passe, faisons table (SQL) rase
18        sql_update('spip_articles', array('maj' => 'maj', 'popularite' => "popularite * $a"), 'popularite>1');
19
20        // enregistrer les metas...
21        $row = sql_fetsel('MAX(popularite) AS max, SUM(popularite) AS tot', "spip_articles");
22        ecrire_meta("popularite_max", $row['max']);
23        ecrire_meta("popularite_total", $row['tot']);
24
25
26        // Une fois par jour purger les referers du jour ; qui deviennent
27        // donc ceux de la veille ; au passage on stocke une date_statistiques
28        // dans spip_meta - cela permet au code d'etre "reentrant", ie ce cron
29        // peut etre appele par deux bases SPIP ne partageant pas le meme
30        // _DIR_TMP, sans tout casser...
31
32        $aujourdhui = date("Y-m-d");
33        if (($d = $GLOBALS['meta']['date_statistiques']) != $aujourdhui) {
34               
35                spip_log("Popularite: purger referer depuis $d");
36                ecrire_meta('date_statistiques', $aujourdhui);
37                if (strncmp($GLOBALS['connexions'][0]['type'], 'sqlite', 6) == 0) {
38                        spip_query("UPDATE spip_referers SET visites_veille=visites_jour, visites_jour=0");
39                } else
40                        // version 3 fois plus rapide, mais en 2 requetes
41                        #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'");
42                        #spip_query("UPDATE spip_referers SET visites_jour=0");
43                        // version 4 fois plus rapide que la premiere, en une seule requete
44                        // ATTENTION : peut poser probleme cf https://core.spip.net/issues/2505
45                {
46                        sql_alter("TABLE spip_referers DROP visites_veille,
47                        CHANGE visites_jour visites_veille INT(10) UNSIGNED NOT NULL DEFAULT '0',
48                        ADD visites_jour INT(10) UNSIGNED NOT NULL DEFAULT '0'");
49                }
50               
51               
52                spip_log("Popularite: purger referers_articles depuis $d");
53                if (strncmp($GLOBALS['connexions'][0]['type'], 'sqlite', 6) == 0) {
54                        spip_query("UPDATE spip_referers_articles SET visites_veille=visites_jour, visites_jour=0");
55                } else
56                        // version 3 fois plus rapide, mais en 2 requetes
57                        #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'");
58                        #spip_query("UPDATE spip_referers SET visites_jour=0");
59                        // version 4 fois plus rapide que la premiere, en une seule requete
60                        // ATTENTION : peut poser probleme cf https://core.spip.net/issues/2505
61                {
62                        sql_alter("TABLE spip_referers_articles DROP visites_veille,
63                        CHANGE visites_jour visites_veille INT(10) UNSIGNED NOT NULL DEFAULT '0',
64                        ADD visites_jour INT(10) UNSIGNED NOT NULL DEFAULT '0'");
65                }
66        }
67
68        // et c'est fini pour cette fois-ci
69        return 1;
70
71}
72
73// surcharge du cron de calcul des visites pour ajoute rles visites_jour et visites_veilles sur les spip_referers_articles
74include_spip('genie/visites'); // ?
75
76function genie_visites($t) {
77        $encore = calculer_visites2($t);
78       
79        // Si ce n'est pas fini on redonne la meme date au fichier .lock
80        // pour etre prioritaire lors du cron suivant
81        if ($encore) {
82                return (0 - $t);
83        }
84       
85        // SPIP 3
86        // nettoyer les IP des floodeurs quand on a fini de compter les stats
87        if(function_exists('visites_nettoyer_flood'))
88                visites_nettoyer_flood();
89       
90        return 1;
91}
92
93/**
94 * Calcule les statistiques de visites sur le site et les articles et les liens entrants, en plusieurs étapes
95 *
96 * @uses compte_fichier_visite()
97 * @uses genie_popularite_constantes()
98 *
99 * @param int $t
100 *     Timestamp de la dernière exécution de cette tâche
101 * @return null|int
102 *     - null si aucune visite à prendre en compte ou si tous les fichiers de visite sont traités,
103 *     - entier négatif s'il reste encore des fichiers à traiter
104 **/
105function calculer_visites2($t) {
106        include_spip('base/abstract_sql');
107       
108        spip_log("Check des visites de " . date("Y-m-d H:i:s", $t) ,"test_genie_calculer_visites");
109       
110        // Initialisations
111        $visites = array(); # visites du site
112        $visites_a = array(); # tableau des visites des articles
113        $referers = array(); # referers du site
114        $referers_a = array(); # tableau des referers des articles
115
116        // charger un certain nombre de fichiers de visites,
117        // et faire les calculs correspondants
118
119        // Traiter jusqu'a 100 sessions datant d'au moins 30 minutes
120        $sessions = preg_files(sous_repertoire(_DIR_TMP, 'visites'));
121
122        $compteur = _CRON_LOT_FICHIERS_VISITE;
123        $date_init = time() - 30 * 60;
124        foreach ($sessions as $item) {
125                if (($d = @filemtime($item)) < $date_init) {
126                        if (!$d) {
127                                $d = $date_init;
128                        } // si le fs ne donne pas de date, on prend celle du traitement, mais tout cela risque d'etre bien douteux
129                        $d = date("Y-m-d", $d);
130                        spip_log("traite la session $item");
131                        compte_fichier_visite($item,
132                                $visites[$d], $visites_a[$d], $referers[$d], $referers_a[$d]);
133                        spip_unlink($item);
134                        if (--$compteur <= 0) {
135                                break;
136                        }
137                }
138                #else spip_log("$item pas vieux");
139        }
140       
141        if (!count($visites)) {
142                return;
143        }
144
145        include_spip('genie/popularites');
146        list($a, $b) = genie_popularite_constantes(24 * 3600);
147
148        // Maintenant on dispose de plusieurs tableaux qu'il faut ventiler dans
149        // les tables spip_visites, spip_visites_articles, spip_referers
150        // et spip_referers_articles ; attention a affecter tout ca a la bonne
151        // date (celle de la visite, pas celle du traitement)
152        foreach (array_keys($visites) as $date) {
153                if ($visites[$date]) {
154                       
155                        // 1. les visites du site (facile)
156                        if (!sql_countsel('spip_visites', "date='$date'")) {
157                                sql_insertq('spip_visites',
158                                        array('date' => $date, 'visites' => $visites[$date]));
159                        } else {
160                                sql_update('spip_visites', array('visites' => "visites+" . intval($visites[$date])), "date='$date'");
161                        }
162
163                        // 2. les visites des articles
164                        if ($visites_a[$date]) {
165                                $ar = array();  # tableau num -> liste des articles ayant num visites
166                                foreach ($visites_a[$date] as $id_article => $n) {
167                                        if (!sql_countsel('spip_visites_articles',
168                                                "id_article=$id_article AND date='$date'")
169                                        ) {
170                                                sql_insertq('spip_visites_articles',
171                                                        array(
172                                                                'id_article' => $id_article,
173                                                                'visites' => 0,
174                                                                'date' => $date
175                                                        ));
176                                        }
177                                        $ar[$n][] = $id_article;
178                                }
179                                foreach ($ar as $n => $liste) {
180                                        $tous = sql_in('id_article', $liste);
181                                        sql_update('spip_visites_articles',
182                                                array('visites' => "visites+$n"),
183                                                "date='$date' AND $tous");
184
185                                        $ref = $noref = array();
186                                        foreach ($liste as $id) {
187                                                if (isset($referers_a[$id])) {
188                                                        $ref[] = $id;
189                                                } else {
190                                                        $noref[] = $id;
191                                                }
192                                        }
193                                        // il faudrait ponderer la popularite ajoutee ($n) par son anciennete eventuelle
194                                        // sur le modele de ce que fait genie/popularites
195                                        if (count($noref)) {
196                                                sql_update('spip_articles',
197                                                        array(
198                                                                'visites' => "visites+$n",
199                                                                'popularite' => "popularite+" . number_format(round($n * $b, 2), 2, '.', ''),
200                                                                'maj' => 'maj'
201                                                        ),
202                                                        sql_in('id_article', $noref));
203                                        }
204
205                                        if (count($ref)) {
206                                                sql_update('spip_articles',
207                                                        array(
208                                                                'visites' => "visites+" . ($n + 1),
209                                                                'popularite' => "popularite+" . number_format(round($n * $b, 2), 2, '.', ''),
210                                                                'maj' => 'maj'
211                                                        ),
212                                                        sql_in('id_article', $ref));
213                                        }
214
215                                        ## Ajouter un JOIN sur le statut de l'article ?
216                                }
217                        }
218                        if (!isset($GLOBALS['meta']['activer_referers']) or $GLOBALS['meta']['activer_referers'] == "oui") {
219                                // 3. Les referers du site
220                                // insertion pour les nouveaux, au tableau des increments sinon
221                                if ($referers[$date]) {
222                                        $ar = array();
223                                        $trouver_table = charger_fonction('trouver_table', 'base');
224                                        $desc = $trouver_table('referers');
225                                        $n = preg_match('/(\d+)/', $desc['field']['referer'], $r);
226                                        $n = $n ? $r[1] : 255;
227                                        foreach ($referers[$date] as $referer => $num) {
228                                                $referer_md5 = sql_hex(substr(md5($referer), 0, 15));
229                                                $referer = substr($referer, 0, $n);
230                                                if (!sql_countsel('spip_referers', "referer_md5=$referer_md5")) {
231                                                        sql_insertq('spip_referers',
232                                                                array(
233                                                                        'visites' => $num,
234                                                                        'visites_jour' => $num,
235                                                                        'visites_veille' => 0, // $num ??
236                                                                        'date' => $date,
237                                                                        'referer' => $referer,
238                                                                        'referer_md5' => $referer_md5
239                                                                ));
240                                                } else {
241                                                        $ar[$num][] = $referer_md5;
242                                                }
243                                        }
244
245                                        // appliquer les increments sur les anciens
246                                        // attention on appelle sql_in en mode texte et pas array
247                                        // pour ne pas passer sql_quote() sur les '0x1234' de referer_md5, cf #849
248                                        foreach ($ar as $num => $liste) {
249                                                sql_update('spip_referers', array('visites' => "visites+$num", 'visites_jour' => "visites_jour+$num"),
250                                                        sql_in('referer_md5', join(', ', $liste)));
251                                        }
252                                }
253
254                                // 4. Les referers d'articles
255                                if ($referers_a[$date]) {
256                                        $ar = array();
257                                        $insert = array();
258                                        // s'assurer d'un slot pour chacun
259                                        foreach ($referers_a[$date] as $id_article => $referers) {
260                                                foreach ($referers as $referer => $num) {
261                                                        $referer_md5 = sql_hex(substr(md5($referer), 0, 15));
262                                                        $prim = "(id_article=$id_article AND referer_md5=$referer_md5)";
263                                                        if (!sql_countsel('spip_referers_articles', $prim)) {
264                                                                sql_insertq('spip_referers_articles',
265                                                                        array(
266                                                                                'visites' => $num,
267                                                                                'id_article' => $id_article,
268                                                                                'referer' => $referer,
269                                                                                'referer_md5' => $referer_md5,
270                                                                                'visites_jour' => $num,
271                                                                                'visites_veille' => 0 // $num ?
272                                                                        ));
273                                                        } else {
274                                                                $ar[$num][] = $prim;
275                                                        }
276                                                }
277                                        }
278                                        // ajouter les visites
279                                        foreach ($ar as $num => $liste) {
280                                                sql_update('spip_referers_articles', array('visites' => "visites+$num", 'visites_jour' => "visites_jour+$num"), join(" OR ", $liste));
281                                        }
282                                }
283                        }
284                }
285        }
286
287        // S'il reste des fichiers a manger, le signaler pour reexecution rapide
288        if ($compteur == 0) {
289                spip_log("il reste des visites a traiter...");
290
291                return -$t;
292        }
293}
Note: See TracBrowser for help on using the repository browser.