squellete2
[aidenligne_francais_universite.git] / ecrire / public / cacher.php
CommitLineData
c495c100
P
1<?php
2
3/***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2007 *
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
13if (!defined("_ECRIRE_INC_VERSION")) return;
14
15//
16// Le format souhaite : "a/bout-d-url.md5" (.gz s'ajoutera pour les gros caches)
17// Attention a modifier simultanement le sanity check de
18// la fonction retire_cache() de inc/invalideur
19//
20// http://doc.spip.org/@generer_nom_fichier_cache
21function generer_nom_fichier_cache($contexte) {
22
23 if ($contexte === NULL) {
24 $fichier_requete = nettoyer_uri();
25 } else {
26 $fichier_requete = '';
27 foreach ($contexte as $var=>$val)
28 $fichier_requete .= "&$var=$val";
29 }
30
31 $fichier_cache = preg_replace(',^/+,', '', $fichier_requete);
32 $fichier_cache = preg_replace(',\.[a-zA-Z0-9]*,', '', $fichier_cache);
33 $fichier_cache = preg_replace(',&[^&]+=([^&]+),', '&\1', $fichier_cache);
34 $fichier_cache = rawurlencode(strtr($fichier_cache, '/&-', '--_'));
35 if (strlen($fichier_cache) > 24)
36 $fichier_cache = substr(preg_replace('/([a-zA-Z]{1,3})[^-]*-/',
37 '\1-', $fichier_cache), -22);
38
39 // Pour la page d'accueil
40 if (!$fichier_cache)
41 $fichier_cache = 'INDEX-';
42
43 // Morceau de md5 selon HOST, $dossier_squelettes, $fond et $marqueur
44 // permet de changer de chemin_cache si l'on change l'un de ces elements
45 // donc, par exemple, de gerer differents dossiers de squelettes
46 // en parallele, ou de la "personnalisation" via un marqueur (dont la
47 // composition est totalement libre...)
48 $md_cache = md5(
49 $fichier_requete . ' '
50 . $_SERVER['HTTP_HOST'] . ' '
51 . $GLOBALS['fond'] . ' '
52 . $GLOBALS['dossier_squelettes'] . ' '
53 . (isset($GLOBALS['marqueur']) ? $GLOBALS['marqueur'] : '')
54 );
55 $fichier_cache .= '.'.substr($md_cache, 1, 8);
56
57 // Sous-repertoires 0...9a..f ; ne pas prendre la base _DIR_CACHE
58 $repertoire = _DIR_CACHE;
59 if(!@file_exists($repertoire)) {
60 $repertoire = preg_replace(','._DIR_TMP.',', '', $repertoire);
61 $repertoire = sous_repertoire(_DIR_TMP, $repertoire);
62 }
63 $subdir = sous_repertoire($repertoire, substr($md_cache, 0, 1), true);
64
65 return $subdir.$fichier_cache;
66}
67
68// Faut-il compresser ce cache ? A partir de 16ko ca vaut le coup
69// http://doc.spip.org/@cache_gz
70function cache_gz($page) {
71 if ($GLOBALS['flag_gz'] AND strlen($page['texte']) > 16*1024)
72 return '.gz';
73 else
74 return '';
75}
76
77// gestion des delais d'expiration du cache
78// $page passee par reference pour accelerer
79// http://doc.spip.org/@cache_valide
80function cache_valide(&$page, $date) {
81
82 if (!$page) return 1;
83
84 // Cache invalide par la meta 'derniere_modif'
85 if ($GLOBALS['derniere_modif_invalide']
86 AND $date < $GLOBALS['meta']['derniere_modif'])
87 return 1;
88
89 // Sinon comparer l'age du fichier a sa duree de cache
90 $duree = intval($page['entetes']['X-Spip-Cache']);
91 if ($duree == 0) #CACHE{0}
92 return -1;
93 else if ($date + $duree < time())
94 return 1;
95 else
96 return 0;
97}
98
99
100// Creer le fichier cache
101# Passage par reference de $page par souci d'economie
102// http://doc.spip.org/@creer_cache
103function creer_cache(&$page, &$chemin_cache) {
104
105 // Normaliser le chemin et supprimer l'eventuelle contrepartie -gz du cache
106 $chemin_cache = str_replace('.gz', '', $chemin_cache);
107 $gz = cache_gz($page);
108 supprimer_fichier(_DIR_CACHE . $chemin_cache . ($gz ? '' : '.gz'));
109
110 // l'enregistrer, compresse ou non...
111 $chemin_cache .= $gz;
112 $ok = ecrire_fichier(_DIR_CACHE . $chemin_cache, serialize($page));
113
114 spip_log("Creation du cache $chemin_cache pour "
115 . $page['entetes']['X-Spip-Cache']." secondes". ($ok?'':' (erreur!)'));
116
117 // Inserer ses invalideurs
118 include_spip('inc/invalideur');
119 maj_invalideurs($chemin_cache, $page);
120
121}
122
123
124// purger un petit cache (tidy ou recherche) qui ne doit pas contenir de
125// vieux fichiers
126// http://doc.spip.org/@nettoyer_petit_cache
127function nettoyer_petit_cache($prefix, $duree = 300) {
128 // determiner le repertoire a purger : 'tmp/CACHE/rech/'
129 $dircache = sous_repertoire(_DIR_CACHE,$prefix);
130 if (spip_touch($dircache.'purger_'.$prefix, $duree, true)) {
131 foreach (preg_files($dircache,'[.]txt$') as $f) {
132 if (time() - (@file_exists($f)?@filemtime($f):0) > $duree)
133 @unlink($f);
134 }
135 }
136}
137
138
139// Interface du gestionnaire de cache
140// Si son 3e argument est non vide, elle passe la main a creer_cache
141// Sinon, elle recoit un contexte (ou le construit a partir de REQUEST_URI)
142// et affecte les 4 autres parametres recus par reference:
143// - use_cache qui vaut
144// -1 s'il faut calculer la page sans la mettre en cache
145// 0 si on peut utiliser un cache existant
146// 1 s'il faut calculer la page et la mettre en cache
147// - chemin_cache qui est le chemin d'acces au fichier ou vide si pas cachable
148// - page qui est le tableau decrivant la page, si le cache la contenait
149// - lastmodified qui vaut la date de derniere modif du fichier.
150
151// http://doc.spip.org/@public_cacher_dist
152function public_cacher_dist($contexte, &$use_cache, &$chemin_cache, &$page, &$lastmodified) {
153
154 // Second appel, destine a l'enregistrement du cache sur le disque
155 if ($chemin_cache) return creer_cache($page, $chemin_cache);
156
157 // Toute la suite correspond au premier appel
158
159 // Cas ignorant le cache car complement dynamique
160 if ($_SERVER['REQUEST_METHOD'] == 'POST'
161 OR (substr($contexte['fond'],0,8)=='modeles/')
162// Mode auteur authentifie appelant de ecrire/ : il ne faut rien lire du cache
163// et n'y ecrire que la compilation des squelettes (pas les pages produites)
164// car les references aux repertoires ne sont pas relatifs a l'espace public
165 OR !_DIR_RESTREINT) {
166 $use_cache = -1;
167 $lastmodified = 0;
168 $chemin_cache = "";
169 $page = array();
170 return;
171 }
172
173 $chemin_cache = generer_nom_fichier_cache($contexte);
174 if ($GLOBALS['flag_gz'] AND @file_exists(_DIR_CACHE.$chemin_cache.'.gz'))
175 $chemin_cache .= '.gz';
176
177 // HEAD : cas sans jamais de calcul pour raisons de performance
178 if ($_SERVER['REQUEST_METHOD'] == 'HEAD') {
179 $use_cache = 0;
180 $page = array();
181 $lastmodified = @file_exists(_DIR_CACHE . $chemin_cache) ?
182 @filemtime(_DIR_CACHE . $chemin_cache) : 0;
183 return;
184 }
185
186 // Faut-il effacer des pages invalidees (en particulier ce cache-ci) ?
187 if (isset($GLOBALS['meta']['invalider'])) {
188 // ne le faire que si la base est disponible
189 if (spip_connect()) {
190 include_spip('inc/invalideur');
191 retire_caches($chemin_cache);
192 }
193 }
194
195 // Cas sans jamais de cache pour raison interne
196 if (isset($GLOBALS['var_mode']) &&
197 (isset($_COOKIE['spip_session'])
198 || isset($_COOKIE['spip_admin'])
199 || @file_exists(_ACCESS_FILE_NAME))) {
200 supprimer_fichier(_DIR_CACHE . $chemin_cache);
201 }
202
203 // $delais par defaut (pour toutes les pages sans #CACHE{})
204 if (!isset($GLOBALS['delais'])) $GLOBALS['delais'] = 3600;
205
206 // Lire le fichier cache et determiner sa validite
207 if (lire_fichier(_DIR_CACHE . $chemin_cache, $page)) {
208 $lastmodified = @file_exists(_DIR_CACHE . $chemin_cache) ?
209 @filemtime(_DIR_CACHE . $chemin_cache) : 0;
210 $page = @unserialize($page);
211 $use_cache = cache_valide($page, $lastmodified);
212 if (!$use_cache) return; // cache utilisable
213 } else
214 $use_cache = 1; // fichier cache absent : provoque le calcul
215
216 // Si pas valide mais pas de connexion a la base, le garder quand meme
217 if (!spip_connect()) {
218 if (file_exists(_DIR_CACHE . $chemin_cache))
219 $use_cache = 0;
220 else {
221 spip_log("Erreur base de donnees, impossible utiliser $chemin_cache");
222 include_spip('inc/minipres');
223 echo minipres(_T('info_travaux_titre'), _T('titre_probleme_technique'));
224 exit;
225 }
226 }
227
228 if ($use_cache < 0) $chemin_cache = '';
229 return;
230}
231
232?>