• Aucun résultat trouvé

Base de données et site web sur la gestion d'échantillons

N/A
N/A
Protected

Academic year: 2021

Partager "Base de données et site web sur la gestion d'échantillons"

Copied!
47
0
0

Texte intégral

(1)

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�

(2)

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

(3)

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.

(4)

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

(5)

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.

(6)

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.

(7)

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é.

(8)

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.

(9)

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.

(10)

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

(11)

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.

(12)

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

(13)

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 :

(14)
(15)

2. Modèle Logique de Données (MLD) :

Figure 7 : Modèle Logique de Données de la base

(16)

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

(17)

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)

(18)

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

(19)

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 ,

(20)

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.

(21)

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

(22)

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.

(23)

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

(24)

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. */

(25)

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 &#169; 2008<br>INRA<br>Tous droits r&eacute;serv&eacute;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());

(26)

$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>");

(27)

?>

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>' );

}

(28)

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.

(29)

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.

(30)

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

(31)

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.

(32)

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: '&lt;Préc', nextText: 'Proch&gt;', 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 » :

(33)

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");

(34)

// 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)."' ;" ) ;

(35)

//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 } }}

(36)

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).

(37)

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 »

(38)

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") {

(39)

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 :

(40)

 La fonction « stockerEchantillon » insère les données reçues de la page « stockerEchantillon.php ».

(41)

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.

Figure

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
Figure 4 : Exemple d’un cas concret d’échantillons
Figure 6 : Modèle Conceptuel de Données de la base
Table Sample :
+7

Références

Documents relatifs

[r]

Recherche des valeurs possibles de x : Dans un problème d’inconnue x, l’inconnue ne peut parfois pas prendre toutes les valeurs réelles, soit parce qu’on a un quotient dont

Alors le poids de Merlin

[r]

3– Déterminer la taille et la position de l’image.. 4– Déterminer la taille et la position

Les résultats ne montrent pas de marquage particulier et les niveaux de plomb sont inférieurs aux valeurs de références existantes applicables pour des logements.. Elles

Remarque : au passé composé, le participe passé avec l’auxiliaire « avoir » s’accorde en genre et en nombre si le COD est placé avant le

Hier soir, j’ai appelé ma sœur pour ______ parler d’un problème et ______ demander un conseil, mais elle n’a pas répondu donc je ______ ai laissé un message. Puis, j’ai