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

Last change on this file since 113218 was 113218, checked in by jluc@…, 4 months ago

La durée dynamique d'un cache peut désormais aussi se calculer avec d'autres données du cache qu'une variable d'environnement + exemple de la doc : jusquaminuit (Eric OSC)

File size: 6.9 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
41        $objet='';
42        // determiner l'objet modifie : forum, article, etc
43        if (preg_match(',["\']([a-z_]+)[/"\'],', $cond, $r)) {
44                $objet = objet_type($r[1]);
45                if (!$objet) {  // cas par exemple de 'recalcul' ?
46                        spip_log("suivre_invalideur avec typesignal {$r[1]} sans objet_type", 'cachelab_signal_exotique_ou_erreur');
47                        // stocker la date_modif_extra_$extra (ne sert a rien)
48                        ecrire_meta('derniere_modif_extra_' . $r[1], time());
49                        $f="cachelab_suivre_invalideur_{$r[1]}";
50                }
51                else {
52                        // stocker la date_modif_$objet (ne sert a rien)
53                        ecrire_meta('derniere_modif_' . $objet, time());
54                        $f="cachelab_suivre_invalideur_$objet";
55                }
56
57                if (function_exists($f)) {
58                        spip_log ("suivre_invalideur appelle $f($cond,$modif)", "cachelab");
59                        $modif = $f($cond, $modif);      // $f renvoie la nouvelle valeur de $modif
60                        // si l'invalidation a été totalement traitée par $f, ya plus rien à faire
61                        if (!$modif)
62                                return;
63                }
64        }
65
66        // affecter la meta si $derniere_modif_invalide est un array (de types d'objets)
67        // et que c'est un de ces objets qui est modifié
68        // OU bien si ce n'est pas un array
69        if (!is_array($GLOBALS['derniere_modif_invalide'])
70                or ($objet
71                        and in_array($objet, $GLOBALS['derniere_modif_invalide']))) {
72                ecrire_meta('derniere_modif', time());
73                include_spip ('inc/cachelab');
74                spip_log ("invalidation totale / signal '$cond' avec objet '$objet'", "suivre_invalideur");
75        }
76        else 
77                spip_log ("invalidation évitée : $cond", "cachelab_not");
78}
79
80//
81// Surcharge de maj_invalideurs
82// le core indique : "Calcul des pages : noter dans la base les liens d'invalidation"
83//
84// Appelé à la fin de creer_cache
85// $page est le tableau décrivant le cache qui vient d'être calculé
86// avec les clés suivantes pour ses métadonnées :
87// squelette,source,process_ins,invalideurs,entetes,duree,texte,notes,contexte,lastmodified,sig
88// http://code.spip.net/@maj_invalideurs
89//
90// S'il y a une entete X-Spip-Methode-Duree-Cache on récupère la méthode
91// et on appelle la fonction cachelab_calcule_duree_cache_lamethode
92// avec en argument la valeur de l'argument dans l'envt ou de date_creation par défaut
93// On corrige alors la durée du cache avec la valeur retournée.
94//
95// S'il y a une entete X-Spip-Filtre-Cache on récupère le filtre
96// et on l'appelle avec le cache entier en argument
97// Le filtre peut modifier n'importe quelle partie du cache, métadonnée ou résultat de compilation.
98//
99
100// define ('LOG_INVALIDATION_CORE', true);
101function maj_invalideurs($fichier, &$page) {
102global $Memoization;
103// Rq : ici, le texte du cache est non zipé (cf function creer_cache dans memoization),
104// tandis que la version en cache peut être zipée (avec index 'gz').
105        if  (LOG_INVALIDATION_CORE) {
106                // Abondamment appelé. À part pour pas noyer les autres
107                spip_log ("maj_invalideurs($fichier, &page)", "invalideur_core_maj_invalideurs");
108                spip_log ("maj_invalideurs($fichier, &page)\n".print_r($page,1), "invalideur_core_maj_invalideurs_details");
109        };
110
111static $var_cache;
112        $infos = $hint_squel = '';
113        if (!isset($var_cache))
114                $var_cache = _request('var_cache');
115        if ($var_cache=='sessionnement') // on veut le sessionnement seul à l'écran
116                $hint_squel = ' title="'.attribut_html($page['source']).'" ';
117        else
118                $infos = $page['source'];               // on prépare les infos supplémentaires
119
120        // Pour le calcul dynamique d'une durée de cache, la fonction user
121        // reçoit la *valeur* de l'une des valeurs de l'environnement (par défaut "date_creation")
122        // Exemple #CACHE{1200,duree-progressive date_naissance}
123        if (isset($page['entetes']['X-Spip-Methode-Duree-Cache'])) {
124                $f = 'cachelab_duree_'.$page['entetes']['X-Spip-Methode-Duree-Cache'];
125                list ($f, $arg) = split_first_arg($f, 'date_creation');
126                if (function_exists($f)) {
127                        if (!isset($page['contexte'][$arg])) {
128                                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");
129                                return;
130                        }
131                        $duree = $f($page['contexte'][$arg],$page);
132                        if (!is_null($duree)) {
133                                if (!defined('LOG_CACHELAB_DUREES_DYNAMIQUES') or LOG_CACHELAB_DUREES_DYNAMIQUES)
134                                        spip_log ("#CACHE $f ($arg={$page['contexte'][$arg]}) renvoie : $duree s", "cachelab");
135
136                                if ($var_cache)
137                                        echo "<div class='cachelab_blocs' $hint_squel><h6>Durée dynamique : $duree</h6><small>$infos</small></div>";
138
139                                $page['duree'] = $duree;
140                                $page['entetes']['X-Spip-Cache']=$duree;
141
142                                // On garde un souvenir
143                                // unset ($page['entetes']['X-Spip-Methode-Duree-Cache']);
144
145                                // Comme memoization, on ajoute une heure "histoire de pouvoir tourner
146                                // sur le cache quand la base de donnees est plantée (à tester)"
147                                // TODO CORE ? changer creer_cache pour qu'il appelle maj_invalideurs *avant* d'avoir écrit le cache
148                                $Memoization->set($fichier, $page, 3600+$duree);
149                        }
150                }
151                else 
152                        spip_log ("#CACHE duree cache : la fonction '$f' n'existe pas (arg='$arg')\n".print_r($page,1), "cachelab_erreur");
153        }
154       
155        // Exemple : #CACHE{1200,filtre-bidouille grave} peut grave bidouiller le cache yc ses métadonnées
156        if (isset($page['entetes']['X-Spip-Filtre-Cache'])) {
157                $f = 'cachelab_filtre_'.$page['entetes']['X-Spip-Filtre-Cache'];
158                list ($f, $arg) = split_first_arg($f);
159                if (function_exists($f)) {
160                        if (!defined('LOG_CACHELAB_FILTRES') or LOG_CACHELAB_FILTRES)
161                                spip_log ("#CACHE appelle le filtre $f ($arg)", "cachelab");
162                        $toset = $f($page, $arg);
163                        // Le filtre renvoie un booléen qui indique s'il faut mémoizer le cache
164                        if ($toset)
165                                $Memoization->set($fichier, $page, $cache['entete']['X-Spip-Cache']);
166                }
167                else 
168                        spip_log ("#CACHE filtre : la fonction '$f' n'existe pas (arg='$arg')\n".print_r($page,1), "cachelab_erreur");
169        }
170       
171        if ($var_cache)
172                echo '<div class="cachelab_blocs" '.$hint_squel.'><h6>Sessionnement : '
173                                .cachelab_etat_sessionnement($page['invalideurs'], 'précis')
174                         .'</h6><small>'.$infos.'</small></div>';
175}
Note: See TracBrowser for help on using the repository browser.