source: spip-zone/_plugins_/isocode/trunk/isocode_fonctions.php @ 100375

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

Mise au point des commentaires.

  • Property svn:eol-style set to native
File size: 12.1 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'ensemble des fonctions implémentant l'API du plugin.
4 *
5 * @package SPIP\ISOCODE\API
6 */
7if (!defined('_ECRIRE_INC_VERSION')) {
8        return;
9}
10
11
12/**
13 * Charge en base de données une liste de tables de codes ISO donnée.
14 * Si la liste est vide, la fonction charge toutes les tables disponibles.
15 *
16 * @api
17 * @filtre
18 *
19 * @uses isocode_lister_tables()
20 * @uses isocode_trouver_service()
21 * @uses lire_source()
22 * @uses isocode_decharger_tables()
23 *
24 * @param array $tables
25 *      Liste des tables à charger. Si le tableau est vide l'ensemble des tables
26 *      seront chargées.
27 *      Les tables doivent être libellées sans le préfixe `spip_`.
28 *
29 * @return array
30 *      Tableau associatif résultat de l'action de vidage:
31 *      - index `ok`         : `true` si le vidage a réussi, `false` sinon.
32 *      - index `tables_ok`  : liste des tables vidées avec succès ou tableau vide sinon.
33 *      - index `tables_nok` : liste des tables en erreur ou tableau vide sinon.
34 *      - index `tables_sha` : liste des tables inchangées (SHA identique) ou tableau vide sinon.
35 */
36function isocode_charger_tables($tables = array()) {
37
38        $retour = array(
39                'ok'         => true,
40                'tables_ok'  => array(),
41                'tables_nok' => array(),
42                'tables_sha' => array()
43        );
44
45        // Suivant le tableau fourni en argument, on détermine la liste exacte des tables à charger.
46        // Le cas où le service existe mais que la liste de tables associées est vide est traité dans
47        // la boucle des services ci-après.
48        if (!$tables) {
49                // Le tableau est vide : il faut charger toutes les tables de tous les services supportés.
50                $tables = isocode_lister_tables();
51        } elseif (is_string($tables)) {
52                // L'argument n'est pas un tableau mais une chaîne, on considère que l'appelant a demandé
53                // le chargement d'une table identifiée par cette chaîne.
54                $tables = array($tables);
55        } elseif (!is_array($tables)) {
56                // L'argument n'est pas compréhensible, on met la liste à vide pour sortir sans traitement
57                // et on enregistre l'erreur.
58                $retour['ok'] = false;
59                $retour['tables_nok'][] = $tables;
60                $tables = array();
61        }
62
63        // On charge chacune des tables spécifiées en identifiant au préalable le service concerné.
64        // -- Pour éviter d'avoir une mise à jour bancale, il faudrait inclure les requêtes SQL dans
65        // une transaction ce qui n'est pas possible avec spip aujourd'hui.
66        // De fait, on ne peut pas assurer que si une erreur se produit le résultat soit cohérent et
67        // on renvoie juste l'erreur --
68        if ($tables) {
69                include_spip('inc/config');
70                foreach ($tables as $_table) {
71                        $erreur_table = true;
72                        $source_identique = false;
73
74                        // On détermine le service qui supporte le chargement de la table
75                        $service = isocode_trouver_service($_table);
76                        if ($service) {
77                                // Lecture des données contenues soit dans un fichier soit dans une page web et renvoie d'une liste
78                                // d'éléments prêts à être enregistrés dans la table concernée.
79                                // Si la table est déjà chargée et que le fichier ou la page source n'a pas changé, la fonction de
80                                // lecture ne renvoie aucun élément pour éviter des traitements inutiles mais renvoie un indicateur
81                                // sur le SHA.
82                                spip_timer('lire');
83                                include_spip('inc/isocode_sourcer');
84                                list($enregistrements, $sha, $source_identique) = lire_source($service, $_table);
85                                $duree_lire = spip_timer('lire');
86                                if ($enregistrements) {
87                                        spip_timer('ecrire');
88                                        // Suppression des éléments éventuels déjà chargés. On ne gère pas d'erreur
89                                        // sur ce traitement car elle sera forcément détectée lors de l'insertion qui suit.
90                                        isocode_decharger_tables($_table);
91
92                                        // Insertion dans la base de données des éléments extraits
93                                        $sql_ok = sql_insertq_multi("spip_${_table}", $enregistrements);
94                                        if ($sql_ok !== false) {
95                                                // On stocke les informations de chargement de la table dans une meta.
96                                                $meta = array(
97                                                        'service' => $service,
98                                                        'sha'     => $sha,
99                                                        'nbr'     => count($enregistrements),
100                                                        'maj'     => date('Y-m-d H:i:s')
101                                                );
102                                                ecrire_config("isocode/tables/${_table}", $meta);
103                                                $erreur_table = false;
104                                        }
105                                        $duree_ecrire = spip_timer('ecrire');
106                                        spip_log("La table <${_table}> a été chargée (lecture source: ${duree_lire} - insertion BD: ${duree_ecrire})", 'isocode' . _LOG_DEBUG);
107                                }
108                        }
109
110                        // Si la table est en erreur, on passe l'indicateur global à erreur et on stocke la table en nok
111                        // ou en sha identique suivant la cas.
112                        // Si le traitement est ok on stocke juste la table.
113                        if ($erreur_table) {
114                                $retour['ok'] = false;
115                                if ($source_identique) {
116                                        $retour['tables_sha'][] = $_table;
117                                } else {
118                                        $retour['tables_nok'][] = $_table;
119                                }
120                        } else {
121                                $retour['tables_ok'][] = $_table;
122                        }
123                }
124        }
125
126        return $retour;
127}
128
129
130/**
131 * Supprime en base de données, le contenu des tables de codes ISO choisies.
132 * Si la liste des tables est vide la fonction considère que toutes les tables doivent être vidées.
133 * La meta concernant les informations de chargement de chaque table est aussi effacée.
134 *
135 * @api
136 * @filtre
137 *
138 * @uses isocode_lister_tables()
139 *
140 * @param array $tables
141 *      Liste des tables à vider. Si le tableau est vide l'ensemble des tables
142 *      seront vidées.
143 *      Les tables doivent être libellées sans le préfixe `spip_`.
144 *
145 * @return array
146 *      Tableau associatif résultat de l'action de vidage:
147 *      - index `ok`         : `true` si le vidage a réussi, `false` sinon.
148 *      - index `tables_ok`  : liste des tables vidées avec succès ou tableau vide sinon.
149 *      - index `tables_nok` : liste des tables en erreur ou tableau vide sinon.
150 */
151function isocode_decharger_tables($tables = array()) {
152
153        $retour = array(
154                'ok'         => true,
155                'tables_ok'  => array(),
156                'tables_nok' => array()
157        );
158
159        // Suivant le tableau fourni en argument, on détermine la liste exacte des tables à charger.
160        // Le cas où le service existe mais que la liste de tables associées est vide est traité dans
161        // la boucle des services ci-après.
162        if (!$tables) {
163                // Le tableau est vide : il faut charger toutes les tables de tous les services supportés.
164                $tables = isocode_lister_tables();
165        } elseif (is_string($tables)) {
166                // L'argument n'est pas un tableau mais une chaine, on considère que l'appelant a demandé
167                // le chargement d'une table identifiée par cette chaine.
168                $tables = array($tables);
169        } elseif (!is_array($tables)) {
170                // L'argument n'est pas compréhensible, on met la liste à vide pour sortir sans traitement
171                // et on enregistre l'erreur.
172                $retour['ok'] = false;
173                $retour['tables_nok'][] = $tables;
174                $tables = array();
175        }
176
177        // On boucle sur la liste des tables et on vide chaque table référencée.
178        if ($tables) {
179                include_spip('inc/config');
180                foreach ($tables as $_table) {
181                        $sql_ok = sql_delete("spip_${_table}");
182                        if ($sql_ok !== false) {
183                                // Supprimer la meta propre à la table.
184                                effacer_config("isocode/tables/${_table}");
185                                // Enregistrer le succès du déchargement de la table
186                                $retour['tables_ok'][] = $_table;
187                        } else {
188                                $retour['ok'] = false;
189                                $retour['tables_nok'][] = $_table;
190                        }
191                }
192        }
193
194        return $retour;
195}
196
197
198/**
199 * Détermine le service associé au chargement de la table de codes ISO choisie.
200 * Si la table est vide ou invalide, la fonction renvoie une chaîne vide.
201 *
202 * @api
203 * @filtre
204 *
205 * @uses isocode_lister_services()
206 *
207 * @param $table
208 *      Nom d'une table sans le préfixe `spip_`.
209 *
210 * @return string
211 *      Nom du service permettant le chargement de la table ou chaîne vide si aucun service n'est trouvé.
212 */
213function isocode_trouver_service($table) {
214
215        static $services = array();
216        static $tables = array();
217        $service = '';
218
219        if (is_string($table) and $table) {
220                if (!$services) {
221                        $services = isocode_lister_services();
222                }
223
224                foreach ($services as $_service) {
225                        if (!isset($tables[$_service])) {
226                                include_spip("services/${_service}/${_service}_api");
227                                $tables[$_service] = array_keys($GLOBALS['isocode'][$_service]['tables']);
228                        }
229                        if (in_array(strtolower($table), $tables[$_service])) {
230                                $service = $_service;
231                                break;
232                        }
233                }
234        }
235
236        return $service;
237}
238
239
240/**
241 * Retourne la liste des services disponibles pour le chargement des tables de codes ISO.
242 * La fonction lit les sous-répertoires du répertoire `services/` du plugin.
243 *
244 * @api
245 * @filtre
246 *
247 * @return array
248 *      La liste des services disponibles ou tableau vide aucun service n'est détecté.
249 */
250function isocode_lister_services() {
251
252        $services = array();
253
254        if ($dossiers = glob(_DIR_PLUGIN_ISOCODE . '/services/*', GLOB_ONLYDIR)) {
255                foreach ($dossiers as $_dossier) {
256                        $services[] = strtolower(basename($_dossier));
257                }
258        }
259
260        return $services;
261}
262
263
264/**
265 * Vérifie si le service demandé est fait bien partie de la liste des services disponibles.
266 *
267 * @api
268 * @filtre
269 *
270 * @uses isocode_lister_services()
271 *
272 * @param string $service
273 *      Nom du service à vérifier.
274 *
275 * @return bool
276 *      `true` si le service est disponible, `false` sinon.
277 */
278function isocode_service_disponible($service) {
279
280        $disponible = false;
281        if ($service and in_array(strtolower($service), isocode_lister_services())) {
282                $disponible = true;
283        }
284
285        return $disponible;
286}
287
288
289/**
290 * Retourne la liste de toutes les tables gérées par le plugin ou de celles associées à un ou plusieurs
291 * services donnés.
292 *
293 * @api
294 * @filtre
295 *
296 * @uses isocode_lister_services()
297 * @uses isocode_service_disponible()
298 *
299 * @param array $services
300 *      Liste des services pour lesquels la liste des tables associées est demandée.
301 *      Si la liste est vide la fonction renvoie les tables de tous les services disponibles.
302 *
303 * @return array
304 *      Liste des tables sans le préfixe `spip_`.
305 */
306function isocode_lister_tables($services = array()) {
307
308        $tables = array();
309
310        // Si le tableau des services est vide c'est que l'on veut toutes les tables de tous
311        // les services disponibles.
312        // On accepte tous les cas où l'argument est vide sans être un tableau.
313        if (!$services) {
314                $services = isocode_lister_services();
315        }
316
317        // Si l'argument est non vide et est une chaine on considère que c'est un service et on le
318        // transforme en un tableau à un élément.
319        // Sinon c'est une erreur.
320        if (!is_array($services)) {
321                $services = is_string($services) ? array($services) : array();
322        }
323
324        // On collecte pour chaque service, la liste des tables qu'il supporte.
325        foreach ($services as $_service) {
326                if (isocode_service_disponible($_service)) {
327                        include_spip("services/${_service}/${_service}_api");
328                        $tables = array_merge($tables, array_keys($GLOBALS['isocode'][$_service]['tables']));
329                }
330        }
331
332        return $tables;
333}
334
335
336/**
337 * Informe sur la liste des tables déjà chagées en base de données.
338 * Les informations de la meta de chaque table sont complétées et renvoyées.
339 *
340 * @api
341 * @filtre
342 *
343 * @return array
344 *      Liste des tables de codes ISO sans le préfixe `spip_` et leurs informations de chargement.
345 */
346function isocode_informer_tables_chargees() {
347
348        // On initialise la liste des tables en lisant la meta idoine.
349        include_spip('inc/config');
350        $tables = lire_config('isocode/tables', array());
351
352        // On complète chaque bloc d'informations par le nom de la table et son libéllé.
353        if ($tables) {
354                foreach ($tables as $_table => $_informations) {
355                        $tables[$_table]['nom'] = $_table;
356                        $tables[$_table]['libelle'] = _T("isocode:label_table_${_table}");
357                }
358        }
359
360        return $tables;
361}
362
363
364/**
365 * Indique si une table est déjà chargée ou pas en base de données.
366 * La fonction scrute la table `spip_${table}` et non la meta propre à la table.
367 *
368 * @api
369 * @filtre
370 *
371 * @param string $table
372 *      Nom de la table sans le préfixe `spip_`.
373 * @param array  $meta_table
374 *      Meta propre à la table, créée lors du chargement de celle-ci et retournée si la table
375 *      est déjà chargée.
376 *
377 * @return bool
378 *      `true` si la table est chargée, `false` sinon.
379 */
380function isocode_table_chargee($table, &$meta_table) {
381        $meta_table = array();
382        $table_chargee = false;
383
384        $retour = sql_countsel("spip_${table}");
385        if ($retour) {
386                // Récupérer la meta propre au règne afin de la retourner.
387                include_spip('inc/config');
388                $meta_table = lire_config("isocode/tables/${table}");
389                $table_chargee = true;
390        }
391
392        return $table_chargee;
393}
Note: See TracBrowser for help on using the repository browser.