Widgets
Fonctionnalités
Les widgets suivants sont disponnibles :
- des listes d'éléments avec possibilité d'un choix "autre"
- des zones de textes longues ou courtes
- des boutons radio
- des cases a cocher
- des cases a cocher
- des listes à choix multiples
Les widgets sont des objets PHP5 qui gèrent la validation des données, leur enregistrement en base de donnée, l'affichage des valeurs par défaut et des erreurs.
Introduction
La mise en oeuvre du système est très simple: on commence par instancier le widget qu'on veur afficher, on lui associe un label (un texte explicatif correpondant généralement à la balise <label> en HTML) et on l'affiche le plus simplement du monde. Cela donne en gros :
<?php $widget = new WidgetXyz("name", "id", $session_id); $label = new Label($widget, "texte"); ?> ... <!-- Dans le code HTML --> <?php $label->printHtmlCode(); ?>
Instructions détaillées
Le système se décompose ainsi :
- un dossier lib/ contenant les fonctions et classes PHP
- un dossier bdd/ contenant la base de données SQLite
- un dossier templates/ contenant les templates des pages du site et du questionnaire
Dans le dossier racine se trouvent quelques fichiers php qui sont les points d'entrée du système. Ces fichiers en général font trois choses :
- inclusion des fichiers de lib nécessaires via un include_once(dirname(__FILE__).'/lib/my-lib.php');
- préparation des données pour le templace
- appel du templace (via un include similaire)
Cette structure, je l'ai utilisée pour beaucoup de sites en PHP et permet de facilement séparer le code PHP générique, du code PHP lié à une page spécifique et le code HTML (le template).
Les templates sont des fichiers contenant presque que du HTML avec de temps en temps des structures comme celle-ci :
<table> <caption>éléments</caption> <tr><th>A</th><th>B</th></tr> <?php foreach($elements as $l){ ?> <tr><td><?php phtml($l['A']) ?></td><td><?php phtml($l['B']) ?></td></tr> <?php } ?> </table>
Le code PHP est minimal ce qui permet de facilement voir ce qui se passe. Pour afficher des valeurs dans du code HTML, j'ai développé plusieurs fonctions permettant de traiter les caractères spéciaux :
- html() : alias de htmlspecialchars() qui encode les entitées <, > et &
- urlhtml() : alias de htmlspecialchars(urlencode()) encode les entitées HTML et les caractères pour les URL.
- phtml() : alias de print(html())
- purlhtml() : alias de print(urlhtml())
Ces fonctions se situent dans lib/common.php
Maintenant comme cela ne suffisait pas pour faire des questionnaires (le code HTML devenait inmaintenable, surtout dés qu'il fallait gérer l'affichage des erreurs et le remplissage des valeurs par défaut). Pour cela, j'ai donc créé un système de widgets qui s'utilisent de la manière suivante :
Le fichier servant de point d'entrée au questionnaire va inclure tout d'abord les widgets dont il a besoin. In va ensuite instancier les classes widget pour créer les différents widgets. Par exemple :
-
Une entrée de texte :
$my_widget = new WidgetEntry("nom du widget", "id du widget", $form_id);
-
Un ensemble de boutons radio :
$w1_gender = new WidgetRadios("info.gender", "f.info.gender", $form_id); $w1_gender->addItem('M', 'M'); $w1_gender->addItem('Mme', 'Mme'); $w1_gender->addItem('Mlle', 'Mlle'); $w1_gender->addItem('Valeur envoyée', 'Valeur affichée');
- Ainsi de suite ...
Vous pouvez voir une valeur $form_id envoyée au constructeur. Cette valeur est un numéro qui correspond grosso-modo a une session utilisateur. Elle sera insérée dans la base de données avec chaque réponse donnée.
Une fois les widgets créés, des labels vont être associés à chaque widget. Différents types de labels existent en fonction du rendu HTML que l'on souhaite avoir. Par exemple :
$l1_gender = new LabelMin($w1_gender, "Sexe :");
Ensuite, en fonction de la page qui vient d'être postée, les widgets de cette page sont insérés dans la base de donnée (la validation est automatique, il est possible de sous-classer un widget pour avoir une validation plus précise). Cela se fait ainsi :
$widget->insertDatabaseFrom($_POST)
Cette méthode retourne false en cas d'échec de validation ou de base de donnée, true sinon (ou renvoie une exception pour toute autre erreur). Le message d'erreur éventuel est stocké dans l'objet.
Ensuite tout est automatique. Si il y a eu une erreur, on ne passe pas à la page suivante (et lors de l'affichage du widget, le message d'erreur sera affiché). Si tout s'est bien passé, la page suivante du formulaire est affichée.