source: spip-zone/_plugins_/cache/trunk/inc/cache.php @ 113835

Last change on this file since 113835 was 113835, checked in by eric@…, 10 days ago

Mise à jour des services et API et début du formulaire de vidage

  • Property svn:eol-style set to native
File size: 16.6 KB
Line 
1<?php
2/**
3 * Ce fichier contient les fonctions d'API du plugin Cache Factory.
4 *
5 * @package SPIP\CACHE\API
6 */
7if (!defined('_ECRIRE_INC_VERSION')) {
8        return;
9}
10
11
12/**
13 * Ecrit un contenu dans un cache spécifié par son identifiant.
14 *
15 * @api
16 *
17 * @uses cache_configuration_lire()
18 * @uses cache_cache_configurer()
19 * @uses cache_cache_composer()
20 *
21 * @param string       $plugin
22 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
23 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
24 * @param array|string $cache
25 *        Identifiant du cache sous la forme d'une chaine (le chemin du fichier) ou d'un tableau fournissant
26 *        les composants canoniques du nom.
27 * @param array|string $contenu
28 *        Contenu sous forme de tableau à sérialiser ou sous la forme d'une chaine.
29 *
30 * @return bool
31 *         True si l'écriture s'est bien passée, false sinon.
32 */
33function cache_ecrire($plugin, $cache, $contenu) {
34
35        // Initialisation du retour de la fonction
36        $cache_ecrit = false;
37       
38        // Lecture de la configuration des caches du plugin.
39        // Si celle-ci n'existe pas encore elle est créée (cas d'un premier appel).
40        static $configuration = array();
41        include_spip('cache/cache');
42        if (empty($configuration[$plugin]) and (!$configuration[$plugin] = cache_configuration_lire($plugin))) {
43                $configuration[$plugin] = cache_cache_configurer($plugin);
44        }
45       
46        // Le cache peut-être fourni soit sous la forme d'un chemin complet soit sous la forme d'un
47        // tableau permettant de calculer le chemin complet. On prend en compte ces deux cas.
48        $fichier_cache = '';
49        include_spip('inc/flock');
50        if (is_array($cache)) {
51                // Création du répertoire du cache à créer, si besoin.
52                $erreur_sous_dossier = false;
53                if ($configuration[$plugin]['sous_dossier']) {
54                        if (!empty($cache['sous_dossier'])) {
55                                // Si le cache nécessite un sous-dossier on crée le répertoire au besoin.
56                                sous_repertoire($configuration[$plugin]['dossier_base'], rtrim($cache['sous_dossier'], '/'));
57                        } else {
58                                // C'est une erreur, le sous-dossier n'a pas été fourni alors qu'il est requis. On arrête l'écriture.
59                                $erreur_sous_dossier = true;
60                        }
61                }
62
63                // Détermination du chemin du cache si pas d'erreur sur le sous-dossier :
64                // - le nom sans extension est construit à partir des éléments fournis sur le conteneur et
65                //   de la configuration du nom pour le plugin.
66                if (!$erreur_sous_dossier) {
67                        $fichier_cache = cache_cache_composer($plugin, $cache, $configuration[$plugin]);
68                }
69        } elseif (is_string($cache)) {
70                // Le chemin complet du fichier cache est fourni. Aucune vérification ne peut être faite
71                // il faut donc que l'appelant ait utilisé l'API pour calculer le fichier au préalable.
72                $fichier_cache = $cache;
73        }
74       
75        if ($fichier_cache) {
76                // Suivant que la configuration demande une sérialisation ou pas, on vérife le format du contenu
77                // de façon à toujours écrire une chaine.
78                $contenu_cache = '';
79                if ($configuration[$plugin]['serialisation']) {
80                        if (!is_array($contenu)) {
81                                $contenu = $contenu ? array($contenu) : array();
82                        }
83                        $contenu_cache = serialize($contenu);
84                } else {
85                        if (is_string($contenu)) {
86                                $contenu_cache = $contenu;
87                        }
88                }
89
90                // Ecriture du fichier cache sécurisé ou pas suivant la configuration.
91                $ecrire = 'ecrire_fichier';
92                if ($configuration[$plugin]['securisation']) {
93                        $ecrire = 'ecrire_fichier_securise';
94                }
95                $cache_ecrit = $ecrire($fichier_cache, $contenu_cache);
96        }
97       
98        return $cache_ecrit;
99}
100
101
102/**
103 * Lit le cache spécifié par son identifiant et renvoie le contenu sous forme de tableau
104 * ou de chaine éventuellement vide.
105 *
106 * @api
107 *
108 * @uses cache_configuration_lire()
109 * @uses cache_cache_configurer()
110 * @uses cache_cache_composer()
111 *
112 * @param string       $plugin
113 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
114 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
115 * @param array|string $cache
116 *        Identifiant du cache sous la forme d'une chaine (le chemin du fichier) ou d'un tableau fournissant
117 *        les composants canoniques du nom.
118 *
119 * @return array|string|bool
120 *        Contenu du fichier sous la forme d'un tableau, d'une chaine ou false si une erreur s'est produite.
121 */
122function cache_lire($plugin, $cache) {
123
124        // Initialisation du contenu du cache
125        $cache_lu = false;
126       
127        // Lecture de la configuration des caches du plugin.
128        // Si celle-ci n'existe pas encore elle est créée (cas d'un premier appel, peu probable pour une lecture).
129        static $configuration = array();
130        include_spip('cache/cache');
131        if (empty($configuration[$plugin]) and (!$configuration[$plugin] = cache_configuration_lire($plugin))) {
132                $configuration[$plugin] = cache_cache_configurer($plugin);
133        }
134
135        // Le cache peut-être fourni soit sous la forme d'un chemin complet soit sous la forme d'un
136        // tableau permettant de calculer le chemin complet. On prend en compte ces deux cas.
137        $fichier_cache = '';
138        if (is_array($cache)) {
139                // Détermination du chemin du cache :
140                // - le nom sans extension est construit à partir des éléments fournis sur le conteneur et
141                //   de la configuration du nom pour le plugin.
142                $fichier_cache = cache_cache_composer($plugin, $cache, $configuration[$plugin]);
143        } elseif (is_string($cache)) {
144                // Le chemin complet du fichier cache est fourni. Aucune vérification ne peut être faite
145                // il faut donc que l'appelant ait utilisé l'API pour calculer le fichier au préalable.
146                $fichier_cache = $cache;
147        }
148
149        // Détermination du nom du cache en fonction du plugin appelant et du type
150        if ($fichier_cache) {
151                // Lecture du fichier cache sécurisé ou pas suivant la configuration.
152                include_spip('inc/flock');
153                $lire = 'lire_fichier';
154                if ($configuration[$plugin]['securisation']) {
155                        $lire = 'lire_fichier_securise';
156                }
157                $contenu_cache = '';
158                $lecture_ok = $lire($fichier_cache, $contenu_cache);
159               
160                if ($lecture_ok) {
161                        if ($configuration[$plugin]['serialisation']) {
162                                $cache_lu = unserialize($contenu_cache);
163                        } else {
164                                $cache_lu = $contenu_cache;
165                        }
166                }
167        }
168
169        return $cache_lu;
170}
171
172
173/**
174 * Teste l'existence d'un cache sur le disque et, si il existe, renvoie le chemin complet.
175 *
176 * @api
177 *
178 * @uses cache_configuration_lire()
179 * @uses cache_cache_configurer()
180 * @uses cache_cache_composer()
181 *
182 * @param string       $plugin
183 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
184 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
185 * @param array|string $cache
186 *        Identifiant du cache sous la forme d'une chaine (le chemin du fichier) ou d'un tableau fournissant
187 *        les composants canoniques du nom.
188 *
189 * @return string
190 */
191function cache_existe($plugin, $cache) {
192
193        // Lecture de la configuration des caches du plugin.
194        // Si celle-ci n'existe pas encore elle est créée (cas d'un premier appel).
195        static $configuration = array();
196        include_spip('cache/cache');
197        if (empty($configuration[$plugin]) and (!$configuration[$plugin] = cache_configuration_lire($plugin))) {
198                $configuration[$plugin] = cache_cache_configurer($plugin);
199        }
200
201        // Le cache peut-être fourni soit sous la forme d'un chemin complet soit sous la forme d'un
202        // tableau permettant de calculer le chemin complet. On prend en compte ces deux cas.
203        $fichier_cache = '';
204        if (is_array($cache)) {
205                // Détermination du chemin du cache :
206                // - le nom sans extension est construit à partir des éléments fournis sur le conteneur et
207                //   de la configuration du nom pour le plugin.
208                $fichier_cache = cache_cache_composer($plugin, $cache, $configuration[$plugin]);
209        } elseif (is_string($cache)) {
210                // Le chemin complet du fichier cache est fourni. Aucune vérification ne peut être faite
211                // il faut donc que l'appelant ait utilisé l'API cache_existe() pour calculer le fichier au préalable.
212                $fichier_cache = $cache;
213        }
214
215        // Vérifier l'existence du fichier.
216        if ($fichier_cache) {
217                if (!file_exists($fichier_cache)) {
218                        $fichier_cache = '';
219                }
220        }
221
222        return $fichier_cache;
223}
224
225
226/**
227 * Renvoie le chemin complet du cache sans tester son existence.
228 * Cette fonction est une encapsulation du service cache_cache_composer().
229 *
230 * @api
231 *
232 * @uses cache_configuration_lire()
233 * @uses cache_cache_configurer()
234 * @uses cache_cache_composer()
235 *
236 * @param string $plugin
237 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
238 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
239 * @param array  $cache
240 *        Identifiant du cache sous la forme d'un tableau fournissant les composants canoniques du nom.
241 *
242 * @return string
243 */
244function cache_nommer($plugin, $cache) {
245
246        // Lecture de la configuration des caches du plugin.
247        // Si celle-ci n'existe pas encore elle est créée (cas d'un premier appel).
248        static $configuration = array();
249        include_spip('cache/cache');
250        if (empty($configuration[$plugin]) and (!$configuration[$plugin] = cache_configuration_lire($plugin))) {
251                $configuration[$plugin] = cache_cache_configurer($plugin);
252        }
253
254        // Le cache est toujours fourni sous la forme d'un tableau permettant de calculer le chemin complet.
255        $fichier_cache = '';
256        if (is_array($cache)) {
257                // Détermination du chemin du cache :
258                // - le nom sans extension est construit à partir des éléments fournis sur le conteneur et
259                //   de la configuration du nom pour le plugin.
260                $fichier_cache = cache_cache_composer($plugin, $cache, $configuration[$plugin]);
261        }
262
263        return $fichier_cache;
264}
265
266
267/**
268 * Supprime le cache spécifié par son identifiant.
269 *
270 * @api
271 *
272 * @uses cache_configuration_lire()
273 * @uses cache_cache_configurer()
274 * @uses cache_cache_composer()
275 * @uses supprimer_fichier()
276 *
277 * @param string       $plugin
278 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
279 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
280 * @param array|string $cache
281 *        Identifiant du cache sous la forme d'une chaine (le chemin du fichier) ou d'un tableau fournissant
282 *        les composants canoniques du nom.
283 *
284 * @return bool
285 *         True si la suppression s'est bien passée, false sinon.
286 */
287function cache_supprimer($plugin, $cache) {
288
289        // Initialisation du contenu du cache
290        $cache_supprime = false;
291       
292        // Lecture de la configuration des caches du plugin.
293        // Si celle-ci n'existe pas encore elle est créée (cas d'un premier appel, peu probable pour une lecture).
294        static $configuration = array();
295        include_spip('cache/cache');
296        if (empty($configuration[$plugin]) and (!$configuration[$plugin] = cache_configuration_lire($plugin))) {
297                $configuration[$plugin] = cache_cache_configurer($plugin);
298        }
299
300        // Le cache peut-être fourni soit sous la forme d'un chemin complet soit sous la forme d'un
301        // tableau permettant de calculer le chemin complet. On prend en compte ces deux cas.
302        $fichier_cache = '';
303        if (is_array($cache)) {
304                // Détermination du chemin du cache :
305                // - le nom sans extension est construit à partir des éléments fournis sur le conteneur et
306                //   de la configuration du nom pour le plugin.
307                $fichier_cache = cache_cache_composer($plugin, $cache, $configuration[$plugin]);
308        } elseif (is_string($cache)) {
309                // Le chemin complet du fichier cache est fourni. Aucune vérification ne peut être faite
310                // il faut donc que l'appelant ait utilisé l'API cache_existe() pour calculer le fichier au préalable.
311                $fichier_cache = $cache;
312        }
313
314        // Détermination du nom du cache en fonction du plugin appelant et du type
315        if ($fichier_cache) {
316                // Lecture du fichier cache sécurisé ou pas suivant la configuration.
317                include_spip('inc/flock');
318                $cache_supprime = supprimer_fichier($fichier_cache);
319        }
320
321        return $cache_supprime;
322}
323
324
325/**
326 * Retourne la description complète des caches d'un plugin filtrés sur une liste de critères.
327 *
328 * @api
329 *
330 * @uses cache_configuration_lire()
331 * @uses cache_cache_configurer()
332 * @uses cache_cache_composer()
333 * @uses cache_cache_decomposer()
334 * @uses cache_cache_completer()
335 *
336 * @param string       $plugin
337 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
338 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
339 * @param array $filtres
340 *        Tableau associatif `[champ] = valeur` ou `[champ] = !valeur` de critères de filtres sur les composants
341 *        de caches. Les opérateurs égalité et inégalité sont possibles.
342 *
343 * @return array
344 *        Tableau des descriptions des fichiers cache créés par le plugin indexé par le chemin complet de
345 *        chaque fichier cache.
346 */
347function cache_repertorier($plugin, $filtres = array()) {
348
349        // Initialisation de la liste des caches
350        $caches = array();
351
352        // Lecture de la configuration des caches du plugin.
353        // Si celle-ci n'existe pas encore elle est créée (cas d'un premier appel, peu probable pour une lecture).
354        static $configuration = array();
355        include_spip('cache/cache');
356        if (empty($configuration[$plugin]) and (!$configuration[$plugin] = cache_configuration_lire($plugin))) {
357                $configuration[$plugin] = cache_cache_configurer($plugin);
358        }
359
360        // Rechercher les caches du plugin sans appliquer de filtre si ce n'est sur le sous-dossier éventuellement.
361        // Les autres filtres seront appliqués sur les fichiers récupérés.
362        $pattern_fichier = $configuration[$plugin]['dossier_base'];
363        if ($configuration[$plugin]['sous_dossier']) {
364                if (array_key_exists('sous_dossier', $filtres)) {
365                        $pattern_fichier .= rtrim($filtres['sous_dossier'], '/') . '/';
366                } else {
367                        $pattern_fichier .= '*/';
368                }
369        }
370
371        // On complète le pattern avec une recherche d'un nom quelconque mais avec l'extension configurée.
372        $pattern_fichier .= '*' . $configuration[$plugin]['extension'];
373
374        // On recherche les fichiers correspondant au pattern.
375        $fichiers_cache = glob($pattern_fichier);
376
377        if ($fichiers_cache) {
378                foreach ($fichiers_cache as $_fichier_cache) {
379                        // On décompose le chemin de chaque cache afin de renvoyer l'identifiant canonique du cache.
380                        $cache = cache_cache_decomposer($plugin, $_fichier_cache, $configuration[$plugin]);
381
382                        // Maintenant que les composants sont déterminés on applique les filtres pour savoir si on
383                        // complète et stocke le cache.
384                        $cache_conforme = true;
385                        foreach ($filtres as $_critere => $_valeur) {
386                                $operateur_egalite = true;
387                                $valeur = $_valeur;
388                                if (substr($_valeur, 0, 1) == '!') {
389                                        $operateur_egalite = false;
390                                        $valeur = ltrim($_valeur, '!');
391                                }
392                                if (isset($cache[$_critere])
393                                and (($operateur_egalite and ($cache[$_critere] != $valeur))
394                                        or (!$operateur_egalite and ($cache[$_critere] == $valeur)))) {
395                                        $cache_conforme = false;
396                                        break;
397                                }
398                        }
399
400                        if ($cache_conforme) {
401                                // On permet au plugin de completer la description canonique
402                                $cache = cache_cache_completer($plugin, $cache, $_fichier_cache, $configuration[$plugin]);
403
404                                // On stocke la description du fichier cache dans le tableau de sortie.
405                                $caches[$_fichier_cache] = $cache;
406                        }
407                }
408        }
409
410        return $caches;
411}
412
413
414/**
415 * Supprime, pour un plugin donné, les caches désignés par leur chemin complet.
416 *
417 * @api
418 *
419 * @param string $plugin
420 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
421 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
422 * @param array  $caches
423 *        Liste des fichiers caches désignés par leur chemin complet.
424 *
425 * @return bool
426 *         True si la suppression s'est bien passée, false sinon.
427 */
428function cache_vider($plugin, $caches) {
429
430        // Initialisation du retour
431        $cache_vide = false;
432
433        if ($caches) {
434                $fichiers_cache = is_string($caches) ? array($caches) : $caches;
435                include_spip('inc/flock');
436                foreach ($fichiers_cache as $_fichier) {
437                        supprimer_fichier($_fichier);
438                }
439                $cache_vide = true;
440        }
441       
442        return $cache_vide;
443}
444
445
446/**
447 * Lit la configuration standard des caches d'un plugin utilisateur.
448 *
449 * @api
450 *
451 * @uses lire_config()
452 *
453 * @param string $plugin
454 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
455 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
456 *
457 * @return array
458 *        Tableau de configuration des caches d'un plugin utilisateur ou tableau vide si aucune configuration n'est encore
459 *        enregistrée.
460 */
461function cache_configuration_lire($plugin) {
462
463        // Initialisation de la configuration à retourner
464        $configuration_lue = array();
465
466        if ($plugin) {
467                // Récupération de la meta du plugin Cache
468                include_spip('inc/config');
469                $configuration_lue = lire_config("cache/${plugin}", array());
470        }
471
472        return $configuration_lue;
473}
Note: See TracBrowser for help on using the repository browser.