Ce devoir reprend les notions introduites au devoir
1, telles que la programmation de pages dynamiques ou la gestion des
sessions, et y rajoute l'interfaçage avec une base de
données et un peu de scripting côté
client.
Pour réaliser cette application, vous allez
procéder en suivant les étapes suivantes :
Une petite entreprise possède un stock d'articles,
identifiés chacun par une référence
unique. Elle tient également à jour une liste de clients qui
achètent ces articles. Le croisement des articles et des
clients correspond à la liste des achats
effectués.
Deux types d'employés sont considérés
ici :
Dans ce devoir, vous allez réaliser une petite application
de gestion de stocks en PHPMySQL, permettant la gestion conjointe des
articles, des clients et des achats, et présentant des
fonctionnalités différentes en fonction des
autorisations données aux commerciaux et aux comptables.
En fonction de ces autorisation, les différents utilisateurs
pourront accéder aux interfaces suivantes :
L'image ci-dessous présente un exemple de ce que pourrait
être l'une des interfaces de modification pour un vendeur.
La première chose à faire est de créer la base, les tables et les utilisateurs de votre base de données MySQL. Pour cela, vous utiliserez l'interface d'administration de votre serveur PHP-MySQL.
CREATE
TABLE
`articles`
(
`nom`
VARCHAR(
50
)
NOT
NULL
,
`description`
VARCHAR(
200
)
,
`prix`
FLOAT
NOT
NULL
,
PRIMARY
KEY
(
`reference`
)
CREATE
TABLE
`clients`
(
`nom`
VARCHAR(
100
)
NOT
NULL
,
`prenom`
VARCHAR(
100
)
NOT
NULL
,
`adresse`
VARCHAR(
200
)
NOT
NULL
,
`codepostal`
INT
UNSIGNED
NOT
NULL
,
`ville`
VARCHAR(
100
)
NOT
NULL
,
`pays`
VARCHAR(
50
)
DEFAULT
'France'
NOT
NULL
,
`telephone`
VARCHAR(
50
)
,
PRIMARY
KEY
(
`numero` )
CREATE
TABLE `achats` (
`id_achat` INT NOT NULL
AUTO_INCREMENT
,
`id_client` INT NOT NULL ,
`id_article` INT NOT NULL ,
`quantite` INT NOT NULL ,
`date` DATE NOT NULL ,
PRIMARY KEY ( `id_achat` ),
INDEX (`id_article`),
FOREIGN KEY (`id_article`)
REFERENCES articles(`reference`)
ON UPDATE CASCADE ON DELETE RESTRICT,
INDEX (`id_client`),
FOREIGN KEY (`id_client`)
REFERENCES clients(`numero`)
) ENGINE=INNODB;
Une fois ces trois tables créées, utilisez l'interface d'administration pour examiner leurs structure et comprendre la sémantique sous-jascente.
Remarque : compte tenu des contraintes données sur les clés étrangères, les champs à utiliser pour les jointures sont les suivants : le numéro de client et la référence d'un article sont respectivment représentés dans la table d'achats par "id_client" et "id_article". Par exemple, pour obtenir toutes les informations relatives aux différents achats, on formulera une requête du type :
SELECT * FROM achats, clients, articles WHERE achats.id_client = clients.numero AND achats.id_article = articles.reference;
Vous allez maintenant réaliser le coeur de votre application. La logique applicative se compose de trois parties : la connexion de l'utilisateur et la mémorisation de ses privilèges, l'insertion de données dans la base et la consultation des données.
Chacune de ces trois parties sera réalisée par une ou plusieurs pages PHP, qui peuvent éventuellement faire appel à d'autres pages pour les fonctions standard de connexion et de déconnexion à la base pour l'envoi des requêtes. Ci-dessous sont décrites les fonctionnalités à implémenter pour chaque partie. Les pages et éléments d'interface statiques sont décrits plus loin.
Cette partie se compose d'un formulaire de connexion et d'une page de traitement des données envoyées par ce formulaire.
Formulaire de connexion (page d'accueil de l'application) : il s'agit d'une page PHP comportant le nom de votre application, un formulaire XHTML simple (des champs login et mot de passe et un bouton de validation), plus éventuellement un message d'erreur passé en paramètre, si la tentative de connexion précédente s'est mal passée.
Page de traitement : À la réception d'une requête HTTP provenant du formulaire de connexion, cette page utilisera les paramètres de cette requête pour effectuer une demande de connexion au serveur de BD (Aide : https://www.w3schools.com/php/php_mysql_connect.asp ; je vous conseille d'utiliser mysqli en procédural), et réagira en fonction de la réponse de celui-ci :
Indiquez clairement dans votre code la requête envoyée à la base pour déterminer le type d'utilisateur.
Cette partie gère l'ajout et la modification des données de la base. Elle est réservée aux utilisateurs possédant des privilèges de vendeur. Elle fonctionne sur le même principe pour les trois tables de la base : si l'utilisateur souhaite effectuer une modification d'un enregistrement existant, il commence par le sélectionner. Ensuite, il accède à un formulaire de saisie (rempli ou non, en fonction de l'action - insertion ou modification - à effectuer), et envoie les données à une page de traitement qui se charge de l'insertion ou de la modification.
Formulaire de choix d'un item (modification) : ce formulaire présente simplement la liste des enregistrements de la table concernée, et propose un lien vers le formulaire de saisie, avec un paramètre contenant l'id de l'enregistrement choisi.
Formulaire de saisie (insertion et modification) : ce formulaire permet à l'utilisateur de saisir les valeurs des différents champs de chaque table (il est donc spécifique au format de cette table) ; s'il reçoit en paramètre l'id d'un des enregistrements de la table, il sera pré-rempli aux valeurs de cet enregistrement.
Remarques :
Page de traitement : cette page reçoit la requête HTTP du formulaire de saisie et va :
Cette partie est constituée d'une unique page PHP, qui reçoit une requête HTTP de consultation sur une table, récupère les données correspondantes dans la base et génère une page web pour les afficher à l'utilisateur.
Remarque : l'affichage de la table des achats fera apparaître, en plus des données de cette table, le nom du client et de l'article impliqués dans l'achat, le prix unitaire de cet article, et le prix total de l'achat.
L'interface proposée
à tous les utilisateurs sera structurée de la
façon suivante :
Concernant les langages utilisés, vous réaliserez vos pages de façon à ce que le client reçoive du XHTML strict, c'est-à-dire n'incluant pas d'éléments ou d'attributs de mise en forme. Une feuille de style CSS commune pour toute votre application sera fournie dans un fichier à part. Vous pouvez toutefois utiliser des attributs de style CSS dans le contenu de votre page, si cela s'avère nécessaire.
L'image donnée plus haut est un exemple vous donnant une idée de la structure de cette interface, mais vous êtes libre de la structurer comme bon vous semble. Dans tous les cas, il vous est demandé de ne pas utiliser de cadres. Vous fonctionnerez avec des éléments table ou div, pour positionner les trois parties de l'interface, et localiserez les traitements correspondants dans d'autres fichiers PHP, inclus dans la page courante grâce à la directive PHP include.
De façon à alléger un peu le travail du serveur tout en conservant un contrôle des erreurs de saisie, vous allez rajouter quelques fonctions JavaScript - dans un fichier à part - qui vont permettre de valider les contenus saisis dans les formulaires du côté client.
Pour cela, vous devez d'une part écrire ces fonctions, puis compléter le code XHTML pour indiquer les événements qui les déclencheront (Aide : http://openweb.eu.org/articles/validation_formulaire/)
Pour vous entraîner, commencez par ne repérer que les champs vides. Écrivez ensuite une fonction qui renvoie vrai si une chaîne de caractères est numérique et faux sinon. Créez-en ensuite d'autres, pour valider les champs entier, prix, code postal...
Question subsidiaire : vous pouvez aussi rajouter d'autres scripts, par exemple pour déployer automatiquement les menus quand vous passez dessus avec la souris, ou pour trier dynamiquement les tableaux de données par ordre croissant ou décroissant pour un champ donné. Vous trouverez de nombreux exemples de scripts à adapter sur http://www.toutjavascript.com/ et sur http://www.javascriptfr.com/.
Le code (correctement commenté) de la dernière version du devoir sera compressé dans un fichier au format ZIP.
Vous enverrez ce fichier par courriel à Lionel Médini (lionel.medini _at_ univ-lyon1.fr). J'accuserai réception de vos messages pour vous signifier que je les aurai bien reçus et que les pièces jointes sont ouvrables. Le fait d'avoir reçu un accusé de réception à votre envoi ne signifie pas que le devoir a été corrigé, ou qu'aucun des fichiers de votre application ne manque.
L'objet du message devra impérativement contenir les mots "e-Miage", "C216", "rendu" et "devoir 2", ainsi que vos nom et prénom.