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

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

Et voilà les codes de pays ISO-3166 : alpha2, alpha3 et numérique.
Le nom des pays est inclus en anglais et français.
A voir si cela peut aider por Pays car le fichier est ici plus complet et on peut le mettre à jour assez facilement.

  • Property svn:eol-style set to native
File size: 9.9 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        'iso3166countries' => array(
107                'basic_fields'  => array(
108                        'English name'  => 'label_en',
109                        'French name'   => 'label_fr',
110                        'Alpha-2'               => 'code_alpha2',
111                        'Alpha-3'           => 'code_alpha3',
112                        'Numeric'       => 'code_num',
113                ),
114                'delimiter'    => ";",
115                'extension'    => '.txt'
116        ),
117);
118
119// ----------------------------------------------------------------------------
120// ----------------- API du service ISO - Actions principales -----------------
121// ----------------------------------------------------------------------------
122
123/**
124 * Lit le fichier .tab ou .txt contenant les enregistrements d'une des tables ISO et renvoie un tableau
125 * prêt pour une insertion en base de données.
126 *
127 * @api
128 *
129 * @param string $table
130 *      Nom de la table ISO incluse dans la base de données spip (sans le préfixe) à savoir,
131 *              `iso639codes`, `iso639names`, `iso639macros`, `iso639retirements`, `iso639families` ou `iso15924scripts`.
132 * @param int    $sha_file
133 *      Sha calculé à partir du fichier .tab des enregistrements de la table concernée. Le sha est retourné
134 *      par la fonction afin d'être stocké par le plugin.
135 *
136 * @return array
137 *      Tableau des enregistrements de la table concernée prêts à une insertion en base de données.
138 */
139function iso_read_table($table, &$sha_file) {
140
141        // Initialisations
142        $records = array();
143        $sha_file = false;
144        $f_complete_record = "${table}_complete_by_record";
145        $f_complete_table = "${table}_complete_by_table";
146        $file_to_spip = $GLOBALS['iso_service'][$table]['basic_fields'];
147        $delimiter = $GLOBALS['iso_service'][$table]['delimiter'];
148        $extension = $GLOBALS['iso_service'][$table]['extension'];
149
150        if (in_array($table, array_keys($GLOBALS['iso_service']))) {
151                // Ouvrir le fichier des enregistrements de la table spécifiée.
152                $file = find_in_path("services/iso/${table}${extension}");
153                if (file_exists($file) and ($sha_file = sha1_file($file))) {
154                        // Lecture du fichier .tab ou .txt comme un fichier texte sachant que :
155                        // - le délimiteur de colonne est une tabulation ou une virgule
156                        // - pas de caractère d'enclosure
157                        $lines = file($file);
158                        if ($lines) {
159                                $headers = array();
160                                foreach ($lines as $_number => $_line) {
161                                        $values = explode($delimiter, trim($_line, "\r\n"));
162                                        if ($_number == 0) {
163                                                // Stockage des noms de colonnes car la première ligne contient toujours le header
164                                                $headers = $values;
165                                        } else {
166                                                // Création de chaque enregistrement de la table
167                                                $fields = array();
168                                                foreach ($headers as $_cle => $_header) {
169                                                        $fields[$file_to_spip[trim($_header)]] = isset($values[$_cle]) ? $values[$_cle] : '';
170                                                }
171                                                // Si besoin on appelle une fonction pour chaque enregistrement afin de le compléter
172                                                if (function_exists($f_complete_record)) {
173                                                        $fields = $f_complete_record($fields);
174                                                }
175                                                $records[] = $fields;
176                                        }
177                                }
178                                // Si besoin on appelle une fonction pour toute la table
179                                if (function_exists($f_complete_table)) {
180                                        $records = $f_complete_table($records);
181                                }
182                        }
183                }
184        }
185
186        return $records;
187}
188
189
190// ----------------------------------------------------------------
191// ------------ Fonctions internes utilisées par l'API ------------
192// ----------------------------------------------------------------
193
194function iso639families_complete_by_record($fields) {
195
196        // Initialisation des champs additionnels
197        $sil_to_spip = $GLOBALS['iso_service']['iso639families']['add_fields']['sil'];
198        foreach($sil_to_spip as $_label => $_field) {
199                $fields[$_field] = '';
200        }
201
202        // On récupère la page de description de la famille sur le site SIL.
203        include_spip('inc/distant');
204        $url = _CODELANG_SIL_ISO639_3_ENDPOINT . $fields['code_639_5'];
205        $options = array('transcoder' => true);
206        $flux = recuperer_url($url, $options);
207
208        // On décrypte la page et principalement le premier tableau pour en extraire les données
209        // additionnelles suivantes :
210        // - scope : C(ollective)
211        // - equivalent : éventuellement le code ISO-639-1
212        // - code set : ISO-639-5 et/ou ISO-639-2
213        include_spip('inc/filtres');
214        $table = extraire_balise($flux['page'], 'table');
215        if ($table) {
216                // On extrait la première table de la page qui contient les données voulues
217                $rows = extraire_balises($table, 'tr');
218                if ($rows) {
219                        foreach ($rows as $_row) {
220                                // Chaque ligne de la table est composée de deux colonnes, le première le libellé
221                                // et la deuxième la valeur.
222                                $columns = extraire_balises($_row, 'td');
223                                $columns = array_map('supprimer_tags', $columns);
224                                if (count($columns) == 2) {
225                                        $keys = explode(':', trim($columns[0]));
226                                        $key = trim($keys[0]);
227                                        $value = str_replace(' ', '', trim($columns[1]));
228                                        switch ($key) {
229                                                case 'Equivalent':
230                                                        $equivalent = explode(':', $value);
231                                                        $fields[$sil_to_spip[$key]] = isset($equivalent[1]) ? trim($equivalent[1]) : '';
232                                                        break;
233                                                case 'Code sets':
234                                                case 'Code set':
235                                                        $fields[$sil_to_spip[$key]] = str_replace('and', ',', $value);
236                                                        break;
237                                                case 'Scope':
238                                                        $fields[$sil_to_spip[$key]] = substr($value, 0, 1);
239                                                        break;
240                                                default:
241                                                        break;
242                                        }
243                                }
244                        }
245                }
246        }
247
248        return $fields;
249}
250
251
252function iso639families_complete_by_table($records) {
253
254        // Initialisation des champs additionnels
255        $hierarchies =array();
256        $loc_to_spip = $GLOBALS['iso_service']['iso639families']['add_fields']['loc'];
257
258        // On récupère la page de description de la famille sur le site SIL.
259        include_spip('inc/distant');
260        $url = _CODELANG_LOC_ISO639_5_HIERARCHY;
261        $options = array('transcoder' => true);
262        $flux = recuperer_url($url, $options);
263
264        // On décrypte la page et principalement le tableau pour en extraire la colonne hiérarchie
265        // de chaque famille et créer la colonne parent dans la table iso639families.
266        include_spip('inc/filtres');
267        $table = extraire_balise($flux['page'], 'table');
268        if ($table) {
269                // On extrait la première table de la page qui contient les données voulues
270                $rows = extraire_balises($table, 'tr');
271                if ($rows) {
272                        // La première ligne du tableau est celle des titres de colonnes : on la supprime.
273                        array_shift($rows);
274                        foreach ($rows as $_row) {
275                                // Chaque ligne de la table est composée de deux colonnes, le première le libellé
276                                // et la deuxième la valeur.
277                                $columns = extraire_balises($_row, 'td');
278                                $columns = array_map('supprimer_tags', $columns);
279                                if (count($columns) >= 2) {
280                                        // La première colonne contient la hiérarchie et la seconde le code alpha-3 de la famille.
281                                        $code = trim($columns[1]);
282                                        $hierarchies[$code] = str_replace(array(' ', ':'), array('', ','), trim($columns[0]));
283                                }
284                        }
285                }
286        }
287
288        // On complète maintenant le tableau des enregistrements avec la colonne additionnelle hierarchy et la colonne
289        // dérivée parent qui ne contient que le code alpha-3 de la famille parente si elle existe.
290        foreach($records as $_cle => $_record) {
291                $code = $_record['code_639_5'];
292                $records[$_cle]['parent'] = '';
293                if (isset($hierarchies[$code])) {
294                        $records[$_cle][$loc_to_spip['Hierarchy']] = $hierarchies[$code];
295                        // Calcul du parent : si la hierarchie ne contient qu'un code c'est qu'il n'y a pas de parent.
296                        // Sinon, le parent est le premier code qui précède le code du record.
297                        $parents = explode(',', $hierarchies[$code]);
298                        if (count($parents) > 1) {
299                                array_pop($parents);
300                                $records[$_cle]['parent'] = array_pop($parents);
301                        }
302                } else {
303                        $records[$_cle][$loc_to_spip['Hierarchy']] = '';
304                }
305        }
306
307        return $records;
308}
Note: See TracBrowser for help on using the repository browser.