En préambule, je voudrais dédier ce travail à Hervé Le Crosnier. Au début des années 90, j'ai eu la chance de suivre un stage d'initiation à HTML assuré par lui. Il est plus que probable qu'il ne s'en souvienne pas, mais depuis ce stage, quand je mesure le chemin parcouru, je ne peux que dire merci Hervé, un grand MERCI.
La classe PHP dont il est question ici se pose deux objectifs : Dans un premier temps, il s'agit de lire des enregistrements ISO2709 afin de récupérer des informations. Dans un second temps, et pour être complétement efficiente, la classe devrait idéalement nous permettre de constituer de nouveaux enregistrements respectant ce format.
Le format d'échange ISO 2709 fournit une norme pour l'échange de données bibliographiques. Il offre une interface unifiée permettant la description d'enregistrements organisés en champs et sous-champs.
Ce format définit pour un enregistrement 3 zones :Comme on peut le voir, la structure d'un enregistrement au format ISO 2709 est assez simple une fois que l'on en a compris le principe. La manipulation de tels enregistrements se résume à des opérations élémentaires (décomposition de l'enregistrement, consultation de la "table des matières" pour accéder à un champ, etc.) La difficulté principale reste de maintenir la synchronisation entre les trois zones de l'enregistrement lors de l'insertion ou de la suppression de champs. La classe présentée ici à pour but d'accomplir ces accès et cette synchronisation de manière relativement transparente pour le programmeur.
Comme toute classe PHP, la classe iso2709_record comprend des propriétés qui peuvent être accédées par votre code. Certaines de ces propriétés sont utilisées pour la gestion interne de l'objet défini dans la classe.
propriété | type | description | |
---|---|---|---|
enregistrement ISO2709 | full_record | string | enregistrement complet |
guide | chaîne | portion 'guide' | |
directory | chaîne | portion 'répertoire' | |
data | chaîne | portion 'zone de données' | |
tableaux internes | inner_guide | tableau associatif |
guide sous forme de tableau associatif
structure: $this->inner_guide = array(
|
inner_directory | tableau multi-dimensionnel |
tableau correspondant au répertoire de l'enregistrement
structure: $this->inner_guide[x] = array(
|
|
inner_data | tableau multi-dimensionnel |
tableau correspondant au répertoire de l'enregistrement
structure: $this->inner_data[x] = array(
|
|
caractères spéciaux | record_end | chaîne | caractère de fin de notice (IS3 de l'ISO 6630) |
field_end | chaîne | caractère de fin de champ (IS2 de l'ISO 6630) | |
subfield_begin | chaîne | caractère de début de sous-champ (IS1 de l'ISO 6630) | |
NSB_begin | chaîne | caractère débutant un NSB (Non Sorting Block) | |
NSB_end | chaîne | caractère de fin NSB (Non Sorting Block) | |
note Les propriétés décrivant des caractères spéciaux ont toutes dans cette classe un équivalent préfixé par rgx_ contenant les mêmes caractères sous une forme utilisable dans des expressions régulières compatibles PERL. | |||
divers | update_mode | entier | mode de mise à jour de l'enregistrement |
errors | tableau | tableau contenant les messages d'erreurs liés au format de l'enregistrement (méthode valid()) ou aux modifications effectuées sur celui-ci. |
Dans l'état actuel des choses, la gestion des objets de PHP ne comprend aucune notion de propriétes ou méthodes publiques ou privées. Les propriétés de la classe sont donc toutes accessibles depuis n'importe quel endroit de votre code. Cependant, je ne recommande pas de modifier les propriétés préfixées par inner_ sans bien réfléchir avant. Ces variables sont en effet utilisées de manière interne dans la classe pour la gestion de l'enregistrement. On peut donc les modifier, mais sans garantie quant à la synchronisation de l'ensemble.
prototype : iso2709_record([string record], [flag update_mode])
Le constructeur est appelé lors de la création de la classe. Il admet deux paramètres :
prototype : get_subfield(string label [, mixed refs])
La fonction get_subfield retourne le contenu du champ spécifié par le paramètres qui lui sont passés. L'appel de la méthode peut être effectué de différentes manières. Le paramètre label est l'étiquette du champ. Ce peut être une expression régulière (le point est alors un caractère "joker". ex : 7.0 indique les champs 700 et 710).
La valeur retournée par la fonction est un tableau dont la structure est définie par les paramètres passés (ref).
exemples d'appels valides de get_subfield :
$isbn = $myRecord->get_subfield('010')
$isbn[0] = 'contenu du premier champ 010' $isbn[1] = 'contenu du second champ 010' ...
$nom_auteur = $myRecord->get_subfield('7..', a)
$nom_auteur[0] = 'contenu du sous-champ 700$a' $nom_auteur[1] = 'contenu du sous-champ 701$a' ... $nom_auteur[x] = 'contenu du dernier sous-champ 712$a'
$nom_auteur = $myRecord->get_subfield('7..', a, b)
$nom_auteur[0][a] = 'contenu du sous-champ 700$a' $nom_auteur[0][b] = 'contenu du sous-champ 700$b' $nom_auteur[1][a] = 'contenu du sous-champ 701$a' ... $nom_auteur[x][a] = 'contenu du dernier sous-champ 712$a' $nom_auteur[x][b] = 'contenu du dernier sous-champ 712$b'
Avec ceci, on doit en principe pouvoir accéder n'importe quel sous-champ de l'enregistrement. Si vous avez des besoins plus complexes, rien ne vous empêche de 'parser' directement les propriétes de la classe (cf. section propriétés).
prototype : add_field(string label, string indicators, mixed field_content)
Cette méthode permet l'ajout d'un champ à un enregistrement ISO2709. On peut l'appeler de différentes manières : le nombre de paramètres est variable. On doit fournir en premier lieu l'étiquette du champ et les éventuels indicateurs, ceux-çi pouvant être de longueur nulle si le champ n'a pas d'indicateurs.
Le passage du contenu du champ se fait par le paramètre field_content sous la forme d'un nombre variable de chaînes comprenant alternativement l'étiquette du sous-champ et le contenu du sous-champ. Si une seule chaîne est fournie, le champ est réputé n'avoir pas d'étiquette de sous-champ et contenir uniquement la chaîne fournie.
La seconde possibilité est de passer le contenu du champ sous la forme d'un tableau multi-dimensionnel dont chaque ligne est un array constitué par l'étiquette du sous-champ et le contenu du sous-champ.
exemples d'appels valides de add_field :
$myRecord->add_field('001', '', '01-0002977')
$myRecord->add_field(200, '1 ', a, 'Minable le pingouin', f, 'Texte d'Helen Lester')
$monChamp[0] = array( a => 'Lester');
$monChamp[1] = array( b => 'Helen');
$myRecord->add_field(700, ' 1', $monChamp);
La méthode add_field() retourne TRUE en cas de succès et FALSE en cas d'échec (mauvais format pour les paramètres). Dans ce dernier cas, un message est ajouté au tableau des erreurs (cf. méthode show_errors).
prototype : delete_field(string label)
La méthode delete_field() est à utiliser pour supprimer un champ de l'enregistrement ISO2709. Son fonctionnement est relativement simple : on passe comme paramètre l'étiquette du champ à supprimer. Il est possible de supprimer plusieurs champs en un seul appel dans la mesure où le paramètre label peut être une expression régulière. En pratique, on peut considérer que le point est un caractère "joker".
exemples d'appels valides de delete_field :
$myRecord->delete_field('001')
$myRecord->delete_field('71.')
$myRecord->delete_field('..2')
La méthode delete_field() retourne TRUE en cas de succès et FALSE en cas d'échec (mauvais format pour le label). Dans ce dernier cas, un message est ajouté au tableau des erreurs (cf. méthode show_errors).
prototypes :
set_rs(string/char value)
set_dt(string/char value)
set_bl(string/char value)
set_hl(string/char value)
set_el(string/char value)
set_ru(string/char value)
Cet ensemble de méthodes permet de positionner les valeurs non calculées du guide de l'enregistrement. Pour connaître le codage des valeurs concernées, je vous invite à vous reporter aux spécifications du format UNIMARC (ou autre).
Nomenclature des fonctions :
fonction | position concernée | élément | description |
---|---|---|---|
set_rs() | 5 | record status | Etat de la notice |
set_dt() | 6 | document type | Type de document |
set_bl() | 7 | bibliographic level | Type de la notice |
set_hl() | 8 | hierarchical level | Niveau hiérarchique |
set_el() | 17 | encoding level | Niveau de catalogage |
set_ru() | 18 | record update | Forme du catalogage descriptif |
L'appel de ces méthodes est on ne peut plus simple : on passe le code souhaité comme paramètre unique. Le guide (inner_guide) est modifié. Cependant, la mise à jour de l'enregistrement est toujours gérée suivant les modes USER_UPDATE et AUTO_UPDATE. Si la classe a été déclarée avec le mode USER_UPDATE, la modification ne sera effective qu'après l'appel de la méthode update().
prototype : update(void)
Cette méthode n'est à invoquer que si la classe a été créée avec le drapeau update_mode fixé à USER_UPDATE. Si ce n'est pas le cas, l'appel à cette méthode sera effectué à chaque opération d'insertion ou d'effacement effectuée sur l'enregistrement, ce qui rend superflue une mise à jour par le script appelant (cf. le constructeur : iso2709_record).
Le rôle de cette méthode est de synchroniser l'enregistrement courant avec sa représentation interne dans la classe. Les propriétés full_record, guide et directory sont mises à jour à partir du contenu des tableaux inner_data, inner_guide, inner_directory.
Cette méthode ne retourne rien.
prototype : valid(void)
Cette méthode vérifie le format ISO2709 de l'enregistrement. Elle retournera TRUE si l'enregistrement courant est valide et FALSE dans le cas contraire. Attention Cette méthode valide le format ISO2709 uniquement. Aucune erreur de sera générée si votre enregistrement contient, par exemple, 2 champs 700, ce qui est interdit par le standard UNIMARC.
prototypes :
ISO_encode(string chaine)
ISO_decode(string chaine)
Ces deux méthodes assurent la conversion des caractères codés suivant le format ISO 5426 vers le format ISO 8859-1.
La fonction ISO_encode convertit le format ISO 8859-1 vers le format ISO 5426 et ISO_decode fait l'inverse.
Ces deux fonctions retournent la chaîne passée en paramètre mais convertie suivant le cas.
De mon point de vue, ces deux méthodes sont implémentées de manière 'partielle mais suffisante', ce qui veut dire que cette implémentation n'est pas complète dans la mesure où j'ai énormément de mal à trouver des informations suffisantes sur le format ISO 5426 et l'ISO 646. Pour l'anecdote, la fonction ISO_decode est adaptée d'un bout de code C posté sur le forum de l'application bien connue recode et la fonction ISO_encode en découle directement. Si des personnes avaient plus de documentation sur le sujet, je leur serais reconnaissant de m'en faire part. L'implémentation actuelle est a peu près satisfaisante pour les langues latines et romanes, mais incomplète pour l'allemand et les alphabets 'exotiques'.
Voici un exemple d'utilisation très simple destiné à clarifier un peu tout ça. Il illustre la création d'un enregistrement ISO 2709 minimal. Les commentaires sont dans le script.
<?
|