source: spip-zone/_plugins_/n-core/trunk/inc/ncore_type_noisette.php @ 109830

Last change on this file since 109830 was 109830, checked in by eric@…, 3 years ago

Changement des noms noisette et rang en type_noisette et rang_noisette pour éviter toute confusion.

  • Property svn:eol-style set to native
File size: 14.2 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'API N-Core de gestion des types de noisette, c'est-à-dire les squelettes et leur YAML.
4 *
5 * @package SPIP\NCORE\API\TYPE_NOISETTE
6 */
7if (!defined('_ECRIRE_INC_VERSION')) {
8        return;
9}
10
11
12/**
13 * Charge ou recharge les descriptions des types de noisette à partir des fichiers YAML.
14 * Les types de noisettes sont recherchés dans un répertoire relatif fourni en argument.
15 * La fonction optimise le chargement en effectuant uniquement les traitements nécessaires
16 * en fonction des modifications, ajouts et suppressions des types de noisettes identifiés en comparant
17 * les md5 des fichiers YAML.
18 *
19 * @api
20 * @uses ncore_type_noisette_lister()
21 * @uses ncore_type_noisette_stocker()
22 *
23 * @param string $plugin
24 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
25 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
26 * @param string $dossier
27 *        Chemin relatif (avec un `/` final) dans lequel chercher les fichiers YAML de description des noisettes.
28 *        Par défaut, les noisettes seront recherchées dans le dossier `noisettes/`.
29 * @param bool   $recharger
30 *        Si `true` force le rechargement de toutes les types de noisettes, sinon le chargement se base sur le
31 *        md5 des fichiers YAML. Par défaut vaut `false`.
32 * @param string $stockage
33 *        Identifiant du service de stockage à utiliser si précisé. Dans ce cas, ni celui du plugin
34 *        ni celui de N-Core ne seront utilisés. En général, cet identifiant est le préfixe d'un plugin
35 *        fournissant le service de stockage souhaité.
36 *
37 * @return bool
38 *        `false` si une erreur s'est produite, `true` sinon.
39 */
40function type_noisette_charger($plugin, $dossier = 'noisettes/', $recharger = false, $stockage = '') {
41
42        // Retour de la fonction
43        $retour = true;
44
45        // Initialiser le contexte de rechargement
46        // TODO : voir si on ajoute un var_mode=recalcul_noisettes ?
47
48        // On recherche les types de noisette directement par leur fichier YAML de configuration car il est
49        // obligatoire. La recherche s'effectue dans le path en utilisant le dossier relatif fourni.
50        if ($fichiers = find_all_in_path($dossier, '.+[.]yaml$')) {
51                // On charge l'API de stockge de N-Core.
52                // Ce sont ces fonctions qui aiguillent ou pas vers une éventuelle fonction spécifique de stockage.
53                include_spip("ncore/ncore");
54
55                // Initialisation des tableaux de types de noisette.
56                $types_noisette_a_ajouter = $types_noisette_a_changer = $types_noisette_a_effacer = array();
57
58                // Récupération des signatures md5 des noisettes déjà enregistrées.
59                // Si on force le rechargement il est inutile de gérer les signatures et les noisettes modifiées ou obsolètes.
60                $signatures = array();
61                if (!$recharger) {
62                        $signatures = ncore_type_noisette_lister($plugin, 'signature', $stockage);
63                        // On initialise la liste des types de noisette à supprimer avec l'ensemble des types de noisette déjà stockés.
64                        $types_noisette_a_effacer = $signatures ? array_keys($signatures) : array();
65                }
66
67                foreach ($fichiers as $_squelette => $_chemin) {
68                        $type_noisette = basename($_squelette, '.yaml');
69                        // Si on a forcé le rechargement ou si aucun md5 n'est encore stocké pour le type de noisette
70                        // on positionne la valeur du md5 stocké à chaine vide.
71                        // De cette façon, on force la lecture du fichier YAML du type de noisette.
72                        $md5_stocke = (isset($signatures[$type_noisette]) and !$recharger)
73                                ? $signatures[$type_noisette]
74                                : '';
75
76                        // Initialisation de la description par défaut du type de noisette
77                        // -- on y inclut le plugin appelant et la signature
78                        $description_defaut = array(
79                                'type_noisette' => $type_noisette,
80                                'nom'           => $type_noisette,
81                                'description'   => '',
82                                'icon'          => 'noisette-24.png',
83                                'necessite'     => array(),
84                                'contexte'      => array(),
85                                'ajax'          => 'defaut',
86                                'inclusion'     => 'statique',
87                                'parametres'    => array(),
88                                'plugin'        => $plugin,
89                                'signature'     => '',
90                        );
91
92                        // On vérifie que le md5 du fichier YAML est bien différent de celui stocké avant de charger
93                        // le contenu. Sinon, on passe au fichier suivant.
94                        $md5 = md5_file($_chemin);
95                        if ($md5 != $md5_stocke) {
96                                include_spip('inc/yaml');
97                                $description = yaml_charger_inclusions(yaml_decode_file($_chemin));
98
99                                // TODO : ne faudrait-il pas "valider" le fichier YAML ici ou alors lors du stockage ?
100                                // Traitements des champs pouvant être soit une chaine soit un tableau
101                                if (!empty($description['necessite']) and is_string($description['necessite'])) {
102                                        $description['necessite'] = array($description['necessite']);
103                                }
104                                if (!empty($description['contexte']) and is_string($description['contexte'])) {
105                                        $description['contexte'] = array($description['contexte']);
106                                }
107
108                                // On n'inclue ce type de noisette que si les plugins qu'il nécessite explicitement dans son
109                                // fichier de configuration sont bien tous activés.
110                                // Rappel: si un type de noisette est incluse dans un plugin non actif elle ne sera pas détectée
111                                //         lors du find_all_in_path() puisque le plugin n'est pas dans le path SPIP.
112                                //         Ce n'est pas ce cas qui est traité ici.
113                                $type_noisette_a_garder = true;
114                                if (!empty($description['necessite'])) {
115                                        foreach ($description['necessite'] as $_plugin_necessite) {
116                                                if (!defined('_DIR_PLUGIN_' . strtoupper($_plugin_necessite))) {
117                                                        $type_noisette_a_garder = false;
118                                                        break;
119                                                }
120                                        }
121                                }
122
123                                // Si la noisette est à garder on finalise sa description et on détermine si elle est nouvelle ou modifiée.
124                                // En mode rechargement forcé toute noisette est considérée comme nouvelle.
125                                // Sinon, la noisette doit être retirée de la base car un plugin qu'elle nécessite a été désactivée:
126                                // => il suffit pour cela de la laisser dans la liste des noisettes obsolètes.
127                                if ($type_noisette_a_garder) {
128                                        // Mise à jour du md5
129                                        $description['signature'] = $md5;
130                                        // Complétude de la description avec les valeurs par défaut
131                                        $description = array_merge($description_defaut, $description);
132                                        // Sérialisation des champs necessite, contexte et parametres qui sont des tableaux
133                                        $description['necessite'] = serialize($description['necessite']);
134                                        $description['contexte'] = serialize($description['contexte']);
135                                        $description['parametres'] = serialize($description['parametres']);
136                                        // Complément spécifique au plugin utilisateur si nécessaire
137                                        $description = ncore_type_noisette_completer($plugin, $description, $stockage);
138
139                                        if (!$md5_stocke or $recharger) {
140                                                // Le type de noisette est soit nouveau soit on est en mode rechargement forcé:
141                                                // => il faut le rajouter.
142                                                $types_noisette_a_ajouter[] = $description;
143                                        } else {
144                                                // La description stockée a été modifiée et le mode ne force pas le rechargement:
145                                                // => il faut mettre à jour le type de noisette.
146                                                $types_noisette_a_changer[] = $description;
147                                                // => et il faut donc le supprimer de la liste de types de noisette obsolètes
148                                                $types_noisette_a_effacer = array_diff($types_noisette_a_effacer, array($type_noisette));
149                                        }
150                                } else {
151                                        // Le type de noisette ne peut plus être utilisé car un des plugins qu'il nécessite n'est plus actif.
152                                        // => il faut le laisser dans la liste des obsolètes.
153                                        continue;
154                                }
155                        } else {
156                                // Le type de noisette n'a pas changé et n'a donc pas été réchargé:
157                                // => Il faut donc juste indiquer qu'il n'est pas obsolète.
158                                $types_noisette_a_effacer = array_diff($types_noisette_a_effacer, array($type_noisette));
159                        }
160                }
161
162                // Mise à jour du stockage des types de noisette si au moins un des 3 tableaux est non vide et que le chargement forcé
163                // n'est pas demandé:
164                // -- Suppression des types de noisettes obsolètes ou de tous les types de noisettes si on est en mode rechargement forcé.
165                //    Pour permettre une optimisation du traitement en mode rechargement forcé on passe toujours le mode.
166                // -- Update des types de noisette modifiés.
167                // -- Insertion des nouveaux types de noisette.
168                if ($recharger
169                        or (!$recharger and ($types_noisette_a_ajouter or $types_noisette_a_effacer or $types_noisette_a_changer))) {
170                        $types_noisette = array('a_ajouter' => $types_noisette_a_ajouter);
171                        if (!$recharger) {
172                                $types_noisette['a_effacer'] = $types_noisette_a_effacer;
173                                $types_noisette['a_changer'] = $types_noisette_a_changer;
174                        }
175                        $retour = ncore_type_noisette_stocker($plugin, $types_noisette, $recharger, $stockage);
176                }
177        }
178
179        return $retour;
180}
181
182
183/**
184 * Retourne, pour un type de noisette donné, la description complète ou seulement un champ précis.
185 * Les champs textuels peuvent subir une traitement typo si demandé.
186 *
187 * @api
188 * @uses ncore_type_noisette_decrire()
189 *
190 * @param string  $plugin
191 *        Le service permet de distinguer l'appelant qui peut-être un plugin comme le noiZetier ou
192 *        un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
193 *        La fonction utilisera la fonction de lecture de la description brute d'un type de noisette, spécifique
194 *        au service, ou à défaut, celle fournie par N-Core.
195 * @param string  $type_noisette
196 *        Identifiant du type de noisette.
197 * @param string  $information
198 *        Information spécifique à retourner ou vide pour retourner toute la description.
199 * @param boolean $traiter_typo
200 *        Indique si les données textuelles doivent être retournées brutes ou si elles doivent être traitées
201 *        en utilisant la fonction _T_ou_typo. Par défaut l'indicateur vaut `false`.
202 *        Les champs sérialisés sont eux toujours désérialisés.
203 * @param string  $stockage
204 *        Identifiant du service de stockage à utiliser si précisé. Dans ce cas, ni celui du plugin
205 *        ni celui de N-Core ne seront utilisés. En général, cet identifiant est le préfixe d'un plugin
206 *        fournissant le service de stockage souhaité.
207 *
208 * @return array|string
209 *        La description complète ou champ précis demandé pour un type de noisette donné. Les champs
210 *        de type tableau sont systématiquement désérialisés et si demandé, les champs textuels peuvent être
211 *        traités avec la fonction _T_ou_typo().
212 */
213function type_noisette_lire($plugin, $type_noisette, $information = '', $traiter_typo = false, $stockage = '') {
214
215        // On indexe le tableau des descriptions par le plugin appelant en cas d'appel sur le même hit
216        // par deux plugins différents.
217        static $donnees_typo = array('nom', 'description');
218        static $description_noisette = array();
219
220        // Stocker la description de la noisette si besoin
221        if (!isset($description_noisette[$plugin][$type_noisette])) {
222                // On charge l'API de N-Core.
223                // Ce sont ces fonctions qui aiguillent ou pas vers une fonction spécifique du service.
224                include_spip("ncore/ncore");
225
226                // Lecture de toute la configuration de la noisette: les données retournées sont brutes.
227                $description = ncore_type_noisette_decrire($plugin, $type_noisette, $stockage);
228
229                // Sauvegarde de la description de la page pour une consultation ultérieure dans le même hit.
230                if ($description) {
231                        // Traitements des champs tableaux sérialisés
232                        $description['contexte'] = unserialize($description['contexte']);
233                        $description['necessite'] = unserialize($description['necessite']);
234                        $description['parametres'] = unserialize($description['parametres']);
235                }
236
237                // Stockage de la description
238                $description_noisette[$plugin][$type_noisette] = $description;
239        }
240
241        if ($information) {
242                if (isset($description_noisette[$plugin][$type_noisette][$information])) {
243                        if (in_array($information, $donnees_typo) and $traiter_typo) {
244                                // Traitements de la donnée textuelle
245                                $retour = _T_ou_typo($description_noisette[$plugin][$type_noisette][$information]);
246                        } else {
247                                $retour = $description_noisette[$plugin][$type_noisette][$information];
248                        }
249                } else {
250                        $retour = '';
251                }
252        } else {
253                $retour = $description_noisette[$plugin][$type_noisette];
254                // Traitements des données textuels
255                if ($traiter_typo) {
256                        foreach ($donnees_typo as $_champ) {
257                                if (isset($retour[$_champ])) {
258                                        $retour[$_champ] = _T_ou_typo($retour[$_champ]);
259                                }
260                        }
261                }
262        }
263
264        return $retour;
265}
266
267/**
268 * Renvoie une liste de descriptions de types de noisette éventuellement filtrée sur certains champs.
269 *
270 * @api
271 * @uses ncore_type_noisette_lister()
272 *
273 * @param string $plugin
274 *        Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
275 *        ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
276 * @param array  $filtres
277 *        Tableau associatif `[champ] = valeur` de critères de filtres sur les descriptions de types de noisette.
278 *        Le seul opérateur possible est l'égalité.
279 * @param string $stockage
280 *        Identifiant du service de stockage à utiliser si précisé. Dans ce cas, ni celui du plugin
281 *        ni celui de N-Core ne seront utilisés. En général, cet identifiant est le préfixe d'un plugin
282 *        fournissant le service de stockage souhaité.
283 *
284 * @return array
285 *        Tableau des descriptions des types de noisette trouvés indexé par le type de noisette.
286 */
287function type_noisette_repertorier($plugin, $filtres = array(), $stockage = '') {
288
289        // On indexe le tableau des des types de noisette par le plugin appelant en cas d'appel sur le même hit
290        // par deux plugins différents.
291        static $types_noisette = array();
292
293        if (!isset($types_noisette[$plugin])) {
294                // On charge l'API de N-Core.
295                // Ce sont ces fonctions qui aiguillent ou pas vers une fonction spécifique du service.
296                include_spip("ncore/ncore");
297
298                // On récupère la description complète de tous les types de noisettes détectés par le plugin appelant
299                $types_noisette[$plugin] = ncore_type_noisette_lister($plugin, '', $stockage);
300        }
301
302        // Application des filtres éventuellement demandés en argument de la fonction
303        $types_noisette_filtres = $types_noisette[$plugin];
304        if ($filtres) {
305                foreach ($types_noisette_filtres as $_type_noisette => $_description) {
306                        foreach ($filtres as $_critere => $_valeur) {
307                                if (isset($_description[$_critere]) and ($_description[$_critere] != $_valeur)) {
308                                        unset($types_noisette_filtres[$_type_noisette]);
309                                        break;
310                                }
311                        }
312                }
313        }
314
315        return $types_noisette_filtres;
316}
Note: See TracBrowser for help on using the repository browser.