Completed
Push — spip-3.0 ( 5d8b58 )
by cam
53:01 queued 42:30
created

cacher.php ➔ public_cacher_dist()   F

Complexity

Conditions 28
Paths 1586

Size

Total Lines 111
Code Lines 64

Duplication

Lines 5
Ratio 4.5 %

Importance

Changes 0
Metric Value
cc 28
eloc 64
c 0
b 0
f 0
nc 1586
nop 5
dl 5
loc 111
rs 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
if (!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
21
 *
22
 * @param array $contexte
23
 * @param array $page
24
 * @return string
25
 */
26
function generer_nom_fichier_cache($contexte, $page) {
27
28
	$cache = $page['contexte_implicite']['cache'] . '-';
29
30
	foreach ($contexte as $var=>$val) {
31
		$val = is_array($val) ? var_export($val,true) : strval($val);
32
		$cache .= str_replace('-', '_', $val) . '-' ;
33
	}
34
35
	$cache = str_replace('/', '_', rawurlencode($cache));
36
37
	if (strlen($cache) > 24) {
38
		$cache = preg_replace('/([a-zA-Z]{1,3})[^-_]*[-_]/', '\1-', $cache);
39
		$cache = substr($cache, 0, 24);
40
	}
41
42
	// Morceau de md5 selon HOST, $dossier_squelettes et $marqueur
43
	// permet de changer le nom du cache en changeant ceux-ci
44
	// donc, par exemple, de gerer differents dossiers de squelettes
45
	// en parallele, ou de la "personnalisation" via un marqueur (dont la
46
	// composition est totalement libre...)
47
	$md_cache = md5(
48
		var_export($page['contexte_implicite'],true) . ' '
49
		. var_export($contexte,true)
50
	);
51
52
	$cache .= '-'.substr($md_cache, 1, 32-strlen($cache));
53
54
	// Sous-repertoires 0...9a..f ; ne pas prendre la base _DIR_CACHE
55
	$rep = _DIR_CACHE;
56
57
	$rep = sous_repertoire($rep, '', false,true);
58
	$subdir = sous_repertoire($rep, substr($md_cache, 0, 1), true,true);
59
	return $subdir.$cache;
60
}
61
62
/**
63
 * Faut-il compresser ce cache ? A partir de 16ko ca vaut le coup
64
 * (pas de passage par reference car on veut conserver la version non compressee
65
 * pour l'afficher)
66
 * on positionne un flag gz si on comprime, pour savoir si on doit decompresser ou pas
67
 * http://doc.spip.org/@gzip_page
68
 *
69
 * @param array $page
70
 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,boolean|string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
71
 */
72
function gzip_page($page) {
73
	if (function_exists('gzcompress') AND strlen($page['texte']) > 16*1024) {
74
		$page['gz'] = true;
75
		$page['texte'] = gzcompress($page['texte']);
76
	} else {
77
		$page['gz'] = false;
78
	}
79
	return $page;
80
}
81
82
/**
83
 * Faut-il decompresser ce cache ?
84
 * (passage par reference pour alleger)
85
 * on met a jour le flag gz quand on decompresse, pour ne pas risquer
86
 * de decompresser deux fois de suite un cache (ce qui echoue)
87
 *
88
 * http://doc.spip.org/@gunzip_page
89
 *
90
 * @param array $page
91
 * @return void
92
 */
93
function gunzip_page(&$page) {
94
	if ($page['gz']) {
95
		$page['texte'] = gzuncompress($page['texte']);
96
		$page['gz'] = false; // ne pas gzuncompress deux fois une meme page
97
	}
98
}
99
100
/**
101
 * gestion des delais d'expiration du cache...
102
 * $page passee par reference pour accelerer
103
 * 
104
 * @param array $page
105
 * @param int $date
106
 * @return int
107
 * 1 si il faut mettre le cache a jour
108
 * 0 si le cache est valide
109
 * -1 si il faut calculer sans stocker en cache
110
 */
111
/// http://doc.spip.org/@cache_valide
112
function cache_valide(&$page, $date) {
113
114
	// Apparition d'un nouvel article post-date ?
115
	if ($GLOBALS['meta']['post_dates'] == 'non'
116
	  AND isset($GLOBALS['meta']['date_prochain_postdate'])
117
	  AND time() > $GLOBALS['meta']['date_prochain_postdate']) {
118
		spip_log('Un article post-date invalide le cache');
119
		include_spip('inc/rubriques');
120
		calculer_prochain_postdate(true);
121
	}
122
123
	if (defined('_VAR_NOCACHE') AND _VAR_NOCACHE) return -1;
124
	if (isset($GLOBALS['meta']['cache_inhib']) AND $_SERVER['REQUEST_TIME']<$GLOBALS['meta']['cache_inhib']) return -1;
125
	if (defined('_NO_CACHE')) return (_NO_CACHE==0 AND !isset($page['texte']))?1:_NO_CACHE;
126
127
	// pas de cache ? on le met a jour, sauf pour les bots (on leur calcule la page sans mise en cache)
128
	if (!$page OR !isset($page['texte']) OR !isset($page['entetes']['X-Spip-Cache'])) return _IS_BOT?-1:1;
129
130
	// #CACHE{n,statique} => on n'invalide pas avec derniere_modif
131
	// cf. ecrire/public/balises.php, balise_CACHE_dist()
132
	if (!isset($page['entetes']['X-Spip-Statique']) OR $page['entetes']['X-Spip-Statique'] !== 'oui') {
133
134
		// Cache invalide par la meta 'derniere_modif'
135
		// sauf pour les bots, qui utilisent toujours le cache
136
		if (!_IS_BOT
137
		AND $GLOBALS['derniere_modif_invalide']
138
		AND $date < $GLOBALS['meta']['derniere_modif'])
139
			return 1;
140
141
	}
142
143
	// Sinon comparer l'age du fichier a sa duree de cache
144
	$duree = intval($page['entetes']['X-Spip-Cache']);
145
	if ($duree == 0)  #CACHE{0}
146
		return -1;
147
	// sauf pour les bots, qui utilisent toujours le cache
148
	else if (!_IS_BOT AND $date + $duree < time())
149
		return 1;
150
	else
151
		return 0;
152
}
153
154
/**
155
 * Creer le fichier cache
156
 * Passage par reference de $page par souci d'economie
157
 *
158
 * http://doc.spip.org/@creer_cache
159
 *
160
 * @param array $page
161
 * @param string $chemin_cache
162
 * @return void
163
 */
164
function creer_cache(&$page, &$chemin_cache) {
165
166
	// Ne rien faire si on est en preview, debug, ou si une erreur
167
	// grave s'est presentee (compilation du squelette, MySQL, etc)
168
	// le cas var_nocache ne devrait jamais arriver ici (securite)
169
	// le cas spip_interdire_cache correspond a une ereur SQL grave non anticipable
170
	if ((defined('_VAR_NOCACHE') AND _VAR_NOCACHE)
171
		OR defined('spip_interdire_cache'))
172
		return;
173
174
	// Si la page c1234 a un invalideur de session 'zz', sauver dans
175
	// 'tmp/cache/MD5(chemin_cache)_zz'
176
	if (isset($page['invalideurs'])
177
	AND isset($page['invalideurs']['session'])) {
178
		// on verifie que le contenu du chemin cache indique seulement
179
		// "cache sessionne" ; sa date indique la date de validite
180
		// des caches sessionnes
181
		if (!lire_fichier(_DIR_CACHE . $chemin_cache, $tmp)
182
		OR !$tmp = @unserialize($tmp)) {
183
			spip_log('Creation cache sessionne '.$chemin_cache);
184
			$tmp = array(
185
				'invalideurs' => array('session' => ''),
186
				'lastmodified' => time()
187
			);
188
			ecrire_fichier(_DIR_CACHE . $chemin_cache, serialize($tmp));
189
		}
190
		$chemin_cache .= '_'.$page['invalideurs']['session'];
191
	}
192
193
	// ajouter la date de production dans le cache lui meme
194
	// (qui contient deja sa duree de validite)
195
	$page['lastmodified'] = time();
196
197
198
	// l'enregistrer, compresse ou non...
199
	$ok = ecrire_fichier(_DIR_CACHE . $chemin_cache,
200
		serialize(gzip_page($page)));
201
202
	spip_log("Creation du cache $chemin_cache pour "
203
		. $page['entetes']['X-Spip-Cache']." secondes". ($ok?'':' (erreur!)'));
204
205
	// Inserer ses invalideurs
206
	include_spip('inc/invalideur');
207
	maj_invalideurs($chemin_cache, $page);
208
209
}
210
211
212
/**
213
 * purger un petit cache (tidy ou recherche) qui ne doit pas contenir de
214
 * vieux fichiers ; (cette fonction ne sert que dans des plugins obsoletes)
215
 *
216
 * http://doc.spip.org/@nettoyer_petit_cache
217
 *
218
 * @param string $prefix
219
 * @param int $duree
220
 * @return void
221
 */
222
function nettoyer_petit_cache($prefix, $duree = 300) {
223
	// determiner le repertoire a purger : 'tmp/CACHE/rech/'
224
	$dircache = sous_repertoire(_DIR_CACHE,$prefix);
225
	if (spip_touch($dircache.'purger_'.$prefix, $duree, true)) {
226
		foreach (preg_files($dircache,'[.]txt$') as $f) {
227
			if (time() - (@file_exists($f)?@filemtime($f):0) > $duree)
228
				spip_unlink($f);
229
		}
230
	}
231
}
232
233
234
/**
235
 * Interface du gestionnaire de cache
236
 * Si son 3e argument est non vide, elle passe la main a creer_cache
237
 * Sinon, elle recoit un contexte (ou le construit a partir de REQUEST_URI)
238
 * et affecte les 4 autres parametres recus par reference:
239
 * - use_cache qui vaut
240
 *     -1 s'il faut calculer la page sans la mettre en cache
241
 *      0 si on peut utiliser un cache existant
242
 *      1 s'il faut calculer la page et la mettre en cache
243
 * - chemin_cache qui est le chemin d'acces au fichier ou vide si pas cachable
244
 * - page qui est le tableau decrivant la page, si le cache la contenait
245
 * - lastmodified qui vaut la date de derniere modif du fichier.
246
 * Elle retourne '' si tout va bien
247
 * un message d'erreur si le calcul de la page est totalement impossible
248
 *
249
 * http://doc.spip.org/@public_cacher_dist
250
 *
251
 * @param array $contexte
252
 * @param int $use_cache
253
 * @param string $chemin_cache
254
 * @param array $page
255
 * @param int $lastmodified
256
 * @return string|void
257
 */
258
function public_cacher_dist($contexte, &$use_cache, &$chemin_cache, &$page, &$lastmodified) {
259
260
	# fonction de cache minimale : dire "non on ne met rien en cache"
261
	# $use_cache = -1; return;
262
263
	// Second appel, destine a l'enregistrement du cache sur le disque
264
	if (isset($chemin_cache)) return creer_cache($page, $chemin_cache);
265
266
	// Toute la suite correspond au premier appel
267
	$contexte_implicite = $page['contexte_implicite'];
268
269
	// Cas ignorant le cache car completement dynamique
270
	if ($_SERVER['REQUEST_METHOD'] == 'POST'
271
	  OR _request('connect')) {
272
		$use_cache = -1;
273
		$lastmodified = 0;
274
		$chemin_cache = "";
275
		$page = array();
276
		return;
277
	}
278
279
	// Controler l'existence d'un cache nous correspondant
280
	$chemin_cache = generer_nom_fichier_cache($contexte, $page);
281
	$lastmodified = 0;
282
283
	// charger le cache s'il existe
284
	if (lire_fichier(_DIR_CACHE . $chemin_cache, $page))
285
		$page = @unserialize($page);
286
	else
287
		$page = array();
288
289
	// s'il est sessionne, charger celui correspondant a notre session
290
	if (isset($page['invalideurs'])
291
	AND isset($page['invalideurs']['session'])) {
292
		$chemin_cache_session = $chemin_cache . '_' . spip_session();
293
		if (lire_fichier(_DIR_CACHE . $chemin_cache_session, $page_session)
294
		AND $page_session = @unserialize($page_session)
295
		AND $page_session['lastmodified'] >= $page['lastmodified'])
296
			$page = $page_session;
297
		else
298
			$page = array();
299
	}
300
301
302
	// Faut-il effacer des pages invalidees (en particulier ce cache-ci) ?
303
	if (isset($GLOBALS['meta']['invalider'])) {
304
		// ne le faire que si la base est disponible
305
		if (spip_connect()) {
306
			include_spip('inc/invalideur');
307
			retire_caches($chemin_cache); # API invalideur inutile
308
			supprimer_fichier(_DIR_CACHE.$chemin_cache);
309
			if (isset($chemin_cache_session) and $chemin_cache_session)
310
				supprimer_fichier(_DIR_CACHE.$chemin_cache_session);
311
		}
312
	}
313
314
	// Si un calcul, recalcul [ou preview, mais c'est recalcul] est demande,
315
	// on supprime le cache
316
	if (defined('_VAR_MODE') && _VAR_MODE &&
317
		(isset($_COOKIE['spip_session'])
318
		|| isset($_COOKIE['spip_admin'])
319
		|| @file_exists(_ACCESS_FILE_NAME))
320
	) {
321
		$page = array('contexte_implicite'=>$contexte_implicite); // ignorer le cache deja lu
322
		include_spip('inc/invalideur');
323
		retire_caches($chemin_cache); # API invalideur inutile
324
		supprimer_fichier(_DIR_CACHE.$chemin_cache);
325
		if (isset($chemin_cache_session) and $chemin_cache_session)
326
			supprimer_fichier(_DIR_CACHE.$chemin_cache_session);
327
	}
328
329
	// $delais par defaut
330
	// pour toutes les pages sans #CACHE{} hors modeles/ et espace priv�
331
	// qui sont a cache nul par defaut
332
	if (!isset($GLOBALS['delais'])) {
333
		define('_DUREE_CACHE_DEFAUT', 24*3600);
334
		$GLOBALS['delais'] = _DUREE_CACHE_DEFAUT;
335
	}
336
337
	// determiner la validite de la page
338
	if ($page) {
339
		$use_cache = cache_valide($page, isset($page['lastmodified']) ? $page['lastmodified'] : 0);
340
		// le contexte implicite n'est pas stocke dans le cache, mais il y a equivalence
341
		// par le nom du cache. On le reinjecte donc ici pour utilisation eventuelle au calcul
342
		$page['contexte_implicite'] = $contexte_implicite;
343
		if (!$use_cache) {
344
			// $page est un cache utilisable
345
			gunzip_page($page);
346
			return;
347
		}
348
	} else {
349
		$page = array('contexte_implicite'=>$contexte_implicite);
350
		$use_cache = cache_valide($page,0); // fichier cache absent : provoque le calcul
351
	}
352
353
	// Si pas valide mais pas de connexion a la base, le garder quand meme
354
	if (!spip_connect()) {
355
		if (isset($page['texte'])) {
356
			gunzip_page($page);
357
			$use_cache = 0;
358
		}
359 View Code Duplication
		else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
360
			spip_log("Erreur base de donnees, impossible utiliser $chemin_cache");
361
			include_spip('inc/minipres');
362
			return minipres(_T('info_travaux_titre'),  _T('titre_probleme_technique'));
363
		}
364
	}
365
366
	if ($use_cache < 0) $chemin_cache = '';
367
	return;
368
}
369
370
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
371