source: spip-zone/_plugins_/spip-pmb/trunk/inc/unimarc.php @ 69210

Last change on this file since 69210 was 69210, checked in by marcimat@…, 7 years ago

Compat PHP 5.4

File size: 11.1 KB
Line 
1<?php
2if (!defined("_ECRIRE_INC_VERSION")) return;
3
4// faire #UNIMARC{310,a} dans boucle NOTICES
5
6/**
7 * Analyse une entree de tableau de descrition
8 * 
9 *
10 * @param array $unimarc Code unimarc a analyser
11 *              [c:numero_zone]                                         010, 300, 310 ...
12 *              [id:identifiant sur pmb parfois]
13 *              [s:contenu]
14 *                      [{i}]                                                   indice dans la liste (remplissage automatique par php depuis 0)
15 *                              [c:sous_zone]                           1 caractere entre 0 et 9 ou a et z, parfois 2 caracteres.
16 *                              [value:valeur]
17 *
18 * @return array
19 *   - nom : le nom de la categorie
20 *   - valeur : sa valeur
21 *
22**/
23function pmb_parse_unimarc($unimarc) {
24        $zone = $unimarc->c;
25        $id = $unimarc->id; // souvent vide
26        $res = array();
27        // Le champ $s contient la liste des informations
28        if (isset($unimarc->s) && is_array($unimarc->s)) {
29                $groupe = $unimarc->s;
30               
31                // si une fonction specifique existe, on la retourne
32                if (function_exists($parse = 'pmb_parse_unimarc_data_' . $zone)) {
33                        return $parse($groupe, $id);
34                }
35
36                // sinon, on utilise le parsage prevu...
37                foreach($groupe as $element) {
38                        $sous_zone = $element->c;
39                        $valeur = $element->value;
40
41                        // correction systematique de la valeur
42                        // car certains caracteres sont faux...
43                        $valeur = pmb_nettoyer_caracteres($valeur);
44                        $new = pmb_parse_unimarc_defaut($valeur, $zone, $sous_zone, $id, $element, $groupe);
45                        if ($new) {
46                                $res = array_merge($res, $new);
47                        } else {
48                                // impossible de parser ce code.
49                                # echo "<br />** ELEMENT NON TRAITE : $zone / $sous_zone";
50                                # echo "\n<pre>"; print_r($element); echo "</pre>";
51                        }
52                }
53        }
54        return $res;
55}
56
57
58/**
59 * Cherche dans le tableau de descripton des unimarc
60 * la zone et la sous zone demandees
61 * et retourne la ou les couples cle/valeurs
62 * correspondantes.
63 *
64 * [100]
65 *
66 *              Tableau des cles autorisees
67 *              'a' => 'isbn', // sous zone => nom de la correspondance humaine. Peut etre un tableau :
68 *              'b' => array('titre', 'pmb_nettoyer_caracteres') // filtre a appliquer sur la valeur
69 *              'c' => array('texte', 'couper', 300) // filtre a appliquer sur la valeur : couper($valeur, 300)
70 *              '9' => 'id/nom' // recherche la cle 9 et une valeur extraite d'une valeur 'id:xxx'
71 *
72 *              Ou encore, possibilite pour un attribut de donner plusieurs champs
73 *              en indiquant directement les valeurs a retourner A EVALUER (eval)...
74 *              'a' => array(
75 *                              'isbn' => '$valeur',
76 *                              'id' => '$id',
77 *              ),
78 *
79 * @return array
80 *              Tableau de tableau ('cle' => cle, 'valeur' => valeur)
81**/
82function pmb_parse_unimarc_defaut($valeur, $zone, $sous_zone, $id, $element, $groupe) {
83        static $tab = false;
84        if (!$tab) {
85                $tab = pmb_parse_unimarc_data();
86        }
87
88        if (!isset($tab[$zone]) or !is_array($tab[$zone])) {
89                return false;
90        }
91
92        // si l'element est dedans, c'est bon signe !
93        if (isset($tab[$zone][$sous_zone]) and $t = $tab[$zone][$sous_zone]) {
94
95                // si tableau, c'est qu'il y a
96                // une association cle / valeur directement
97
98                if (is_array($t)) {
99                       
100                        // tableau de cle/valeurs
101                        if (is_string(reset(array_keys($t)))) {
102
103                                $res = array();
104                                foreach ($t as $c => $v) {
105                                        $res[] = array(
106                                                'cle' => $c,
107                                                'valeur' => eval('return ' . $v . ';'),
108                                        );
109                                }
110                               
111                                return $res;
112                       
113                        // filtre sur la donnee
114                        } else {
115                               
116                                $cle = $t[0];
117                                $filtre = $t[1];
118                                $args = isset($t[2]) ? $t[2] : array();
119                                array_unshift($args, $valeur);
120                                $valeur = call_user_func_array($filtre, $args);
121                        }
122                // juste la valeur
123                } else {
124                        // soit 'nom' soit 'id:nom'
125                        list($t, $sous) = explode(':', $t);
126                        if (!$sous) {
127                                // simple 'nom'
128                                $cle = $t;
129                        } else {
130                                // 'id:nom'
131                                list($valeur_cle, $valeur) = explode(':', $valeur, 2);
132                                if ($valeur AND $valeur_cle==$t) {
133                                        $cle = $sous;
134                                        $valeur = $valeur;
135                                } else {
136                                        $cle = $valeur = '';
137                                }
138                        }
139                }
140               
141                if ($cle and strlen($valeur)) {
142                        return array(
143                                array(
144                                        'cle' => $cle,
145                                        'valeur' => $valeur,
146                                )
147                        );
148                }
149        }
150
151        return false;
152}
153
154
155/**
156 * Passe les \n en <br />
157**/
158function pmb_nettoyer_caracteres_texte($valeur) {
159        $valeur = str_replace(
160                array( "\n"),
161                array("<br />"), $valeur);
162        return $valeur;
163}
164
165
166
167/**
168 *  Liste des infos connues d'unimarc
169 * et indique comment les traiter.
170 * Cf. pmb_parse_unimarc_defaut()
171 *
172**/
173function pmb_parse_unimarc_data() {
174        $t = array(
175
176
177                // ISBN (International Standard Book Number)
178                '010' => array(
179                        'a' => 'isbn',
180                        'b' => 'reliure',
181                        'd' => 'prix' // disponibilite ou prix
182                ),
183               
184
185                // Langue de la ressource
186                '101' => array(
187                        'a' => 'langues',
188                ),
189
190
191                // Pays de publication ou de production
192                '102' => array(
193                        'a' => 'pays',
194                ),
195
196
197                // Titre et mention de responsabilité
198                '200' => array(
199                        'a' => array('titre', 'pmb_nettoyer_caracteres_texte'),
200                        'c' => array('titre_auteur_different', 'pmb_nettoyer_caracteres_texte'),
201                        'd' => array('titre_parallele', 'pmb_nettoyer_caracteres_texte'),
202                        'e' => array('soustitre', 'pmb_nettoyer_caracteres_texte'),
203                        'f' => 'auteur', // premiere mention de responsabilite...
204                ),
205
206
207                // Mention d’édition
208                '205' => array(
209                        'a' => 'edition' // Mention d’édition
210                ),
211               
212                // Publication, production, diffusion, etc.
213                '210' => array(
214                        'a' => 'lieu_publication',
215                        'c' => array(
216                                'editeur'=>'$valeur',
217                                'id_editeur'=>'$id',
218                        ),
219                        'd' => 'annee_publication',
220                        'e' => 'lieu_fabrication',
221                        'h' => 'date_fabrication',
222                ),
223
224
225                // Description matérielle
226                '215' => array(
227                        'a' => 'importance', // Indication du type de document et importance matérielle
228                        'c' => array('presentation', 'pmb_nettoyer_caracteres_texte'), // Autres caracteristiques materielles
229                        'd' => 'format',
230                        'e' => 'materiel_accompagnement', // Matériel d’accompagnement
231                ),
232
233
234                // Collection
235                '225' => array(
236                        'a' => array(
237                                'collection' => '$valeur',
238                                'id_collection' => '$id',
239                        ),
240                        'i' => 'sous_collection', 
241                        'v' => 'numero_volume', // Numero dans la collection, numero du volume
242                ),
243
244
245                // Note générale
246                '300' => array(
247                        'a' => 'note_generale',
248                ),
249
250
251                // Note de contenu
252                '327' => array(
253                        'a' => array('note_contenu', 'pmb_nettoyer_caracteres_texte'),
254                ),
255
256
257                // Résumé ou extrait
258                '330' => array(
259                        'a' => array('resume', 'pmb_nettoyer_caracteres_texte'),
260                ),
261
262
263                // Parties, Ensembles
264                '461' => array(
265                        't' => array('titre_partie', 'pmb_nettoyer_caracteres_texte'), // Partie de x
266                        'v' => 'numero_partie',
267                ),
268
269                // Unité matérielle
270                // a quelle unite apartient cette notice,
271                // c'est a dire un chapitre (notice) pour un livre (unite);
272                // il y a normalement un id a recuperer...
273                '463' => array(
274                        // y a aussi plusieurs 9 decrivant un lien... ?
275                        't' => 'unite_materielle', // Titre
276                        '9' => 'id:id_unite_materielle', // il y a differents 9... avec des valeurs 'id:3219'
277                ),
278
279                // Indexation en vocabulaire libre
280                // (mots cles)
281                '610' => array(
282                        'a' => 'mots_cles', // Descripteur
283                ),
284               
285
286
287                // Classification décimale Dewey
288                '676' => array(
289                        'a' => 'indice_dewey', 
290                        'v' => 'edition_dewey',
291                ),
292
293
294                // Traites a part dans des fonctions specialisees.
295                // 700 - Nom de personne - Responsabilité principale
296                // 701 - Nom de personne - Autre responsabilité principale
297                // 702 - Nom de personne - Responsabilité secondaire
298                // 710 - Nom de collectivite - Responsabilité principale
299                // 711 - Nom de collectivite - Autre responsabilité principale
300                // 712 - Nom de collectivite - Responsabilité secondaire
301
302                // Adresse électronique et mode d'accès
303                '856' => array(
304                        'u' => 'source', // Identificateur électronique normalisé (URI ex URL)
305                ),
306               
307                // Image associee
308                '896' => array(
309                        'a' => 'source_logo',
310                ),
311
312                // les 900 sont des donnees locales...
313                // traitees a part dans une fonction specialisee
314
315        );
316
317
318        // on propose une surcharge de notre tableau dans une fonction
319        // pmb_parse_unimarc_data_locales() qui permet egalement
320        // de modifier le tableau au besoin.
321        if (function_exists('pmb_parse_unimarc_data_locales')) {
322                $t = pmb_parse_unimarc_data_locales($t);
323        }
324       
325        return $t;
326}
327
328/*
329// exemple de fonction locale, a placer dans un fichier de fonctions SPIP.
330function pmb_parse_unimarc_data_locales($tab) {
331        $tab['900'] = array(
332                'a' => 'toto'
333        );
334        return $tab;
335}
336*/
337
338
339
340
341/**
342 * les 70x sont des liens vers des auteurs
343 * Et il peut y avoir plusieurs zones identiques.
344 * Il faut donc concatener avec les auteurs deja trouves
345 */
346
347// Nom de personne - Responsabilité principale
348function pmb_parse_unimarc_data_700($groupe, $id) {
349        return pmb_parse_unimarc_data_7xx($groupe, $id, 'personne');
350}
351
352// Nom de personne - Autre responsabilité principale
353function pmb_parse_unimarc_data_701($groupe, $id) {
354        return pmb_parse_unimarc_data_7xx($groupe, $id, 'personne', 2);
355}
356
357// Nom de personne - Responsabilité secondaire
358function pmb_parse_unimarc_data_702($groupe, $id) {
359        return pmb_parse_unimarc_data_7xx($groupe, $id, 'personne', 3);
360}
361
362
363// Nom de collectif - Responsabilité principale
364function pmb_parse_unimarc_data_710($groupe, $id) {
365        return pmb_parse_unimarc_data_7xx($groupe, $id, 'collectivite');
366}
367
368// Nom de collectif - Autre responsabilité principale
369function pmb_parse_unimarc_data_711($groupe, $id) {
370        return pmb_parse_unimarc_data_7xx($groupe, $id, 'collectivite', 2);
371}
372
373// Nom de collectif - Responsabilité secondaire
374function pmb_parse_unimarc_data_712($groupe, $id) {
375        return pmb_parse_unimarc_data_7xx($groupe, $id, 'collectivite', 3);
376}
377
378// type : 'personne', 'collectivite' ...
379function pmb_parse_unimarc_data_7xx($groupe, $id, $type, $indice='') {
380        $nom = $prenom = '';
381        $type = '_' . $type;
382        foreach ($groupe as $element) {
383                switch($element->c) {
384                        case 'a':
385                                $nom = pmb_nettoyer_caracteres($element->value);
386                                break;
387                        case 'b':
388                                $prenom = pmb_nettoyer_caracteres($element->value);
389                                break;
390                }
391        }
392        if ($nom) {
393                if ($prenom) {
394                        $nom = $prenom . ' ' . $nom;
395                }
396                return array(
397                        array(
398                                'cle' => "id_auteur$type$indice",
399                                'valeur' => $id,
400                        ),
401                        array(
402                                'cle' => "liensauteurs$type$indice",
403                                'valeur' => "<a href=\"" . generer_url_public('pmb_auteur', "id_auteur=$id") . "\">" . $nom . "</a>",
404                                '@post_traitements' => array('inter' => ', '),
405                        ),
406                        array(
407                                'cle' => "lesauteurs$type$indice",
408                                'valeur' => $nom,
409                                '@post_traitements' => array('inter' => ', '),
410                        ),
411
412                );
413        }
414}
415
416
417/**
418 * les 900 sont des donnees locales...
419 * et traitees separements...
420 * il ne semble pas possible de savoir toujours ce que c'est...
421 * cependant, PMB pour ses champs extras exportables envoie :
422 * [900]
423 *              [a] Valeur du champ
424 *              [l] Label du champ
425 *              [n] Colonne SQL du champ.
426 *
427 * Il envoie plusieurs 900 aussi.
428 * On en fait autant de champ #N avec #LABEL_N
429 * fonction pour traiter les champs extras
430 * declares en 900
431 *              n = champ sql
432 *              a = valeur
433 *              l = label humain
434 */
435function pmb_parse_unimarc_data_900($groupe, $id) {
436        $cle = $label = $valeur = '';
437        foreach ($groupe as $element) {
438                switch($element->c) {
439                        case 'n':
440                                $cle = strtolower($element->value);
441                                break;
442                        case 'l':
443                                $label = pmb_nettoyer_caracteres($element->value);
444                                break;
445                        case 'a':
446                                $valeur = pmb_nettoyer_caracteres($element->value);
447                                break;
448                }
449        }
450        if ($cle and $valeur and $label) {
451                return array(
452                        array(
453                                'cle'    => $cle,
454                                'valeur' => pmb_nettoyer_caracteres($valeur),
455                        ),
456                        array(
457                                'cle'    => 'label_' . $cle,
458                                'valeur' => pmb_nettoyer_caracteres($label),
459                        ),
460                );
461        }
462}
463
464?>
Note: See TracBrowser for help on using the repository browser.