source: spip-zone/_plugins_/cachelab/trunk/inc/cachelab_invalideur.php @ 112724

Last change on this file since 112724 was 112724, checked in by jluc@…, 2 years ago

unit tests sur le sessionnement des inclusions + stylage des infos de var_cache par pipeline

File size: 7.2 KB
Line 
1<?php
2//
3// Fonctions définies par invalideur.php dans le core,
4// et surchargées par CacheLab
5//
6
7if (!defined('_ECRIRE_INC_VERSION')) {
8        return;
9}
10include_spip('inc/cachelab_utils');
11
12/**
13 * Invalider les caches liés à telle condition
14 *
15 * Les invalideurs sont de la forme 'objet/id_objet'.
16 * La condition est géneralement "id='objet/id_objet'".
17 *
18 * Ici on se contente de noter la date de mise à jour dans les metas,
19 * pour le type d'objet en question (non utilisé cependant) et pour
20 * tout le site (sur la meta `derniere_modif`)
21 *
22 * @global derniere_modif_invalide
23 *     Par défaut à `true`, la meta `derniere_modif` est systématiquement
24 *     calculée dès qu'un invalideur se présente. Cette globale peut
25 *     être mise à `false` (aucun changement sur `derniere_modif`) ou
26 *     sur une liste de type d'objets (changements uniquement lorsqu'une
27 *     modification d'un des objets se présente).
28 *
29 * @param string $cond
30 *     Condition d'invalidation
31 * @param bool $modif
32 *     Inutilisé
33 **/
34
35
36function suivre_invalideur($cond, $modif = true) {
37        if (!$modif) {
38                return;
39        }
40       
41global $Memoization;
42static $len_prefix;
43        if (!isset($Memoization) or !$Memoization or !in_array($Memoization->methode(), array('apc', 'apcu'))) {
44                spip_log("cachelab_applique ($action, $cle...) : Memoization n'est pas activé", 'cachelab_erreur');
45                return false;
46        }
47
48        // determiner l'objet modifie : forum, article, etc
49        if (preg_match(',["\']([a-z_]+)[/"\'],', $cond, $r)) {
50                $objet = objet_type($r[1]);
51                if (!$objet) {
52                        // stocker la date_modif_extra_$extra (ne sert a rien)
53                        ecrire_meta('derniere_modif_extra_' . $r[1], time());
54                        $f="cachelab_suivre_invalideur_{$r[1]}";
55                }
56                else {
57                        // stocker la date_modif_$objet (ne sert a rien)
58                        ecrire_meta('derniere_modif_' . $objet, time());
59                        $f="cachelab_suivre_invalideur_$objet";
60                }
61                if (function_exists($f)) {
62                        spip_log ("suivre_invalideur appelle $f($cond,$modif)", "cachelab");
63                        $modif = $f($cond, $modif);      // $f renvoie la nouvelle valeur de $modif
64                        // si l'invalidation a été totalement traitée par $f, ya plus rien à faire
65                        if (!$modif)
66                                return;
67                }
68        }
69
70        // si $derniere_modif_invalide est un array('article', 'rubrique')
71        // n'affecter la meta que si c'est un de ces objets qui est modifié
72        if (is_array($GLOBALS['derniere_modif_invalide'])) {
73                if (in_array($objet, $GLOBALS['derniere_modif_invalide'])) {
74                        include_spip ('inc/cachelab');
75                        cachelab_cibler('del');
76                        spip_log ("suivre_invalideur / objet invalidant : '$objet' ($cond)", "cachelab");
77                        spip_log ("suivre_invalideur / objet invalidant : '$objet' ($cond)", "suivre_invalideur");
78                        ecrire_meta('derniere_modif', time());
79                }
80                else
81                        spip_log ("NON invalidant : $cond", "suivre_invalideur");
82
83        } // sinon, cas standard du core, toujours affecter la meta et tout effacer
84        else {
85                ecrire_meta('derniere_modif', time());
86                include_spip ('inc/cachelab');
87                cachelab_cibler('del');
88                spip_log ("suivre_invalideur standard / objet '$objet' ($cond)", "cachelab");
89                spip_log ("suivre_invalideur standard / objet '$objet' ($cond)", "suivre_invalideur");
90                // et tout effacer
91        }
92}
93
94//
95// Surcharge de maj_invalideurs
96// le core indique : "Calcul des pages : noter dans la base les liens d'invalidation"
97//
98// Appelé à la fin de creer_cache
99// $page est le tableau décrivant le cache qui vient d'être calculé
100// avec les clés suivantes pour ses métadonnées :
101// squelette,source,process_ins,invalideurs,entetes,duree,texte,notes,contexte,lastmodified,sig
102// http://code.spip.net/@maj_invalideurs
103//
104// S'il y a une entete X-Spip-Methode-Duree-Cache on récupère la méthode
105// et on appelle la fonction cachelab_calcule_duree_cache_lamethode
106// avec en argument la valeur de l'argument dans l'envt ou de date_creation par défaut
107// On corrige alors la durée du cache avec la valeur retournée.
108//
109// S'il y a une entete X-Spip-Filtre-Cache on récupère le filtre
110// et on l'appelle avec le cache entier en argument
111// Le filtre peut modifier n'importe quelle partie du cache, métadonnée ou résultat de compilation.
112//
113
114// define ('LOG_INVALIDATION_CORE', true);
115function maj_invalideurs($fichier, &$page) {
116global $Memoization;
117// Rq : ici, le texte du cache est non zipé (cf function creer_cache dans memoization),
118// tandis que la version en cache peut être zipée (avec index 'gz').
119        if  (LOG_INVALIDATION_CORE) {
120                // Abondamment appelé. À part pour pas noyer les autres
121                spip_log ("maj_invalideurs($fichier, &page)", "invalideur_core_maj_invalideurs");
122                spip_log ("maj_invalideurs($fichier, &page)\n".print_r($page,1), "invalideur_core_maj_invalideurs_details");
123        };
124
125static $var_cache;
126        $infos = $hint_squel = '';
127        if (!isset($var_cache))
128                $var_cache = _request('var_cache');
129        if ($var_cache=='sessionnement') // on veut le sessionnement seul à l'écran
130                $hint_squel = ' title="'.attribut_html($page['source']).'" ';
131        else
132                $infos = $page['source'];               // on prépare les infos supplémentaires
133
134        // Pour le calcul dynamique d'une durée de cache, la fonction user
135        // reçoit la *valeur* de l'une des valeurs de l'environnement (par défaut "date_creation")
136        // Exemple #CACHE{1200,duree-progressive date_naissance}
137        if (isset($page['entetes']['X-Spip-Methode-Duree-Cache'])) {
138                $f = 'cachelab_duree_'.$page['entetes']['X-Spip-Methode-Duree-Cache'];
139                list ($f, $arg) = split_first_arg($f, 'date_creation');
140                if (function_exists($f)) {
141                        if (!isset($page['contexte'][$arg])) {
142                                spip_log ("#CACHE avec squelette {$page['source']} et calcul de durée avec $f mais pas de '$arg' dans le contexte ".print_r($page['contexte'],1), "cachelab_erreur");
143                                return;
144                        }
145                        $duree = $f($page['contexte'][$arg]);
146                        spip_log ("#CACHE $f ($arg={$page['contexte'][$arg]}) renvoie : $duree s", "cachelab");
147
148                        if ($var_cache)
149                                echo "<div class='cachelab_blocs' $hint_squel><h6>Durée dynamique : $duree</h6><small>$infos</small></div>";
150
151                        $page['duree'] = $duree;
152                        $page['entetes']['X-Spip-Cache']=$duree;
153
154                        // On garde un souvenir
155                        // unset ($page['entetes']['X-Spip-Methode-Duree-Cache']);
156
157                        // Comme memoization, on ajoute une heure "histoire de pouvoir tourner
158                        // sur le cache quand la base de donnees est plantée (à tester)"
159                        // TODO CORE ? changer creer_cache pour qu'il appelle maj_invalideurs *avant* d'avoir écrit le cache
160                        $Memoization->set($fichier, $page, 3600+$duree);
161                }
162                else 
163                        spip_log ("#CACHE duree cache : la fonction '$f' n'existe pas (arg='$arg')\n".print_r($page,1), "cachelab_erreur");
164        }
165       
166        // Exemple : #CACHE{1200,filtre-bidouille grave} peut grave bidouiller le cache yc ses métadonnées
167        if (isset($page['entetes']['X-Spip-Filtre-Cache'])) {
168                $f = 'cachelab_filtre_'.$page['entetes']['X-Spip-Filtre-Cache'];
169                list ($f, $arg) = split_first_arg($f);
170                if (function_exists($f)) {
171                        spip_log ("#CACHE appelle le filtre $f ($arg)", "cachelab");
172                        $toset = $f($page, $arg);
173                        // Le filtre renvoie un booléen qui indique s'il faut mémoizer le cache
174                        if ($toset)
175                                $Memoization->set($fichier, $page, $cache['entete']['X-Spip-Cache']);
176                }
177                else 
178                        spip_log ("#CACHE filtre : la fonction '$f' n'existe pas (arg='$arg')\n".print_r($page,1), "cachelab_erreur");
179        }
180       
181        if ($var_cache)
182                echo '<div class="cachelab_blocs" '.$hint_squel.'><h6>Sessionnement : '
183                                .cachelab_etat_sessionnement($page['invalideurs'], 'précis')
184                         .'</h6><small>'.$infos.'</small></div>';
185}
Note: See TracBrowser for help on using the repository browser.