HAL Id: hal-02818580
https://hal.inrae.fr/hal-02818580
Submitted on 6 Jun 2020
HAL is a multi-disciplinary open access archive for the deposit and dissemination of sci-entific research documents, whether they are pub-lished or not. The documents may come from teaching and research institutions in France or
L’archive ouverte pluridisciplinaire HAL, est destinée au dépôt et à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des établissements d’enseignement et de recherche français ou étrangers, des laboratoires
Joshua Amavi
To cite this version:
Joshua Amavi. Base de données et site web sur la gestion d’échantillons. [Stage] Université d’Orléans (UO), Orléans, FRA. 2008, 45 p. �hal-02818580�
Rapport de Stage de
Licence
Base de Données et Site Web sur la Gestion d’échantillons
Stage effectué du 15 Avril au 21 Juillet 2008
AMAVI Joshua
Licence Informatique Mention : Sciences et technologies pour l’Information et la
Communication (STIC)
Maître de Stage : Isabelle BOURGAIT
Tuteur de Stage : Jérémie VAUTARD
REMERCIEMENTS :
Dans le cadre de mon stage fait à l’INRA d’Orléans je remercie :
Monsieur Jean-Charles BASTIEN, directeur de l’Unité d’Amélioration Génétique et
Physiologie Forestière de m’avoir accueilli au sein de son unité pour mon stage de
Licence Informatique.
Je tiens à remercier particulièrement Mlle Isabelle BOURGAIT, mon maître de stage,
pour m’avoir accepté en tant que stagiaire sur le projet sur lequel j’ai travaillé, et
pour toute son aide et attention qu’elle m’a apporté.
Mes remerciements vont aussi à Monsieur Daniel SAUVARD, chargé de recherche
dans l’Unité de Recherche Zoologie Forestière, pour son aide lors de la phase de
conception.
Je remercie également les biologistes de l’unité AGPF avec qui j’ai été amené à
discuter pour l’avancement de mon travail.
Je remercie également mon tuteur de stage Monsieur Jérémie VAUTARD, pour sa
visite et ses conseils.
Et enfin je remercie toute ma famille pour leur soutien qu’ils m’ont apporté tout au long
du déroulement de mon stage.
Sommaire :
INTRODUCTION : ... 3
I. PRESENTATION DE L’INRA : ... 4
A. INRA en général : ... 4
B. INRA d’Orléans : ... 4
C. L’Unité de Recherches AGPF : ... 6
II. SUJET DE STAGE & OUTILS DE DEVELOPPEMENT : ... 6
A. Sujet de Stage : ... 6
B. Outils de développement : ... 7
III. ANALYSE & CONCEPTION : ... 8
A. Analyse : ... 8 1. Analyse de l’existant : ... 8 2. Méthodes Utilisées : ... 8 3. Collection d’Information : ... 8 4. Etude détaillée : ... 9 B. Conception : ... 11
1. Modèle Conceptuel de Données (MCD) : ... 11
2. Modèle Logique de Données (MLD) : ... 13
3. Dictionnaire des données : ... 14
4. Extrait du code de création de la base sous PostGreSQL : ... 17
5. Exemple d’une hiérarchie d’échantillons :... 18
IV. DEVELOPPEMENT DE L’INTERFACE : ... 20
A. Cahier des Charges : ... 20
B. Choix des techniques : ... 20
C. Structure & Organisation des pages : ... 20
D. Contraintes & Prise en Main: ... 21
1. Contraintes : ... 21
2. Prise en Main : ... 21
E. Codage des pages : ... 26
1. nouvelEchantillon.php : ... 26 2. detruireEchantillon.php : ... 29 3. stockerEchantillon.php : ... 30 4. traitement.php : ... 34 5. Validation.php : ... 37 CONCLUSION : ... 39 BIBLIOGRAPHIE : ... 40 WEBOGRAPHIE : ... 40 ANNEXES : ... 41
INTRODUCTION :
Pour clore mon cycle de licence en Informatique j’ai eu à effectuer un stage d’une durée de 3 mois en entreprise qui a débuté le 15 Avril 2008, pour valider mes connaissances et avoir une expérience en entreprise.
Ce stage s’est donc déroulé au sein de l’unité de recherche « Amélioration, Génétique et Physiologie forestières » de l’Institut National de la Recherche Agronomique d’Orléans. J’ai été accueilli par mon maître de stage Mlle Isabelle BOURGAIT qui est bio-informaticienne dans l’unité. Mon stage a donc porté sur l’élaboration d’une base de données pour les biologistes de l’unité et le développement d’une application sous forme de site web.
Ce stage m’a permis de m’insérer dans un milieu qui m’était inconnu, de discuter avec des personnes qui ont eu une formation différente de la mienne (la plupart biologiste). Il m’a apporté une grande expérience dans la réalisation d’un projet informatique depuis la phase de conception jusqu’à celle de réalisation. J’ai été aussi amené à assister à des réunions.
Ce rapport vise donc à résumer les différentes étapes de la réalisation de mon stage, à parler des moyens et méthodes utilisés pour sa réalisation et à les justifier. Enfin à parler de ce que j’ai tiré d’utile et les différents enseignements pour le futur.
Je vais donc commencer par la présentation de l’INRA et du centre d’Orléans, ensuite parler du travail que j’ai effectué en détail, et terminer par une conclusion.
I.
PRESENTATION DE L’INRA :
A.
INRA en général :
L’Institut National de la Recherche Agronomique (INRA) est un organisme de recherche scientifique publique qui mène des recherches finalisées pour une alimentation adaptée, pour un environnement préservé, et pour une agriculture compétitive et durable.
Créé en 1946, l’INRA est maintenant le premier institut de recherche agronomique en Europe, et le deuxième dans le monde. L’INRA est compétent pour répondre à la demande sociale dans trois domaines qui ont un lien très fort entre eux : l’agriculture, l’alimentation et l’environnement. Les différentes missions de l’INRA sont :
produire et diffuser des connaissances scientifiques ;
Concevoir des innovations et des savoir-faire pour la société ;
Eclairer, par son expertise, les décisions des acteurs publics et privés ;
Développer la culture scientifique et technique et participer au débat science/société ; Former à la recherche et par la recherche.
L’INRA exerce une politique de partenariat et de collaboration avec :
la communauté scientifique : organisme de recherche et enseignement supérieur le monde agricole, les entreprises et les collectivités territoriales
la communauté scientifique internationale (Etats-Unis, Japon, Canada, Brésil, Chine…) L’INRA compte en tout :
8 576 agents au 31 décembre 2006, dont 48 % sont des femmes, répartis comme suit : 1826 scientifiques, 2 396 ingénieurs, 4 354 techniciens et administratifs.
14 départements scientifiques 21 centres de recherches régionaux Budget 2006 : 678 millions d’euros
B.
INRA d’Orléans :
Le centre d’Orléans qui est l’un des 21 centres régionaux de l’INRA, comprend des unités de recherche implantées à Ardon à proximité d’Orléans et un domaine d’expérimentation animale près de Bourges.
Il est présidé par M. Dominique King et est constitué de 6 unités qui traitent de quatre domaines de recherche qui sont :
La sélection d’arbres forestiers
La biologie des insectes forestiers ravageurs
La maîtrise des érosions et des pollutions, l'évaluation de risques agro-climatiques
L'amélioration génétique des performances des troupeaux et la qualité de leurs produits Voici la liste des unités du centre :
L’unité de recherche « Amélioration, Génétique et Physiologie forestières ». Elle accueille et collabore avec "le conservatoire génétique des arbres forestiers " de l’ONF.
L’unité de recherche « Zoologie Forestière » assure le suivi des populations d’insectes en expansion sous l’effet des changements environnementaux.
L’unité de service « Infosol » dont la mission est de constituer et de gérer un système d’information à vocation nationale sur les sols
L’unité expérimentale « Amélioration des arbres forestiers » qui est une unité d’appui à la recherche et travaille principalement avec l’UR AGPF
L’unité expérimentale de Bourges, rattaché au département de « Génétique Animale » et répond aux besoins des filières animales et à l’attente de la recherche
L’unité de recherche « Science du Sol »
Figure 1 : Organigramme de l’INRA d’Orléans
J’ai effectué mon stage au sein de L’Unité de Recherches Amélioration, Génétique et Physiologie forestières (UAGPF), dans le laboratoire de Bioinformatique (encadré en rouge sur la figure 1) sous la direction d’Isabelle BOURGAIT, la bio- informaticienne de l’unité.
C.
L’Unité de Recherches AGPF :
L’Unité de Recherches AGPF traite sur les thèmes suivant :
Le développement de connaissances en génétique et en physiologie des arbres forestiers. La conduite de programmes d'amélioration sur les feuillus (peupliers, frênes, merisier) et
sur les conifères (Douglas, mélèzes, pin sylvestre, épicéas) pour la création de variétés adaptées aux contextes écologiques et économiques.
La gestion de données dendrométriques issues de différents dispositifs expérimentaux L’unité est dotée de laboratoires de biochimie, d’histologie, de biologie moléculaire, de culture in
vitro et de bio informatique.
Les effectifs de l’unité AGPF sont de 34 personnes permanentes dont 23 chercheurs et ingénieurs. Ses personnels se regroupent en 3 équipes que sont l’Equipe Génétique, Méristèmes et Xylème. L’unité héberge aussi :
La Cellule Technique du Groupement d'Intérêt Scientifique (GIS) et L’office National des Forêts (ONF) qui est associé à l’INRA
Figure 2: Organigramme de l’UR AGPF
II.
SUJET DE STAGE & OUTILS DE DEVELOPPEMENT :
A.
Sujet de Stage :
Les biologistes de l’unité manipulent dans les différents laboratoires des échantillons de divers types (bois, feuille, poudre, bourgeon, ADN …). Leur souhait est de connaître le suivi de ses
échantillons depuis leur réception dans les laboratoires jusqu’à leur stockage dans des congélateurs. Le projet consiste donc à élaborer une base de données qui puisse renseigner sur les échantillons qu’ils manipulent, l’endroit où ils sont stockés, les différents traitements et analyses qu’ils ont subis. Elle renseignera aussi sur la hiérarchie des échantillons puisqu’un échantillon peut se transformer partiellement ou totalement en un autre.
Ensuite il faudra faire des écrans de saisie et de consultation des données de la base. Chaque laboratoire devra avoir son espace de travail puisque les différents traitements et analyses effectués sur les échantillons varient d’un laboratoire à un autre.
B.
Outils de développement :
Voici les différents outils qui étaient à ma disposition pour mener à bien ce projet : Caractéristiques de ma machine :
DELL Optiplex GX620 INTEL PENTIUM CPU 3Ghz, 1go de RAM Système d’exploitation : Windows Xp service pack 2 version 2002
Le Serveur de développement :
PowerEdge 2800 (DELL), Biprocesseur Xeon 3.0 GHz/ 1Mo FSB 800 MHz Mémoire Vive : 4 Go de RAM
Disque Durs : 3 disques durs chacun de 73 Go en RAID5 Système d’exploitation : Redhat entreprise 3*3 Kernel 2.4.21-20 Elsmp
Langages de programmation :
HTML : (Hypertext Markup Language) est le format de données utilisé pour les pages web. Il est aussi nommé langage de balisage. Il est couplé aux feuilles de styles pour une mise en forme des pages web.
PHP version 5.0 : (Hypertext PreProcessor) est un langage de programmation côté serveur qui permet de rendre dynamique les pages web.
JavaScript : Langage de programmation de scripts côté client il permet de rendre plus réactive les pages web et facilite l’ergonomie de celles-ci.
AJAX : (Asynchronous JavaScript And XML), est un terme qui évoque l'utilisation conjointe d'un ensemble de technologies libres couramment utilisées sur le Web :
HTML (ou XHTML) pour la structure sémantique des informations ;
CSS pour la présentation des informations ;
DOM et JavaScript pour afficher et interagir dynamiquement avec l'information présentée ;
l'objet XMLHttpRequest pour échanger et manipuler les données de manière asynchrone avec le serveur Web.
XML (eXtensible Markup Language), est un langage de balisage générique. En alternative au format XML, J’ai utilisé le format JSON.
JSON : (JavaScript Object Notation) est un format de données générique. Il utilise la notation des objets JavaScript pour transmettre de l'information structurée. Il est léger et au format texte. Un document JSON ne comprend que deux éléments structurels : des ensembles de paires nom / valeur et des listes ordonnées de valeurs.
Base de Données :
PostGreSQL version 7.4 est le SGBDR (Système de Gestion de Base de Données Relationnelles) utilisé à l’unité. Il est un système de base de données non commercial et dispose de nombreuses
fonctionnalités qui lui permettent d'égaler des produits commerciaux lourds tels que Oracle. Logiciels et utilitaires utilisés :
NotePad++ version 4.9.2 : est un éditeur de code source très puissant qui supporte plusieurs langages. Je l’ai utilisé pour éditer mes fichiers HTML, PHP, CSS et JavaScript.
Navigateur Mozilla Firefox 2.0 : est un navigateur web libre qui offre la possibilité d’ajouter des extensions et des thèmes graphiques. J’ai ajouté une extension qui est :
Firebug version 1.05 : est une extension qui propose des outils facilitant le
développement de site web. Il signale les erreurs JavaScript et CSS des pages web. En plus il permet de suivre en détail les requêtes AJAX1 lancées au serveur et les réponses
du serveur.
WAMPSERVER version 2.0 : Windows Apache MySQL PHP est une plateforme de développement Web sous Windows. Il permet de développer des applications web dynamiques à l’aide du server apache 2, du langage PHP et d’une base de données ici PostGreSQL.
PgAdmin III version 1.0.2 : une interface graphique pour administrer la base de données sous PostGreSQL.
III.
ANALYSE & CONCEPTION :
A.
Analyse :
1. Analyse de l’existant :
Aucune base de données parmi celles qui ont été développées pour l’unité AGPF ne répondait aux souhaits des biologistes de l’unité pour la gestion des échantillons de laboratoire. Actuellement ils ont des fichiers Excel et leur cahier de laboratoire pour noter les informations que contiendra la base. La base devra constituer un outil pour mieux gérer les échantillons et non un outil qui
remplacera leur cahier de laboratoire.
J’ai donc comme charge de faire l’analyse des besoins des biologistes et ensuite élaborer la base qui conviendra. Une analyse préalable a été faite par mon Maître de Stage Isabelle BOURGAIT. Elle a utilisé la méthode Merise pour effectuer ce travail.
2. Méthodes Utilisées :
La méthode que j’ai utilisée pour la réalisation de ce projet est la méthode Merise. La méthode Merise est une méthode d'analyse, de conception et de réalisation de système d'information informatisé. J’ai choisi Merise par rapport à UML (Unified Modeling Language ou langage de
modélisation unifié) puisque le système à modéliser n’était pas complexe, et aussi pour rester en
conformité avec le travail préalable qu’à effectuer mon maître de stage. 3. Collection d’Information :
Lors du déroulement de mon stage j’ai été amené à discuter avec les biologistes de l’unité pour savoir concrètement ce qu’ils attendaient de l’application. Jai donc visité chaque laboratoire qui m’a permis d’avoir un aperçu du travail effectué. J’ai été amené à leur poser des questions :
sur la manière dont ils réceptionnent leur échantillons et les stockent, sur les différents traitements et analyses effectués sur les échantillons.
1
En résumé ils m’ont parlé de la manière dont ils procédaient et de la manière dont ils veulent procéder maintenant.
Un fichier Word nommé « ListeChampTable.doc » a été édité par mon maître de stage lors de l’élaboration du cahier des charges pour avoir plus de renseignements sur les informations à stocker dans la base auprès des biologistes de l’unité. J’ai été amené à faire une synthèse des réponses reçues.
Figure 3 : Extrait du document Word ListeChampTable.doc (en croix les informations nécessaires)
Des réunions ont été organisées par mon maître de stage dans le but de parler le même langage et de choisir les termes à garder.
4. Etude détaillée :
Voici un exemple d’échantillons manipulés dans les laboratoires et des traitements qu’ils peuvent subir.
Figure 4 : Exemple d’un cas concret d’échantillons
La base de données à développer dont le nom est « Samples » devra répondre aux questions suivantes :
Les informations concernant un échantillon (nom, type, quantité restante en stock, son unité de mesure, …)
La localisation d’un échantillon (s’il est dans un congélateur ou n’existe plus)
Connaître le ou les parents d’un échantillon (dans le cas d’une fusion de plusieurs parents) Les informations concernant la réception et l’origine d’un échantillon (Opérateur externe qui
l’a apporté, opérateur interne qui l’a reçu ou qui est allé le récolter, l’état dans lequel il a été reçu, l’espèce duquel il est issu …). Dans le cas où l’échantillon en question est issu d’un traitement on se réfère à l’origine et la réception de ses parents initiaux.
Les différents traitements que cet échantillon a subis (Transformation, Division, Prélèvement, Groupement avec ou sans position) et les opérateurs qui les ont effectués
Le ou les échantillons initiaux d’un échantillon donné
Connaître tous les échantillons qui se trouvent dans un groupement ou un congélateur ou une pièce donnée
Les différentes analyses qu’un échantillon a subies et les renseignements sur les résultats obtenus, et la date où l’analyse a été effectuée
Savoir à quelle date un échantillon a été détruit et comment
Nous avons donc 5 types de traitements d’échantillons :
1) TRANSFORMATION : un échantillon A devient un échantillon A1 (exemple broyage). Tout A est détruit et on ne créera toujours qu’un seul A1. (voir figure 4)
2) DIVISION : un échantillon A devient plusieurs échantillons A1, A2,…., An . Tout A est détruit et on a toujours au-moins 2 nouveaux échantillons. (voir figure 4)
3) PRELEVEMENT : une partie de l’échantillon A devient un ou plusieurs échantillons A1, A2,…, An. L’échantillon A n’est pas détruit entièrement et on peut avoir plusieurs échantillons créés. 4) FUSION : on prend au moins 2 échantillons A, B qui en deviennent qu’un seul AB. Les
échantillons A et B ne sont pas forcément utilisés en totalité par contre, on n’a qu’un seul échantillon créé. Celui-ci pourra être divisé par la suite.
5) GROUPEMENT : on prend au moins 2 échantillons que l’on regroupe ensemble mais sans les mélanger. Il y a 2 types de groupement.
• Les plaques 96 ou les gels. Les échantillons de départ ne sont pas forcément pris en totalité à l’arrivée, ils ont une position bien définie dans le nouvel échantillon.
Figure 5 : Plaque 96
• Les groupements en boite pour le stockage. Les échantillons de départ sont pris en totalité et ils peuvent ne pas avoir de place attitrée dans le nouvel échantillon (groupement dans un sac).
La base de données « Samples » doit gérer 5 groupes d’utilisateurs et les utilisateurs eux-mêmes. Elle doit gérer aussi les lieux de stockages qui sont des congélateurs, des chambres froides etc.… La base de données sera adaptée pour une autre unité du Centre.
Quelques exemples d’analyses effectués sur les échantillons : génotypage, séquençage, dosage de sucre. Pour une question de temps cette partie n’est pas encore gérée.
L’interface graphique qui est un site web en intranet devrait pouvoir stocker ces informations et les visualiser.
B.
Conception :
2. Modèle Logique de Données (MLD) :
Figure 7 : Modèle Logique de Données de la base
Voici donc un récapitulatif sur les tables de la base de données :
Nom de la table Description
SAMPLE Liste des échantillons de la base
SAMPLE_TYPE Renseigne sur la nature des échantillons (feuille, bois, plaque, …)
OPERATOR Liste des utilisateurs de la base de données
TEAM Liste des différents groupes
OPERATOR_TEAM Liste des opérateurs et de leur groupe
TREATMENT Concerne les différents traitements sur les échantillons
TREATMENT_QUALIFIER Sert à rajouter des informations aux traitements
RELATIONSHIP Hiérarchie des échantillons
TREATMENT_OPERATOR Renseigne sur les opérateurs qui ont effectué un traitement donné
PLACE Liste des différents endroits de stockage
SAMPLE _PLACE Endroits où sont stockés les échantillons
SAMPLE_INITIAL Renseigne sur les parents initiaux des échantillons
GROUPMENT Position des échantillons dans un groupement
DICTIONARY Liste des types de traitements, d’analyse, d’échantillon et de leurs valeurs
DESTRUCTION Renseigne sur la destruction des échantillons
RECEPTION Renseignements sur la réception des échantillons
Figure 8 : Récapitulatif sur la description des tables et relations
3. Dictionnaire des données :
Par convention le nom de la base de données, des tables et des attributs sont en anglais. Table Sample :
Dans la table « sample » on a les renseignements généraux sur un échantillon.
SAMPLE
sample_id Identifiant
name Nom de l’échantillon
unit Unité de mesure de l’échantillon (cm, g, mg, ml…)
quantity Quantité liée à l’unité destroyed Renseigne sur la destruction de l’échantillon (booléen)
conditioning Renseigne sur le conditionnement de l’échantillon (en boite, tube, flacon, bouteille…)
comment Champ commentaire
team_fid Identifiant du groupe
Table Sample_type :
Un échantillon peut avoir plusieurs types ou natures. Cette table nous permet de renseigner sur les types d’un échantillon donné.
SAMPLE_TYPE name Nom du type
Table Reception :
La table « Reception » renseigne sur les informations obtenues à la réception des échantillons dans un laboratoire.
RECEPTION
reception_id Identifiant de la relation réception
date_reception Date de réception de l’échantillon
state Etat de l’échantillon à la réception (congelé, frais,
poudre, en morceau)
sample_fid Identifiant de l’échantillon
operator_fid Identifiant de l’opérateur qui a reçu l’échantillon
Table Team :
La table « Team » va nous renseigner sur les 5 groupes qui vont utiliser l’application. Il y a un 6ème
groupe nommé Admin qui pourra faire des actions d’administration comme rajouter un nouvel opérateur, rajouter de nouveaux lieux de stockage.
TEAM
team_id Identifiant
name Nom du groupe
password Mot de passe
db_group Nom du groupe PostGreSQL qui permet de
connaître le droit (ajout, suppression, lecture) des groupes.
Table Operator :
C’est dans la table « Operator » où l’on référencie tous les utilisateurs de l’application, qui seront des biologistes, des stagiaires ou des scientifiques.
OPERATOR
operator_id Identifiant
name Nom de l’operateur
status Rôle de l’opérateur (stagiaire, permanent)
present Renseigne si l’opérateur est toujours présent dans
l’unité
Table Place :
La table « Place » nous renseigne sur les différents lieux de stockage où sont stockés les échantillons. Elle permettra aussi d’avoir des renseignements sur la hiérarchie entre ces lieux de stockage. Exemple : Une pièce contient un congélateur et le congélateur à son tour contient des tiroirs ou des étagères.
PLACE
place_id Identifiant
container_fid Identifiant du lieu qui contient celui-ci
name Nom du lieu de stockage
type_place Type du lieu (Congélateur 20°C, Congélateur
-80°C, Pièce, Etage/Tiroir…)
level_place Niveau dans la hiérarchie (0 si c’est le premier)
Table Treatment :
La table « Treatment » nous renseigne sur les différents traitements qu’a subis un échantillon.
TREATMENT
treatment_id Identifiant
type_treatment Type du traitement (Transformation, Division…)
date_treatment Date où le traitement a été effectué
protocol Protocole du traitement
name Sert à identifier le traitement
comment Champ commentaire
Table Treatment_qualifier :
La table « Treatment_qualifier » renseigne sur les informations utiles supplémentaires concernant un traitement que l’on n’a pas prévu parmi les champs de la table « Treatment ».
TREATMENT_ QUALIFIER
type_qualifier Type du qualifier
value Valeur du qualifier
treatment_fid Identifiant du traitement concerné
Table Relationship :
La table « Relationship » qui est l’une des plus importantes est une table association qui lie
l’échantillon parent, l’échantillon fils, et le traitement qu’a subi le parent pour donner le fils. Elle nous permet donc de reconstruire « l’arbre généalogique » d’un échantillon en sachant les différents traitements appliqués.
RELATIONSHIP
relationship_id Identifiant
Sample_fid Identifiant de l’échantillon fils
Parent_fid Identifiant de l’échantillon parent
Treatment_fid Identifiant du traitement
level_relationship Niveau de parenté dans la hiérarchie (égal à celui du parent + 1). L’échantillon initial est de niveau 1.
level_fusion Niveau de fusion (égal à celui du parent +1) s’il est
issu de fusion
present Renseigne si l’échantillon est toujours dans un
groupe ou pas
Table Sample_initial :
La table « Sample_initial » renseigne sur les échantillons initiaux d’un échantillon donné. Comme ça il nous sera facile de retrouver son origine puisque c’est l’échantillon initial qui a été réceptionné dans le laboratoire.
SAMPLE_INITIAL relationship_fid Identifiant du Relationship
initial_fid Identifiant du premier échantillon Table Groupment :
Si le traitement donnant l’échantillon fils est un groupement avec position, la table « Groupment » nous renseigne sur la position du parent dans ce groupement.
GROUPMENT
relationship_fid Identifiant du Relationship
row Ligne du groupement où se situe l’échantillon
Table Dictionary :
La table « Dictionary » est un dictionnaire de données. Elle aide à la saisie.
DICTIONARY entity Type de la donnée à mettre
name Valeur de la donnée
Table Sample_place :
La table « Sample_place » sert à gérer le stockage des échantillons. SAMPLE_PLACE
sample_fid Identifiant de l’échantillon place_fid Identifiant du lieu de stockage operator_fid Identifiant de l’opérateur
date_arrival Date de stockage
Table Destruction :
La table « Destruction » permet de gérer la suppression des échantillons.
DESTRUCTION sample_fid Identifiant de l’échantillon
operator_fid Identifiant de l’opérateur
date_destruction Date de destruction de l’échantillon
reason Raison de la destruction de l’échantillon
protocol Protocole de destruction
comment Champ commentaire
Table Operator_team :
La table « Operator_team » nous permet de savoir à quel groupe appartient un opérateur donné. Un opérateur peut appartenir à plusieurs groupes différents.
OPERATOR_TEAM operator_fid Identifiant de l’opérateur
team_fid Identifiant du groupe
Table Treatment_operator :
La table « Treatment_operator » nous renseigne sur les opérateurs qui ont fait un traitement donné car un traitement peut être réalisé par plusieurs opérateurs.
TREATMENT_OPERATOR treatment_fid Identifiant du traitement
operator_fid Identifiant de l’opérateur
4. Extrait du code de création de la base sous PostGreSQL :
CREATE TABLE SAMPLE (
SAMPLE_ID SERIAL NOT NULL, TEAM_FID INTEGER NOT NULL , NAME varchar(50) NOT NULL , UNIT varchar(100) NOT NULL , QUANTITY float4 NOT NULL , DESTROYED bool NOT NULL , CONDITIONING varchar(100) NULL , COMMENT varchar(1000) NULL ,
CONSTRAINT PK_SAMPLE PRIMARY KEY (SAMPLE_ID) );
CREATE TABLE SAMPLE_TYPE (
SAMPLE_FID INTEGER NOT NULL , NAME varchar(100) NOT NULL, CONSTRAINT PK_SAMPLE_TYPE PRIMARY KEY (SAMPLE_FID, NAME));
CREATE TABLE RECEPTION (
RECEPTION_ID SERIAL NOT NULL, SAMPLE_FID INTEGER NOT NULL , OPERATOR_FID INTEGER NOT NULL , DATE_RECEPTION date NOT NULL , STATE varchar(100) NULL,
CONSTRAINT PK_RECEPTION PRIMARY KEY (RECEPTION_ID));
CREATE TABLE TREATMENT (
TREATMENT_ID SERIAL NOT NULL, TYPE_TREATMENT varchar(100) NOT NULL , DATE_TREATMENT date NOT NULL , PROTOCOL varchar(1000) NULL ,
NAME varchar(100) NULL , COMMENT varchar(1000) NULL, CONSTRAINT PK_TREATMENT PRIMARY KEY (TREATMENT_ID));
CREATE TABLE PLACE (
PLACE_ID SERIAL NOT NULL, CONTAINER_FID INTEGER NOT NULL , NAME varchar(100) NOT NULL , TYPE_PLACE varchar(100) NOT NULL , LEVEL_PLACE INTEGER NOT NULL , COMMENT varchar(1000) NULL, CONSTRAINT PK_PLACE PRIMARY KEY (PLACE_ID) );
CREATE TABLE OPERATOR (
OPERATOR_ID SERIAL NOT NULL, NAME varchar(100) NOT NULL , STATUS varchar(25) NOT NULL , PRESENT bool NOT NULL , COMMENT varchar(1000) NULL,
CONSTRAINT PK_OPERATOR PRIMARY KEY (OPERATOR_ID));
CREATE TABLE DESTRUCTION (
SAMPLE_FID INTEGER NOT NULL , OPERATOR_FID INTEGER NOT NULL , REASON varchar(100) NOT NULL , DATE_DESTRUCTION date NOT NULL , PROTOCOL varchar(1000) NULL , COMMENT varchar(1000) NULL, CONSTRAINT PK_DESTRUCTION PRIMARY KEY (SAMPLE_FID));
CREATE TABLE RELATIONSHIP (
RELATIONSHIP_ID SERIAL NOT NULL, TREATMENT_FID INTEGER NOT NULL , SAMPLE_FID INTEGER NOT NULL, PARENT_FID INTEGER NOT NULL , LEVEL_RELATIONSHIP INTEGER NOT NULL , LEVEL_FUSION INTEGER NOT NULL , PRESENT bool NULL, CONSTRAINT PK_RELATIONSHIP PRIMARY KEY (RELATIONSHIP_ID));
ALTER TABLE SAMPLE ADD CONSTRAINT FK_SAMPLE_TEAM FOREIGN KEY (TEAM_FID) REFERENCES TEAM (TEAM_ID) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE SAMPLE_TYPE ADD
CONSTRAINT FK_SAMPLE_TYPE_SAMPLE FOREIGN KEY (SAMPLE_FID)
REFERENCES SAMPLE (SAMPLE_ID) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE RECEPTION ADDCONSTRAINT FK_RECEPTION_SAMPLE
FOREIGN KEY (SAMPLE_FID) REFERENCES SAMPLE (SAMPLE_ID) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE DESTRUCTION ADD CONSTRAINT FK_DESTRUCTION_SAMPLE
FOREIGN KEY (SAMPLE_FID) REFERENCES SAMPLE (SAMPLE_ID) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE DESTRUCTION ADD CONSTRAINT FK_DESTRUCTION_OPERATOR FOREIGN KEY (OPERATOR_FID) REFERENCES OPERATOR (OPERATOR_ID) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE RELATIONSHIP ADD CONSTRAINT FK_RELATIONSHIP_TREATMENT FOREIGN KEY
(TREATMENT_FID) REFERENCES TREATMENT (TREATMENT_ID) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE RELATIONSHIP ADDCONSTRAINT FK_RELATIONSHIP_SAMPLE FOREIGN KEY (SAMPLE_FID) REFERENCES SAMPLE (SAMPLE_ID) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE RELATIONSHIP ADDCONSTRAINT FK_RELATIONSHIP_SAMPLE2 FOREIGN KEY (PARENT_FID) REFERENCES SAMPLE (SAMPLE_ID) ON UPDATE CASCADE ON DELETE CASCADE;
5. Exemple d’une hiérarchie d’échantillons :
Sur l’exemple de la Figure 8 ci-dessous, nous avons trois échantillons initiaux A1, A10, et A20 qui sont réceptionnés dans un laboratoire.
A1 par une transformation donne A2. A10 aussi par une transformation donne A11. Ensuite une partie de A2 est fusionnée avec une partie de A11 pour donner A3.
Une partie de A3 est mis dans le groupement avec position A100. Et la partie restante est transformée en AB1.
Une partie de A20 est mise aussi dans le groupement avec position A100.
AB11 se transforme en AB11. Ce dernier est fusionné avec A11 et A20 pour donner AF1. AF1 se transforme en AF11.
Figure 8a : Exemple d’une hiérarchie d’échantillons
Voici donc la manière dont les données seront stockées dans la base de données. Sample_
initial relationship groupment
Initial_fi
d Parent_fid treatment Sample_fid
Level_relatio
nship Level_fusion row col
A1 - - A1 1 1 - -
A1 A1 Transformation A2 2 1 - -
A1 A2 Fusion A3 3 2 - -
A10 - - A10 1 1 - -
A10 A10 Transformation A11 2 1 - -
A10 A11 Fusion A3 3 2 - -
A10 A11 Groupe avec position
A100 3 1 A 1
A10 A100 Groupe sans position
A200 4 1
A20 - - A20 1 1 - -
A20 A20 Groupe avec position A100 2 1 A 2 A1 A3 Groupe avec position A100 4 2 A 5 A10 A1 A3 Transformation AB1 4 2 - - A10
A1 AB1 Transformation AB11 5 2 - -
A10
A10 A11 Fusion AF1 6 2 - -
A1 AB11 Fusion AF1 6 3 - -
A10
A20 A20 Fusion AF1 6 3 - -
A1 AF1 Transformation AF11 7 3 - -
A10 A20
IV.
DEVELOPPEMENT DE L’INTERFACE :
A.
Cahier des Charges :
Le travail a été séparé en trois parties :
1) Dans un premier temps la réalisation des pages de saisie de la réception de l’échantillon, des traitements effectués sur l’échantillon, du stockage de l’échantillon et de la destruction de l’échantillon
2) Après cela la réalisation des pages de sorties des résultats
3) En troisième partie la réalisation de la page de saisie des analyses et l’adaptation aux pages des résultats
Si j’arrive à bout de ces trois parties et qu’il me reste encore du temps, il y aura donc la possibilité de faire une quatrième partie qui consistera à faire une interface permettant d’importer dans la base les fichiers Excel d’échantillons existants.
B.
Choix des techniques :
La base de données a été codée sous PostGreSQL. L’interface Web qui l'accompagne est codée en PHP. L’utilisation de JavaScript a été utile pour rendre réactives les pages et pour utiliser la technologie AJAX (Asynchronous JavaScript and XML, j’en parlerai plus loin). J’ai utilisé AJAX pour éviter de recharger toute une page facilitant donc la saisie de certains champs des formulaires.
C.
Structure & Organisation des pages :
Figure 9: Structure des pages
Toutes les pages du site web adoptent la structure de la Figure 9 ci-dessus : L’en-tête de la page
Le Menu Horizontal : divisé en plusieurs onglets que sont la Reception, le Traitement, l’Analyse, le Stock, les Sorties, et l’Espace Admin qui apparait quand le groupe Admin est connecté. Chaque onglet est dirigé vers une nouvelle page qui traite sur son titre.
Figure 10 : Menu Horizontal
Le Menu Vertical Le Corps de la page Le Pied de la page
C’est donc la partie « Corps de la page » qui est amenée à changer d’une page à une autre. La figure ci-dessous nous montre l’organisation des fichiers du site web :
Figure 11 : Organisation des fichiers du site web
D.
Contraintes & Prise en Main:
1. Contraintes :
Une structure de base du site a été proposée par mon maître de stage pour que mon travail soit dans la même logique que les autres sites web qui ont été développés pour l’unité AGPF.
J’ai donc consacré du temps pour comprendre la façon dont était organisée cette structure et voir la façon dont je devais l’adapter à mon travail. Nous allons donc avoir plus de détails sur ce point dans la partie suivante « prise en main ».
2. Prise en Main :
Dans le dossier « include » nous avons les fichiers suivant :
Variable.php :
Le fichier Variable.php contient des variables globales qui sont utiles pour la configuration des pages.
Paramètres de connexion à la base sous PostGreSQL
$base = "Samples"; // $base contient le nom de la base de données $server = "XXX.XX.XXX.XX"; // $server contient l’adresse IP du serveur
Gestion de la connexion à l’interface
$Login = 1; // $Login vaut 1 si l’utilisateur doit se connecter avec un nom et mot de passe et 0 si le site est en accès libre
$pageLogin = "index.php"; // La variable $pageLogin contient l’adresse de la page sur laquelle on doit rediriger si l’utilisateur entre un login ou un mot de passe erroné.
Informations générales sur le site
$pageTitle = ' Gestion des Echantillons'; // La variable $pageTitle contient le titre de la page $siteTitle = 'Gestion des Echantillons'; // La variable $siteTitle contient le titre du site à mettre sur toutes les pages
$heightTitle = 100; // La variable $heightTitle contient la hauteur du titre du site $heightMenu = 40; // // La variable $heightMenu contient la hauteur du menu
$siteLogo[1] = 'http://www.inra.fr' ; //$siteLogo[1] contient l’adresse sur lequel renvoi le Site lorsqu’on clique sur le premier logo
$siteLogo[2] = 'http://www.orleans.inra.fr';
$siteLogo[3] = 'http://www.orleans.inra.fr/les_unites/ur_agpf';
$imageLogo[1] = './image/LogoINRA-Vert.jpg'; // contient l’adresse de l’image représentant le premier logo
$imageLogo[2] = './image/CentreOrleans.gif'; $imageLogo[3] = './image/UAGPF.png';
$nbLogo = count($siteLogo); // La variable $nbLogo contient le nombre de logos $heightLogo = 40; // La variable $heightLogo contient la hauteur des logos $widthLogo = 70; // La variable $widthLogo contient la largeur des logos
Pour rajouter un quatrième logo il suffit d’ajouter les variables $imageLogo[4] et $siteLogo[4].
Figure 12 : L’entête et le Menu Horizontal avec les variables globales Définition du Menu
$nbImage = 2; /* nombre d'images pour encadrer le menu, =0 pas d’image, =1 une image à gauche, =2 deux images des deux côtés, =3 trois images à droite */
$imageMenu = "<img src=\"./image/adn.gif\"width=\"90\"height=\"20\">" ; /*choix de l'image qui est la même des 2 côtés */
$menu[1] = "Reception"; //définition du premier menu voir la Figure 11 ci-dessus $menu[2] = "Traitement"; //définition du deuxième menu voir la Figure 11 ci-dessus $menu[3] = "Analyse"; //définition du troisième menu voir la Figure 11 ci-dessus $menu[4] = "Stock"; //définition du quatrième menu voir la Figure 11 ci-dessus $menu[5] = "Destruction"; //définition du cinquième menu voir la Figure 11 ci-dessus $menu[6] = "Sorties"; /* définition du sixième menu voir la Figure 11 ci-dessus $nbMenu = count($menu); // nombre de menus
Pour rajouter un septième menu il suffit d’ajouter la variable $menu[7] à la liste ci-dessus et de lui donner le nom du menu. */
de définir le lien qui permettra d’atteindre la page correspondante au menu[1], on fera pareil pour les 6 autres. */
En ce qui concerne le menu des Administrateurs on fait comme suit :
$nbMenuAdmin = 1; // Nombre de menus concernant les administrateurs $menuAdmin[1] = "Espace Admin"; // Définition du premier menu
$menuPageAdmin[1] = "espaceAdmin.php"; // Définition du lien pour atteindre le premier menu Enfin on a la taille du menu qui est calculée comme suit :
$lgMenu = floor((100 / ($nbMenu + $nbImage))) - $nbMenu ; Message de bas de page :
$copyright = "Copyright © 2008<br>INRA<br>Tous droits réservés<br>"; $copyright .= "Responsable : Jean-Charles BASTIEN<br>";
$copyright .= "Contact : <a href=\"mailto:bioinfo@orleans.inra.fr\">Isabelle BOURGAIT</a>"; Le résultat donne la figure ci-dessous :
Figure 13: Le pied de page
Database.php :
Dans le fichier « DataBase.php » est défini la classe Database. Cette classe contient des fonctions qui gèrent la connexion et la déconnexion à la base, la récupération du résultat d’une requête SQL, etc…
Utile.php :
Dans le fichier « utile.php » on trouve :
la fonction connection($base, $server) qui se sert de la classe Database pour se connecter à la base
la fonction testConnection ($base, $server, $langue) qui vérifie si le login et le mot de passe de l’utilisateur sont valides.
Code de la fonction testConnection :
function testConnection ($base, $server, $langue) { $connect = connection($base, $server);
if($connect == false) {
print "<script language=\"JavaScript\" type=\"text/JavaScript\">";
if ($langue == "E") print "alert('The connection is not posible')"; else print "alert('Vous n'avez pas pu être connecté')";
print "</script>";
Rediriger(); // redirige vers l’adresse contenu dans $pageLogin
die(); } else {
//Mémorisation du numéro IP et de la date de connexion
$_SESSION['IP'] = $_SERVER['REMOTE_ADDR']; $_SESSION['date_connect'] = date("d/m/Y",time());
$result = $connect->Query("SELECT TEAM_ID, NAME, PASSWORD, DB_GROUP FROM TEAM WHERE TEAM_ID = '" .$_POST['groupe'] ."' AND PASSWORD = '" . $_POST['motdepasse'] . "' ;" );
if( pg_num_rows($result) == 0 ) $_SESSION['Login'] = “”;
else {
$row = pg_fetch_array($result);
$_SESSION['Id'] = $row['team_id']; // contient l’identifiant du groupe connecté
$_SESSION['Login'] = $row['name']; // contient le nom du groupe connecté
$_SESSION['Group'] = $row['db_group']; } } $connect->Disconnect_database(); } en_tete.php :
Le fichier « en_tete.php » permet de dessiner l’entête de page voir Figure 9. Il contient le code suivant :
<?php
// On met une ancre en haut de page pour pouvoir remonter la page quand on se trouve en fin de page
print( '<a name = "top"></a>' );
print( '<table align="center"><tr>'); // Création d'une table qui a 2 colonnes
print('<td width="60%">' . $siteTitle . '</td>'); // 1ère colonne : Le titre de la page
print('<td width="40%" >'); // debut de la 2ème colonne : les logos
for ($i = 1; $i <= $nbLogo; $i++) {
print( '<a href="' . $siteLogo[$i] . '" target="_blank"><img src="'
. $imageLogo[$i] . '" width="' . $widthLogo . '" height="' . $heightLogo . '" border="0"></a>' ); }
print('</td>'); // fin de la 2ème colonne : les logos
print('</tr></table>'); // fin du tableau
?>
menuHorizontal.php :
Le fichier « menuHorizontal.php » permet de dessiner le menu de la page voir Figure 9. Il contient le code suivant :
<?php
// On dessine un tableau avec autant de cellule que de menu plus 2 images de chaque cote, si nécessaire
print( '<table width="100%" border="0" cellspacing="0">'); print('<tr>'); if ($nbImage >= 1 && $nbImage < 3)
print( '<td width="' . $lgMenu . '%" align="left" >' . $imageMenu . '</td>'); // Il faut voir si on est admin et s'il y a un menu spécial
$nbAdmin = 0;
if (isset($_SESSION['Group']) and (substr($_SESSION['Group'], 0, 5) == "admin")) { $nbAdmin = $nbMenuAdmin;
for ($i = ($nbMenu + 1); $i<= ($nbMenu + $nbAdmin); $i++) { $menu[$i] = $menuAdmin[$i - $nbMenu];
$menuPage[$i] = $menuPageAdmin[$i - $nbMenu]; }
}
for ($i = 1; $i <= ($nbMenu + $nbAdmin); $i++) {
print( "<td width=\"" . $lgMenu . "%\" align=\"center\"><a href=\"" . $menuPage[$i] . "\"" . $menuSousPage[$i] . ">" . $menu[$i] . "</a></td>");
if ($i != $nbMenu + $nbAdmin) print( "<td width=\"1%\" align=\"center\">|</td>"); }
if ($nbImage >= 2) print ("<td width=\"" . $lgMenu . "%\" align=\"right\">" . $imageMenu . "</td>"); print( "</tr>");
?>
menuVertical.php :
Le fichier « menuVertical.php » permet de dessiner le menu vertical de la page voir Figure 13 ci-dessus :
Figure 14 : Menu Vertical
Il contient le code suivant : <?php
if($Login == 0 ) {
print( '<h2>' . strtoupper($_SESSION['Login']) . '</h2>' );
print( '<form action = "index.php" method = "post" ><input type="submit" name="deconnect" value="Deconnexion" /></form>' );
}
E.
Codage des pages :
Les pages essentielles que j’ai codées pour l’instant sont les suivantes : « index.php », «
nouvelEchantillon.php », « detruireEchantillon.php », « stockerEchantillon.php », « traitement.php », « validation.php ».
Le code minimal PHP donnant la structure de base des pages qu’on a vus sur la Figure 9 est le suivant :
<?php
session_start() ; // commence la session
include("./include/Variable.php"); // Contient les variables globales include("./include/Utile.php"); // Contient les fonctions utiles
include("./include/Database.php"); // Contient la connexion à la base
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"> <head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Titre de la page </title>
<link href="./style/styleEchantillon.css" rel="stylesheet" media="all" type="text/css" /> <script language="Javascript" src="./js/function.js"></script>
<style type="text/css"></style> </head>
<body>
<!-- L'en-tête -->
<div id="en_tete"> <?php include("en_tete.php"); ?> </div>
<!-- Les menus -->
<div id="menuHorizontal"><?php include("menuHorizontal.php"); ?></div>
<div id="menuVertical"> <?phpinclude("menuVertical.php"); ?> </div> <!-- Le corps de page -->
<div id="corps">
<?php
// On met toujours un go to top, il y a un top au niveau du haut de la feuille, en_tete.php; juste sous le body
if ($langue == "E") print "<a href=\"#top\">Go to top</a>"; else print "<a href=\"#top\">Allez au début</a>";
?>
</div>
<!-- Le pied de page -->
<div id="pied_de_page"> <?php print($copyright); ?></div> </body>
</html>
1. nouvelEchantillon.php :
Cette page comprend deux grandes parties pour le moment : les informations sur la réception de l’échantillon initial, et les informations générales sur ce dernier. Les informations concernant son origine seront rajoutées après. Les informations générales sont donc son nom, son type, son unité de mesure, son conditionnement et un commentaire.
Figure 15a : Page « nouvelEchantillon.php »
Comme il y a la possibilité d’avoir plus d’un type pour un échantillon j’ai rajouté un bouton « Ajouter un autre type » qui à l’aide de JavaScript donne le résultat suivant quand on clique dessus :
Figure 15b: Aperçu de « nouvelEchantillon.php » en cliquant deux fois sur « Ajouter un autre type »
Lorsque l’utilisateur a fini de remplir les champs et qu’il clique sur « Valider » une vérification des champs obligatoires est faite via JavaScript. Si tout est correct, un récapitulatif des données qu’il a saisit s’affiche.
Figure 16: Boîte de dialogue JavaScript affichant le récapitulatif des données saisies dans le formulaire
S’il clique sur « OK » les données sont insérées dans la base. Dans le cas contraire il revient au formulaire pour modifier ce qui ne va pas.
S’il y a des champs obligatoires qui ne sont pas remplis, ces champs sont coloriés via une fonction JavaScript.
Figure 17: Aperçu de « nouvelEchantillon.php » lorsque les champs obligatoires nom, opérateur et type2 ne sont pas remplis
2. detruireEchantillon.php : La page detruireEchantillon.php ressemble à ceci :
Figure 18 : Page « detruireEchantillon.php »
Elle est donc faite en une seule partie Destruction pour renseigner sur les champs Nom de l’échantillon, Date de Destruction, Opérateur, Cause, Protocole et commentaire. Pour les champs Cause et Protocole la première liste déroulante propose des choix de valeur, si la cause ou le protocole ne se trouve pas dans la liste il faudra plutôt renseigner le champ de saisie à côté. Pour le remplissage du champ « date » j’ai utilisé un plug-in2 à la bibliothèque JQuery3. Ce plug-in
nommé « Calendar » permet de renseigner le champ date d’un formulaire à partir d’un calendrier.
Figure 19 : Plug-in « Calendar » à la bibliothèque JavaScript JQuery
1
Un plug-in est une bibliothèque complémentaire à une bibliothèque de base. 3
JQuery est une bibliothèque JavaScript qui permet de manipuler le DOM très facilement, de gérer les évènements, de créer des effets graphiques.
Voici le code HTML qui donne ce résultat :
<link rel="stylesheet" href="./style/jquery-calendar.css" type="text/css" /> //Feuille de style associé au calendrier <script type="text/javascript" src="./js/jquery.js" ></script>
<script type="text/javascript" src="./js/jquery-calendar.js"></script> <script type="text/javascript">
$(document).ready(function(){
popUpCal.regional['fr'] = {clearText: 'Effacer', closeText: 'Fermer', prevText: '<Préc', nextText: 'Proch>', currentText: 'En cours', dayNames: ['Di','Lu','Ma','Me','Je','Ve','Sa'], //définition du nom des jours
monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin', //définition du nom des mois
'Juillet','Août','Septembre','Octobre','Novembre','Décembre']}; popUpCal.setDefaults(popUpCal.regional['fr']);
//---
$('#date').calendar(); // le calendrier est appliqué sur le champ dont l’identifiant est date
});
</script>
Tous les champs dates du site sont paramétrés comme cela. 3. stockerEchantillon.php :
C’est cette page qui permet la saisie des données concernant le stockage d’un échantillon. Il ressemble à ceci :
Figure 20 : Page « stockerEchantillon.php »
Le formulaire comprend les champs Nom de l’échantillon, Date de Stockage, Opérateur, Type du lieu de Stockage et Lieu/Endroit. Pour remplir le champ Lieu/Endroit je me suis servi d’AJAX pour pouvoir recharger partiellement la page. L’utilisateur choisit d’abord le type du Lieu/Endroit, en fonction de son choix une requête AJAX est lancée pour récupérer les endroits qui sont de ce type dans la base de données. Je me sers après du résultat pour remplir la liste déroulante du champ Lieu/Endroit. Après quoi l’utilisateur choisira le Lieu où il voudra stocker son échantillon. Une nouvelle requête AJAX est lancée au serveur pour proposer ensuite les différents étagères et tiroirs qui sont contenus dans ce lieu s’il y en a.
La page est ainsi mise à jour dynamiquement sans qu’elle soit rechargée.
Voici un exemple qui montre l’entête du paquet envoyé au serveur via l’outil Firebug quand on choisit « Congelateur -80°C » pour le champ « type du Lieu/Endroit » :
Figure 21 : Firebug montrant l’entête d’une requête AJAX envoyée au serveur
Le code JavaScript permettant l’envoi de la requête AJAX est structuré comme suit :
function creationXHR() { //Permet de créer l’objet XMLHttpRequest() en fonction du navigateur
var resultat=null;
try { //test pour les navigateurs : Mozilla, Opéra, ...
resultat= new XMLHttpRequest(); }
catch (Error) {
try { //test pour les navigateurs Internet Explorer > 5.0
resultat= new ActiveXObject("Msxml2.XMLHTTP"); }
catch (Error) {
try { //test pour le navigateur Internet Explorer 5.0
resultat= new ActiveXObject("Microsoft.XMLHTTP"); } catch (Error) { resultat= null; } } } return resultat; }
function requeteAjax(type) { //Permet d’envoyer la requête Ajax //réinitialise la liste déroulante des lieux à chaque changement
document.getElementById("lieu1").options.length = 1; //cas où il n'y a pas de type sélectionné
if (type == "0") return null ;
objetXHR = creationXHR(); //création d'un objet XHR multi-navigateurs
//construction de la chaine des paramètres
// Code contenu permet de coder en UTF8 une chaine de caractère
var parametres = "type=" + codeContenu("type");
// Configuration de la méthode utilisée, du script serveur ciblé et désactivation du type asynchrone
objetXHR.open("post","./php_ajax/php_ajax.php", false);
objetXHR.onreadystatechange = actualiser ; //désignation de la fonction de rappel
objetXHR.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); objetXHR.send(parametres); //envoi de la requête
}
A l’aide de Firebug nous avons le résultat suivant pour l’exemple du dessus :
Figure 22: Firebug montrant les données envoyées au serveur par la requête AJAX
Le serveur renvoie les résultats sous format JSON (JavaScript Object Notation) qui est très pratique. JSON est la notation objet de JavaScript pour transmettre de l’information structurée. Voici l’aperçu donné par Firebug de la réponse du serveur:
Figure 23: Firebug montrant le résultat en format JSON du serveur à la requête AJAX
« Frigo A et frigo B » sont les congélateurs -80°C trouvés dans la base de données.
Le code PHP qui permet au serveur de traiter la requête est le suivant (fichier « php_ajax.php »): <?php
session_start() ;
//avec réponse sous format Texte structurée en objet JSON
//indique que le type de la réponse renvoyée au client sera du Texte header("Content-Type: text/plain ; charset=utf-8");
//anti Cache pour HTTP/1.1
header("Cache-Control: no-cache , private");
//anti Cache pour HTTP/1.0 header("Pragma: no-cache");
include("../include/Variable.php"); // Contient les variables globales include("../include/Utile.php"); // Contient les fonctions utiles include("../include/Database.php") ; //contient la classe Database //récupération du paramètre type
if(isset($_REQUEST['type'])) $type = $_REQUEST['type'];
else $type="Pièce"; //par défaut $connect = connection($base, $server) ;
if($connect == false) die("connection impossible");
else {
//Création et envoi de la requête SQL
$result = $connect->Query("SELECT place_id, name FROM place WHERE type_place ='".utf8_decode($type)."' ;" ) ;
//initialisation des variables
$debut = true;
echo "{\"listeLieu\":[";
//test si il y a des résultats if (pg_num_rows($result)){
//boucle sur les différentes lignes de résultats, permet de formater le résultat en JSON while ($row = pg_fetch_array($result)) {
//gestion de l'accolade du début if ($debut){ echo "{"; $debut = false; } else { echo ",{"; }
echo '"name":"' . utf8_encode($row['name']) . '" }'; $_SESSION['tableau'][$row['name']] = $row['place_id'] ; } //fin du while
} //fin du if
echo "]}"; //cloture le tableau et l'objet
$connect->Disconnect_database(); // Fermeture de la connexion à la base
}
?>
Voici le code JavaScript qui récupère la réponse du serveur et met à jour la page :
// fonction de rappel appelé dans la fonction requeteAjax, elle s’exécute quand le serveur retourne le résultat function actualiser(){
if (objetXHR.readyState == 4) { //test si le résultat est disponible
if (objetXHR.status == 200) { // signifie que la requête a été accompli avec succès
//récupère le résultat au format texte
var nouveauResultat = objetXHR.responseText;
//conversion de la chaine JSON en objet JSON
var objetJSON=nouveauResultat.parseJSON();
//Mise à jour du champ select qui contient le nom des lieux
for (var i=0; i<objetJSON.listeLieu.length; i++) {
var elementOption = document.createElement('option');
var texteOption = document.createTextNode(objetJSON.listeLieu[i].name); elementOption.setAttribute('value', objetJSON.listeLieu[i].name);
elementOption.appendChild(texteOption);
document.getElementById("lieu1").appendChild(elementOption); }
// Ce block permet de supprimer les champs créés pour permettre un nouveau choix du type du Lieu/Endroit If (document.getElementById("lieu1").childNodes.length > 1) { If (nblieu > 0) { while(nblieu > 1) { document.getElementById("nblieu").parentNode.removeChild(document.getElementById("lieu"+nblieu).parentNode); nblieu--; } nblieu = 0; }
nblieu ++; document.getElementById("nblieu").value = nblieu; if(document.getElementById("type").value != "Piece") document.getElementById("lieu1").onchange=function() { requeteAjax2(this.value); } else document.getElementById("lieu1").onchange= ""; } // fin du for } }}
Après ces opérations la page ressemble à ceci :
Figure 24: Aperçu de la page « stockerEchantillon.php » après les réponses aux requêtes AJAX
Comme pour la page « nouvelEchantillon.php » une vérification des champs obligatoires est faite et un récapitulatif des données saisies s’affiche quand on clique sur le bouton « Valider ».
4. traitement.php :
Cette page permet de saisir les informations concernant les divers traitements effectués sur les échantillons qui sont : transformation, division, prélèvement, fusion, groupement avec ou sans position. La page est divisée en trois grandes parties :
Une partie concernant les informations sur le traitement, une autre sur le ou les parents qui sont utilisés, et la dernière sur le ou les fils créés.
La première partie sur le traitement proprement dit :
Figure 25: Première partie de la page « traitement.php »
Les champs Opérateur, Nom, Valeur marchent de la même manière que le champ « type de l’échantillon » de la page « nouvelEchantillon.php » parce qu’on peut rajouter des opérateurs et des informations (Nom, Valeur).
Figure 26: Deuxième partie de la page « traitement.php »
Description sur les fils créés :
Figure 27a: Troisième partie de la page « traitement.php »
Figure 27b: Troisième partie de la page « traitement.php » en sélectionnant « Groupement avec
position » comme traitement
En fonction du « type de traitement » choisi, la deuxième partie et la troisième partie sont modifiées. En résumé pour ce qui concerne les traitements :
soit on a un seul parent utilisé et un ou plusieurs fils créés soit on a un ou plusieurs parents utilisés et un seul fils créé
Les modifications des parties deux et trois se font via une fonction JavaScript nommée « traitement » se trouvant dans le fichier « function.js ». Voici le code de cette fonction :
function traitement(option) {
//Permet de supprimer les contenus de la deuxième et troisième partie si un traitement est sélectionné if(option==1) {
… }
var ttt = document.getElementById("typettt").value; // récupère le traitement sélectionné
if(ttt == "Transformation") {
// La partie deux et trois sont rendus visibles
document.getElementById("echantillonParent").style.display="block"; document.getElementById("echantillonFils").style.display="block";
// Construit un seul parent en se servant du block 1 et 2 de la figure 26 ci-dessus
construireSaisieEchantillon(1, "block1", "block2", "parent_" ); //voir le code de cette fonction en annexe p43 // Construit un seul fils en se servant du block 3 et 4 de la figure 27a ci-dessus
construireSaisieEchantillon(1, "block3", "block4", "fils_" ); //voir le code de cette fonction en annexe p43
}
else if(ttt == "Division" || ttt == "Prelevement" ) {
if(option==1) document.getElementById("sp_nbfils").style.display="block";
else {
var nb = document.getElementById("nbfils").value; //récupère le nombre de fils à créer
document.getElementById("echantillonParent").style.display="block"; document.getElementById("echantillonFils").style.display="block";
// Construit un seul parent en se servant du block 1 et 2 de la figure 26 ci-dessus
construireSaisieEchantillon(1, "block1", "block2", "parent_" );//voir le code de cette fonction en annexe p43
// Construit nb fils en se servant du block 3 et 4 de la figure 27a ci-dessus
construireSaisieEchantillon(nb, "block3", "block4", "fils_" ); //voir le code de cette fonction en annexe p43
} }
else if(ttt == "Fusion") {
else {
var nb = document.getElementById("nbparent").value; //récupère le nombre de parents à utiliser
document.getElementById("echantillonParent").style.display="block"; document.getElementById("echantillonFils").style.display="block";
// Construit nb parents en se servant du block 1 et 2 de la figure 26 ci-dessus
construireSaisieEchantillon(nb, "block1", "block2", "parent_" );//voir le code de cette fonction en annexe p43
construireSaisieEchantillon(1, "block3", "block4", "fils_" ); //voir le code de cette fonction en annexe p43
} }
else if(ttt == "Groupement avec Position") {
// La partie trois est rendu visible voir figure 27b
document.getElementById("Plaque").style.display="block";
creerPlaque(); // crée un groupement avec position, voir en annexe p43
} }
Lorsque l’utilisateur choisi un parent dans la partie deux, une requête AJAX est lancée pour remplir les champs « Unité de Mesure » et « Quantité en Stock » du parent concerné.
5. Validation.php :
C’est sur cette page que sont envoyées les données des formulaires des autres pages. Et c’est cette page qui permet d’insérer les données dans la base de données.
Elle regroupe 4 fonctions PHP qui sont :
La fonction « insertionEchantillon » insère les données reçues de la page
« nouvelEchantillon.php ». Dans cette fonction on récupère les informations générales sur l’échantillon et l’identifiant du groupe connecté puis on l’insère dans la table « sample ». Pour les tables dont l’identifiant est auto-incrémenté (SERIAL en PostGreSQL voir la page 16), PostGreSQL crée automatiquement des séquences. Le nom de ces séquences est sous la forme « nomdelatable_nomdel’identifiant_seq ». En exécutant la requête ci-dessous, on a l’identifiant du dernier échantillon qui a été inséré.
$result = $connect->Query("SELECT last_value FROM sample_sample_id_seq;" ) ;
Avec l’identifiant et les informations sur la réception on insère les données dans la table « reception » par la requête :
$result = $connect->Query("INSERT INTO reception (sample_fid , operator_fid, date_reception, state) VALUES ($idEcht, $idOperateur, '$date', '$etat');" ) ;
Enfin on insère dans la table « sample_type » l’identifiant de l’échantillon et ses types. A chaque fois qu’il y a une nouvelle valeur pour les champs Etat, type, Unité de mesure, Conditionnement on insère cette valeur dans la table « dictionary ».
La fonction « detruireEchantillon » insère les données reçues de la page
« detruireEchantillon.php ». Dans cette fonction, on récupère les données du formulaire dans des variables PHP et après on fait l’insertion avec la requête suivante :
$result = $connect->Query("INSERT INTO destruction (sample_fid, operator_fid, date_destruction, reason, protocol, comment ) VALUES ($idEcht, $idOperateur , '$date', '$cause', '$protocole', '$commentaire');" ) ;
Après cela on met à jour l’attribut « destroyed » dans la table « sample » par la requête :
La fonction « stockerEchantillon » insère les données reçues de la page « stockerEchantillon.php ».
CONCLUSION :
Mon stage à l’INRA se déroule bien. Il me reste encore un mois pour arriver à bout de mon travail. Par rapport au cahier des charges je pense que j’ai bien avancé. Je suis au point 2 « la réalisation des pages de sorties des résultats ». Je pense donc arriver au point 3 de ce cahier des charges qui est « la réalisation de la page de saisie des analyses et l’adaptation aux pages des résultats ». La semaine prochaine le site web sera en phase de test auprès des utilisateurs.
Pour moi ce stage est ma première expérience en entreprise. Et pour une première expérience je me suis bien débrouillé. Ce stage m’a permis d’avoir une ouverture sur des connaissances
biologiques et la manière dont fonctionne une entreprise. J’ai eu à visiter des forums de
développement, et à lire quelques livres pour assimiler le langage JavaScript, la technologie AJAX, et à approfondir mes connaissances en PHP. J’ai eu à manipuler aussi la documentation de PHP pour la recherche de détails sur certaines fonctions.
J’ai été confronté à certaines difficultés comme la planification de mon travail, la rédaction de compte rendu de réunions, l’adaptation à PgAdmin l’interface qui permet d’administrer la base de données sous PostGreSQL. J’ai eu à faire plein de synthèses puisque les utilisateurs de l’application n’opèrent pas de la même façon. Une des difficultés étaient de simuler les données dans la base lors de la phase de conception pour voir si elle pourra répondre aux questions qui lui seront posées. Comme avantage de ce stage j’ai eu à chercher des mots en anglais, ce qui m’a permis d’agrandir mon vocabulaire avec des mots comme « sample », « qualifier », « conditioning », « initial » …
La réalisation du projet dans son intégralité est un atout majeur pour mes futurs projets que j’aurai à faire. J’ai eu à consacrer 3 semaines sur les parties analyse et conception, et 4 semaines sur le développement de l’application web.