3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2011 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
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 \***************************************************************************/
14 if (!defined('_ECRIRE_INC_VERSION')) return;
16 include_spip('base/serial');
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);
24 // Donne le nombre de fichiers dans un repertoire (plat, pour aller vite)
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;
32 while (($fichier = @readdir
($h)) !== false)
33 if ($fichier[0]!='.'){
35 if ($nb AND rand(1,10)==1){
36 $taille +
= filesize("$dir/$fichier");
41 return array($total,$taille?
$taille/($nb_estim_taille-$nb):_TAILLE_MOYENNE_FICHIER_CACHE
);
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() {
50 for ($i=0;$i<16;$i++
) {
52 $dir = sous_repertoire(_DIR_CACHE
, $l);
53 list($n,$s) = nombre_de_fichiers_repertoire($dir);
57 return $total * $taille / 16;
60 // Invalider les caches lies a telle condition
61 // ici on se contente de noter la date de mise a jour dans les metas
62 // http://doc.spip.org/@suivre_invalideur
63 function suivre_invalideur($cond, $modif=true) {
67 // determiner l'objet modifie : forum, article, etc
68 if (preg_match(',id_([a-z]+),', $cond, $r))
70 // cas particulier des signatures
71 else if (strpos($cond, 'varia/pet'))
74 // stocker la date_modif_$objet (ne sert a rien pour le moment)
76 ecrire_meta('derniere_modif_'.$objet, time());
78 // si $derniere_modif_invalide est un array('forum', 'signature')
79 // n'affecter la meta que si un de ces objets est modifie
80 if (is_array($GLOBALS['derniere_modif_invalide'])) {
81 if (in_array($objet, $GLOBALS['derniere_modif_invalide']))
82 ecrire_meta('derniere_modif', time());
84 // sinon, cas standard, toujours affecter la meta
86 ecrire_meta('derniere_modif', time());
93 // Utilisee pour vider le cache depuis l'espace prive
94 // (ou juste les squelettes si un changement de config le necessite)
95 // si $atime est passee en argument, ne pas supprimer ce qui a servi
96 // plus recemment que cette date (via fileatime)
97 // retourne le nombre de fichiers supprimes
98 // http://doc.spip.org/@purger_repertoire
99 function purger_repertoire($dir, $options=array()) {
100 $handle = @opendir
($dir);
101 if (!$handle) return;
105 while (($fichier = @readdir
($handle)) !== false) {
106 // Eviter ".", "..", ".htaccess", ".svn" etc.
107 if ($fichier[0] == '.') continue;
108 $chemin = "$dir/$fichier";
109 if (is_file($chemin)) {
110 if (!isset($options['atime'])
111 OR (@fileatime
($chemin) < $options['atime'])) {
112 supprimer_fichier($chemin);
116 else if (is_dir($chemin)){
117 if ($fichier != 'CVS')
118 $total +
= purger_repertoire($chemin, $options);
119 if (isset($options['subdir']) && $options['subdir'])
120 spip_unlink($chemin);
123 if (isset($options['limit']) AND $total>=$options['limit'])
133 // Methode : on prend un des sous-repertoires de CACHE/
134 // on considere qu'il fait 1/16e de la taille du cache
135 // et on le ratiboise en supprimant les fichiers qui n'ont pas
136 // ete sollicites dans l'heure qui vient de s'ecouler
138 // http://doc.spip.org/@appliquer_quota_cache
139 function appliquer_quota_cache() {
143 $tour_quota_cache = intval(1+
$GLOBALS['meta']['tour_quota_cache'])%16
;
144 ecrire_meta('tour_quota_cache', $tour_quota_cache);
146 $l = dechex($tour_quota_cache);
147 $dir = sous_repertoire(_DIR_CACHE
, $l);
148 list($nombre,$taille) = nombre_de_fichiers_repertoire($dir);
149 $total_cache = $taille * $nombre;
150 spip_log("Taille du CACHE estimee ($l): "
151 .(intval(16*$total_cache/(1024*1024/10))/10)." Mo","invalideur");
153 // Nombre max de fichiers a supprimer
156 $trop = $total_cache - ($quota_cache/16)*1024*1024;
157 $trop = 3 * intval($trop / $taille);
159 $n = purger_repertoire($dir,
161 'atime' => time() - _AGE_CACHE_ATIME
,
163 'subdir' => true // supprimer les vieux sous repertoire de session (avant [15851])
166 spip_log("$dir : $n/$trop caches supprimes [taille moyenne $taille]","invalideur");
167 $total_cache = intval(max(0,(16*$total_cache) - $n*$taille)/(1024*1024)*10)/10;
168 spip_log("cache restant estime : $total_cache Mo, ratio ".$total_cache/$quota_cache,"invalideur");
170 // redemander la main pour eviter que le cache ne gonfle trop
171 // mais pas si on ne peut pas purger car les fichiers sont trops recents
173 $total_cache/$quota_cache>1.5
176 spip_log("Il faut encore purger","invalideur");
185 // Destruction des fichiers caches invalides
188 // Securite : est sur que c'est un cache
189 // http://doc.spip.org/@retire_cache
190 function retire_cache($cache) {
193 "|^([0-9a-f]/)?([0-9]+/)?[^.][\-_\%0-9a-z]+--[0-9a-f]+(\.gz)?$|i",
195 // supprimer le fichier (de facon propre)
196 supprimer_fichier(_DIR_CACHE
. $cache);
198 spip_log("Nom de fichier cache incorrect : $cache");
201 #######################################################################
203 ## Ci-dessous les fonctions qui restent appellees dans le core
204 ## pour pouvoir brancher le plugin invalideur ;
205 ## mais ici elles ne font plus rien
208 // Supprimer les caches marques "x"
209 // A priori dans cette version la fonction ne sera pas appelee, car
210 // la meta est toujours false ; mais evitons un bug si elle est appellee
211 // http://doc.spip.org/@retire_caches
212 function retire_caches($chemin = '') {
213 if (isset($GLOBALS['meta']['invalider_caches']))
214 effacer_meta('invalider_caches'); # concurrence
218 // Pour que le compilo ajoute un invalideur a la balise #PARAMETRES_FORUM
219 // Noter l'invalideur de la page contenant ces parametres,
220 // en cas de premier post sur le forum
221 // http://doc.spip.org/@code_invalideur_forums
222 function code_invalideur_forums($p, $code) {
227 // Fonction permettant au compilo de calculer les invalideurs d'une page
228 // (note: si absente, n'est pas appellee)
230 // http://doc.spip.org/@calcul_invalideurs
231 function calcul_invalideurs($corps, $primary, &$boucles, $id_boucle) {
236 // Cette fonction permet de supprimer tous les invalideurs
237 // Elle ne touche pas aux fichiers cache eux memes ; elle est
238 // invoquee quand on vide tout le cache en bloc (action/purger)
240 // http://doc.spip.org/@supprime_invalideurs
241 function supprime_invalideurs() { }
244 // Calcul des pages : noter dans la base les liens d'invalidation
245 // http://doc.spip.org/@maj_invalideurs
246 function maj_invalideurs ($fichier, &$page) { }
248 // pour les forums l'invalideur est : 'id_forum/a23'
249 // pour les petitions et autres, l'invalideur est par exemple :
251 // http://doc.spip.org/@insere_invalideur
252 function insere_invalideur($inval, $fichier) { }
256 // Marquer les fichiers caches invalides comme etant a supprimer
258 // http://doc.spip.org/@applique_invalideur
259 function applique_invalideur($depart) { }