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

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

Il n'est pas besoin de préserver les taxons non importés et non espèce car il ne sont pas supprimés lors du vidage d'un règne.
Corriger encore un rang qui trainait depuis le renommage en rang_taxon.
Du PHPDoc pour expliquer tout ça.

  • Property svn:eol-style set to native
File size: 13.1 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'ensemble des constantes et des utilitaires nécessaires au fonctionnement du plugin.
4 *
5 */
6if (!defined('_ECRIRE_INC_VERSION')) {
7        return;
8}
9
10
11$GLOBALS['_taxonomie']['regnes'] = array('animalia', 'plantae', 'fungi');
12
13if (!defined('_TAXONOMIE_RANG_TYPE_PRINCIPAL')) {
14        /**
15         * Type de rang selon la nomenclature taxonomique.
16         */
17        define('_TAXONOMIE_RANG_TYPE_PRINCIPAL', 'principal');
18}
19if (!defined('_TAXONOMIE_RANG_TYPE_SECONDAIRE')) {
20        /**
21         * Type de rang selon la nomenclature taxonomique.
22         */
23        define('_TAXONOMIE_RANG_TYPE_SECONDAIRE', 'secondaire');
24}
25if (!defined('_TAXONOMIE_RANG_TYPE_INTERCALAIRE')) {
26        /**
27         * Type de rang selon la nomenclature taxonomique.
28         */
29        define('_TAXONOMIE_RANG_TYPE_INTERCALAIRE', 'intercalaire');
30}
31
32// TODO : vérifier les rangs stirp, morph, aberration, unspecified.
33// TODO : vérifier pourquoi le rang serie n'est pas dans la liste de ITIS
34$GLOBALS['_taxonomie']['rangs'] = array(
35        'kingdom'       => array('type' => _TAXONOMIE_RANG_TYPE_PRINCIPAL, 'est_espece' => false, 'synonyme' => ''),
36        'subkingdom'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
37        'infrakingdom'  => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
38        'superphylum'   => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => 'superdivision'),
39        'phylum'        => array('type' => _TAXONOMIE_RANG_TYPE_PRINCIPAL, 'est_espece' => false, 'synonyme' => 'division'),
40        'subphylum'     => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => 'subdivision'),
41        'infraphylum'   => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => 'infradivision'),
42        'superdivision' => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => 'superphylum'),
43        'division'      => array('type' => _TAXONOMIE_RANG_TYPE_PRINCIPAL, 'est_espece' => false, 'synonyme' => 'phylum'),
44        'subdivision'   => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => 'subphylum'),
45        'infradivision' => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => 'infraphylum'),
46        'superclass'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
47        'class'         => array('type' => _TAXONOMIE_RANG_TYPE_PRINCIPAL, 'est_espece' => false, 'synonyme' => ''),
48        'subclass'      => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
49        'infraclass'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
50        'superorder'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
51        'order'         => array('type' => _TAXONOMIE_RANG_TYPE_PRINCIPAL, 'est_espece' => false, 'synonyme' => ''),
52        'suborder'      => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
53        'infraorder'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
54        'section'       => array('type' => _TAXONOMIE_RANG_TYPE_SECONDAIRE, 'est_espece' => false, 'synonyme' => ''),
55        'subsection'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
56        'superfamily'   => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
57        'family'        => array('type' => _TAXONOMIE_RANG_TYPE_PRINCIPAL, 'est_espece' => false, 'synonyme' => ''),
58        'subfamily'     => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
59        'tribe'         => array('type' => _TAXONOMIE_RANG_TYPE_SECONDAIRE, 'est_espece' => false, 'synonyme' => ''),
60        'subtribe'      => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
61        'genus'         => array('type' => _TAXONOMIE_RANG_TYPE_PRINCIPAL, 'est_espece' => false, 'synonyme' => ''),
62        'subgenus'      => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => false, 'synonyme' => ''),
63        'species'       => array('type' => _TAXONOMIE_RANG_TYPE_PRINCIPAL, 'est_espece' => true, 'synonyme' => ''),
64        'subspecies'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => true, 'synonyme' => ''),
65        'variety'       => array('type' => _TAXONOMIE_RANG_TYPE_SECONDAIRE, 'est_espece' => true, 'synonyme' => ''),
66        'subvariety'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => true, 'synonyme' => ''),
67        'form'          => array('type' => _TAXONOMIE_RANG_TYPE_SECONDAIRE, 'est_espece' => true, 'synonyme' => ''),
68        'subform'       => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => true, 'synonyme' => ''),
69        'race'          => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => true, 'synonyme' => 'variety'),
70        'stirp'         => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => true, 'synonyme' => ''),
71        'morph'         => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => true, 'synonyme' => ''),
72        'aberration'    => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => true, 'synonyme' => ''),
73        'unspecified'   => array('type' => _TAXONOMIE_RANG_TYPE_INTERCALAIRE, 'est_espece' => true, 'synonyme' => '')
74);
75
76if (!defined('_TAXONOMIE_RANG_REGNE')) {
77        /**
78         * Nom anglais du rang principal `règne`.
79         */
80        define('_TAXONOMIE_RANG_REGNE', 'kingdom');
81}
82if (!defined('_TAXONOMIE_RANG_GENRE')) {
83        /**
84         * Nom anglais du rang principal `genre`.
85         */
86        define('_TAXONOMIE_RANG_GENRE', 'genus');
87}
88if (!defined('_TAXONOMIE_RANG_ESPECE')) {
89        /**
90         * Nom anglais du rang principal `espèce`.
91         */
92        define('_TAXONOMIE_RANG_ESPECE', 'species');
93}
94
95if (!defined('_TAXONOMIE_LANGUES_POSSIBLES')) {
96        /**
97         * Liste des langues utilisables pour les noms communs et les textes des taxons.
98         */
99        define('_TAXONOMIE_LANGUES_POSSIBLES', 'fr:en:es:pt:de:it');
100}
101
102
103/**
104 * Renvoie la liste des règnes supportés par le plugin.
105 *
106 * @package SPIP\TAXONOMIE\REGNE
107 *
108 * @api
109 *
110 * @return array
111 *        Liste des noms scientifiques en minuscules des règnes supportés.
112 */
113function regne_lister() {
114
115        return $GLOBALS['_taxonomie']['regnes'];
116}
117
118
119/**
120 * Renvoie le type de rang principal, secondaire ou intercalaire.
121 *
122 * @package SPIP\TAXONOMIE\RANG
123 *
124 * @api
125 *
126 * @param string $rang
127 *        Nom anglais du rang en minuscules.
128 *
129 * @return string
130 *        `principal`, `secondaire` ou `intercalaire` si le rang est valide, chaine vide sinon.
131 */
132function rang_informer_type($rang) {
133
134        // Initialisation à chaine vide pour le cas où le rang n'est pas dans la liste des rangs admis.
135        $type = '';
136
137        if (!empty($GLOBALS['_taxonomie']['rangs'][$rang])) {
138                $type = $GLOBALS['_taxonomie']['rangs'][$rang]['type'];
139        }
140
141        return $type;
142}
143
144
145/**
146 * Détermine si un rang est celui d'une espèce ou d'un taxon de rang inférieur.
147 *
148 * @package SPIP\TAXONOMIE\RANG
149 *
150 * @api
151 *
152 * @param string $rang
153 *        Nom anglais du rang en minuscules.
154 *
155 * @return bool
156 *        `true` si le rang est celui d'une espèce ou d'un taxon de rang inférieur, `false` sinon.
157 */
158function rang_est_espece($rang) {
159
160        // Initialisation à false pour le cas où le rang n'est pas dans la liste des rangs admis.
161        $est_espece = false;
162
163        if (!empty($GLOBALS['_taxonomie']['rangs'][$rang])) {
164                $est_espece = $GLOBALS['_taxonomie']['rangs'][$rang]['est_espece'];
165        }
166
167        return $est_espece;
168}
169
170
171/**
172 * Extrait, de la table `spip_taxons`, la liste des taxons non espèce d'un règne donné - importés via un fichier ITIS -
173 * ayant fait l'objet d'une modification manuelle et la liste des taxons non espèce créés lors de l'ajout d'une espèce
174 * et donc non importés avec le fichier ITIS.
175 *
176 * @package SPIP\TAXONOMIE\TAXON
177 *
178 * @api
179 *
180 * @param string $regne
181 *        Nom scientifique du règne en lettres minuscules : `animalia`, `plantae`, `fungi`.
182 *
183 * @return array
184 *        Liste des taxons modifiées manuellement et créés suite à l'ajout d'une espèce.
185 *        Chaque élément de la liste est un tableau composé, pour les taxons modifiés manuellement des index
186 *        `tsn`, `nom_commun`, `descriptif` et pour les taxons créés via une espèce de tous les champs de l'objet
187 *        taxon, à l'exception de l'id (`id_taxon`) et de la date de mise à jour (`maj`).
188 */
189function taxon_preserver($regne) {
190
191        // Récupération de la description de la table spip_taxons afin de connaitre la liste des colonnes.
192        include_spip('base/objets');
193        $description_table = lister_tables_objets_sql('spip_taxons');
194
195        // Récupération de la liste des taxons importés via le fichier ITIS du règne concerné et édités manuellement.
196        // Ces champs éditables (nom_commun, descriptif, texte et sources) seront réinjectés après le chargement du règne
197        // via un update.
198        $from = array('spip_taxons');
199        $select = array_merge($description_table['champs_editables'], array('tsn'));
200        $where = array(
201                'regne=' . sql_quote($regne),
202                'edite=' . sql_quote('oui'),
203                'importe=' . sql_quote('oui'),
204                'espece=' . sql_quote('non')
205        );
206        $taxons['edites'] = sql_allfetsel($select, $from, $where);
207
208        // Récupération de la liste des taxons non importés via le fichier ITIS du règne concerné mais créés lors de l'ajout
209        // d'une espèce.
210        // Ces taxons préservés uniquement pour le besoin de l'exportation par IEConfig car il ne sont pas effacés
211        // lors du rechargement du règne.
212        // -- on récupère tous les champs du taxons sauf ceux qui seront mis à jour automatique lors de l'insertion de
213        //    l'objet en BD (id_taxon, maj).
214        $select = array_diff(array_keys($description_table['field']), array('id_taxon', 'maj'));
215        $where = array(
216                'regne=' . sql_quote($regne),
217                'importe=' . sql_quote('non'),
218                'espece=' . sql_quote('non')
219        );
220        $taxons['crees'] = sql_allfetsel($select, $from, $where);
221
222        return $taxons;
223}
224
225
226/**
227 * Fusionne les traductions d'une balise `<multi>` avec celles d'une autre balise `<multi>`.
228 * L'une des balise est considérée comme prioritaire ce qui permet de régler le cas où la même
229 * langue est présente dans les deux balises.
230 * Si on ne trouve pas de balise `<multi>` dans l'un ou l'autre des paramètres, on considère que
231 * le texte est tout même formaté de la façon suivante : texte0[langue1]texte1[langue2]texte2...
232 *
233 * @package SPIP\TAXONOMIE\TAXON
234 *
235 * @api
236 *
237 * @param string $multi_prioritaire
238 *        Balise multi considérée comme prioritaire en cas de conflit sur une langue.
239 * @param string $multi_non_prioritaire
240 *        Balise multi considérée comme non prioritaire en cas de conflit sur une langue.
241 *
242 * @return string
243 *        La chaine construite est toujours une balise `<multi>` complète ou une chaine vide sinon.
244 */
245function taxon_merger_traductions($multi_prioritaire, $multi_non_prioritaire) {
246
247        $multi_merge = '';
248
249        // On extrait le contenu de la balise <multi> si elle existe.
250        $multi_prioritaire = trim($multi_prioritaire);
251        $multi_non_prioritaire = trim($multi_non_prioritaire);
252
253        // Si les deux balises sont identiques on sort directement avec le multi prioritaire ce qui améliore les
254        // performances.
255        if ($multi_prioritaire == $multi_non_prioritaire) {
256                $multi_merge = $multi_prioritaire;
257        } else {
258                include_spip('inc/filtres');
259                if (preg_match(_EXTRAIRE_MULTI, $multi_prioritaire, $match)) {
260                        $multi_prioritaire = trim($match[1]);
261                }
262                if (preg_match(_EXTRAIRE_MULTI, $multi_non_prioritaire, $match)) {
263                        $multi_non_prioritaire = trim($match[1]);
264                }
265
266                if ($multi_prioritaire) {
267                        if ($multi_non_prioritaire) {
268                                // On extrait les traductions sous forme de tableau langue=>traduction.
269                                $traductions_prioritaires = extraire_trads($multi_prioritaire);
270                                $traductions_non_prioritaires = extraire_trads($multi_non_prioritaire);
271
272                                // On complète les traductions prioritaires avec les traductions non prioritaires dont la langue n'est pas
273                                // présente dans les traductions prioritaires.
274                                foreach ($traductions_non_prioritaires as $_lang => $_traduction) {
275                                        if (!array_key_exists($_lang, $traductions_prioritaires)) {
276                                                $traductions_prioritaires[$_lang] = $_traduction;
277                                        }
278                                }
279
280                                // On construit le contenu de la balise <multi> mergé à partir des traductions prioritaires mises à jour.
281                                // Les traductions vides sont ignorées.
282                                ksort($traductions_prioritaires);
283                                foreach ($traductions_prioritaires as $_lang => $_traduction) {
284                                        if ($_traduction) {
285                                                $multi_merge .= ($_lang ? '[' . $_lang . ']' : '') . trim($_traduction);
286                                        }
287                                }
288                        } else {
289                                $multi_merge = $multi_prioritaire;
290                        }
291                } else {
292                        $multi_merge = $multi_non_prioritaire;
293                }
294
295                // Si le contenu est non vide on l'insère dans une balise <multi>
296                if ($multi_merge) {
297                        $multi_merge = '<multi>' . $multi_merge . '</multi>';
298                }
299        }
300
301        return $multi_merge;
302}
303
304
305/**
306 * Traduit un champ de la table `spip_taxons` dans la langue du site.
307 *
308 * @package SPIP\TAXONOMIE\TAXON
309 *
310 * @api
311 *
312 * @param string $champ
313 *        Nom du champ dans la base de données.
314 *
315 * @return string
316 *        Traduction du champ dans la langue du site.
317 */
318function taxon_traduire_champ($champ) {
319
320        $traduction = '';
321        if ($champ) {
322                $traduction = _T("taxon:champ_${champ}_label");
323        }
324
325        return $traduction;
326}
Note: See TracBrowser for help on using the repository browser.