source: spip-zone/_plugins_/_core_/statistiques/genie/visites.php @ 26992

Last change on this file since 26992 was 26992, checked in by fil@…, 11 years ago

manque de quotes (denisb)

File size: 7.5 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2009                                                *
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
14if (!defined("_ECRIRE_INC_VERSION")) return;
15@define('_CRON_LOT_FICHIERS_VISITE',100);
16
17### Pour se debarrasser du md5, comment faire ? Un index sur 'referer' ?
18### ou alors la meme notion, mais sans passer par des fonctions HEX ?
19
20//
21// prendre en compte un fichier de visite
22//
23// http://doc.spip.org/@compte_fichier_visite
24function compte_fichier_visite($fichier, &$visites, &$visites_a, &$referers, &$referers_a) {
25
26        // Noter la visite du site (article 0)
27        $visites ++;
28
29        $content = array();
30        if (lire_fichier($fichier, $content))
31                $content = @unserialize($content);
32        if (!is_array($content)) return;
33
34        foreach ($content as $source => $num) {
35                list($log_type, $log_id_num, $log_referer)
36                        = preg_split(",\t,", $source, 3);
37               
38                // Noter le referer
39                if ($log_referer)
40                        $referers[$log_referer]++;
41
42                // S'il s'agit d'un article, noter ses visites
43                if ($log_type == 'article'
44                AND $id_article = intval($log_id_num)) {
45                        $visites_a[$id_article] ++;
46                        if ($log_referer)
47                                $referers_a[$id_article][$log_referer]++;
48                }
49        }
50}
51
52
53// http://doc.spip.org/@calculer_visites
54function calculer_visites($t) {
55        include_spip('base/abstract_sql');
56
57        // Initialisations
58        $visites = array(); # visites du site
59        $visites_a = array(); # tableau des visites des articles
60        $referers = array(); # referers du site
61        $referers_a = array(); # tableau des referers des articles
62
63        // charger un certain nombre de fichiers de visites,
64        // et faire les calculs correspondants
65
66        // Traiter jusqu'a 100 sessions datant d'au moins 30 minutes
67        $sessions = preg_files(sous_repertoire(_DIR_TMP, 'visites'));
68
69        $compteur = _CRON_LOT_FICHIERS_VISITE;
70        $date_init = time()-30*60;
71        foreach ($sessions as $item) {
72                if (($d=@filemtime($item)) < $date_init) {
73                        if (!$d) $d = $date_init; // si le fs ne donne pas de date, on prend celle du traitement, mais tout cela risque d'etre bien douteux
74                        $d = date("Y-m-d",$d);
75                        spip_log("traite la session $item");
76                        compte_fichier_visite($item,
77                                $visites[$d], $visites_a[$d], $referers[$d], $referers_a[$d]);
78                        spip_unlink($item);
79                        if (--$compteur <= 0)
80                                break;
81                }
82                #else spip_log("$item pas vieux");
83        }
84        if (!count($visites))
85                return;
86
87        include_spip('genie/popularites');
88        list($a,$b) = genie_popularite_constantes(24*3600);
89
90        // Maintenant on dispose de plusieurs tableaux qu'il faut ventiler dans
91        // les tables spip_visites, spip_visites_articles, spip_referers
92        // et spip_referers_articles ; attention a affecter tout ca a la bonne
93        // date (celle de la visite, pas celle du traitement)
94        foreach(array_keys($visites) as $date)
95                if ($visites[$date]) {
96
97                        // 1. les visites du site (facile)
98                        if (!sql_countsel('spip_visites', "date='$date'"))
99                                sql_insertq('spip_visites',
100                                        array('date' => $date, 'visites' => $visites[$date]));
101                        else 
102                                sql_update('spip_visites', array('visites' => "visites+".intval($visites[$date])), "date='$date'");
103               
104                        // 2. les visites des articles
105                        if ($visites_a[$date]) {
106                                $ar = array();  # tableau num -> liste des articles ayant num visites
107                                foreach($visites_a[$date] as $id_article => $n) {
108                                        if (!sql_countsel('spip_visites_articles',
109                                                 "id_article=$id_article AND date='$date'")){
110                                                sql_insertq('spip_visites_articles',
111                                                                array('id_article' => $id_article,
112                                                                      'visites' => 0,
113                                                                      'date' => $date));
114                                        }
115                                        $ar[$n][] = $id_article;
116                                }
117                                foreach ($ar as $n => $liste) {
118                                        $tous = sql_in('id_article', $liste);
119                                        sql_update('spip_visites_articles',
120                                                array('visites' => "visites+$n"),
121                                                   "date='$date' AND $tous");
122               
123                                        $ref = $noref = array();
124                                        foreach($liste as $id) {
125                                                if (isset($referers_a[$id]))
126                                                        $ref[]= $id ;
127                                                else $noref[]=$id;
128                                        }
129                                        // il faudrait ponderer la popularite ajoutee ($n) par son anciennete eventuelle
130                                        // sur le modele de ce que fait genie/popularites
131                                        if (count($noref))
132                                                sql_update('spip_articles',
133                                                        array('visites' => "visites+$n",
134                                                         'popularite' => "popularite+".round($n*$b,2),
135                                                         'maj' => 'maj'),
136                                                        sql_in('id_article',$noref));
137                                                           
138                                        if (count($ref))
139                                                sql_update('spip_articles',
140                                                           array('visites' => "visites+".($n+1),
141                                                         'popularite' => "popularite+".round($n*$b,2),
142                                                         'maj' => 'maj'),
143                                                        sql_in('id_article',$ref));
144                                                           
145                                        ## Ajouter un JOIN sur le statut de l'article ?
146                                }
147                        }
148                        // 3. Les referers du site
149                        // insertion pour les nouveaux, au tableau des increments sinon
150                        if ($referers[$date]) {
151                                $ar = array();
152                                $trouver_table = charger_fonction('trouver_table', 'base');
153                                $desc = $trouver_table('referers');
154                                $n = preg_match('/(\d+)/',$desc['field']['referer'], $r);
155                                $n = $n ? $r[1] : 255;
156                                foreach ($referers[$date] as $referer => $num) {
157                                        $referer_md5 = sql_hex(substr(md5($referer), 0, 15));
158                                        $referer = substr($referer,0,$n);
159                                        if (!sql_countsel('spip_referers', "referer_md5=$referer_md5"))
160                                                sql_insertq('spip_referers',
161                                                        array('visites' => $num,
162                                                              'visites_jour' => $num,
163                                                              'visites_veille' => $num,
164                                                              'date' => $date,
165                                                              'referer' => $referer,
166                                                              'referer_md5' => $referer_md5));
167                                        else $ar[$num][] = $referer_md5;
168                                }
169               
170                        // appliquer les increments sur les anciens
171                        // attention on appelle sql_in en mode texte et pas array
172                        // pour ne pas passer sql_quote() sur les '0x1234' de referer_md5, cf #849
173                                foreach ($ar as $num => $liste) {
174                                        sql_update('spip_referers', array('visites' => "visites+$num", 'visites_jour' => "visites_jour+$num"), sql_in('referer_md5',join(', ', $liste)));
175                                }
176                        }
177                       
178                        // 4. Les referers d'articles
179                        if ($referers_a[$date]) {
180                                $ar = array();
181                                $insert = array();
182                                // s'assurer d'un slot pour chacun
183                                foreach ($referers_a[$date] as $id_article => $referers)
184                                        foreach ($referers as $referer => $num) {
185                                                $referer_md5 = sql_hex(substr(md5($referer), 0, 15));
186                                                $prim = "(id_article=$id_article AND referer_md5=$referer_md5)";
187                                                if (!sql_countsel('spip_referers_articles', $prim))
188                                                        sql_insertq('spip_referers_articles',
189                                                             array('visites' => $num,
190                                                                   'id_article' => $id_article,
191                                                                   'referer' => $referer,
192                                                                   'referer_md5' => $referer_md5));
193                                                else $ar[$num][] = $prim;
194                                        }
195                                // ajouter les visites
196                                foreach ($ar as $num => $liste) {
197                                        sql_update('spip_referers_articles', array('visites' => "visites+$num"), join(" OR ", $liste));
198                                        ## Ajouter un JOIN sur le statut de l'article ?
199                                }
200                        }
201                }
202
203        // S'il reste des fichiers a manger, le signaler pour reexecution rapide
204        if ($compteur==0) {
205                spip_log("il reste des visites a traiter...");
206                return -$t;
207        }
208}
209
210//
211// Calcule les stats en plusieurs etapes
212//
213// http://doc.spip.org/@genie_visites_dist
214function genie_visites_dist($t) {
215        $encore = calculer_visites($t);
216
217        // Si ce n'est pas fini on redonne la meme date au fichier .lock
218        // pour etre prioritaire lors du cron suivant
219        if ($encore)
220                return (0 - $t);
221
222        return 1;
223}
224?>
Note: See TracBrowser for help on using the repository browser.