source: spip-zone/_plugins_/codes_langues/trunk/services/iso/iso_api.php @ 98925

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

On ajoute une table pour les codets des écritures (ISO 15924)

  • Property svn:eol-style set to native
File size: 9.7 KB
Line 
1<?php
2/**
3 * Ce fichier contient l'ensemble des constantes et fonctions implémentant les services ISO.
4 *
5 * @package SPIP\CODELANG\SERVICES\ISO
6 */
7if (!defined('_ECRIRE_INC_VERSION')) {
8        return;
9}
10
11
12if (!defined('_CODELANG_SIL_ISO639_3_ENDPOINT')) {
13        /**
14         * URL de base pour charger la page de documentation d'un code de langue alpha-3 sur le site
15         * sil.org
16         */
17        define('_CODELANG_SIL_ISO639_3_ENDPOINT', 'http://www-01.sil.org/iso639-3/documentation.asp?id=');
18}
19if (!defined('_CODELANG_LOC_ISO639_5_HIERARCHY')) {
20        /**
21         * URL de base pour charger la page du tableau de la hiérarchie ISO-639-5 sur le site
22         * de la Library of Congress.
23         */
24        define('_CODELANG_LOC_ISO639_5_HIERARCHY', 'https://www.loc.gov/standards/iso639-5/hier.php');
25}
26
27
28$GLOBALS['iso_service'] = array(
29        'iso639codes' => array(
30                'basic_fields' => array(
31                        'Id'            => 'code_639_3',
32                        'Part2B'                => 'code_639_2b',
33                        'Part2T'                => 'code_639_2t',
34                        'Part1'                 => 'code_639_1',
35                        'Scope'                 => 'scope',
36                        'Language_Type' => 'type',
37                        'Ref_Name'              => 'ref_name',
38                        'Comment'               => 'comment'
39                ),
40                'delimiter'    => "\t",
41                'extension'    => '.tab'
42        ),
43        'iso639names' => array(
44                'basic_fields'  => array(
45                        'Id'                    => 'code_639_3',
46                        'Print_Name'    => 'print_name',
47                        'Inverted_Name' => 'inverted_name'
48                ),
49                'delimiter'    => "\t",
50                'extension'    => '.tab'
51        ),
52        'iso639macros' => array(
53                'basic_fields'  => array(
54                        'M_Id'                  => 'macro_639_3',
55                        'I_Id'                  => 'code_639_3',
56                        'I_Status'              => 'status'
57                ),
58                'delimiter'    => "\t",
59                'extension'    => '.tab'
60        ),
61        'iso639retirements' => array(
62                'basic_fields'  => array(
63                        'Id'                    => 'code_639_3',
64                        'Ref_Name'              => 'ref_name',
65                        'Ret_Reason'    => 'ret_reason',
66                        'Change_To'     => 'change_to',
67                        'Ret_Remedy'    => 'ret_remedy',
68                        'Effective'     => 'effective_date'
69                ),
70                'delimiter'    => "\t",
71                'extension'    => '.tab'
72        ),
73        'iso639families' => array(
74                'basic_fields'  => array(
75                        'URI'                     => 'uri',
76                        'code'                    => 'code_639_5',
77                        'Label (English)' => 'label_en',
78                        'Label (French)'  => 'label_fr'
79                ),
80                'add_fields'    => array(
81                        'sil'                   => array(
82                                'Equivalent'    => 'code_639_1',
83                                'Code set'          => 'code_set',
84                                'Code sets'         => 'code_set',
85                                'Scope'         => 'scope'
86                        ),
87                        'loc'                   => array(
88                                'Hierarchy'         => 'hierarchy'
89                        )
90                ),
91                'delimiter'    => "\t",
92                'extension'    => '.tab'
93        ),
94        'iso15924scripts' => array(
95                'basic_fields'  => array(
96                        'Code'                  => 'code_15924',
97                        'English Name'  => 'label_en',
98                        'Nom français'  => 'label_fr',
99                        'N°'            => 'code_num',
100                        'PVA'           => 'alias_en',
101                        'Date'          => 'date_ref',
102                ),
103                'delimiter'    => ";",
104                'extension'    => '.txt'
105        ),
106);
107
108// ----------------------------------------------------------------------------
109// ----------------- API du service ISO - Actions principales -----------------
110// ----------------------------------------------------------------------------
111
112/**
113 * Lit le fichier .tab ou .txt contenant les enregistrements d'une des tables ISO et renvoie un tableau
114 * prêt pour une insertion en base de données.
115 *
116 * @api
117 *
118 * @param string $table
119 *      Nom de la table ISO incluse dans la base de données spip (sans le préfixe) à savoir,
120 *              `iso639codes`, `iso639names`, `iso639macros`, `iso639retirements`, `iso639families` ou `iso15924scripts`.
121 * @param int    $sha_file
122 *      Sha calculé à partir du fichier .tab des enregistrements de la table concernée. Le sha est retourné
123 *      par la fonction afin d'être stocké par le plugin.
124 *
125 * @return array
126 *      Tableau des enregistrements de la table concernée prêts à une insertion en base de données.
127 */
128function iso_read_table($table, &$sha_file) {
129
130        // Initialisations
131        $records = array();
132        $sha_file = false;
133        $f_complete_record = "${table}_complete_by_record";
134        $f_complete_table = "${table}_complete_by_table";
135        $file_to_spip = $GLOBALS['iso_service'][$table]['basic_fields'];
136        $delimiter = $GLOBALS['iso_service'][$table]['delimiter'];
137        $extension = $GLOBALS['iso_service'][$table]['extension'];
138
139        if (in_array($table, array_keys($GLOBALS['iso_service']))) {
140                // Ouvrir le fichier des enregistrements de la table spécifiée.
141                $file = find_in_path("services/iso/${table}${extension}");
142                if (file_exists($file) and ($sha_file = sha1_file($file))) {
143                        // Lecture du fichier .tab ou .txt comme un fichier texte sachant que :
144                        // - le délimiteur de colonne est une tabulation ou une virgule
145                        // - pas de caractère d'enclosure
146                        $lines = file($file);
147                        if ($lines) {
148                                $headers = array();
149                                foreach ($lines as $_number => $_line) {
150                                        $values = explode($delimiter, trim($_line, "\r\n"));
151                                        if ($_number == 0) {
152                                                // Stockage des noms de colonnes car la première ligne contient toujours le header
153                                                $headers = $values;
154                                        } else {
155                                                // Création de chaque enregistrement de la table
156                                                $fields = array();
157                                                foreach ($headers as $_cle => $_header) {
158                                                        $fields[$file_to_spip[trim($_header)]] = isset($values[$_cle]) ? $values[$_cle] : '';
159                                                }
160                                                // Si besoin on appelle une fonction pour chaque enregistrement afin de le compléter
161                                                if (function_exists($f_complete_record)) {
162                                                        $fields = $f_complete_record($fields);
163                                                }
164                                                $records[] = $fields;
165                                        }
166                                }
167                                // Si besoin on appelle une fonction pour toute la table
168                                if (function_exists($f_complete_table)) {
169                                        $records = $f_complete_table($records);
170                                }
171                        }
172                }
173        }
174
175        return $records;
176}
177
178
179// ----------------------------------------------------------------
180// ------------ Fonctions internes utilisées par l'API ------------
181// ----------------------------------------------------------------
182
183function iso639families_complete_by_record($fields) {
184
185        // Initialisation des champs additionnels
186        $sil_to_spip = $GLOBALS['iso_service']['iso639families']['add_fields']['sil'];
187        foreach($sil_to_spip as $_label => $_field) {
188                $fields[$_field] = '';
189        }
190
191        // On récupère la page de description de la famille sur le site SIL.
192        include_spip('inc/distant');
193        $url = _CODELANG_SIL_ISO639_3_ENDPOINT . $fields['code_639_5'];
194        $options = array('transcoder' => true);
195        $flux = recuperer_url($url, $options);
196
197        // On décrypte la page et principalement le premier tableau pour en extraire les données
198        // additionnelles suivantes :
199        // - scope : C(ollective)
200        // - equivalent : éventuellement le code ISO-639-1
201        // - code set : ISO-639-5 et/ou ISO-639-2
202        include_spip('inc/filtres');
203        $table = extraire_balise($flux['page'], 'table');
204        if ($table) {
205                // On extrait la première table de la page qui contient les données voulues
206                $rows = extraire_balises($table, 'tr');
207                if ($rows) {
208                        foreach ($rows as $_row) {
209                                // Chaque ligne de la table est composée de deux colonnes, le première le libellé
210                                // et la deuxième la valeur.
211                                $columns = extraire_balises($_row, 'td');
212                                $columns = array_map('supprimer_tags', $columns);
213                                if (count($columns) == 2) {
214                                        $keys = explode(':', trim($columns[0]));
215                                        $key = trim($keys[0]);
216                                        $value = str_replace(' ', '', trim($columns[1]));
217                                        switch ($key) {
218                                                case 'Equivalent':
219                                                        $equivalent = explode(':', $value);
220                                                        $fields[$sil_to_spip[$key]] = isset($equivalent[1]) ? trim($equivalent[1]) : '';
221                                                        break;
222                                                case 'Code sets':
223                                                case 'Code set':
224                                                        $fields[$sil_to_spip[$key]] = str_replace('and', ',', $value);
225                                                        break;
226                                                case 'Scope':
227                                                        $fields[$sil_to_spip[$key]] = substr($value, 0, 1);
228                                                        break;
229                                                default:
230                                                        break;
231                                        }
232                                }
233                        }
234                }
235        }
236
237        return $fields;
238}
239
240
241function iso639families_complete_by_table($records) {
242
243        // Initialisation des champs additionnels
244        $hierarchies =array();
245        $loc_to_spip = $GLOBALS['iso_service']['iso639families']['add_fields']['loc'];
246
247        // On récupère la page de description de la famille sur le site SIL.
248        include_spip('inc/distant');
249        $url = _CODELANG_LOC_ISO639_5_HIERARCHY;
250        $options = array('transcoder' => true);
251        $flux = recuperer_url($url, $options);
252
253        // On décrypte la page et principalement le tableau pour en extraire la colonne hiérarchie
254        // de chaque famille et créer la colonne parent dans la table iso639families.
255        include_spip('inc/filtres');
256        $table = extraire_balise($flux['page'], 'table');
257        if ($table) {
258                // On extrait la première table de la page qui contient les données voulues
259                $rows = extraire_balises($table, 'tr');
260                if ($rows) {
261                        // La première ligne du tableau est celle des titres de colonnes : on la supprime.
262                        array_shift($rows);
263                        foreach ($rows as $_row) {
264                                // Chaque ligne de la table est composée de deux colonnes, le première le libellé
265                                // et la deuxième la valeur.
266                                $columns = extraire_balises($_row, 'td');
267                                $columns = array_map('supprimer_tags', $columns);
268                                if (count($columns) >= 2) {
269                                        // La première colonne contient la hiérarchie et la seconde le code alpha-3 de la famille.
270                                        $code = trim($columns[1]);
271                                        $hierarchies[$code] = str_replace(array(' ', ':'), array('', ','), trim($columns[0]));
272                                }
273                        }
274                }
275        }
276
277        // On complète maintenant le tableau des enregistrements avec la colonne additionnelle hierarchy et la colonne
278        // dérivée parent qui ne contient que le code alpha-3 de la famille parente si elle existe.
279        foreach($records as $_cle => $_record) {
280                $code = $_record['code_639_5'];
281                $records[$_cle]['parent'] = '';
282                if (isset($hierarchies[$code])) {
283                        $records[$_cle][$loc_to_spip['Hierarchy']] = $hierarchies[$code];
284                        // Calcul du parent : si la hierarchie ne contient qu'un code c'est qu'il n'y a pas de parent.
285                        // Sinon, le parent est le premier code qui précède le code du record.
286                        $parents = explode(',', $hierarchies[$code]);
287                        if (count($parents) > 1) {
288                                array_pop($parents);
289                                $records[$_cle]['parent'] = array_pop($parents);
290                        }
291                } else {
292                        $records[$_cle][$loc_to_spip['Hierarchy']] = '';
293                }
294        }
295
296        return $records;
297}
Note: See TracBrowser for help on using the repository browser.