source: spip-zone/_plugins_/taxonomie/trunk/taxonomie_ieconfig.php @ 114311

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

Factoriser les traitement d'importation

  • Property svn:eol-style set to native
File size: 14.3 KB
Line 
1<?php
2
3if (!defined('_ECRIRE_INC_VERSION')) {
4        return;
5}
6
7/**
8 * Pipeline ieconfig pour l'import/export des données de configuration du plugin et de certaines données de production.
9 *
10 * @param array $flux
11 *
12 * @return array
13 */
14function taxonomie_ieconfig($flux) {
15
16        // On détermine l'action demandée qui peut être : afficher le formulaire d'export ou d'import, construire le
17        // tableau d'export ou exécuter l'importation.
18        $action = $flux['args']['action'];
19
20        if ($action == 'form_export') {
21                // Construire le formulaire d'export :
22                // -- on demande le minimum à savoir si l'utilisateur veut inclure dans son export l'ensemble des données
23                //    de Taxonomie.
24                $saisies = array(
25                        array(
26                                'saisie' => 'fieldset',
27                                'options' => array(
28                                        'nom'   => 'taxonomie_fieldset',
29                                        'label' => '<:taxonomie:titre_page_taxonomie:>',
30                                        'icone' => 'taxon-16.png',
31                                ),
32                                'saisies' => array(
33                                        array(
34                                                'saisie' => 'oui_non',
35                                                'options' => array(
36                                                        'nom' => 'taxonomie_export_option',
37                                                        'label' => '<:taxonomie:export_option:>',
38                                                        'explication' => '<:taxonomie:export_explication:>',
39                                                        'defaut' => '',
40                                                ),
41                                        ),
42                                ),
43                        ),
44                );
45                $flux['data'] = array_merge($flux['data'], $saisies);
46
47        } elseif (($action == 'export') and (_request('taxonomie_export_option') == 'on')) {
48                // Générer le tableau d'export
49                $flux['data']['taxonomie'] = taxonomie_ieconfig_exporter();
50
51        } elseif (($action == 'form_import') and isset($flux['args']['config']['taxonomie'])) {
52                // Construire le formulaire d'import :
53                // On affiche la version de Taxonomie et le schéma de base de données avec lesquels le fichier d'import
54                // à été créé.
55                $import = $flux['args']['config']['taxonomie'];
56                $texte_explication = _T(
57                        'taxonomie:import_resume',
58                        array('version' => $import['version'], 'schema' => $import['schema'])
59                );
60
61                // La configuration : une case suffit car on applique toujours un remplacement et la configuration est
62                // toujours présente dans un export.
63                $informer_plugin = chercher_filtre('info_plugin');
64                $version = $informer_plugin('taxonomie', 'version', true);
65                $schema = $informer_plugin('taxonomie', 'schema');
66                $plugin = $informer_plugin('taxonomie', 'nom');
67                if ($schema == $import['schema']) {
68                        $explication_config = _T(
69                                'taxonomie:import_configuration_explication',
70                                array('version' => $version, 'schema' => $schema));
71                } else {
72                        $explication_config = _T(
73                                'taxonomie:import_configuration_avertissement',
74                                array('version' => $version, 'schema' => $schema));
75                }
76
77                $saisies = array(
78                        array(
79                                'saisie'  => 'fieldset',
80                                'options' => array(
81                                        'nom'   => 'taxonomie_export',
82                                        'label' => $plugin,
83                                        'icone' => 'taxonomie-24.png',
84                                ),
85                                'saisies' => array(
86                                        array(
87                                                'saisie'  => 'explication',
88                                                'options' => array(
89                                                        'nom'   => 'taxonomie_export_explication',
90                                                        'texte' => $texte_explication,
91                                                ),
92                                        ),
93                                        array(
94                                                'saisie'  => 'case',
95                                                'options' => array(
96                                                        'nom'         => 'taxonomie_import_config',
97                                                        'label'       => '<:taxonomie:import_configuration_label:>',
98                                                        'label_case'  => '<:taxonomie:import_configuration_labelcase:>',
99                                                        'explication' => $explication_config
100                                                ),
101                                        ),
102                                ),
103                        ),
104                );
105
106                // On détermine les règnes existant dans le site: si un règne n'est pas présent sur le site
107                // aucun import n'est possible.
108                include_spip('taxonomie_fonctions');
109                $regnes = regne_repertorier();
110                if ($regnes) {
111                        // Pour chaque règne présent dans le fichier on crée la même liste de saisies instanciées pour le règne.
112                        foreach ($import['contenu']['regnes'] as $_regne) {
113                                // Titre du règne qui sert de séparation dans le formulaire.
114                                if (($import['contenu'][$_regne]['taxons']['edites'])
115                                or ($import['contenu'][$_regne]['especes'])) {
116                                        $explication = ucfirst(_T("taxonomie:regne_${_regne}"));
117                                        $saisies[0]['saisies'][] = array(
118                                                'saisie'  => 'explication',
119                                                'options' => array(
120                                                        'nom'   => "${_regne}_import_regne",
121                                                        'texte' => $explication,
122                                                ),
123                                        );
124                                }
125
126                                // Taxons importés et édités (du règne au genre).
127                                $data = array();
128                                if ($import['contenu'][$_regne]['taxons']['edites']) {
129                                        $data['fusionner'] = _T('taxonomie:import_taxons_edites_fusionner');
130                                        // Identifier si le site contient déjà des taxons édités et décider de l'avertissement
131                                        // nécessaire et des options.
132                                        $taxons_modifies = taxon_preserver($_regne);
133                                        if (!empty($taxons_modifies['edites'])) {
134                                                $explication = _T('taxonomie:import_taxons_edites_explication');
135                                                $data['ajouter'] = _T('taxonomie:import_taxons_edites_ajouter');
136                                        } else {
137                                                $explication = _T('taxonomie:import_taxons_edites_avertissement');
138                                        }
139                                        $saisies[0]['saisies'][] = array(
140                                                'saisie'  => 'radio',
141                                                'options' => array(
142                                                        'nom'         => "${_regne}_import_edites",
143                                                        'label'       => '<:taxonomie:import_taxons_edites_label:>',
144                                                        'explication' => $explication,
145                                                        'datas'       => $data,
146                                                ),
147                                        );
148                                }
149
150                                // Espèces et taxons créés manuellement (non importés).
151                                $data = array();
152                                if ($import['contenu'][$_regne]['especes']) {
153                                        $data['fusionner'] = _T('taxonomie:import_especes_fusionner');
154                                        // Identifier si le site contient déjà des espèces et décider de l'avertissement
155                                        // nécessaire et des options.
156                                        $where = array(
157                                                'regne=' . sql_quote($_regne),
158                                                'importe=' . sql_quote('non'),
159                                                'espece=' . sql_quote('oui')
160                                        );
161                                        $nb_especes = sql_countsel('spip_taxons', $where);
162                                        if ($nb_especes > 0) {
163                                                $explication = _T('taxonomie:import_especes_explication');
164                                                $data['ajouter'] = _T('taxonomie:import_especes_ajouter');
165                                        } else {
166                                                $explication = _T('taxonomie:import_especes_avertissement');
167                                        }
168                                        $saisies[0]['saisies'][] = array(
169                                                'saisie'  => 'radio',
170                                                'options' => array(
171                                                        'nom'         => "${_regne}_import_especes",
172                                                        'label'       => '<:taxonomie:import_especes_label:>',
173                                                        'explication' => $explication,
174                                                        'datas'       => $data,
175                                                ),
176                                        );
177                                }
178                        }
179                } else {
180                        $saisies[0]['saisies'][] = array(
181                                'saisie'  => 'explication',
182                                'options' => array(
183                                        'nom'   => "taxonomie_import_regne",
184                                        'texte' => '<:taxonomie:import_regne_avertissement:>',
185                                ),
186                        );
187                }
188
189                $flux['data'] = array_merge($flux['data'], $saisies);
190        }
191
192        // Import de la configuration
193        if (($action == 'import') and isset($flux['args']['config']['taxonomie'])) {
194                // On récupère les demandes d'importation.
195                $importation['configuration'] = _request('taxonomie_import_config');
196
197                include_spip('taxonomie_fonctions');
198                $importation['donnees'] = array();
199                $regnes = regne_repertorier();
200                foreach ($regnes as $_regne) {
201                        if ($valeur = _request("${_regne}_import_edites")) {
202                                $importation['donnees']['edites'][$_regne] = $valeur;
203                        }
204                        if ($valeur = _request("${_regne}_import_especes")) {
205                                $importation['donnees']['especes'][$_regne] = $valeur;
206                        }
207                }
208
209                // Si au moins l'une est requise on appelle la fonction d'import.
210                if ($importation['configuration']
211                or $importation['donnees']) {
212                        if (!taxonomie_ieconfig_importer($importation, $flux['args']['config']['taxonomie'])) {
213                                $flux['data'] .= _T('taxonomie:ieconfig_probleme_import_config').'<br />';
214                        }
215                }
216        }
217
218        return $flux;
219}
220
221
222// --------------------------------------------------------------------
223// ------------------------- API IMPORT/EXPORT ------------------------
224// --------------------------------------------------------------------
225
226/**
227 * Retourne le tableau d'export du plugin Taxonomie contenant toujours sa configuration et les taxons nécessitant d'être
228 * sauvegardés car non créés via les fichiers ITIS.
229 * Les taxons concernés sont :
230 * - les taxons du règne au genre, importés via les fichiers ITIS puis édités manuellement;
231 * - les taxons ascendants d'une espèce (entre le genre et l'espèce non compris), non inclus dans un fichier ITIS
232 *   et insérés lors de la création d'une espèce;
233 * - les taxons de type espèce et descendants créés manuellement.
234 *
235 * @return array
236 *         Tableau d'export pour le pipeline ieconfig_exporter.
237 **/
238function taxonomie_ieconfig_exporter() {
239
240        $export = array();
241
242        // Insérer une en-tête qui permet de connaitre la version du plugin Taxonomie utilisé lors de l'export
243        $informer_plugin = chercher_filtre('info_plugin');
244        $export['version'] = $informer_plugin('taxonomie', 'version', true);
245        $export['schema'] = $informer_plugin('taxonomie', 'schema');
246        $export['contenu'] = array();
247
248        // Exportation de la configuration du plugin rangée dans la meta taxonomie uniquement.
249        // Etant donné que l'on utilise ce pipeline pour les données de production de Taxonomie, on exporte aussi
250        // sa configuration via ce pipeline et non via le pipeline ieconfig_metas.
251        include_spip('inc/config');
252        $export['configuration'] = lire_config('taxonomie');
253        $export['contenu']['configuration'] = $export['configuration'] ? 'on' : '';
254
255        // Les metas de chargement de chaque règne ne sont pas exportées mais on identifie quand même la liste des règnes
256        // insérés dans la base. Les taxons seront ensuite exportés par règne pour permettre un import plus ciblé.
257        include_spip('inc/taxonomie');
258        $export['contenu']['regnes'] = array();
259        $regnes = regne_lister_defaut();
260        foreach ($regnes as $_regne) {
261                if (regne_existe($_regne, $meta_regne)) {
262                        $export['contenu']['regnes'][] = $_regne;
263                }
264        }
265
266        // Exportation de la table spip_taxons des taxons nécessitant d'être sauvegardés.
267        if ($export['contenu']['regnes']) {
268                // Récupération de la description de la table spip_taxons afin de connaitre la liste des colonnes.
269                include_spip('base/objets');
270                $from ='spip_taxons';
271                $description_table = lister_tables_objets_sql($from);
272                $select = array_diff(array_keys($description_table['field']), array('id_taxon', 'maj'));
273
274                // Pour faciliter l'import et aussi mieux le cibler les taxons exportés sont rangés par règne (index au nom
275                // du règne). Ensuite, on sépare aussi les taxons édités (index [taxons][edites]), les taxons créés en tant
276                // qu'ascendant d'une espèce (index [taxons][crees]) et les espèces créées manuellement (index [especes]).
277                foreach ($export['contenu']['regnes'] as $_regne) {
278                        // Extraction des taxons du règne au genre édités manuellement par les utilisateurs ou créés lors d'un
279                        // ajout d'espèce.
280
281                        // On sauvegarde les champs éditables uniquement des édités et tous les champs pour les autres.
282                        $export[$_regne]['taxons'] = taxon_preserver($_regne);
283                        $export['contenu'][$_regne]['taxons']['edites'] = $export[$_regne]['taxons']['edites'] ? 'on' : '';
284                        $export['contenu'][$_regne]['taxons']['crees'] = $export[$_regne]['taxons']['crees'] ? 'on' : '';
285
286                        // Extraction des espèces et descendants.
287                        $export[$_regne]['especes'] = array();
288                        $where = array(
289                                'regne=' . sql_quote($_regne),
290                                'importe=' . sql_quote('non'),
291                                'espece=' . sql_quote('oui')
292                        );
293                        $export[$_regne]['especes'] = sql_allfetsel($select, $from, $where);
294                        $export['contenu'][$_regne]['especes'] = $export[$_regne]['especes'] ? 'on' : '';
295                }
296        }
297
298        return $export;
299}
300
301/**
302 * Importe tout ou partie d'un fichier d'export ieconfig contenant les données du noiZetier.
303 *
304 * @param array $importation
305 *        Tableau associatif des demandes d'importation issues du formulaire ieconfig. Les index et les valeurs
306 *        possibles sont :
307 *        - `configuration` : vaut `on` pour importer ou null sinon
308 *        - `pages_explicites` : vaut `on` pour importer ou null sinon
309 *        - `compositions_virtuelles` : vaut `remplacer`, `ajouter` ou `fusionner` pour importer ou null sinon.
310 *        - `noisettes` : vaut `remplacer` ou `ajouter` pour importer ou null sinon.
311 * @param array $contenu_import
312 *        Tableau des données du noiZetier issues du fichier d'import.
313 *
314 * @return bool
315 */
316function taxonomie_ieconfig_importer($importation, $contenu_import) {
317
318        // Initialisation de la sortie
319        $retour = true;
320
321        // La configuration
322        if ($importation['configuration']) {
323                // On remplace la configuration actuelle par celle du fichier d'import.
324                include_spip('inc/config');
325                ecrire_config('taxonomie', $contenu_import['configuration']);
326        }
327
328        // Les taxons du règne au genre édités.
329        include_spip('action/editer_objet');
330        $from ='spip_taxons';
331        if (!empty($importation['donnees']['edites'])) {
332                foreach ($importation['donnees']['edites'] as $_regne => $_action) {
333                        // Importation des taxons édités du fichier d'import selon l'action requise.
334                        taxonomie_importer_taxons($contenu_import[$_regne]['taxons']['edites'], $_action, true);
335                }
336        }
337
338        // Les espèces et les éventuels ascendants entre genre et espèce.
339        if (!empty($importation['donnees']['especes'])) {
340                foreach ($importation['donnees']['especes'] as $_regne => $_action) {
341                        // On commence par les taxons entre genre et espèce pour être sur que l'institution fonctionne.
342                        if (!empty($contenu_import[$_regne]['taxons']['crees'])) {
343                                taxonomie_importer_taxons($contenu_import[$_regne]['taxons']['crees'], $_action);
344                        }
345
346                        // Maintenant que les taxons entre genre et espèce ont été rajoutés on boucle sur les espèces et descendants.
347                        taxonomie_importer_taxons($contenu_import[$_regne]['especes'], $_action);
348                }
349        }
350
351        // On invalide le cache
352        include_spip('inc/invalideur');
353        suivre_invalideur('taxonomie-import-config');
354
355        return $retour;
356}
357
358
359function taxonomie_importer_taxons($taxons, $action, $taxons_edites = false) {
360
361        // On boucle sur les taxons édités du règne et on les traite en fonction de l'action choisie.
362        foreach ($taxons as $_taxon) {
363                // On force le statut à prop pour une espèce.
364                if ($_taxon['espece'] == 'oui') {
365                        $_taxon['statut'] = 'prop';
366                }
367
368                // Pour chaque taxon on vérifié si il existe en base et si il est déjà édité.
369                // On récupère en outre l'id pour utiliser l'API objet.
370                $select = array('id_taxon', 'edite');
371                $where = array('tsn=' . intval($_taxon['tsn']));
372                if ($taxon_base = sql_fetsel($select, 'spip_taxons', $where)) {
373                        if (($action == 'fusionner')
374                        or (($action == 'ajouter') and ($taxon_base['edite'] != 'oui'))) {
375                                // On modifie l'espèce avec l'API qui appellera elle-même les pipelines pre_edition
376                                // pour la mise à jour de l'indicateur edite à oui et post_edition pour la modification
377                                // du statut qui dans ce cas ne produira rien.
378                                objet_modifier('taxon', $taxon_base['id_taxon'], $_taxon);
379                        }
380                } elseif (!$taxons_edites) {
381                        objet_inserer('taxon', null, $_taxon);
382                }
383        }
384}
Note: See TracBrowser for help on using the repository browser.