source: spip-zone/_plugins_/taxonomie/trunk/inc/taxonomer.php @ 93093

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

Correction de la fonction de merge des traductions.

  • Property svn:eol-style set to native
File size: 12.3 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'ensemble des constantes et des utilitaires nécessaires au fonctionnement du plugin.
4 *
5 * @package SPIP\TAXONOMIE
6 */
7
8if (!defined("_ECRIRE_INC_VERSION")) return;
9
10if (!defined('_TAXONOMIE_REGNE_ANIMAL'))
11        /**
12         * Nom latin du règne animal (animaux).
13         */
14        define('_TAXONOMIE_REGNE_ANIMAL', 'animalia');
15if (!defined('_TAXONOMIE_REGNE_VEGETAL'))
16        /**
17         * Nom latin du règne végétal (plantes).
18         */
19        define('_TAXONOMIE_REGNE_VEGETAL', 'plantae');
20if (!defined('_TAXONOMIE_REGNE_FONGIQUE'))
21        /**
22         * Nom latin du règne fongique (champignons).
23         */
24        define('_TAXONOMIE_REGNE_FONGIQUE', 'fungi');
25
26if (!defined('_TAXONOMIE_REGNES'))
27        /**
28         * Liste des règnes supportés par le plugin (concanétation des noms séparés par le signe deux-points).
29         */
30        define('_TAXONOMIE_REGNES',
31                implode(':', array(
32                        _TAXONOMIE_REGNE_ANIMAL,
33                        _TAXONOMIE_REGNE_VEGETAL,
34                        _TAXONOMIE_REGNE_FONGIQUE
35                )));
36
37if (!defined('_TAXONOMIE_RANG_REGNE'))
38        /**
39         * Nom anglais du rang `règne`.
40         */
41        define('_TAXONOMIE_RANG_REGNE', 'kingdom');
42// Suivant le règne l'embranchement se nomme phylum (animalia) ou division (fungi, plantae).
43// Néanmoins, le terme phylum est souvent accepté pour l'ensemble des règnes
44if (!defined('_TAXONOMIE_RANG_PHYLUM'))
45        /**
46         * Nom anglais du rang `phylum` ou `embranchement`.
47         * Ce nom est utilisé pour le règne `animalia`
48         */
49        define('_TAXONOMIE_RANG_PHYLUM', 'phylum');
50if (!defined('_TAXONOMIE_RANG_DIVISION'))
51        /**
52         * Nom anglais du rang `division`.
53         * Ce nom est utilisé pour le règne `fungi` ou `plantae` et correspond au `phylum` pour le règne animal.
54         */
55        define('_TAXONOMIE_RANG_DIVISION', 'division');
56if (!defined('_TAXONOMIE_RANG_CLASSE'))
57        /**
58         * Nom anglais du rang `classe`.
59         */
60        define('_TAXONOMIE_RANG_CLASSE', 'class');
61if (!defined('_TAXONOMIE_RANG_ORDRE'))
62        /**
63         * Nom anglais du rang `ordre`.
64         */
65        define('_TAXONOMIE_RANG_ORDRE', 'order');
66if (!defined('_TAXONOMIE_RANG_FAMILLE'))
67        /**
68         * Nom anglais du rang `famille`.
69         */
70        define('_TAXONOMIE_RANG_FAMILLE', 'family');
71if (!defined('_TAXONOMIE_RANG_GENRE'))
72        /**
73         * Nom anglais du rang `genre`.
74         */
75        define('_TAXONOMIE_RANG_GENRE', 'genus');
76if (!defined('_TAXONOMIE_RANG_ESPECE'))
77        /**
78         * Nom anglais du rang `espèce`.
79         */
80        define('_TAXONOMIE_RANG_ESPECE', 'species');
81if (!defined('_TAXONOMIE_RANG_SOUS_ESPECE'))
82        /**
83         * Nom anglais du rang intercalaire `sous-espèce`.
84         */
85        define('_TAXONOMIE_RANG_SOUS_ESPECE', 'subspecies');
86if (!defined('_TAXONOMIE_RANG_VARIETE'))
87        /**
88         * Nom anglais du rang `variété`.
89         */
90        define('_TAXONOMIE_RANG_VARIETE', 'variety');
91if (!defined('_TAXONOMIE_RANG_SOUS_VARIETE'))
92        /**
93         * Nom anglais du rang intercalaire `sous-variété`.
94         */
95        define('_TAXONOMIE_RANG_SOUS_VARIETE', 'subvariety');
96if (!defined('_TAXONOMIE_RANG_RACE'))
97        /**
98         * Nom anglais du rang `race`.
99         */
100        define('_TAXONOMIE_RANG_RACE', 'race');
101if (!defined('_TAXONOMIE_RANG_FORME'))
102        /**
103         * Nom anglais du rang `forme`.
104         */
105        define('_TAXONOMIE_RANG_FORME', 'forma');
106if (!defined('_TAXONOMIE_RANG_SOUS_FORME'))
107        /**
108         * Nom anglais du rang intercalaire `sous-règne`.
109         */
110        define('_TAXONOMIE_RANG_SOUS_FORME', 'subforma');
111
112//
113if (!defined('_TAXONOMIE_RANGS_PARENTS_ESPECE'))
114        /**
115         * Liste des rangs utilisés du règne au genre compris (concanétation des noms séparés par le signe deux-points).
116         * On utilise par défaut au niveau 2 le terme phylum du règne animal (division pour les autres règnes)
117         */
118        define('_TAXONOMIE_RANGS_PARENTS_ESPECE',
119                implode(':', array(
120                        _TAXONOMIE_RANG_REGNE,
121                        _TAXONOMIE_RANG_PHYLUM,
122                        _TAXONOMIE_RANG_CLASSE,
123                        _TAXONOMIE_RANG_ORDRE,
124                        _TAXONOMIE_RANG_FAMILLE,
125                        _TAXONOMIE_RANG_GENRE
126                )));
127if (!defined('_TAXONOMIE_RANGS_ESPECE_ET_FILS'))
128        /**
129         * Liste des rangs utilisés de l'espèce à la sous-forme (concanétation des noms séparés par le signe deux-points).
130         */
131        define('_TAXONOMIE_RANGS_ESPECE_ET_FILS',
132                implode(':', array(
133                        _TAXONOMIE_RANG_ESPECE,
134                        _TAXONOMIE_RANG_SOUS_ESPECE,
135                        _TAXONOMIE_RANG_VARIETE,
136                        _TAXONOMIE_RANG_SOUS_VARIETE,
137                        _TAXONOMIE_RANG_RACE,
138                        _TAXONOMIE_RANG_FORME,
139                        _TAXONOMIE_RANG_SOUS_FORME
140                )));
141if (!defined('_TAXONOMIE_RANGS'))
142        /**
143         * Liste complète des rangs utilisés par le plugin (concanétation des noms séparés par le signe deux-points).
144         */
145        define('_TAXONOMIE_RANGS',
146                _TAXONOMIE_RANGS_PARENTS_ESPECE . ':' . _TAXONOMIE_RANGS_ESPECE_ET_FILS);
147
148if (!defined('_TAXONOMIE_CACHE_NOMDIR'))
149        /**
150         * Nom du dossier contenant les fichiers caches des éléments de taxonomie
151         *
152         * @package SPIP\TAXONOMIE\CACHE
153         */
154        define('_TAXONOMIE_CACHE_NOMDIR', 'cache-taxonomie/');
155if (!defined('_TAXONOMIE_CACHE_DIR'))
156        /**
157         * Chemin du dossier contenant les fichiers caches des boussoles
158         *
159         * @package SPIP\TAXONOMIE\CACHE
160         */
161        define('_TAXONOMIE_CACHE_DIR', _DIR_VAR . _TAXONOMIE_CACHE_NOMDIR);
162
163
164/**
165 * Renvoie, à partir de l'url du service, le tableau des données demandées.
166 * Le service utilise dans ce cas une chaine JSON qui est décodée pour fournir
167 * le tableau de sortie. Le flux retourné par le service est systématiquement
168 * transcodé dans le charset du site avant d'être décodé.
169 *
170 * @package SPIP\TAXONOMIE\SERVICES
171 *
172 * @param string        $url
173 *              URL complète de la requête au service web concerné.
174 * @param int|null      $taille_max
175 *              Taille maximale di flux récupéré suite à la requête.
176 *              `null` désigne la taille par défaut.
177 *
178 * @return array
179 */
180function service_requeter_json($url, $taille_max=null) {
181        // Acquisition des données spécifiées par l'url
182        include_spip('inc/distant');
183        $flux = recuperer_page($url, true, false, $taille_max);
184
185        // Tranformation de la chaine json reçue en tableau associatif
186        $data = json_decode($flux, true);
187
188        return $data;
189}
190
191
192/**
193 * Extrait de la table `spip_taxons` la liste des taxons d'un règne donné ayant fait l'objet
194 * d'une modification manuelle.
195 *
196 * @package SPIP\TAXONOMIE\OBJET
197 *
198 * @param string        $regne
199 *              Nom scientifique du règne en lettres minuscules : `animalia`, `plantae`, `fungi`.
200 *
201 * @return array
202 *              Liste des taxons modifiées manuellement. Chaque élément de la liste est un tableau
203 *              composé des index `tsn`, `nom_commun`, `descriptif`.
204 */
205function taxon_preserver_editions($regne) {
206        $select = array('tsn', 'nom_commun', 'descriptif');
207        $where = array('regne=' . sql_quote($regne), 'edite=' . sql_quote('oui'));
208        $taxons = sql_allfetsel($select, 'spip_taxons', $where);
209
210        return $taxons;
211}
212
213
214/**
215 * Fusionne les traductions d'une balise `<multi>` avec celles d'une autre balise `<multi>`.
216 * L'une des balise est considérée comme prioritaire ce qui permet de régler le cas où la même
217 * langue est présente dans les deux balises.
218 * Si on ne trouve pas de balise `<multi>` dans l'un ou l'autre des paramètres, on considère que
219 * le texte est tout même formaté de la façon suivante : texte0[langue1]texte1[langue2]texte2...
220 *
221 * @package SPIP\TAXONOMIE\OBJET
222 *
223 * @param string        $multi_prioritaire
224 *              Balise multi considérée comme prioritaire en cas de conflit sur une langue.
225 * @param string        $multi_non_prioritaire
226 *              Balise multi considérée comme non prioritaire en cas de conflit sur une langue.
227 *
228 * @return string
229 *              La chaine construite est toujours une balise `<multi>` complète ou une chaine vide sinon.
230 */
231function taxon_merger_traductions($multi_prioritaire, $multi_non_prioritaire) {
232        $multi_merge = '';
233
234        // On extrait le contenu de la balise <multi> si elle existe.
235        include_spip('inc/filtres');
236        $multi_prioritaire = trim($multi_prioritaire);
237        $multi_non_prioritaire = trim($multi_non_prioritaire);
238        if (preg_match(_EXTRAIRE_MULTI, $multi_prioritaire, $match)) {
239                $multi_prioritaire = trim($match[1]);
240        }
241        if (preg_match(_EXTRAIRE_MULTI, $multi_non_prioritaire, $match)) {
242                $multi_non_prioritaire = trim($match[1]);
243        }
244
245        if ($multi_prioritaire) {
246                if ($multi_non_prioritaire) {
247                        // On extrait les traductions sous forme de tableau langue=>traduction.
248                        $traductions_prioritaires = extraire_trads($multi_prioritaire);
249                        $traductions_non_prioritaires = extraire_trads($multi_non_prioritaire);
250
251                        // On complète les traductions prioritaires avec les traductions non prioritaires dont la langue n'est pas
252                        // présente dans les traductions prioritaires.
253                        foreach ($traductions_non_prioritaires as $_lang => $_traduction) {
254                                if (!array_key_exists($_lang, $traductions_prioritaires)) {
255                                        $traductions_prioritaires[$_lang] = $_traduction;
256                                }
257                        }
258
259                        // On construit le contenu de la balise <multi> mergé à partir des traductions prioritaires mises à jour.
260                        // Les traductions vides sont ignorées.
261                        ksort($traductions_prioritaires);
262                        foreach ($traductions_prioritaires as $_lang => $_traduction) {
263                                if ($_traduction) {
264                                        $multi_merge .= ($_lang ? '[' . $_lang . ']' : '') . trim($_traduction);
265                                }
266                        }
267                } else {
268                        $multi_merge = $multi_prioritaire;
269                }
270        } else {
271                $multi_merge = $multi_non_prioritaire;
272        }
273
274        // Si le contenu est non vide on l'insère dans une balise <multi>
275        if ($multi_merge) {
276                $multi_merge = '<multi>' . $multi_merge . '</multi>';
277        }
278
279        return $multi_merge;
280}
281
282
283/**
284 * Traduit un champ de la table `spip_taxons` dans la langue du site.
285 *
286 * @package SPIP\TAXONOMIE\OBJET
287 *
288 * @param $champ
289 *              Nom du champ dans la base de données.
290 *
291 * @return string
292 *              Traduction du champ dans la langue du site.
293 */
294function taxon_traduire_champ($champ) {
295        $traduction = '';
296        if ($champ) {
297                $traduction = _T("taxon:champ_${champ}_label");
298        }
299        return $traduction;
300}
301
302
303/**
304 * Ecrit le contenu issu d'un service taxonomique dans un fichier texte afin d'optimiser le nombre
305 * de requêtes adressées au service.
306 *
307 * @package SPIP\TAXONOMIE\CACHE
308 *
309 * @param string        $cache
310 *              Contenu du fichier cache. Si le service appelant manipule un tableau il doit le sérialiser avant
311 *      d'appeler cette fonction.
312 * @param string    $service
313 * @param int       $tsn
314 * @param string    $spip_langue
315 * @param string    $action
316 *
317 * @return boolean
318 *              Toujours à vrai.
319 */
320function cache_taxonomie_ecrire($cache, $service, $tsn, $spip_langue='', $action='') {
321        // Création du dossier cache si besoin
322        sous_repertoire(_DIR_VAR, trim(_TAXONOMIE_CACHE_NOMDIR, '/'));
323
324        // Ecriture du fichier cache
325        $fichier_cache = cache_taxonomie_nommer($service, $tsn, $spip_langue, $action);
326        ecrire_fichier($fichier_cache, $cache);
327
328        return true;
329}
330
331
332/**
333 * Construit le nom du fichier cache en fonction du service, du taxon concernés et
334 * d'autres critères optionnels.
335 *
336 * @package SPIP\TAXONOMIE\CACHE
337 *
338 * @param string    $service
339 * @param int       $tsn
340 * @param string    $spip_langue
341 * @param string    $action
342 *
343 * @return string
344 */
345function cache_taxonomie_nommer($service, $tsn, $spip_langue='', $action='') {
346        // Construction du chemin complet d'un fichier cache
347        $fichier_cache = _TAXONOMIE_CACHE_DIR
348                . $service
349                . ($action ? '_' . $action : '')
350                . '_' . $tsn
351                . ($spip_langue ? '_' . $spip_langue : '')
352                . '.txt';
353
354        return $fichier_cache;
355}
356
357/**
358 * Vérifie l'existence du fichier cache pour un taxon et un service donnés.
359 * Si le fichier existe la fonction retourne son chemin complet.
360 *
361 * @package SPIP\TAXONOMIE\CACHE
362 *
363 * @param string    $service
364 * @param int       $tsn
365 * @param string    $spip_langue
366 * @param string    $action
367 *
368 * @return string
369 *              Chemin du fichier cache si il existe ou chaine vide sinon.
370 */
371function cache_taxonomie_existe($service, $tsn, $spip_langue='', $action='') {
372        // Contruire le nom du fichier cache
373        $fichier_cache = cache_taxonomie_nommer($service, $tsn, $spip_langue, $action);
374
375        // Vérification de l'existence du fichier:
376        // - chaine vide si le fichier n'existe pas
377        // - chemin complet du fichier si il existe
378        if (!file_exists($fichier_cache))
379                $fichier_cache = '';
380
381        return $fichier_cache;
382}
383
384
385/**
386 * Supprime tout ou partie des fichiers cache taxonomiques.
387 *
388 * @package SPIP\TAXONOMIE\CACHE
389 *
390 * @param array|string  $caches
391 *              Liste des fichiers à supprimer ou vide si tous les fichiers cache doivent être supprimés.
392 *              Il est possible de passer un seul fichier comme une chaine.
393 *
394 * @return boolean
395 *              Toujours à `true`.
396 */
397function cache_taxonomie_supprimer($caches=array()){
398        include_spip('inc/flock');
399
400        if ($caches) {
401                $fichiers_cache = is_string($caches) ? array($caches) : $caches;
402        } else {
403                $fichiers_cache = glob(_TAXONOMIE_CACHE_DIR . "*.*");
404        }
405
406        if ($fichiers_cache) {
407                foreach ($fichiers_cache as $_fichier) {
408                        supprimer_fichier($_fichier);
409                }
410        }
411
412        return true;
413}
414
415?>
Note: See TracBrowser for help on using the repository browser.