source: spip-zone/_plugins_/taxonomie/trunk/taxonomie_fonctions.php @ 96992

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

Phpdoc et formatage PSR SPIP

  • Property svn:eol-style set to native
File size: 10.7 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'ensemble des fonctions implémentant l'API du plugin Taxonomie.
4 *
5 * @package SPIP\TAXONOMIE\API
6 */
7if (!defined('_ECRIRE_INC_VERSION')) {
8        return;
9}
10
11
12/**
13 * Charge tous les taxons d'un règne donné, du règne lui-même aux taxons de genre au maximum.
14 * La fonction permet aussi de choisir un rang taxonomique feuille différent du genre.
15 * Les nom communs anglais, français ou espagnols peuvent aussi être chargés en complément mais
16 * ne couvrent pas l'ensemble des taxons.
17 *
18 * @api
19 * @filtre
20 * @uses taxonomie_regne_existe()
21 * @uses taxon_preserver_editions()
22 * @uses taxonomie_vider_regne()
23 * @uses itis_read_hierarchy()
24 * @uses itis_spipcode2language()
25 * @uses itis_read_vernaculars()
26 *
27 * @param string $regne
28 *        Nom scientifique du règne en lettres minuscules : `animalia`, `plantae`, `fungi`.
29 * @param string $rang
30 *        Rang taxonomique minimal jusqu'où charger le règne. Ce rang est fourni en anglais, en minuscules et
31 *        correspond à : `phylum`, `class`, `order`, `family`, `genus`.
32 * @param array  $codes_langue
33 *        Tableau des codes (au sens SPIP) des langues à charger pour les noms communs des taxons.
34 *
35 * @return bool
36 *        `true` si le chargement a réussi, `false` sinon
37 */
38function taxonomie_charger_regne($regne, $rang, $codes_langue = array()) {
39        $retour = false;
40        $taxons_edites = array();
41
42        // Vérifie si le règne existe bien dans la table spip_taxons
43        $regne_existe = taxonomie_regne_existe($regne, $meta_regne);
44        if ($regne_existe) {
45                // Sauvegarde des taxons ayant été modifiés manuellement suite à leur création automatique.
46                include_spip('inc/taxonomer');
47                $taxons_edites = taxon_preserver_editions($regne);
48
49                // Vider le règne avant de le recharger
50                taxonomie_vider_regne($regne);
51        }
52
53        // Lecture de la hiérarchie des taxons à partir du fichier texte extrait de la base ITIS
54        $meta_regne = array();
55        include_spip('services/itis/itis_api');
56        $taxons = itis_read_hierarchy($regne, $rang, $meta_regne['sha']);
57
58        // Ajout des noms communs extraits de la base ITIS dans la langue demandée
59        if ($taxons) {
60                $meta_regne['compteur'] = count($taxons);
61                $traductions = array();
62                foreach ($codes_langue as $_code_langue) {
63                        $langue = itis_spipcode2language($_code_langue);
64                        if ($langue) {
65                                $noms = itis_read_vernaculars($langue, $sha_langue);
66                                if ($noms) {
67                                        $meta_regne['traductions']['itis'][$_code_langue]['sha'] = $sha_langue;
68                                        $nb_traductions = 0;
69                                        foreach ($noms as $_tsn => $_nom) {
70                                                if (array_key_exists($_tsn, $taxons)) {
71                                                        // On ajoute les traductions qui sont de la forme [xx]texte
72                                                        // On sauvegarde le tsn concerné afin de clore les traductions
73                                                        // avec les balises multi et d'optimiser ainsi les traitements
74                                                        // sachant qu'il y a très peu de traductions comparées aux taxons
75                                                        $taxons[$_tsn]['nom_commun'] .= $_nom;
76                                                        $nb_traductions += 1;
77                                                        $traductions[$_tsn] = $_tsn;
78                                                }
79                                        }
80                                        $meta_regne['traductions']['itis'][$_code_langue]['compteur'] = $nb_traductions;
81                                }
82                        }
83                }
84
85                // Clore les traductions avec les balises multi
86                if ($traductions) {
87                        foreach ($traductions as $_tsn) {
88                                $taxons[$_tsn]['nom_commun'] = '<multi>' . $taxons[$_tsn]['nom_commun'] . '</multi>';
89                        }
90                }
91
92                // Réinjection des taxons modifiés manuellement
93                // -- descriptif: remplacement
94                // -- nom commun: merge en considérant que la mise à jour manuelle est prioritaire
95                // -- edite: oui, on conserve bien sur l'indicateur d'édition
96                if ($taxons_edites) {
97                        foreach ($taxons_edites as $_taxon_edite) {
98                                if (($tsn = $_taxon_edite['tsn'])
99                                        and (array_key_exists($tsn, $taxons))
100                                ) {
101                                        $taxons[$tsn]['descriptif'] = $_taxon_edite['descriptif'];
102                                        $taxons[$tsn]['nom_commun'] = taxon_merger_traductions(
103                                                $_taxon_edite['nom_commun'],
104                                                $taxons[$tsn]['nom_commun']);
105                                        $taxons[$tsn]['edite'] = 'oui';
106                                }
107                        }
108                }
109
110                // Insertion dans la base de données
111                $retour = sql_insertq_multi('spip_taxons', array_values($taxons));
112                if ($retour) {
113                        // Insérer les sha dans une meta propre au règne.
114                        // Ca permettra de tester l'utilité ou pas d'un rechargement du règne
115                        $meta_regne['rang'] = $rang;
116                        $meta_regne['maj'] = date('Y-m-d H:i:s');
117                        ecrire_meta("taxonomie_$regne", serialize($meta_regne));
118                }
119        }
120
121        return $retour;
122}
123
124
125/**
126 * Supprime tous les taxons d'un règne donné de la base de données.
127 * La meta concernant les informations de chargement du règne est aussi effacée.
128 * Les modifications manuelles effectuées sur les taxons du règne sont perdues, elles
129 * doivent donc être préservées au préalable.
130 *
131 * @api
132 * @filtre
133 *
134 * @param string $regne
135 *        Nom scientifique du règne en lettres minuscules : `animalia`, `plantae`, `fungi`.
136 *
137 * @return bool
138 *        `true` si le vidage a réussi, `false` sinon
139 */
140function taxonomie_vider_regne($regne) {
141        $retour = sql_delete('spip_taxons', 'regne=' . sql_quote($regne));
142        if ($retour !== false) {
143                // Supprimer la meta propre au règne.
144                effacer_meta("taxonomie_$regne");
145                $retour = true;
146        }
147
148        return $retour;
149}
150
151
152/**
153 * Retourne l'existence ou pas d'un règne en base de données.
154 * La fonction scrute la table `spip_taxons` et non la meta propre au règne.
155 *
156 * @api
157 * @filtre
158 *
159 * @param string $regne
160 *        Nom scientifique du règne en lettres minuscules : `animalia`, `plantae`, `fungi`.
161 * @param array  $meta_regne
162 *        Meta propre au règne, créée lors du chargement de celui-ci et retournée si le règne
163 *        existe.
164 *
165 * @return bool
166 *        `true` si le règne existe, `false` sinon.
167 */
168function taxonomie_regne_existe($regne, &$meta_regne) {
169        $meta_regne = array();
170        $existe = false;
171
172        $retour = sql_countsel('spip_taxons', 'regne=' . sql_quote($regne));
173        if ($retour) {
174                // Récupérer la meta propre au règne afin de la retourner.
175                include_spip('inc/config');
176                $meta_regne = lire_config("taxonomie_$regne");
177                $existe = true;
178        }
179
180        return $existe;
181}
182
183
184/**
185 * Liste dans un tableau les rangs taxonomiques supportés par le plugin, suivant certains critères.
186 * Les règnes et les rangs sont exprimés en anglais et écrits en lettres minuscules.
187 * La fonction permet d'exclure certains rangs de la liste.
188 *
189 * @api
190 * @filtre
191 *
192 * @param string $regne
193 *        Nom scientifique du règne pour lequel la liste des rangs est demandée.
194 *        Cet argument permet de remplacer le rang `phylum` par `division` qui est son synonyme
195 *        pour les règnes fongique et végétal.
196 * @param array  $liste_base
197 *        Liste de base contenant les rangs par défaut à renvoyer. Il existe deux listes de base, à savoir :
198 *        - du règne au genre (`_TAXONOMIE_RANGS_PARENTS_ESPECE`)
199 *        - de l'espèce à la sous-forme (`_TAXONOMIE_RANGS_ESPECE_ET_FILS`)
200 * @param array  $exclusions
201 *        Liste des rangs à exclure de la liste fournie dans l'argument `$liste_base`
202 *
203 * @return array
204 *        Liste des rangs demandée.
205 */
206function taxonomie_lister_rangs($regne = _TAXONOMIE_REGNE_ANIMAL, $liste_base, $exclusions = array()) {
207        include_spip('inc/taxonomer');
208
209        $rangs = explode(':', $liste_base);
210        $rangs = array_diff($rangs, $exclusions);
211
212        if (($regne == _TAXONOMIE_REGNE_FONGIQUE)
213                or ($regne == _TAXONOMIE_REGNE_VEGETAL)
214        ) {
215                if ($index_cherche = array_search(_TAXONOMIE_RANG_PHYLUM, $rangs)) {
216                        $rangs[$index_cherche] = _TAXONOMIE_RANG_DIVISION;
217                }
218        }
219
220        return $rangs;
221}
222
223
224/**
225 * Fournit l'ascendance taxonomique d'un taxon donné par consultation en base de données.
226 *
227 * @api
228 * @filtre
229 *
230 * @param int    $id_taxon
231 *        Id du taxon pour lequel il faut fournir l'ascendance.
232 * @param int    $tsn_parent
233 *        TSN du parent correspondant au taxon id_taxon. Ce paramètre permet d'optimiser le traitement
234 *        mais n'est pas obligatoire. Si il n'est pas connu lors de l'appel il faut passer `null`.
235 * @param string $ordre
236 *        Classement de la liste des taxons : `descendant`(défaut) ou `ascendant`.
237 *
238 * @return array
239 *        Liste des taxons ascendants. Chaque taxon est un tableau associatif contenant les informations
240 *        suivantes : `id_taxon`, `tsn_parent`, `nom_scientifique`, `nom_commun`, `rang`.
241 */
242function taxonomie_informer_ascendance($id_taxon, $tsn_parent = null, $ordre = 'descendant') {
243        $ascendance = array();
244
245        // Si on ne passe pas le tsn du parent correspondant au taxon pour lequel on cherche l'ascendance
246        // alors on le cherche en base de données.
247        // Le fait de passer ce tsn parent est uniquement une optimisation.
248        if (is_null($tsn_parent)) {
249                $tsn_parent = sql_getfetsel('tsn_parent', 'spip_taxons', 'id_taxon=' . intval($id_taxon));
250        }
251
252        while ($tsn_parent > 0) {
253                $select = array('id_taxon', 'tsn_parent', 'nom_scientifique', 'nom_commun', 'rang');
254                $where = array('tsn=' . intval($tsn_parent));
255                $taxon = sql_fetsel($select, 'spip_taxons', $where);
256                if ($taxon) {
257                        $ascendance[] = $taxon;
258                        $tsn_parent = $taxon['tsn_parent'];
259                }
260        }
261
262        if ($ascendance
263                and ($ordre == 'descendant')
264        ) {
265                $ascendance = array_reverse($ascendance);
266        }
267
268        return $ascendance;
269}
270
271
272/**
273 * Fournit les phrases de crédits des sources d'information ayant permis de compléter le taxon.
274 * La référence ITIS n'est pas répétée dans le champ `sources` de chaque taxon car elle est
275 * à la base de chaque règne. Elle est donc insérée par la fonction.
276 *
277 * @api
278 * @filtre
279 * @uses ${service}_credit fonction de formatage des crédits propre à chaque service
280 *
281 * @param int    $id_taxon
282 *        Id du taxon pour lequel il faut fournir les crédits
283 * @param string $sources_specifiques
284 *        Tableau sérialisé des sources possibles autres qu'ITIS (CINFO, WIKIPEDIA...) telles qu'enregistrées
285 *        en base de données dans le champ `sources`.
286 *        Ce paramètre permet d'optimiser le traitement mais n'est pas obligatoire.
287 *
288 * @return array
289 *        Tableau des phrases de crédits indexées par source.
290 */
291function taxonomie_informer_credits($id_taxon, $sources_specifiques = null) {
292        $sources = array();
293
294        // Si on ne passe pas les sources du taxon concerné alors on le cherche en base de données.
295        // Le fait de passer ce champ sources est uniquement une optimisation.
296        if (is_null($sources_specifiques)) {
297                $sources_specifiques = sql_getfetsel('sources', 'spip_taxons', 'id_taxon=' . intval($id_taxon));
298        }
299
300        // On merge ITIS et les autres sources
301        $liste_sources = array('itis' => array());
302        if ($sources_specifiques) {
303                $liste_sources = array_merge($liste_sources, unserialize($sources_specifiques));
304        }
305
306        // Puis on construit la liste des sources pour l'affichage
307        foreach ($liste_sources as $_service => $_infos_source) {
308                include_spip("services/${_service}/${_service}_api");
309                if (function_exists($citer = "${_service}_credit")) {
310                        $sources[$_service] = $citer($id_taxon, $_infos_source);
311                }
312        }
313
314        return $sources;
315}
Note: See TracBrowser for help on using the repository browser.