[SPIP] ~v3.0.20-->v3.0.25
[lhc/web/clavette_www.git] / www / ecrire / inc / invalideur.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2016 *
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 if (!defined('_ECRIRE_INC_VERSION')) return;
15
16 include_spip('base/serial');
17
18 # estime la taille moyenne d'un fichier cache, pour ne pas les regarder (10ko)
19 define('_TAILLE_MOYENNE_FICHIER_CACHE', 1024 * 10);
20 # si un fichier n'a pas servi (fileatime) depuis plus d'une heure, on se sent
21 # en droit de l'eliminer
22 define('_AGE_CACHE_ATIME', 3600);
23
24 // Donne le nombre de fichiers dans un repertoire (plat, pour aller vite)
25 // false si erreur
26 // http://doc.spip.org/@nombre_de_fichiers_repertoire
27 function nombre_de_fichiers_repertoire($dir,$nb_estim_taille = 20) {
28 $taille = 0; // mesurer la taille de N fichiers au hasard dans le repertoire
29 $nb = $nb_estim_taille;
30 if (!$h = @opendir($dir)) return false;
31 $total = 0;
32 while (($fichier = @readdir($h)) !== false)
33 if ($fichier[0]!='.' AND !is_dir("$dir/$fichier")){
34 $total++;
35 if ($nb AND rand(1,10)==1){
36 $taille += filesize("$dir/$fichier");
37 $nb--;
38 }
39 }
40 closedir($h);
41 return array($total,$taille?$taille/($nb_estim_taille-$nb):_TAILLE_MOYENNE_FICHIER_CACHE);
42 }
43
44 // Indique la taille du repertoire cache ; pour de gros volumes,
45 // impossible d'ouvrir chaque fichier, on y va donc a l'estime
46 // http://doc.spip.org/@taille_du_cache
47 function taille_du_cache() {
48 $total = 0;
49 $taille = 0;
50 for ($i=0;$i<16;$i++) {
51 $l = dechex($i);
52 $dir = sous_repertoire(_DIR_CACHE, $l);
53 list($n,$s) = nombre_de_fichiers_repertoire($dir);
54 $total += $n;
55 $taille += $s;
56 }
57 return $total * $taille / 16;
58 }
59
60 // Invalider les caches lies a telle condition
61 // les invalideurs sont de la forme 'objet/id_objet'
62 // la condition est generalement "id='objet/id_objet'"
63 // ici on se contente de noter la date de mise a jour dans les metas
64 // http://doc.spip.org/@suivre_invalideur
65 function suivre_invalideur($cond, $modif=true) {
66 if (!$modif)
67 return;
68
69 // determiner l'objet modifie : forum, article, etc
70 if (preg_match(',["\']([a-z_]+)[/"\'],', $cond, $r))
71 $objet = objet_type($r[1]);
72
73 // stocker la date_modif_$objet (ne sert a rien pour le moment)
74 if (isset($objet))
75 ecrire_meta('derniere_modif_'.$objet, time());
76
77 // si $derniere_modif_invalide est un array('article', 'rubrique')
78 // n'affecter la meta que si un de ces objets est modifie
79 if (is_array($GLOBALS['derniere_modif_invalide'])) {
80 if (in_array($objet, $GLOBALS['derniere_modif_invalide']))
81 ecrire_meta('derniere_modif', time());
82 }
83 // sinon, cas standard, toujours affecter la meta
84 else
85 ecrire_meta('derniere_modif', time());
86
87 }
88
89
90
91 /**
92 * Purge un répertoire de ses fichiers
93 *
94 * Utilisée entre autres pour vider le cache depuis l'espace privé
95 *
96 * @uses supprimer_fichier()
97 *
98 * @param string $dir
99 * Chemin du répertoire à purger
100 * @param array $options
101 * Tableau des options. Peut être :
102 *
103 * - atime : timestamp pour ne supprimer que les fichiers antérieurs
104 * à cette date (via fileatime)
105 * - mtime : timestamp pour ne supprimer que les fichiers antérieurs
106 * à cette date (via filemtime)
107 * - limit : nombre maximum de suppressions
108 * @return int
109 * Nombre de fichiers supprimés
110 **/
111 function purger_repertoire($dir, $options=array()) {
112 $handle = @opendir($dir);
113 if (!$handle) return;
114
115 $total = 0;
116
117 while (($fichier = @readdir($handle)) !== false) {
118 // Eviter ".", "..", ".htaccess", ".svn" etc.
119 if ($fichier[0] == '.') continue;
120 $chemin = "$dir/$fichier";
121 if (is_file($chemin)) {
122 if ( (!isset($options['atime']) OR (@fileatime($chemin) < $options['atime']))
123 AND (!isset($options['mtime']) OR (@filemtime($chemin) < $options['mtime']))
124 ) {
125 supprimer_fichier($chemin);
126 $total ++;
127 }
128 }
129 else if (is_dir($chemin)){
130 $opts = $options;
131 if (isset($otpions['limit']))
132 $otps['limit'] = $otpions['limit'] - $total;
133 $total += purger_repertoire($chemin, $opts);
134 if (isset($options['subdir']) && $options['subdir'])
135 spip_unlink($chemin);
136 }
137
138 if (isset($options['limit']) AND $total>=$options['limit'])
139 break;
140 }
141 closedir($handle);
142
143 return $total;
144 }
145
146
147 //
148 // Methode : on prend un des sous-repertoires de CACHE/
149 // on considere qu'il fait 1/16e de la taille du cache
150 // et on le ratiboise en supprimant les fichiers qui n'ont pas
151 // ete sollicites dans l'heure qui vient de s'ecouler
152 //
153 // http://doc.spip.org/@appliquer_quota_cache
154 function appliquer_quota_cache() {
155 global $quota_cache;
156 $encore = false;
157
158 $tour_quota_cache = intval(1+$GLOBALS['meta']['tour_quota_cache'])%16;
159 ecrire_meta('tour_quota_cache', $tour_quota_cache);
160
161 $l = dechex($tour_quota_cache);
162 $dir = sous_repertoire(_DIR_CACHE, $l);
163 list($nombre,$taille) = nombre_de_fichiers_repertoire($dir);
164 $total_cache = $taille * $nombre;
165 spip_log("Taille du CACHE estimee ($l): "
166 .(intval(16*$total_cache/(1024*1024/10))/10)." Mo","invalideur");
167
168 // Nombre max de fichiers a supprimer
169 if ($quota_cache > 0
170 AND $taille > 0) {
171 $trop = $total_cache - ($quota_cache/16)*1024*1024;
172 $trop = 3 * intval($trop / $taille);
173 if ($trop > 0) {
174 $n = purger_repertoire($dir,
175 array(
176 'atime' => time() - _AGE_CACHE_ATIME,
177 'limit' => $trop,
178 'subdir' => true // supprimer les vieux sous repertoire de session (avant [15851])
179 )
180 );
181 spip_log("$dir : $n/$trop caches supprimes [taille moyenne $taille]","invalideur");
182 $total_cache = intval(max(0,(16*$total_cache) - $n*$taille)/(1024*1024)*10)/10;
183 spip_log("cache restant estime : $total_cache Mo, ratio ".$total_cache/$quota_cache,"invalideur");
184
185 // redemander la main pour eviter que le cache ne gonfle trop
186 // mais pas si on ne peut pas purger car les fichiers sont trops recents
187 if (
188 $total_cache/$quota_cache>1.5
189 AND $n*50>$trop) {
190 $encore = true;
191 spip_log("Il faut encore purger","invalideur");
192 }
193 }
194 }
195 return $encore;
196 }
197
198
199 //
200 // Destruction des fichiers caches invalides
201 //
202
203 // Securite : est sur que c'est un cache
204 // http://doc.spip.org/@retire_cache
205 function retire_cache($cache) {
206
207 if (preg_match(
208 "|^([0-9a-f]/)?([0-9]+/)?[^.][\-_\%0-9a-z]+--[0-9a-f]+(\.gz)?$|i",
209 $cache)) {
210 // supprimer le fichier (de facon propre)
211 supprimer_fichier(_DIR_CACHE . $cache);
212 } else
213 spip_log("Nom de fichier cache incorrect : $cache");
214 }
215
216 #######################################################################
217 ##
218 ## Ci-dessous les fonctions qui restent appellees dans le core
219 ## pour pouvoir brancher le plugin invalideur ;
220 ## mais ici elles ne font plus rien
221 ##
222
223 // Supprimer les caches marques "x"
224 // A priori dans cette version la fonction ne sera pas appelee, car
225 // la meta est toujours false ; mais evitons un bug si elle est appellee
226 // http://doc.spip.org/@retire_caches
227 function retire_caches($chemin = '') {
228 if (isset($GLOBALS['meta']['invalider_caches']))
229 effacer_meta('invalider_caches'); # concurrence
230 }
231
232
233 // Fonction permettant au compilo de calculer les invalideurs d'une page
234 // (note: si absente, n'est pas appellee)
235 /*
236 // http://doc.spip.org/@calcul_invalideurs
237 function calcul_invalideurs($corps, $primary, &$boucles, $id_boucle) {
238 return $corps;
239 }
240 */
241
242 // Cette fonction permet de supprimer tous les invalideurs
243 // Elle ne touche pas aux fichiers cache eux memes ; elle est
244 // invoquee quand on vide tout le cache en bloc (action/purger)
245 //
246 // http://doc.spip.org/@supprime_invalideurs
247 function supprime_invalideurs() { }
248
249
250 // Calcul des pages : noter dans la base les liens d'invalidation
251 // http://doc.spip.org/@maj_invalideurs
252 function maj_invalideurs ($fichier, &$page) { }
253
254 // les invalideurs sont de la forme "objet/id_objet"
255 // http://doc.spip.org/@insere_invalideur
256 function insere_invalideur($inval, $fichier) { }
257
258
259 //
260 // Marquer les fichiers caches invalides comme etant a supprimer
261 //
262 // http://doc.spip.org/@applique_invalideur
263 function applique_invalideur($depart) { }
264
265 ?>