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

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

Refactoring complet du plugin suite au merge des tables spip_taxons et spip_especes. Tout n'est pas encore revenu à) l'état de la version 0.2.0

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