source: spip-zone/_plugins_/boussole/trunk/inc/serveur.php @ 114393

Last change on this file since 114393 was 114393, checked in by eric@…, 17 months ago

En attendant b_b on vire les fins de fichiers PHP

  • Property svn:eol-style set to native
File size: 15.9 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'API de gestion des caches des boussoles hébergées par le site serveur.
4 *
5 * @package SPIP\BOUSSOLE\Serveur\Cache
6 */
7
8if (!defined("_ECRIRE_INC_VERSION")) return;
9
10
11if (!defined('_BOUSSOLE_PATTERN_SHA'))
12        /**
13         * Pattern permettant d'insérer le sha256 calculé à partir du XML d'origine d'une boussole
14         * dans le cache produit */
15        define('_BOUSSOLE_PATTERN_SHA', '%sha_contenu%');
16
17/**
18 * Types d'objet manipulés par le plugin
19 */
20if (!defined('_BOUSSOLE_OBJET_BOUSSOLE'))
21        define('_BOUSSOLE_OBJET_BOUSSOLE', 'boussole');
22if (!defined('_BOUSSOLE_OBJET_GROUPE'))
23        define('_BOUSSOLE_OBJET_GROUPE', 'groupe');
24if (!defined('_BOUSSOLE_OBJET_SITE'))
25        define('_BOUSSOLE_OBJET_SITE', 'site');
26
27
28/**
29 * Génération du cache de chaque boussole hébergée par le serveur et du cache de la liste
30 * de ces boussoles.
31 *
32 * @api
33 * @uses boussole_cacher_xml()
34 * @uses boussole_cacher_liste()
35 *
36 * @return void
37 */
38function boussole_actualiser_caches() {
39
40        // Suppression de tous les caches (.xml et .sha) afin de ne pas conserver des boussoles qui ne sont plus disponibles
41        include_spip('inc/cache');
42        supprimer_caches();
43
44        // Acquisition de la liste des boussoles disponibles sur le serveur.
45        // (on sait déjà que le mode serveur est actif)
46        include_spip('inc/config');
47        $boussoles = lire_config('boussole/serveur/boussoles_disponibles');
48        $boussoles = pipeline('declarer_boussoles', $boussoles);
49
50        if ($boussoles) {
51                // Génération du cache de chaque boussole disponible pour l'action serveur_informer_boussole
52                foreach($boussoles as $_alias => $_infos) {
53                        boussole_cacher_xml($_alias, $_infos['prefixe']);
54                }
55
56                // Génération du cache de la liste des boussoles disponibles pour l'action serveur_lister_boussoles
57                boussole_cacher_liste($boussoles);
58        }
59}
60
61
62/**
63 * Génération du cache xml de la boussole contruit soit à partir de xml non traduit soit à partir d'un xml déjà traduit.
64 * Ce cache est renvoyé sur l'action serveur_informer_boussole
65 *
66 * @api
67 *
68 * @param string        $alias
69 * @param string        $prefixe_plugin
70 * @return bool
71 */
72function boussole_cacher_xml($alias, $prefixe_plugin='') {
73        $retour = false;
74
75        /* Détermination du mode de génération du fichier cache xml
76                - fichier XML contenant une boussole déjà traduite (pas de DTD possible)
77                - fichier XML contenant une boussole source non traduite (conforme à boussole.dtd)
78        */
79        if ($fichier_xml = find_in_path("boussole_traduite-${alias}.xml")) {
80                if (!xml_to_cache($fichier_xml, $alias))
81                        spip_log("Cache XML non créé (alias = $alias)", _BOUSSOLE_LOG . _LOG_ERREUR);
82
83                else
84                        $retour = true;
85        }
86        elseif ($fichier_xml = find_in_path("boussole-${alias}.xml")) {
87                // Validation du fichier XML source (boussole.dtd)
88                if (!boussole_valider_xml($fichier_xml, $erreur))
89                        spip_log("XML source non conforme (alias = $alias) : " . var_export($erreur['detail'], true), _BOUSSOLE_LOG . _LOG_ERREUR);
90
91                // Création du cache à partir du fichier XML source
92                elseif (!xml_to_cache($fichier_xml, $alias, $prefixe_plugin))
93                        spip_log("Cache XML non créé (alias = $alias)", _BOUSSOLE_LOG . _LOG_ERREUR);
94
95                else
96                        $retour = true;
97        }
98        else
99                spip_log("XML source introuvable (alias = $alias)", _BOUSSOLE_LOG . _LOG_ERREUR);
100
101        return $retour;
102}
103
104
105/**
106 * Génération du cache de la liste des boussoles disponibles
107 * Ce cache est renvoyé sur l'action serveur_lister_boussoles
108 *
109 * @api
110 *
111 * @param array $boussoles
112 *
113 * @return bool
114 */
115function boussole_cacher_liste($boussoles) {
116        $retour = false;
117
118        if ($boussoles) {
119                $convertir = charger_fonction('decoder_xml', 'inc');
120                $cache = '';
121                foreach($boussoles as $_alias => $_infos) {
122                        // Construire le nom du fichier cache de la boussole et vérifier qu'il existe
123                        include_spip('inc/cache');
124                        $fichier_cache = cache_boussole_existe($_alias);
125                        if ($fichier_cache) {
126                                // Extraction des seules informations de la boussole pour créer le cache (pas de groupe ni site)
127                                $xml = '';
128                                lire_fichier($fichier_cache, $xml);
129                                $tableau = $convertir($xml);
130
131                                if  (isset($tableau[_BOUSSOLE_NOMTAG_BOUSSOLE])) {
132                                        $cache .= inserer_balise('ouvrante', _BOUSSOLE_NOMTAG_BOUSSOLE, $tableau[_BOUSSOLE_NOMTAG_BOUSSOLE]['@attributes'], 1);
133                                        if (isset($tableau[_BOUSSOLE_NOMTAG_BOUSSOLE]['nom'])) {
134                                                $cache .= inserer_balise('ouvrante', 'nom', array(), 2)
135                                                                . inserer_balise('ouvrante', 'multi', array(), 3)
136                                                                . indenter(3) . trim($tableau[_BOUSSOLE_NOMTAG_BOUSSOLE]['nom']['multi']) . "\n"
137                                                                . inserer_balise('fermante', 'multi', array(), 3)
138                                                                . inserer_balise('fermante', 'nom', array(), 2);
139                                        }
140                                        $cache .= inserer_balise('fermante', _BOUSSOLE_NOMTAG_BOUSSOLE, array(), 1);
141                                }
142                        }
143                }
144
145                if ($cache) {
146                        // Récupération du nom du serveur. On sait que le serveur et actif.
147                        include_spip('inc/config');
148                        $nom_serveur = lire_config('boussole/serveur/nom');
149
150                        $cache = inserer_balise('ouvrante', _BOUSSOLE_NOMTAG_LISTE_BOUSSOLES, array('serveur' => $nom_serveur, 'sha' => _BOUSSOLE_PATTERN_SHA))
151                                   . $cache
152                                   . inserer_balise('fermante', _BOUSSOLE_NOMTAG_LISTE_BOUSSOLES, array());
153                        $sha = sha1($cache);
154                        $cache = str_replace(_BOUSSOLE_PATTERN_SHA, $sha, $cache);
155
156                        // Ecriture du cache et de son sha256
157                        include_spip('inc/cache');
158                        ecrire_cache_liste($cache);
159
160                        $retour = true;
161                }
162        }
163
164        return $retour;
165}
166
167
168/**
169 * Teste la validite du fichier xml de la boussole en fonction de la DTD boussole.dtd
170 *
171 * @package     SPIP\BOUSSOLE\Outils\XML
172 * @api
173 *
174 * @param string $url
175 *              url absolue du fichier xml de description de la boussole
176 * @param array $erreur
177 *              tableau des erreurs collectees suite a la validation xml
178 *
179 * @return boolean
180 */
181function boussole_valider_xml($url, &$erreur) {
182        include_spip('inc/distant');
183
184        $ok = true;
185
186        // On verifie la validite du contenu en fonction de la dtd
187        $valider_xml = charger_fonction('valider', 'xml');
188        $retour = $valider_xml(recuperer_page($url));
189        if ($retour) {
190                $erreurs = is_array($retour) ? $retour[1] : $retour->err;
191                if ($erreurs === false) {
192                        $ok = false;
193                }
194                else if ($erreurs) {
195                        $erreur['detail'] = $erreurs;
196                        $ok = false;
197                }
198        }
199
200        return $ok;
201}
202
203
204/**
205 * Lecture du xml d'une boussole issue d'un plugin ou d'une boussole manuelle
206 * et génération du cache xml incluant les traductions et les chemins des logos
207 *
208 * @package     SPIP\BOUSSOLE\Serveur\Cache
209 *
210 * @param string        $fichier_xml
211 * @param string        $alias_boussole
212 * @param string        $prefixe_plugin
213 * @return bool
214 */
215function xml_to_cache($fichier_xml, $alias_boussole, $prefixe_plugin='') {
216        $retour = false;
217        $cache = '';
218
219        // Détermination du type de boussole pour laquelle on génère le cache
220        $boussole_plugin = (!isset($prefixe_plugin) OR !$prefixe_plugin ? false : true);
221
222        // Extraction du contenu du xml source
223        $xml = '';
224        lire_fichier($fichier_xml, $xml);
225        $convertir = charger_fonction('decoder_xml', 'inc');
226        $tableau = $convertir($xml);
227
228        if  (isset($tableau[_BOUSSOLE_NOMTAG_BOUSSOLE])) {
229                $boussole = $tableau[_BOUSSOLE_NOMTAG_BOUSSOLE];
230                include_spip('inc/filtres');
231                include_spip('inc/filtres_mini');
232
233                // Ouverture de l'élément englobant boussole
234                // -- url absolue du logo à fournir dans la balise
235                $att_boussole =array();
236                $att_boussole['logo'] = url_absolue(find_in_path("images/boussole/boussole-${alias_boussole}.png"));
237                // -- Pour une boussole plugin, insertion de la version du plugin comme version du xml
238                // -- Pour une boussole manuelle la version est un attribut de la balise boussole
239                if ($boussole_plugin) {
240                        $informer = charger_fonction('informer_plugin', 'inc');
241                        $plugin = $informer($prefixe_plugin);
242                        $att_boussole['version'] = (isset($plugin['version']) ? $plugin['version'] : '');
243                }
244                // -- insertion de l'alias du serveur
245                include_spip('inc/config');
246                $nom_serveur = lire_config('boussole/serveur/nom');
247                $att_boussole['serveur'] = $nom_serveur;
248                // -- insertion du pattern pour le sha1 du contenu
249                $att_boussole['sha'] = _BOUSSOLE_PATTERN_SHA;
250                // -- merge de tous les attributs
251                $att_boussole = array_merge($att_boussole, $boussole['@attributes']);
252                $cache .= inserer_balise('ouvrante', _BOUSSOLE_NOMTAG_BOUSSOLE, $att_boussole);
253                // Insertion des balises multi pour le nom, le slogan et le descriptif de la boussole
254                list($nom, $slogan, $description) = $boussole_plugin
255                        ? compiler_traductions_plugin($alias_boussole, _BOUSSOLE_OBJET_BOUSSOLE, $alias_boussole, 1)
256                        : compiler_traductions_manuelle($boussole, 2);
257                $cache .= inserer_traductions($nom, $slogan, $description, 1);
258
259                if (isset($boussole[_BOUSSOLE_NOMTAG_GROUPE])) {
260                        $groupes = array();
261                        if (isset($boussole[_BOUSSOLE_NOMTAG_GROUPE][0]))
262                                $groupes = $boussole[_BOUSSOLE_NOMTAG_GROUPE];
263                        else
264                                $groupes[0] = $boussole[_BOUSSOLE_NOMTAG_GROUPE];
265                        // Insertion des éléments groupe
266                        foreach ($groupes as $_groupe) {
267                                $cache .= inserer_balise('ouvrante', _BOUSSOLE_NOMTAG_GROUPE, $_groupe['@attributes'], 1);
268                                // Insertion des balises multi pour le nom et le slogan du groupe
269                                list($nom, $slogan, $description) = $boussole_plugin
270                                        ? compiler_traductions_plugin($alias_boussole, _BOUSSOLE_OBJET_GROUPE, $_groupe['@attributes']['type'], 2)
271                                        : compiler_traductions_manuelle($_groupe, 3);
272                                $cache .= inserer_traductions($nom, $slogan, $description, 2);
273
274                                // Insertion des éléments site du groupe en cours
275                                if (isset($_groupe[_BOUSSOLE_NOMTAG_SITE])) {
276                                        $sites = array();
277                                        if (isset($_groupe[_BOUSSOLE_NOMTAG_SITE][0]))
278                                                $sites = $_groupe[_BOUSSOLE_NOMTAG_SITE];
279                                        else
280                                                $sites[0] = $_groupe[_BOUSSOLE_NOMTAG_SITE];
281                                        foreach ($sites as $_site) {
282                                                $att_site =array();
283                                                // -- url absolue du logo à fournir dans la balise
284                                                $alias_site = $_site['@attributes']['alias'];
285                                                $att_site['logo'] = url_absolue(find_in_path("images/boussole/site-${alias_boussole}-${alias_site}.png"));
286                                                $att_site = array_merge($att_site, $_site['@attributes']);
287                                                $cache .= inserer_balise('ouvrante', _BOUSSOLE_NOMTAG_SITE, $att_site, 2);
288                                                // Insertion des balises multi pour le nom, le slogan et le descriptif du site
289                                                list($nom, $slogan, $description) = $boussole_plugin
290                                                        ? compiler_traductions_plugin($alias_boussole, _BOUSSOLE_OBJET_SITE, $alias_site, 3)
291                                                        : compiler_traductions_manuelle($_site, 4);
292                                                $cache .= inserer_traductions($nom, $slogan, $description, 3);
293                                                // Cloture de la balise site
294                                                $cache .= inserer_balise('fermante', _BOUSSOLE_NOMTAG_SITE, array(), 2);
295                                        }
296                                }
297                                // Cloture de la balise groupe
298                                $cache .= inserer_balise('fermante', _BOUSSOLE_NOMTAG_GROUPE, array(), 1);
299                        }
300                }
301
302                // Fermeture de l'élément englobant boussole
303                $cache .= inserer_balise('fermante', _BOUSSOLE_NOMTAG_BOUSSOLE);
304
305                // Création du cache et du sha1 associé
306                if ($cache) {
307                        // insertion du sha comme attribut du fichier
308                        $sha = sha1($cache);
309                        $cache = str_replace(_BOUSSOLE_PATTERN_SHA, $sha, $cache);
310
311                        // Ecriture du cache et de son sha256
312                        include_spip('inc/cache');
313                        ecrire_cache_boussole($cache, $alias_boussole);
314
315                        $retour = true;
316                }
317        }
318
319        return $retour;
320}
321
322
323/**
324 * Insertion d'un balise ouvrante, fermante ou vide
325 *
326 * @package     SPIP\BOUSSOLE\Outils\XML
327 *
328 * @param string        $type
329 * @param string        $nom_balise
330 * @param array         $attributs
331 * @param int           $indentation
332 *
333 * @return string
334 */
335function inserer_balise($type='ouvrante', $nom_balise, $attributs=array(), $indentation=0) {
336
337        // Ouverture de la balise
338        $texte = indenter($indentation) . '<' . ($type == 'fermante' ? '/' : '') . $nom_balise;
339        // Insertion des attributs
340        if ($attributs) {
341                foreach ($attributs as $_nom => $_valeur) {
342                        $texte .= ' ' . $_nom . '="' . $_valeur . '"';
343                }
344        }
345        // Fermeture de la balise
346        if ($type == 'vide')
347                $texte .= " />\n";
348        else
349                $texte .= ">\n";
350
351        return $texte;
352}
353
354
355/**
356 * Insertion d'une balise complète <nom>, <slogan> ou <description> incluant les traductions en <multi>
357 *
358 * @package     SPIP\BOUSSOLE\Outils\XML
359 *
360 * @param string        $alias_boussole
361 * @param string        $type_objet
362 * @param string        $alias_objet
363 * @param int   $indentation
364 *
365 * @return string[]
366 */
367function compiler_traductions_plugin($alias_boussole, $type_objet, $alias_objet, $indentation=0) {
368        $nom = '';
369        $slogan = '';
370        $description = '';
371
372        if ($fichier_fr = find_in_path("lang/boussole-${alias_boussole}_fr.php")) {
373                // Determination du nom du module, du prefixe et des items de langue
374                $item_nom = "nom_${type_objet}_${alias_boussole}" . ($type_objet != 'boussole' ? "_${alias_objet}" : '');
375                $item_slogan = "slogan_${type_objet}_${alias_boussole}" . ($type_objet != 'boussole' ? "_${alias_objet}" : '');
376                $item_description = "descriptif_${type_objet}_${alias_boussole}" . ($type_objet != 'boussole' ? "_${alias_objet}" : '');
377
378                // On cherche tous les fichiers de langue destines a la traduction du paquet.xml
379                if ($fichiers_langue = glob(str_replace('_fr.php', '_*.php', $fichier_fr))) {
380                        $nom = $slogan = $description = '';
381                        include_spip('inc/lang_liste');
382
383                        foreach ($fichiers_langue as $_fichier_langue) {
384                                $nom_fichier = basename($_fichier_langue, '.php');
385                                $langue = substr($nom_fichier, strlen("boussole-${alias_boussole}") + 1 - strlen($nom_fichier));
386                                // Si la langue est reconnue, on traite la liste des items de langue
387                                if (isset($GLOBALS['codes_langues'][$langue])) {
388                                        $GLOBALS['idx_lang'] = $langue;
389                                        include($_fichier_langue);
390                                        if (isset($GLOBALS[$langue][$item_nom]))
391                                                $nom .= ($nom ? "\n" : '') . indenter($indentation+2) . "[$langue]" . $GLOBALS[$langue][$item_nom];
392                                        if (isset($GLOBALS[$langue][$item_slogan]))
393                                                $slogan .= ($slogan ? "\n" : '') . indenter($indentation+2) . "[$langue]" . $GLOBALS[$langue][$item_slogan];
394                                        if (isset($GLOBALS[$langue][$item_description]))
395                                                $description .= ($description ? "\n" : '') . indenter($indentation+2) . "[$langue]" . $GLOBALS[$langue][$item_description];
396                                }
397                        }
398                }
399        }
400
401        return array($nom, $slogan, $description);
402}
403
404/**
405 * Insertion d'une balise complète <nom>, <slogan> ou <description> incluant les traductions en <multi>
406 *
407 * @package     SPIP\BOUSSOLE\Outils\XML
408 *
409 * @param array         $objet
410 * @param int   $indentation
411 *
412 * @return string[]
413 */
414function compiler_traductions_manuelle($objet, $indentation=0) {
415        $nom = '';
416        $slogan = '';
417        $description = '';
418
419        if (isset($objet['nom'])) {
420                $nom = indenter($indentation) . trim($objet['nom']['multi']);
421        }
422        if (isset($objet['slogan'])) {
423                $slogan = indenter($indentation) . trim($objet['slogan']['multi']);
424        }
425        if (isset($objet['description'])) {
426                $description = indenter($indentation) . trim($objet['description']['multi']);
427        }
428
429        return array($nom, $slogan, $description);
430}
431
432
433
434/**
435 * Insertion d'une balise complète <nom>, <slogan> ou <description> incluant les traductions en <multi>
436 *
437 * @package     SPIP\BOUSSOLE\Outils\XML
438 *
439 * @param string        $nom
440 * @param string        $slogan
441 * @param string        $description
442 * @param int   $indentation
443 *
444 * @return string
445 */
446function inserer_traductions($nom, $slogan, $description, $indentation=0) {
447        $multis = '';
448
449        // Finaliser la construction des balises multi
450        if ($nom)
451                $multis .= inserer_balise('ouvrante', 'nom', array(), $indentation)
452                                 . inserer_balise('ouvrante', 'multi', array(), $indentation+1)
453                                 . $nom . "\n"
454                                 . inserer_balise('fermante', 'multi', array(), $indentation+1)
455                                 . inserer_balise('fermante', 'nom', array(), $indentation);
456        if ($slogan)
457                $multis .= inserer_balise('ouvrante', 'slogan', array(), $indentation)
458                                 . inserer_balise('ouvrante', 'multi', array(), $indentation+1)
459                                 . $slogan . "\n"
460                                 . inserer_balise('fermante', 'multi', array(), $indentation+1)
461                                 . inserer_balise('fermante', 'slogan', array(), $indentation);
462        if ($description)
463                $multis .= inserer_balise('ouvrante', 'description', array(), $indentation)
464                                 . inserer_balise('ouvrante', 'multi', array(), $indentation+1)
465                                 . $description . "\n"
466                                 . inserer_balise('fermante', 'multi', array(), $indentation+1)
467                                 . inserer_balise('fermante', 'description', array(), $indentation);
468
469        return $multis;
470}
471
472
473/**
474 * Contruction de la chaine de tabulations correspondant au décalage souhaité
475 *
476 * @package     SPIP\BOUSSOLE\Outils\XML
477 *
478 * @param int   $decalage
479 *
480 * @return string
481 */
482function indenter($decalage) {
483        return str_repeat("\t", $decalage);
484}
Note: See TracBrowser for help on using the repository browser.