Documentation développeur
Ce document est destiné aux personnes susceptibles de participer au développement de GENEPI. Il présente l'ensemble des modules existants par défaut dans GENEPI (les modules installés avec l'application) d'un point de vue développeur. Ceci afin de permettre à toutes les personnes intéressés dans le développement de GENEPI de connaitre le fonctionnement de ces modules afin de pouvoir interagir avec ceux ci dans les futurs développements.
Sommaire:
I - Base de données
II - Noyau
III - Authentification
IV - Configuration
V - Gestion de la Structure
VI - Gestion des Animateurs
VII - Gestion des Utilisateurs
VIII - Usages
IX - Tableau de bord
X - Statistiques
I - Base de données
La base de données a été développée grâce à la méthode MERISE.
Ci-après sont présentées chaque table avec leur description et les liens qu'elles ont avec les autres tables:
Nom de la table |
Description |
Rattachée à |
|---|---|---|
| Computer |
Enregistrement de toutes les informations relatives à un ordinateur de la structure. |
|
| Computer_type_of_connexion |
Enregistrement des types de connexion possibles. |
|
| Computer_machine_type |
Enregistrement des types de machine possibles. |
|
| Computer_os |
Enregistrement des noms des systèmes d'exploitation possibles, pour une famille donnée. |
|
| Computer_os_family |
Enregistrement des familles des systèmes d'exploitation possibles. |
|
| Structure |
Enregistrement des informations relatives à la structure qui utilise le progiciel. |
|
| Address |
Enregistrement d'une adresse, avec un numéro de téléphone. |
|
| Address_city |
Enregistrement d'une ville et du code postal associé. Chacun de ces couples est associé à un pays. |
|
| Address_country |
Enregistrement des pays. |
|
| Building |
Enregistrement des infor mations relatives à un bâtiment de la structure. |
|
| Room |
Enregistrement des informations relatives à une pièce d'un bâtiment de la structure. |
|
| User |
Enregistrement des informations relatives à un utilisateur de l'espace. |
|
| User_seg |
Enregistrement des SEG (Socio-Economic Groups), c'est-à-dire les CSP en français. |
|
| User_awareness |
Enregistrement des moyens de connaissance de la structure. |
|
| User_gender |
Enregistrement du sexe de l'utilisateur. |
|
| Act |
Enregistrement de toutes les informations relatives à un acte prédéfini. |
|
| Act_type |
Enregistrement des types d'actes par défaut. |
|
| Act_price |
Enregistrement du prix d'un acte pour une catégorie de public donnée. |
|
| Act_public_category |
Enregistrement des différentes catégories de public. |
|
| Unity |
Enregistrement des différentes unités disponibles. |
|
| Imputation |
Enregistrement de toutes les informations relatives à l'imputation d'un acte prédéfini ou non à un utilisateur. |
|
| Imputation_method_of_payment |
Enregistrement des méthodes de paiement disponibles. |
|
| Imputation_account_transaction |
Enregistrement des informations relatives à une transaction sur un acompte. |
|
| Imputation_purchase |
Enregistrement des informations relatives à un achat. |
|
| Imputation_countable_service |
Enregistrement des informations relatives à un service dénombrable. |
|
| Imputation_unitary_service |
Enregistrement des informations relatives à un service unitaire. |
|
| Imputation_subscription |
Enregistrement des informations relatives à un abonnement. |
|
| Moderator |
Enregistrement des informations relatives à un animateur. |
|
| Login |
Enregistrement des couples identifiant/mot de passe. |
|
| Account |
Enregistrement des informations relatives à un acompte. |
|
| Account_user |
Table permettant de faire le lien entre un acompte et son ou ses possesseur(s). |
|
| Financier |
Enregistrement des informations relatives à un financeur de la structure. |
|
| Imputation_archive |
Table servant à la génération de statistiques portant sur les usages. |
|
| User_archive |
Table servant à la génération de statistiques portant sur les utilisateurs. |
Haut de page
II - Noyau
Objectifs du module
L'objectif principal du module noyau est de dérouler une routine de démarrage à chaque lancement de l'application. Cette routine a plusieurs buts:
- . Déterminer quels modules sont installés
- . Déterminer leurs dépendances et vérifier qu'elles sont satisfaites
- . Charger les modules installés dont les dépendances sont satisfaites
- . Charger les langues installées
- . Démarrer l'application ou bien afficher des messages d'erreur indiquant ce qui est à corriger
- . Permettre l'ajout et suppression de plugin complémentaires développés par des tiers
Principaux concepts
Dans le module noyau, plusieurs concepts sont utilisés, ils sont présentés et expliqués dans ce paragraphe.
Nom du concept |
Description |
|---|---|
| Module |
Un module est un ensemble de fonctionnalités regroupés au sein d'une entité logique à part entière du fait d'une cohérence entre ces fonctionnalités. Les caractéristiques d'un module sont:
|
| Module installé |
Un module installé est un module qui n'est pas nécessairement disponible dans l'application car ses dépendances ne sont pas satisfaites. |
| Module activé |
Un module activé est un module fonctionnel et disponible au sein de l'application via une entrée dans le menu principal ou non. |
| style="border: 1px solid black">Ta ble des modules installés |
A l'initialisation de l'application, le noyau monte une table des modules installés qui contient tous les modules installés de l'application. Le noyau met à jour cette table lors de l'ajout ou suppression d'un module supplémentaire. |
| Table des modules activé |
A l'initialisation de l'application, le noyau monte un contexte (voir section suivante) pour l'application qui sera maintenue durant toute la durée d'éxécution. La table des modules activés fait partie de ce contexte pour permettre ainsi son utilisation dans toute l'application. |
| Table des dépendances |
La table des dépendances regroupe l'ensemble des dépendances pour chaque module installé. Elle permet ainsi de savoir quelles dépendances sont satisfaites ou non. La table des dépendances fait partie du contexte de l'application. |
| Dépendance |
Un module peut avoir une ou plusieurs dépendances, c'est à dire d'autres modules nécessaires à sa bonne exécution. |
| Zone d'erreurs |
A l'initialisation, le noyau récolte toutes les erreurs qui sont survenues et les stocke dans une zone d'erreurs qui fait partie du contexte de l'application. Ceci permet d'afficher les erreurs de manière explicite pour l'utilisateur afin qu'il sache exactement comment les résoudre. |
Architecture
L'architecture en classes du module noyau est représentées ci-dessous:
Nom de la classe |
Fonction |
|---|---|
|
Kernel Properties - abstraite |
Répertorie tous les attributs du module noyau avec les sélecteur et les mutateurs associés. Elle comprend également des méthodes destinées vider ces attributs; ces méthodes servent pour les tests et sont préfixées par « flush ». |
|
Kernel - abstraite - hérite de KernelProperties |
Répertorie les méthodes qui sont appellées au cours de la phase d'initialisation de l'application. |
|
KernelInstance - hérite de KernelProperties |
Classe destinée à être instanciée en fin d'initialisation de l'application afin qu'un objet de type Kernel « réduit » puisse être appellé depuis les autres modules. |
|
KernelContext |
Classe de configuration du contexte de l'application « mgmt ». |
|
Module |
Classe dont une instance représente un module de l'application. |
Solutions
Configuration
La configuration du noyau s'appuie sur deux types de fichiers distincts, tous deux au format xml:
- . Un fichier de configuration présentant une « interface » de l'application: ApplicationsCommonInterface.xml. Ce fichier résumé les différentes applications installées (applications est à prendre ici dans le sens symfony du terme), qui sont au nombre de 2 (« core » et « mgmt ») ainsi que les modules appartenant à ces applications. Le nombre de modules pour « core » est fixe à 3 alors que pour « mgmt », ce nombre est variable mais ne peut pas descendre en dessous du nombre de modules obligatoires.
Structure du fichier ApplicationsCommonInterface.xml
<applications>
<application id=[id_de_l_application]>
<name>nom_de_l_appliation</name>
<path>chemin_relatif_de_apps</path>
<module id=[id_du_module]>
<name>nom_du_module<name>
<path>chemin_relatif_du_chemin_de_l_application</path>
<compulsory>yes_or_no</compulsory>
<module_menu_name>nom_entree_menu_principal</module_menu_name>
</module>
</application>
</applications>
En dehors du nom, du chemin du dossier du module, du caractère obligatoire ou non et de nom de l'entrée menu (vide si le module n'a pas d'entrée dans le menu), on remarque que l'on peut aisément ajouter des caractéristiques dans ce fichier.
Ce fichier a une classe PHP dédiée à sa lecture: ApplicationsCommonInterface.class.php qui se situe à la racine du dossier apps/ et qui contient toutes les méthodes nécessaires à la lecture et l'écriture du fichier, on retiendra:
- . ApplicationsCommonInterface::getApplications() qui renvoie un tableau des chemins des applications, indexé par le nom de ces applications.
- . ApplicationsCommonInterface::getModulesByApp() qui attend un nom d'application en paramètre et qui renvoie un tableau des chemins des modules, indexé par le nom de ces modules.
- . ApplicationsCommonInterface::getModuleProperty() qui attend un nom de module et un nom de propriété pour un module et qui renvoie la valeur de cette propriété.
- . ApplicationsCommonInterface::addModule() et ApplicationsCommonInterface::removeModule() qui permettent d'insérer et de supprimer une entrée sous l'application « mgmt ».
-
. Un fichier par module résumant les dépendances de ce module vis à vis des autres modules (installés, activés ou non): nom_du_module.dependencies.xml.
Structure du fichier nom_du_module.dependencies.xml
<dependencies>
<dependency>
<module>nom_du_module</module>
</dependency>
</dependencies>
Dans la première version du logiciel, un seul type de dépendance est manipulé: une dépendance vis à vis d'un autre module. Cependant, la structure du fichier est telle qu'il est possible d'ajouter de nouveaux types de dépendances, moyennant quelques ajustations du code source.
La principale méthode utilisée pour lire ce fichier (on écrit jamais dans ce fichier) est Kernel::askForDependencies() qui lit le fichier de configuration d'un module dont on a passé le nom en paramètre et qui renvoie un tableau contenant la liste de toutes les dépendances de ce module. En regroupant ce tableau avec la liste des modules installés obtenus auparavant dans ApplicationsCommonInterface.xml, on peut ainsi construire la table des dépendances qui sera ajoutée en tant que variable de contexte.
La même méthode, pour chaque dépendance trouvée, regarde si celle-ci est satisfaite (i.e le module requis est installé), si ce n'est pas le cas, elle place cette dépendance dans la liste des dépendances non satisfaites qui sera ajoutée au contexte.
Modules
Dans le cadre du progiciel, un module peut être de type obligatoire ou non. Un module possède également un statut, parmis les 3 possibles:
- . Inexistant: le dossier du module n'est pas présent dans le répertoire approprié ou bien l'utilisateur n'a pas lancé l'installation du module.
- . Installé: l'utilisateur a voulu ajouter le module a son application mais ce module rencontre des problèmes des dépendances non satisfaites, il n'est donc pas disponible dans l'application.
- . Activé: le module a été installé par l'utilisateur et ne rencontre pas de problèmes de dépendances non satisfaites, il est donc accessible dans l'application.
Lorsqu'un module est installé, il sera activé automatiquement dès que ses dépendances seront toutes satisfaites.
Pour toute opération concernant l'ajout/suppression des modules supplémentaires, un redémarrage de l'application est nécessaire. Pour cela, une action est prévue: module: startup, action: init (ou route « homepage »).
Un module obligatoire n'est pas déchargeable.
Structure d'un module complémentaire (plugin)
Un plugin doit impérativement se présenter sous la forme d'un dossier unique dans lequel se trouvent 2 sous-répertoires obligatoires et 1 falcutatif:
- . actions: contient les contrôleurs du module (classe des actions et eventuellement classe des composants)
- . La classe des actions doit étendre de sfActions et la classe des composants de sfComponents.
- . Il doit y avoir une méthode par action.
- . Le nom de la méthode doit être préfixé par execute suivi du nom de l'action, le tout en camel-cased.
- . templates: contient les templates du module
- . Un template par action ou composant
- . Nom des templates action: commencent par le nom de l'action suffixé par Success, le tout en camel-cased.
- . Nom des templates composants: le nom du composant en minuscule, préfixé par un caractère de soulignement (« _ »).
- . web: contient des ressources web telles que images, feuilles de style CSS ou scripts javascript. L'organisation de ce dossier est laissé à l'appréciation du concepteur du module. Aucun mécanisme n'est prévu pour inclure les feuilles de style et les scripts automatiquement dans les pages du module complémentaire.
Le répertoire du plugin doit également contenir à sa racine un fichier monPlugin.dependencies.xml (ou monPlugin est le nom du répertoire) qui contient les dépendances du plugin (cf section précédente pour plus d'informations sur ce fichier).
Table des modules installés
L'ensemble des modules installés se retrouvent dans une table des modules installés qui se matérialise sous la forme d'un tableau. Ce tableau est complété durant l'appel à la méthode Kernel::initialize() pendant la phase d'initialisation de l'application. Ce tableau sert à l'initialisation mais peut être récupéré autre part dans l'application car elle est ajoutée au contexte. La méthode Kernel::initialize() ne doit pas être modifiée.
Table des modules activés
L'ensemble des modules activés de l'application sont ajoutés dans une table des modules activés qui se matérialise sous la forme d'un tableau. Ce tableau est ajouté au contexte de l'application « mgmt » et peut donc être récupéré et modifié dans toute action de l'application. Cependant, une attention toute particulière devra être prise pendant sa modification car le risque de provoquer une erreur est grand si un module inexistant ou simplement dans l'état « installé » est ajouté au contexte.
Ce tableau est obtenu à partir du tableau des modules installés à l'aide de la méthode Module::checkAll(). Cette méthode ne doit pas être modifiée.
Table des dépendances
La table des dépendances regroupe l'ensemble des dépendances de chaque module. Elle est obtenue à partir de la table des modules installés à l'aide de la méthode Kernel::buildDependenciesTable(). Cette méthode ne doit pas être modifiée.
Cette table est ensuite ajoutée au contexte de l'application « mgmt » afin d'être récupérée notamment dans la page de configuration. Cette table ne doit pas être modifiée, cependant, aucun mécanisme de sécurité afin de protéger cette table en écriture n'est prévu.
Gestion des cultures
Au cours de la phase d'intialisation du noyau, la méthode getInstalledCultures() est apellée. Elle prend en paramètre un objet de la classe sfApplicationConfiguration qui doit contenir la configuration de l'application « mgmt ». Cette méthode retourne la liste des langues supplémentaires disponibles (i.e un dossier pour cette langue est présent dans le dossier « i18n » de « mgmt ») sous la forme d'un tableau de chaines qui représentent les codes des langues (« fr », « de », …).
Par la suite, cette liste est concaténée avec le code « en » (qui représente la langue anglaise, langue de dévéloppement par défaut de l'application). Cette liste totale est ensuite passée à la méthode Symfony sfWebRequest::getPreferredCulture() qui détermine la meilleure langue parmis toutes celles installées pour l'utilisateur qui vient de démarrer l'application.
Instance de Noyau
Une fois l'application initialisée, une instance de noyau est créée et ajoutée au contexte de l'application « mgmt » afin qu'elle puisse être accessible dans le reste de l'application. Cette variable est une instance de la classe KernelInstance. qui contient:
- . La table des dépendances
- . La table des modules installés
- . Les dépendances non satisfaites
- . Une librairie de méthodes pour permettre aux modules de logguer leurs actions (voir la section Log Library de la classe KernelInstance).
Haut de page
III - Authentification
Objectifs du module
Le module d'authentification doit permettre:
- . L'ouverture/Fermeture de session
- . Le cryptage du mot de passe
- . Le suivi et protection de la session
- . Le log des événements d'authentification
- . La gestion des droits de 2 types d'utilisateurs: animateurs et viewers
Outils offerts par le Framework Symfony
La gestion des droits
Symfony différencie deux types de droits:
- . Les droits des utilisateurs authentifiés
- . Les droits propres à chaque utilisateurs, définis par les « credentials »
La définition de ces règles est réalisée de la même manière pour une application que pour un module.
A la racine de l'application, on ajoute un dossier /config/ dans lequel on créé un fichier security.yml.
La définition des règles d'accès se réalise par l'édition du fichier security.yml de la manière suivante:
|
default: |
Pour ajouter ces droits à un utilisateur, on utilise les méthodes:
|
$myUser->setAuthenticated(true); |
La gestion des droits est expliquée plus précisément à l'adresse suivante.
Les accès non-autorisés
|
all: |
|
all: |
Les variables d'une session
Des méthodes proposées par Symfony permettent l'ajout de variable de session accessible depuis n'importe quelle page au cours de la session. Par exemple, pour connaître le nom de l'utilisateur durant sa session, on déclarera:
|
$myUser->setAttribute('test', $name); |
Et on récupérera cette information de la façon suivante:
|
$myUser->getAttribute('test'); |
Les méthodes spécifiques à GENEPI
La classe UsersAuth
Une classe UsersAuth a été développée (dans une lib du module auth) afin de fournir aux modules les méthodes nécessaires à la gestion de session des utilisateurs.
Le menu de configuration
Le menu de configuration doit être affiché uniquement si l'utilisateur est un animateur. Il doit être masqué si l'utilisateur est un viewer. Cette fonction est codée dans le layout. Il fait appel à librairie UsersAuth afin de savoir si l'utilisateur est animateur ou non.
Le menu principal
Dans le menu principal, seules les entrées vers les modules autorisés doivent apparaitre.
Le layout (layout.php) compare donc les credentials requis pour accéder à chacun des modules à ceux de l'utilisateur courant. Le code qui permet cette comparaison est celui ci:
|
$context=sfContext::getInstance(); |
L'affichage du Nom et Prénom de l'utilisateur
L'affichage dans le layout du nom et prénom de l'utilisateur courant est réalisé par les méthodes getname() et getSurname() de la classe usersAuth. Elles permettent la récupération des informations de sessions déclarées à l'authentification.
Les logs des évènements d'authentification
Pour la génération des logs on utilise les méthodes fournies par le kernel.
On logge les erreurs d'authentification dans le fichier error.log et les succès dans info.log.
Haut de page
IV - Configuration
Objectifs du module
Les objectifs du module de configuration sont d'une part de présenter des interfaces de gestion de la configuration et d'autres part de prendre en compte les modifications de la configuration effectuées par l'utilisateur afin de les répercuter sur l'ensemble de l'application. Ces deux aspects se retrouvent à plusieurs niveaux:
- . Gérer les plugins: se référer au document de conception concernant le noyau.
- . Gérer les paramètres
- . Paramètres par défaut
- . Edition des listes prédéfinies
- . Paramètres système (accès à la base de données)
- . Gérer les animateurs
- . Gérer les actes prédéfinis
- . Gérer les prix de ces actes.
Un second aspect du module configuration concerne la possibilité d'exporter l'état de la configuration vers un fichier texte afin que celui-ci puisse être posté sur un forum d'aide à la résolution des problèmes.
Architecture
L'architecture en classes du module configuration est représentée ci-dessous: (il s'agit du modèle dans le MVC)

Nom de la classe |
Fonction |
|---|---|
|
ParametersConfiguration - abstraite |
Cette classe contient un ensemble de constantes, d'attributs et de méthodes utiles pour la gestion des paramètres (paramètres par défaut et paramètres de la base de données). |
|
PredefinedLists - abstraite |
Cette classe contient un ensemble de constantes, d'attributs et de méthodes utiles pour l'édition des listes prédéfinies de l'application. |
Ci-dessous l'architecture en classes du sous-module actes:

Nom de la classe |
Fonction |
|---|---|
|
ActLib - abstraite |
Cette classe contient un ensemble de méthodes utiles pour la gestion de la pré-définition des actes. |
Implémentation
Stockage et manipulation des paramètres
La configuration des paramètres de l'application s'appuie sur deux fichiers, tous deux au format xml:
- . bdd.parameters.xml: contient les paramètres concernant la liaison avec la base de données de l'application. Il contient également la valeur de ces paramètres. Dans ce fichier, il existe une balise
par paramètre. A la sortie de la version 0.9 de GENEPI, ces paramètres sont:
- - Adresse IP du serveur de base de données (id: ip_address, valeur par défaut: localhost ou 127.0.0.1).
- - Port sur lequel le serveur de base de données écoute les requêtes sur la base (id: srv_port, valeur par défaut: 3306)
- - SGBD installé sur le serveur de base de données (id: dbms, valeur par défaut: 1 pour MySQL)
- - Nom de la base de données de l'application (id: db_name, valeur par défaut: à définir)
- - Nom d'utilisateur de la base de données qui doit avoir un accès en lecture et écriture à toutes les tables de la base (id: db_user_name, valeur par défaut: null)
- - Mot de passe associé à l'utilisateur ci-dessus (id: db_password, valeur par défaut: null)
Methodes et attributs associées à la lecture/écriture dans bdd.parameters.xml:
Nom Type Fonction ParametersConfiguration::MYSQL_STRING_FOR_DOCTRINE Constante Contient une chaine de caractère représentant le SGBD MySQL pour Doctrine. ParametersConfiguration::POSTGRESQL_STRING_FOR_DOCTRINE Constante Contient une chaine de caractère représentant le SGBD PostgreSQL pour Doctrine. ParametersConfiguration::$bdd_file Attribut Chaine de caractère contenant le nom du fichier de configuration des paramètres de la base de données (bdd.parameters.xml). ParametersConfiguration::getBddParams() Méthode Renvoie un tableau contenant les valeurs des paramètres concernant la base de données actuellement sauvegardés dans le fichier bdd.parameters.xml. Ce tableau est indexé par les id de ces paramètres. ParametersConfiguration::setBddParams($bdd_values) Méthode Prend en paramètre un tableau du même type que celui renvoyé par la méthode getBddParams(). Sauvegarde les valeurs de ce tableau dans le fichier bdd.parameters.xml. ParametersConfiguration::editYaml() Méthode Lit le fichier bdd.parameters.xml et édite le fichier databases.yml en fonction des valeurs trouvées dans ce fichier. - . id_admin_default.parameters.xml: contient les paramètres par défaut de l'application. Il contient également la valeur de ces paramètres. Dans ce fichier, il existe une balise
par paramètre. A la sortie de la version 0.9 de GENEPI, ces paramètres sont:
- - Batiment par défaut: batiment qui sera proposé par défaut à l'utilisateur lors d'une imputation d'un acte (id: default_building, valeur par défaut: aucune).
- - Salle par défaut: salle qui sera proposée par défaut à l'utilisateur lors d'une imputation d'un acte (id: default_room, valeur par défaut: aucune).
- - Moyen de paiement par défaut: moyen de paiement qui sera proposé par défaut à l'utilisateur lors d'une imputation d'un acte (id: default_method_of_payment, valeur par défaut: aucune).
- - Ordinateur par défaut: ordinateur qui sera proposé par défaut à l'utilisateur lors d'une imputation d'un acte (id: default_computer, valeur par défaut: aucune).
- - Nombre d'entrées à afficher par défaut dans les listes (id: default_num_to_display, valeur par défaut: 0 pour « tous »).
- - Suivre ou non les actions de l'animateur (i.e l'id de l'animateur sera inscrit dans la table « imputation » lors d'une imputation) (id: default_follow_moderator, valeur par défaut: vrai).
- - Langue par défaut: langue à utiliser pour l'interface de l'application (id: default_language, valeur par défaut: français).
- - Monnaie par défaut: monnaie qui sera proposée par défaut à l'utilisateur lors d'une imputation d'un acte (id: default_currency, valeur par défaut: euros).
- - Port MySQL par défaut: port sur lequel le serveur MySQL hébergant la base de données écoute. Le changement de ce paramètre n'affectera pas le fonctionnement de l'application mais sert uniquement à l'aide au débuguage (id: default_mysql_port, valeur par défaut 3306).
- - Port PostgreSQL par défaut: port sur lequel le serveur PostgreSQL hébergant la base de données écoute. Le changement de ce paramètre n'affectera pas le fonctionnement de l'application mais sert uniquement à l'aide au débuguage (id: default_pgsql_port, valeur par défaut 5432).
Methodes et attributs associées à la lecture/écriture dans id_admin_default.parameters.xml:
Nom Type Fonction ParametersConfiguration::$default_values_file Attribut Chaine de caractère contenant le nom du fichier de configuration des paramètres par défaut (default.parameters.xml). ParametersConfiguration::$POSSIBLE_CULTURES Attribut Contient un tableau des langues possiblement installées pour l'application. Ce tableau est indexé par le code international de la langue (ex: 'fr' pour le français). ParametersConfiguration::getDefaultParams() Méthode Renvoie un tableau contenant les valeurs des paramètres par défaut actuellement sauvegardés dans le fichier default.parameters.xml. Ce tableau est indexé par les id de ces paramètres. ParametersConfiguration::setDefaultParams($def_values) Méthode Prend en paramètre un tableau du même type que celui renvoyé par la méthode getDefaultParams(). Sauvegarde les valeurs de ce tableau dans le fichier default.parameters.xml. ParametersConfiguration::getDefault($param_to_search) Méthode Renvoie la valeur du paramètre dont l'id est passé en argument actuellement sauvegardé dans le fichier default.parameters.xml. ParametersConfiguration::setDefault($param_to_set_id,$param_to_set_value) Méthode Edite la valeur du paramètre dont l'id est passé en premier argument, avec la valeur passée en second argument.
Edition des listes prédéfinies
L'édition des listes prédéfinies incombe également au module configuration. Une liste prédéfinie représente une table de la base de données qui contient des données qui vont permettre de caractériser un utilisateur, un ordinateur ou un acte. A la sortie de la version 1 de l'application, ces listes sont:
- . Catégories de public: une liste contenant des catégories dans lesquelles l'animateur va pouvoir classer les utilisateurs de l'espace. Ces catégories sont créées par l'animateur, ce qui lui confère une grande souplesse et une grande adaptabilité à ses propres besoins.
- . Unités: tout types d'unités qui sont amenées à être manipulées par l'animateur dans le progiciel.
- . Moyens de connaissance: listes de moyens de connaissance de la structure (données demandées à l'inscription d'un utilisateur).
- . Catégories socio-professionnelles: listes de CSP pour les utilisateurs
- . Systèmes d'exploitation: liste de systèmes d'exploitation pour les machines du parc de l'EPI (ex; XP, Vista, Ubuntu 9.10 Karmic Koala, 10.6.3 Snow Leopard, …).
- . Familles de systèmes d'exploitation: meta-catégorie pour les systèmes d'exploitation (ex: Windows, Linux, MAC OS, …).
- . Moyens de paiement qui peuvent être utilisés pour une imputation (ex: transaction sur acompte, cheque, liquide, …).
L'édition des listes prédéfinies se fait dans l'onglet « Listes » de la page de gestion des paramètres.
L'édition des listes prédéfinies se fait grâce à des requêtes asynchrones (XMLHttpRequest) réalisées à l'aide du framework JavaScript Jquery. Un appel asynchrone dans Jquery est écrit ainsi:
| $(«element_html_a_remplacer»).load(url, donnees, success); |
- . url: url à joindre qui traitera la requête. Dans le progiciel, cette url est générée en PHP grâce au helper Symfony url_for. Ces méthodes du contrôleur du module de configuration ont été spécialement créée pour recevoir ces requêtes:
-
- - executeUpdateLists: Traite l'ajout/suppression dans les listes prédéfinies.
- - executeUpdateOrders: Traite l'édition du champ « ordre » des listes prédéfinies, et du champ désignation abrégée pour le cas de la liste « Unités » (le champ est un entier qui détermine l'ordre de l'entrée lors de l'affichage de la liste à un autre endroit de l'application que le module configuration).
- - executeRefreshUnities: Met à jour les propositions de la monnaie par défaut (onglet « Valeurs par défaut » de la page de gestion des paramètres) lors de l'ajout d'une unité dans la table « Unités ».
- . donnees: attributs de la requête (passés en POST). Pour une liste d'attributs, observer la syntaxe suivante:
-
{donnee1: valeur1, donnee2: valeur2, ...} - success: fonction à appeler à la réception de la réponse du serveur. Dans le progiciel, chaque mise à jour de table donne lui à 2 requêtes asynchrones POST (3 dans le cas de la table « Unités »). Par conséquent, la 2ème (et la 3ème) requête est exécutée dans une fonction de type success afin d'éviter les requêtes conccurentes et la corruption des données renvoyées par le serveur. Cette méthode de programmation est recommandée.
Ces contrôleurs « asynchrones » s'appuie sur une classe du modèle: PredefinedLists. Cette classe comporte un ensemble de constantes et de méthodes utiles pour la manipulation des listes prédéfinies.
| Nom | Type | Fonction |
|---|---|---|
| PredefinedLists::UNITY | Constante | Chaine de caractère contenant le nom de la table « Unités » formatté par Doctrine. |
| PredefinedLists::UNITY_TITLE | Constante | Chaine de caractère contenant le titre à afficher au dessus de la liste « Unités ». |
| PredefinedLists::PUBLIC_CATEGORIES | Constante | Chaine de caractère contenant le nom de la table «Catégories de public» formatté par Doctrine. |
| PredefinedLists::PUBLIC_CATEGORIES_TITLE | Constante | Chaine de caractère contenant le titre à afficher au dessus de la liste «Catégories de public». |
| PredefinedLists::USER_AWARENESS | Constante | Chaine de caractère contenant le nom de la table «Moyens de connaissance» formatté par Doctrine. |
| PredefinedLists::USER_AWARENESS_TITLE | Constante | Chaine de caractère contenant le titre à afficher au dessus de la liste «Moyens de connaissance». |
| PredefinedLists::USER_SEG | Constante |
Chaine de caractère contenant le nom de la table «Catégories socio-professionelles» formatté par Doctrine. |
| PredefinedLists::USER_SEG_TITLE | Constante | Chaine de caractère contenant le titre à afficher au dessus de la liste «Catégories socio-professionelles». |
| PredefinedLists::COMPUTER_OS | Constante |
Chaine de caractère contenant le nom de la table «Systèmes d'exploiation» formatté par Doctrine. |
| PredefinedLists::COMPUTER_OS_TITLE | Constante |
Chaine de caractère contenant le titre à afficher au dessus de la liste «Systèmes d'exploiation». |
| PredefinedLists::COMPUTER_OS_FAMILY | Constante | Chaine de caractère contenant le nom de la table «Familles de systèmes d'exploitation» formatté par Doctrine. |
| PredefinedLists::COMPUTER_OS_FAMILY_TITLE | Constante | Chaine de caractère contenant le titre à afficher au dessus de la liste «Familles de systèmes d'exploitation». |
| PredefinedLists::instanciate($table_name) | Méthode | Renvoie une nouvelle instance de la table dont le nom est passé en paramètre. Permet ainsi la création d'une nouvelle entrée dans cette table. |
| PredefinedLists::getTableTitle($table_name) | Méthode |
Renvoie le titre à afficher au dessus de la liste dont le nom de la table est passé en paramètre. |
Au niveau des templates des listes prédéfinies, ceux-ci sont factorisés dans des « partials » Symfony. Les « partials » sont des fragments de template réutilisables. Leur nom doit être préfixé par « _ » (caractère de soulignement). On peut inclure in « partial » depuis un template grâce au helper Symfony include_partial(). Pour plus d'informations sur les partials, se réferrer au site du projet symfony.
Gestion des animateurs
Cette fonctionnalité sera traité dans le module « Gestion des animateurs ».
Exportation de la configuration
Cette fonctionnalité, permettant la génération d'un « rapport d'état » de l'application se base sur plusieurs éléments :
- . des variables d'environnement (SERVER_SOFTWARE et HTTP_USER_AGENT)
- . des valeurs issues du fichier de paramètres d'un utilisateur (situé dans /config/login_default.parameters.xml)
- . des valeurs issues du navigateur du client (support du JavaScript, résolution de l'écran)
- . des informations issues du cœur de l'application (état des plugins et des dépendances)
- . les informations fournies par phpinfo().
Une fois que le rapport est généré, il est possible de l'exporter sur son PC, au format texte.
Les même informations se retrouvent alors dans un document au format « .txt ».
Gestion des actes
Par gestion des actes, on entend la création d'actes prédéfinis, qui pourront ensuite être imputés aux utilisateurs de l'espace. Toute cette gestion se fait dans un module, appelé act, qui peut être vu comme un sous-module du module de configuration.
Au sein de ce module, quatre types d'acte sont différenciés :
- . achats (identifiant: 4)
- . abonnements (identifiant: 1)
- . services unitaires (identifiant: 2)
- . services multiples (identifiant: 3)
Ces quatre types d'acte se retrouvent au sein de la base de données, dans la table act_type.
Quelque soit son type, un acte prédéfini sera enregistré dans la table act. Le champ act_type_id sera alors rempli selon l'identifiant ci-dessus.
Ensuite, en fonction du type d'acte, tous les champs d'une entrée dans cette table act ne seront pas remplis de la même façon.
Nous allons maintenant présenter chacun de ces types d'actes, et expliquer comment remplir une entrée dans la table act selon le type d'acte.
Acte de type « Abonnement » :
Pour ce type d'acte, les champs utilisés sont :
- - id (obligatoire)
- - désignation (obligatoire)
- - désignation abrégée (obligatoire)
- - commentaire
- - durée de validité
- - nombre max de membres
- - coût supplémentaire
- - type d'acte (obligatoire)
Les autres champs d'une entrée dans cette table dans le cas d'un abonnement sont laissés à vide.
De plus, nous utilisons deux champs « temporaires » qui n'appartiennent pas à la table mais qui facilitent la saisie pour l'animateur. Il s'agit des champs duration_temp et duration_unity.
Lors de la pré-définition d'un abonnement, le champ durée est en fait caché, et remplacé par ces deux champs temporaires. Le champ duration_temp est simplement un champ texte ne pouvant recevoir que des valeurs numériques et le champ duration_unity est une liste déroulante avec les valeurs suivantes :
- - minute
- - heure
- - jour
- - mois
- - année
Ainsi, à la création d'un abonnement, un utilisateur va devoir fournir une valeur numérique (dans le champ duration_temp) et une unité (dans le champ duration_unity). C'est un formattage de ces deux champs qui va nous donner le champ durée (ou duration dans la base).
Le formatage utilisé est le suivant :
minute:heure:jour:mois:année.
Ainsi, si l'utilisateur choisi 8 puis heures, la donnée entrée dans la base de données sera 00:8:00:00:00.
Ce formatage est réalisé grâce à la méthode ActLib::getFormattedDuration() qui prend en paramètre les champs temporaires duration_temp et duration_unity et qui retourne la valeur formattée de la même manière que présenté plus haut.
Il a été décidé que les champs désignation, désignation abrégée et durée ne pouvaient être modifiés une fois l'abonnement créé.
Cependant, d'autres champs restent modifiables et ainsi, il est nécessaire de pouvoir éditer un abonnement prédéfini. Ainsi, l'opération inverse au formatage de la durée (appelée « explosion ») est nécessaire. Elle est offerte par la méthode ActLib::getExplodedDuration(), qui reçoit en paramètre une durée formatée sous la forme minute:heure:jour:mois:année et qui renvoie un tableau contenant l'unité et la durée.
Enfin, il est possible de supprimer un abonnement prédéfini. Dans ce cas, l'acte n'est pas supprimé de la table Act : seul le champ disabled est passé à 1. Comme des imputations pouvaient faire référence à cet acte, on ne le supprime pas. Il se trouve toujours dans la base de données, n'apparaît plus dans les listes d'actes prédéfinis, mais continue cependant de référencer des imputations.
Acte de type « Service unitaire » :
Pour ce type d'acte, les champs utilisés sont :
- - id (obligatoire)
- - désignation (obligatoire)
- - désignation abrégée (obligatoire)
- - commentaire
- - durée
- - date et heure de début
- - date de fin
- - récurrence
- - type d'acte (obligatoire).
Les autres champs d'une entrée dans cette table dans le cas d'un service unitaire sont laissés à vide.
De plus, nous utilisons plusieurs champs « temporaires » qui n'appartiennent pas à la table mais qui facilitent la saisie pour l'animateur. Comme précédemment, nous utilisons les deux champs duration_temp et duration_unity, couplés aux deux méthodes ActLib::getFormattedDuration() et ActLib::getExplodedDuration(). Nous utilisons de plus 7 autres champs temporaires, codant la récurrence pour chaque jour de la semaine.
Lors de la pré-définition d'un service, les champs durée et récurrence sonrt en fait caché, et remplacés par ces champs temporaires.
Ainsi, à la création d'un service unitaire, un utilisateur va pouvoir déterminer une récurrence pour cet acte. Il se retrouvera face à 7 checkbox, une par jour de la semaine.
Pour enregistrer cette information dans la base de données, nous allons utiliser un codage sur 7 bits, avec un bit par jour de la semaine, en commençant par le lundi. Par exemple, la récurrence 1010010 représente la récurrence lundi – mercredi – samedi.
Ce formatage est fourni par la méthode ActLib::getFormattedRecurrence(). Cette méthode reçoit en paramètre la requête de l'utilisateur et renvoie une chaîne formatée de la manière présentée plus haut.
De plus, deux autres méthodes sont utilisées pour gérer l'insertion des dates et des datetime dans la base de données. Il s'agit des méthodes ActLib::getFormattedDatetime et ActLib::getFormattedDate.
Il a été décidé que les champs désignation, désignation abrégée et durée ne pouvaient être modifiés une fois le service unitaire créé.
Cependant, d'autres champs restent modifiables et ainsi, il est nécessaire de pouvoir éditer un service unitaire prédéfini. Ainsi, l'opération inverse au formatage de la durée (appelée « explosion ») est nécessaire. Elle est offerte par la méthode ActLib::getExplodedDuration(). De même, l'opération inverse au formatage de la récurrence est nécessaire. Elle est offerte par la méthode ActLib::checkRecurrences().
Enfin, il est possible de supprimer un service unitaire prédéfini. Dans ce cas, l'acte n'est pas supprimé de la table Act : seul le champ disabled est passé à 1. Comme des imputations pouvaient faire référence à cet acte, on ne le supprime pas. Il se trouve toujours dans la base de données, n'apparaît plus dans les listes d'actes prédéfinis, mais continue cependant de référencer des imputations.
Acte de type « Service multiple » :
Pour ce type d'acte, les champs utilisés sont :
- - id (obligatoire)
- - désignation (obligatoire)
- - désignation abrégée (obligatoire)
- - commentaire
- - quantité
- - unité
- - type d'acte (obligatoire)
Les autres champs d'une entrée dans cette table dans le cas d'un service multiple sont laissés à vide.
Le champ unité est en fait une liste déroulante remplie par les unités présentes dans la table unity.
Il a été décidé que les champs désignation, désignation abrégée quantité et unité ne pouvaient être modifiés une fois le service multiple créé.
Enfin, il est possible de supprimer un service multiple prédéfini. Dans ce cas, l'acte n'est pas supprimé de la table Act : seul le champ disabled est passé à 1. Comme des imputations pouvaient faire référence à cet acte, on ne le supprime pas. Il se trouve toujours dans la base de données, n'apparaît plus dans les listes d'actes prédéfinis, mais continue cependant de référencer des imputations.
Acte de type « Achat » :
Pour ce type d'acte, les champs utilisés sont :
- - id (obligatoire)
- - désignation (obligatoire)
- - désignation abrégée (obligatoire)
- - commentaire
- - type d'acte (obligatoire)
Les autres champs d'une entrée dans cette table dans le cas d'un achat sont laissés à vide.
Il a été décidé que les champs désignation et désignation abrégée ne pouvaient être modifiés une fois le service unitaire créé.
Enfin, il est possible de supprimer un achat prédéfini. Dans ce cas, l'acte n'est pas supprimé de la table Act : seul le champ disabled est passé à 1. Comme des imputations pouvaient faire référence à cet acte, on ne le supprime pas. Il se trouve toujours dans la base de données, n'apparaît plus dans les listes d'actes prédéfinis, mais continue cependant de référencer des imputations.
Voyons maintenant la façon de mettre un prix sur chacun de ces actes prédéfinis.
Gestion des prix
Une fois qu'un acte est prédéfini, il doit être possible de lui fixer un prix. Cependant, le prix d'un acte dépend de la catégorie de public à laquelle il s'adresse. Par conséquent, nous avons choisi de mettre en place une « matrice des prix », qui se présente sous la forme d'un tableau à deux dimensions, les colonnes étant les catégories de public et les lignes étant les actes prédéfinis créés.
Cette matrice des prix est mise en place dans le module act_price.
A l'affichage, les codes suivants ont été retenus :
- - Une case vide indique qu'aucun prix n'est fixé pour cet acte et cette catégorie de public (donnée enregistrée: -1)
- - "0" indique que l'acte est gratuit pour la catégorie de public concernée (donnée enregistrée: 0)
- - Toute autre valeur numérique (entière ou flottante) est considérée comme valide. (donnée enregistrée: valeur numérique entière et flottante)
Lors de la validation de la matrice des prix, tous les prix saisis correctement sont enregistrés dans la base de données. Par contre, les erreurs ne sont pas enregistrées et sont ré-affichées avec une couleur plus agressive que précédemment.
Lors de la création d'un acte prédéfini, toutes les entrées dans la table act_price sont automatiquement créées, avec la valeur -1 par conséquent. Par la suite, si l'utilisateur ajoute une catégorie de public, une entrée par acte va être ajoutée à cette catégorie de public dans la table act_price.
Enfin, à la suppression d'une catégorie de public, tous les prix correspondant à cette catégorie de public sont supprimés de la table act_price.
Haut de page
V - Gestion de la Structure
Objectifs du module
L'objectif du module de gestion de la structure est d'enregistrer le parc informatique ainsi que les lieux physiques de l'EPI. Les informations entrées via ce module seront ensuite utilisées lors des imputations. De plus, les informations sur les financeurs seront utilisées lors de l'exportation des stats. Un bandeau de logo de tous les financeurs pourra par exemple être affiché.
Architecture du module Structure (struct)
Le module struct est composé d'une seule classe, appelée actions.class.php. Cette classe correspond au contrôleur dans le modèle MVC. Elle contient les méthodes suivantes :
Nom de la méthode |
Fonction |
|---|---|
| executeIndex | Cette méthode est appelée lors de l'accès à la page d'index du module. Elle permet d'afficher les informations relatives à la structure, ainsi que les listes des bâtiments, des salles, des ordinateurs et des financeurs. |
| executeNew... | Cette méthode est appelée lors de la création d'un bâtiment, d'une salle, d'un ordinateur ou d'un financeur. Elle instancie un nouveau formulaire vide du type désiré. Les différents formulaires sont présentés plus loin. |
| executeCreate... | Cette méthode est appelée pour procéder à l'insertion de la nouvelle entité dans la base de données, avec les valeurs entrées par l'utilisateur. Elle redirige alors vers la méthode process...Form. |
| executeEdit... | Cette méthode est appelée pour procéder à l'édition des informations concernant la structure, les bâtiments, les salles, les ordinateurs ou les financeurs. Elle envoie au template editSuccess... les informations nécessaires. |
| executeUpdate... | Cette méthode est appelée pour procéder à la mise à jour de données dans la base de données. Elle appelle la méthode process...Form. |
| process...Form | Cette méthode vérifie si les données entrées sont correctes, c'est-à-dire qu'elle traite le formulaire.. Si c'est le cas, les données sont enregistrées et une notification l'indique à l'utilisateur. Si les données sont incorrectes, rien n'est enregistré et un message d'erreur est renvoyé à l'utilisateur. |
| executeDelete... | Cette méthode procède à la suppression de l'entité. |
| executeAjaxOsName | Cette méthode est utilisée pour proposer une liste d'OS en rapport avec la famille d'OS choisie préalablement. |
NB : La structure ne pouvant être supprimée ni créée, les méthodes executeNew, executeCreate et executeDelete ne sont pas utilisées dans le cas de la structure.
Présentons alors les templates utilisés dans ce module :
Nom du template |
Description |
Actions associées |
|---|---|---|
| _...Form.php | Il s'agit des templates utilisés pour l'affichage des formulaires, en édition ou en création. |
executeNew... et executeEdit... |
| edit...Success.php | Il s'agit des templates utilisés pour l'édition de l'entité désirée. Ils redirigent automatiquement vers le template _...Form.php correspondant. | executeEdit... |
| indexSuccess.php | Il s'agit du template de l'index. |
executeIndex |
| new...Success.php | A la manière des templates d'édition, il s'agit des templates utilisés pour la création de l'entité désirée. Ils redirigent automatiquement vers le template _...Form.php correspondant. | executeNew... |
| _selectOsName.php | Ce template particulier est chargé de l'affichage d'une liste déroulante contenant tous les OS disponibles pour une famille d'OS choisie. | executeAjaxOsName |
Formulaires utilisés
Formulaire de la structure
Ce formulaire, basé sur la table structure, se trouve dans lib/form/doctrine/StructureForm.php. Il contient les champs suivants :
- - Logo_path: Contient le nom du logo, le chemin étant connu à l'avance (uploads/images). Champ obligatoire.
- - Name: Champ optionnel.
- - E-mail: Champ optionnel.
- - Website: Champ optionnel.
- - Telephone_number: Champ optionnel.
- - Siret_number: Champ optionnel.
- - Address_id: Ce champ est caché, nous imbriquons à la place un formulaire d'adresse classique basé sur l'autocomplétion du nom et du code postal de la ville. Champ obligatoire.
Formulaire de bâtiment
Ce formulaire, basé sur la table building, se trouve dans lib/form/doctrine/BuildingForm.php. Il contient les champs suivants :
- - Designation: Champ obligatoire.
- - Shortened designation: Champ optionnel.
- - Address_id: Ce champ est caché, nous imbriquons à la place un formulaire d'adresse classique basé sur l'autocomplétion du nom et du code postal de la ville. Champ obligatoire.
Formulaire de salle
Ce formulaire, basé sur la table room, se trouve dans lib/form/doctrine/RoomForm.php. Il contient les champs suivants :
- - Designation: Champ obligatoire.
- - Shortened designation: Champ obligatoire.
- - Comment: Champ optionnel
Formulaire d'ordinateur
Ce formulaire, basé sur la table computer, se trouve dans lib/form/doctrine/ComputerForm.php. Il contient les champs suivants :
- - Name: Champ obligatoire.
- - Shortened name: Champ obligatoire.
- - Comment: Champ optionnel.
- - Year: Champ optionnel.
- - Mac_address: Champ optionnel.
- - IP_address: Champ optionnel.
- - Room_id: Présenté sous forme d'une liste déroulante. Champ optionnel.
- - Computer_machine_type_id: Présenté sous forme d'une liste déroulante. Champ obligatoire.
- - Computer_os_id: Présenté sous forme de deux listes déroulantes liées. Champ optionnel.
- - Computer_type_of_connexion_id: Présenté sous forme d'une liste déroulante. Champ obligatoire.
Formulaire de financeur
Ce formulaire, basé sur la table room, se trouve dans lib/form/doctrine/FinancierForm.php. Il contient les champs suivants :
- - Name: Champ obligatoire.
- - Logo_path: Contient le nom du logo, le chemin étant connu à l'avance (uploads/images). Champ optionnel.
- - Comment: Champ optionnel.
Haut de page
VI - Gestion des Animateurs
Objectifs du module
L'objectif du module de gestion des animateurs est d'enregistrer les modérateurs de l'EPI. On entend par modérateurs les animateurs et les visualiseurs de l'EPI. Les informations entrées via ce module seront ensuite utilisées lors des imputations si le paramètre « suivre les actions de l'animateur » est coché (voir module de configuration).
Architecture du module Animateurs (moderator)
Le module moderator est composé d'une classe de contôleurs, appelée actions.class.php. Cette classe correspond au contrôleur dans le modèle MVC. Elle contient les méthodes suivantes :
Nom de la méthode |
Fonction |
|---|---|
| executeIndex | Cette méthode est appelée lors de l'accès à la page d'index du module. Elle permet d'afficher les informations relatives aux animateurs/visualiseurs. |
| executeNew | Cette méthode est appelée lors de la création d'un animateur/visualiseur. Elle instancie un nouveau formulaire vide néanmoins pré-rempli par le statut (est un animateur ou non) selon la page d'où cette méthode est appellée. |
| executeCreate | Cette méthode est appelée pour procéder à l'insertion de la nouvelle entité dans la base de données, avec les valeurs entrées par l'utilisateur. Elle redirige alors vers la méthode processForm. |
| executeEdit | Cette méthode est appelée pour procéder à l'édition des informations concernant l'animateur ou le visualiseur. Elle envoie au template editSuccess les informations nécessaires. |
| executeUpdate | Cette méthode est appelée pour procéder à la mise à jour de données dans la base de données. Elle appelle la méthode processForm. |
| processForm | Cette méthode vérifie si les données entrées sont correctes, c'est-à-dire qu'elle traite le formulaire.. Si c'est le cas, les données sont enregistrées et une notification l'indique à l'utilisateur. Si les données sont incorrectes, rien n'est enregistré et un message d'erreur est renvoyé à l'utilisateur. |
| executeDelete | Cette méthode procède à la suppression de l'entité. |
Présentons alors les templates utilisés dans ce module :
Nom du template |
Description |
Actions associées |
|---|---|---|
| _form.php | Il s'agit du template utilisé pour l'affichage des formulaires, en édition ou en création. |
executeNew et executeEdit |
| editSuccess.php | Il s'agit du template utilisé pour l'édition de l'animateur/visualiseur désiré. Il utilise le template _form.php | executeEdit |
| indexSuccess.php | Il s'agit du template de l'index. | executeIndex |
| newSuccess.php | A la manière du template d'édition, il s'agit du template utilisé pour la création d'un animateur/visualisuer. Il utilise le template _form.php | executeNew |
Enfin, ce module comporte également 2 classes de modèles:
- - DefaultParametersFile: Classe instanciable dont l'objet correspondant représente un nouveau fichier de configuration des paramètres par défaut pour un animateur. Pour plus d'informations sur ces fichiers, voir le document de conception sur le module configuration.
| Nom de la méthode | Fonction |
|---|---|
| __construct() | Constructeur de la classe, instancie un nouvel objet. Paramètres: $name: Nom du nouveau fichier $encoding: Type d'encodage pour le nouveau fichier (recommandé: UTF-8) |
| buildEntireFile() | Cette méthode construit le contenu du fichier XML. Elle renvoie ce contenu sous la forme d'une chaine. |
- - ModeratorManagement: Classe non instanciable contenant un ensemble de méthode permettant la création, suppression et modification d'un animateur/visualiseur.
| Nom de la méthode | Fonction |
|---|---|
| createXML() | Méthode à apeller depuis un contrôleur. Elle créé un nouveau fichier de paramètres par défaut pour un nouvel animateur/visualiseur. Elle fait pour cela appel à un objet de type DefaultParametersFile. Paramètres: $moderator_prefix: Préfixe à utiliser pour le nom du fichier XML personnel à l'animateur/visualiseur, c'est à dire son login. |
| deleteXML() | Méthode à apeller depuis un contrôleur. Elle supprime un et un seul fichier XML de paramètres par défaut pour un animateur/visualiseur existant. Paramètres: $moderator_prefix: Préfixe à utiliser pour le nom du fichier XML personnel à l'animateur/visualiseur, c'est à dire son login. |
| checkForDoubloon() | Méthode à apeller depuis un contrôleur. Elle regarde si un login identique à celui passé en paramètre existe déjà dans la base de données. Paramètres: $login_to_check: Login à comparer avec ceux existant dans la base de données. |
| getPasswordAsMd5() | Méthode à apeller depuis un contrôleur. Renvoie le mot de passe actuel d'un animateur/visualiseur dont le login est passé en paramètre haché en MD5. Paramètres: $login: Identifiant dont il faut renvoyer le mot de passe haché en MD5. |
| asMd5WithPrefix() | Méthode à apeller depuis un contrôleur. Renvoie la chaine passée en argument hachée en MD5 avec un préfixe public et fixe: « X21LE7PI12 ». Cette méthode ne doit pas être appellée pour hacher un mot de passe à la création ou authentification d'un modérateur, elle sert à et uniquement à hacher le champ « ancien mot de passe » lors de la modification du mot de passe d'un modérateur. Paramètres: $pass: Chaine à hacher avec préfixe. |
Formulaires utilisés
Formulaire des modérateurs
Ce formulaire, basé sur la table moderator, se trouve dans lib/form/doctrine/ModeratorForm.php, basé sur lib/form/doctrine/base/BaseModeratorForm.php (héritage). Il contient les champs suivants :
Nom du champ |
Id dans la classe de formulaire |
Autres informations |
|---|---|---|
| Nom | "surname" |
Nom de famille du modérateur |
| Prénom |
"name" | Prénom du modérateur |
| Email |
"email" | Adresse e-mail du modérateur |
| Est un animateur | "is_moderator" | Statut du modérateur: est-il animateur ou simple visualiseur. |
Formulaire des logins
Ce formulaire, basé sur la table login, se trouve dans lib/form/doctrine/LoginForm.php, basé sur lib/form/doctrine/base/BaseLoginForm.php (héritage). Il contient les champs suivants :
Nom du champ |
Id dans la classe de formulaire |
Autres informations |
|---|---|---|
| Identifiant | "login" | Identifiant de connexion du modérateur au progiciel |
| Mot de passe | "password" | Mot de passe de connexion du modérateur au progiciel |
| Confirmer | "confirm_password" | Champ utilisé à la création d'un modérateur pour demander confirmation du mot de passe |
| Ancien mot de passe | "former_password" | Champ utilisé à la modification du mot de passe du modérateur pour vérifier que l'utilisateur qui effectue l'opération connait l'ancien mot de passe |
Le formulaire des logins est imbriqué (« embedded ») dans le formulaire des modérateurs grâce aux instructions:
| $subFormLogin = new LoginForm($this->getObject()->getLogin(), $this->getOptions()); $this->embedForm('login', $subFormLogin); |
Comparer deux données
Comparer les mots de passe à la création
Nous l'avons vu au paragraphe précédent, il est nécessaire lors de la création d'un mot de passe pour un modérateur de lui demander de taper deux fois ce mot de passe par mesure de sécurité contre les fautes de frappe.
La solution retenue pour réaliser cette spécification a été de créer un « post-validator » si le formulaire est instancié lors de la création d'un modérateur, et non pas à la modification. Ces deux actions distinctes ne sont à priori pas distinguables l'une de l'autre à l'instanciation du formulaire. Cependant, il a été choisi de passer une option intitulée « new » lors de l'instanciation d'un formulaire à la création d'un modérateur via le second paramètre du constructeur du formulaire
| $this->form = new ModeratorForm($moderator, array('new' => true)); |
Cette option n'est pas passée lors la modification d'un modérateur.
Ainsi, si cette option est passée au constructeur du formulaire ModeratorForm, elle est transmise au formulaire LoginForm grâce à l'instruction que l'on peut voir ligne 1 du cadre code source du paragraphe II.2.b.
Dans le LoginForm, on distingue alors le cas ou cette option est transmise:
| /*In case of a new entry, add a comparison*/ if($this->getOption('new')){ $this->mergePostValidator(new sfValidatorSchemaCompare( 'password', sfValidatorSchemaCompare::EQUAL, 'password_confirm', array(), array('invalid' => 'The password must be the same in the two fields.'))); } |
La méthode mergePostValidator ajoute le post-validator que l'on veut créer à la liste de tous les post-validator déjà existants. Un post-validator est un validator qui sera exécuté après tous les validateurs « classiques ». Il peut concerner un ou plusieurs champs (comme c'est le cas ici).
Ici, le post-validator est défini comme étant un sfValidatorSchemaCompare qui va comparer deux champs spécifiés par leurs ids dans les paramètres 1 et 3 avec un opérateur spécificié dans l'argument 2. L'argument 5 est quant à lui utilisé pour spécifier les messages à afficher notamment, comme ici, si la condition n'est pas respectée.
Comparer les mots de passe à la modification
Toujours par mesure de sécurité, il est nécessaire de demander à l'utilisateur l'ancien mot de passe du modérateur en cours de modification lorsque celui-ci veut mettre à jour le mot de passe.
La solution précédente qui consistait à faire une comparaison stricte entre deux chaines n'est pas valide car entre temps, le mot de passe actuel du modérateur a été crypté en MD5 avec préfixe.
Il a donc été choisi de créer un champ dans le formulaire LoginForm dédié à cette spécification (« former_password ») et de lui assigner un validateur personnalisé baptisé myValidatorFormerPassword dont voici le code source:
| class myValidatorFormerPassword extends sfValidatorString{ protected function configure($options = array(), $messages = array()){ $this->addOption('id'); $this->addMessage('id', 'The entry id has not been specified.'); parent::configure($options,$messages); } protected function doClean($value){ $validatedString = parent::doClean($value); if($this->hasOption('id')){ $specified_pass = ModeratorManagement::asMd5WithPrefix($validatedString); $former_pass = ModeratorManagement::getPasswordAsMd5($this->getOption('id')); if($specified_pass != $former_pass){ throw new sfValidatorError($this, 'You have specified an invalid former password.'); } }else{ throw new sfValidatorError($this, 'id'); } } } |
Dans la méthode doClean de ce validateur, on hache l'ancien mot de passe proposé avec la méthode asMd5WithPrefix et on récupère le mot de passe actuel avec la méthode getPasswordAsMd5. On peut donc ensuite comparer les hash MD5 avec préfixe et lancer une exception si ils sont différents.
Dans le formulaire LoginForm, il ne reste donc plus qu'à créer le widget « former_password » et à lui assigner un validateur de type myValidatorFormerPassword: (si l'on est pas en train de créer un modérateur).
| else{ /*In case of an edit, add a former password input which must be submitted with the old value of the password:*/ $this->widgetSchema['former_password'] = new sfWidgetFormInputPassword(); $this->widgetSchema->setLabel('former_password', 'Former'); $this->setValidator('former_password', new myValidatorFormerPassword(array( 'id' => $this->getOption('login'), 'required' => false, 'min_length' => 6, 'max_length' => 32 ), array( 'min_length' => 'The password length must exceed %min_length% characters.', 'max_length' => 'The password length must not exceed %max_length% characters.'))); $this->widgetSchema['password']->setOption('always_render_empty', true); } |
On remarque qu'il est nécessaire de passer au validateur le login du modérateur en train d'être modifié. Ceci est fait lors de l'instanciation du formulaire de la même manière que l'option « new »:
| $this->form = new ModeratorForm($moderator, array('login_readonly' => true, 'login' => $moderator->getId())); |
L'option « login_readonly » est quant à elle destinée à passer le champ « login » en « readonly » (modification interdite).
Lien avec les autres modules
Module de configuration
La liste des animateurs/visualiseurs doit proposer plusieurs choix pour le nombre d'entrée à afficher. Ce nombre est un paramètre par défaut, il convient donc de récupérer la valeur actuellement sauvegardée pour le modérateur courant (celui qui utilise la session). Ceci est donc fait par un appel à un modèle du module configuration chargé de récupérer les paramètres par défaut (méthode getDefault).
| ParametersConfiguration::setUserPrefix(sfContext::getInstance()->getUser()->getAttribute('login')); $this->defaultRoom = ParametersConfiguration::getDefault('default_num_to_display'); |
Haut de page
VII - Gestion des Utilisateurs
Objectifs du module
L'objectif du module de gestion des utilisateurs est d'enregistrer les utilisateurs de l'EPI. Il sera alors possible pour un animateur d'imputer des actes à cet utilisateur. De plus, l'animateur sera en mesure de sortir des statistiques sur les utilisateurs.
Architecture du module Utilisateurs (user)
Le module user est composé d'une classe de contôleurs, appelée actions.class.php. Cette classe correspond au contrôleur dans le modèle MVC. Elle contient les méthodes suivantes :
Nom de la méthode |
Fonction |
|---|---|
| executeIndex | Cette méthode est appelée lors de l'accès à la page d'index du module. Elle permet d'afficher les informations relatives aux utilisateurs (dont la liste de tous les utilisateurs, la liste des abonnés, la liste des non-abonnés, etc.). |
| executeNew | Cette méthode est appelée lors de la création d'un utilisateur. Elle instancie un nouveau formulaire vide de type UserForm. |
| executeCreate | Cette méthode est appelée pour procéder à l'insertion du nouvel utilisateur dans la base de données, avec les valeurs entrées par l'utilisateur. Elle redirige alors vers la méthode processForm. |
| executeEdit | Cette méthode est appelée pour procéder à l'édition des informations concernant l'utilisateur. Attention, seules les données relatives à l'utilisateur sont modifiables (il ne s'agit pas de modifier ses accomptes ou ses abonnements). Cette méthode envoie alors au template editSuccess les informations nécessaires. |
| executeUpdate | Cette méthode est appelée pour procéder à la mise à jour de données dans la base de données. Elle appelle la méthode processForm. |
| processForm | Cette méthode vérifie si les données entrées sont correctes, c'est-à-dire qu'elle traite le formulaire. Si c'est le cas, les données sont enregistrées et une notification l'indique à l'utilisateur. Si les données sont incorrectes, rien n'est enregistré et un message d'erreur est renvoyé à l'utilisateur. |
| executeDelete | Cette méthode procède à la suppression de l'entité, dans les trois tables concernées : address, user et user_archive. |
| executeAjaxUserInfo | Cette méthode procède à l'affichage d'une fiche résumée pour chaque utilisateur. Elle contient les informations relatives à l'utilisateur, ainsi que la liste de ses abonnements avec leur date d'expiration, et la liste de ses accomptes et leur état. |
| executeAnonymize | Cette méthode est appelée lors de l'affichage de la page d'anonymisation. Elle n'effectue aucune action. |
| executeAnonymization | Cette méthode est appelée pour procéder à l'anonymisation des imputations. Elle reçoit en paramètre (paramètre request) la date limite d'anonymisation. Son fonctionnement sera présenté plus loin dans le document. |
Présentons alors les templates utilisés dans ce module :
Nom du template |
Description |
Actions associées |
|---|---|---|
| _form.php | Il s'agit du template utilisé pour l'affichage du formulaires, en édition ou en création. | executeNew et executeEdit |
| editSuccess.php | Il s'agit du template utilisé pour l'édition de l'utilisateur sélectionné. Il utilise le template _form.php | executeEdit |
| indexSuccess.php | Il s'agit du template de l'index. | executeIndex |
| newSuccess.php | A la manière du template d'édition, il s'agit du template utilisé pour la création d'un utilisateur. Il utilise le template _form.php | executeNew |
| userInfoSuccess.php | Il s'agit du template d'affichage d'une boîte de dialogue résumant les informations relatives à un utilisateur, après un clic sur le nom de cet utilisateur. | executeAjaxUserInfo |
| anonymizeSuccess.php | Il s'agit du template d'affichage du formulaire d'anonymisation. | executeAnonymize |
Enfin, ce module comporte également 1 classe de modèles:
Nom de la classe |
Description |
|---|---|
| UserLib | Cette classe contient une seule méthode, la méthode getAge, qui, à partir d'une date de naissance, renvoie l'âge d'un utilisateur. |
Formulaire utilisé
Ce formulaire, basé sur la table user, se trouve dans lib/form/doctrine/UserForm.php, basé sur lib/form/doctrine/base/BaseUserForm.php (héritage). Il contient les champs suivants :
Nom du champ |
Id dans la classe de formulaire |
Autres informations |
|---|---|---|
| Nom | "surname" | Nom de famille de l'utilisateur |
| Prénom | "name" | Prénom de l'utilisateur |
| Date de naissance |
"birthdate" | Date de naissance de l'utilisateur |
| Date de création de l'utilisateur | "created_at" | Date de création de l'utilisateur |
| Nom de l'organisation |
« orgnization_name » | Nom de l'organisation représentée par cet utilisateur |
| « email » | Adresse e-mail de l'utilisateur |
|
| Numéro de téléphone portable | « cellphone_number » | Numéro du téléphone portable de cet utilisateur |
| Informations complémentaires | « comment » | Informations complémentaires à propos de l'utilisateur |
| Sexe | « user_gender_id » | Sexe de l'utilisateur |
| CSP | « user_seg_id » | Catégorie socio-professionnelle de l'utilisateur |
| Moyen de connaissance | « user_awareness_id » | Moyen de connaissance de l'EPI par l'utilisateur |
| Catégorie de public | « act_public_category_id » | Catégorie de public à laquelle appartient un utilisateur |
| Adresse | « address_id » | Adresse d'un utilisateur |
| Login | « login_id » | Login d'un utilisateur, réservé à un usage futur |
Le formulaire d'addresse est imbriqué (« embedded ») dans le formulaire d'utilisateur grâce aux instructions:
| $subFormAddress = new AddressForm($this->getObject()->getAddress()); $this->embedForm('address', $subFormAddress); |
Points remarquables
Ajout d'un utilisateur
A l'ajout d'un utilisateur, trois tables sont concernées :
- - la table user elle-même
- - la table address
- - la table user_archive.
Les premiers champs du formulaire concernent la table User. A noter que cette table contient un champ login_id, qui n'est pas rempli dans notre cas, car il est réservé à un usage futur.
Les adresses sont stockées dans une table à part, la table Address. Elle est donc imbriquée dans le formulaire d'utilisateur. A la création d'un nouvel utilisateur, une nouvelle entrée est créée dans cette table, même si l'utilisateur n'a pas renseigné son adresse.
Enfin, une entrée dans la table user_archive est créée. Il s'agit d'une duplication d'informations anonymes, à des fins de statistiques. Les informations suivantes sont enregistrées :
- - âge de l'utilisateur (par rapport à la date de création)
- - date de création
- - code postal
- - pays
- - CSP
- - moyen de connaissance
- - sexe
L'animateur n'a pas à entrer manuellement ces données. Elles sont simplement « piochées » dans le formulaire de l'utilisateur. Cette opération est donc transparente pour l'utilisateur.
Modification d'un utilisateur
La modification d'un utilisateur entraîne des modifications dans les trois tables vues précédemment :
- - la table user elle-même
- - la table address
- - la table user_archive.
Comme expliqué précédemment, une modification concernant le profil d'un utilisateur se fait dans la table user ou dans la table address (s'il s'agit d'une mise à jour de l'adresse).
De plus, une modification a lieu dans la table user_archive. Seuls les champs âge et date de création ne peuvent pas être modifiés (car l'âge est toujours calculé par rapport à la date de création, qui ne change pas).
Suppression d'un utilisateur
La suppression d'un utilisateur entraîne des modifications dans les trois tables vues précédemment :
- - la table user
- - la table address
- - la table user_archive.
Mais cette suppression affecte aussi trois autres tables tables :
- - la table imputation
- - la table user_account
- - la table imputation_archive.
En effet, à la suppression d'un utilisateur, il est nécessaire d'anonymiser tous les usages réalisés par cet utilisateur. On parcourt alors les tables imputation et imputation_archive à la recherche des enregistrements faisant référence à cet utilisateur :
| $imputations = Doctrine_Query::create() ->select('i.*') ->from('Imputation i') ->where('i.user_id = ?', $user->id) ->execute(); |
Toutes ces imputations sont alors dé-référencées :
| foreach($imputations as $imputation) { if($imputation->getUserId() != null) { $imputation->setUserId(null); $imputation->save(); } } |
Le même traitement est effectué sur la table imputation_archive.
De plus, si un utilisateur possède un ou plusieurs accomptes, il faut aussi les dé-référencer. Pour cela, on utilise le comportement « en cascade » sur les délétions du SGDB. Ainsi, à la suppression de l'utilisateur, toutes les entrées de la table account_user possédant l'identifiant de l'utilisateur seront aussi supprimées.
Enfin, ce même comportement en cascade est utilisé pour supprimer l'utilisateur dans la table User. On utilise pour cela la table Address. Ainsi, à la suppression de l'adresse d'un utilisateur, cet utilisateur est supprimé.
En résumé, le comportement en cascade peut être schématisé de la façon suivante :
Suppression de l'adresse --> Suppression de l'utilisateur --> Suppression de tous ses accomptes
Anonymisation des usages
Une des fonctionnalité offertes par ce module est l'anonymisation des usages au sein de l'EPI. Pour cela, un animateur a simplement à choisir une date limite d'anonymisation, parmi la liste suivante :
imputations réalisées il y a plus de trois mois
imputations réalisées il y a plus de six mois
imputations réalisées il y a plus d'un an
imputations réalisées il y a plus de deux ans.
On parcourt alors la table Imputation, on filtre les imputations datant de plus longtemps que la date maximale sélectionnée, et on les dé-référence par rapport aux utilisateurs :
| $imputations = Doctrine::getTable('Imputation') ->createQuery('a') ->execute(); foreach($imputations as $imputation) { if((strtotime($imputation->getDate()) getUserId() != null)) { $imputation->setUserId(null); $imputation->save(); $anonymized = 1; } } |
Le même traitement est affecté à la table Imputation_archive.
Une fois qu'un acte est dé-référencé, il n'est plus possible de le supprimer.
Liste des utilisateurs
Au sein du module User, il doit être possible de lister trois types d'utilisateurs :
- - tous les utilisateurs
- - seulement les abonnés
- - seulement les non-abonnés.
Un utilisateur rentre dans la liste des abonnés s'il possède au moins un abonnement en cours de validité, avec une tolérance de 10 jours. Pour posséder un abonnement, un utilisateur doit avoir subi une imputation de type abonnement.
Ainsi, pour lister les utilisateurs abonnés, nous effectuons la requête suivante :
| $this->subscribers = Doctrine_Query::create() ->select('u.*') ->from('User u') ->leftJoin('u.Imputation i') ->whereIn('i.imputation_type', "5") ->leftJoin('i.ImputationSubscription s') ->addWhere('s.final_date > ?',$tenDaysAgo) ->execute(); |
NB : Le type d'imputation numéro 5 correspond à un abonnement.
La liste des non-abonnés correspond à la liste des utilisateurs – la liste des non-abonnés.
Fiche d'un utilisateur
Après un clic sur le nom d'un utilisateur (présent dans la liste des abonnées, par exemple), l'utilisateur arrive sur la fiche d'un utilisateur. Il s'agit d'une boîte de dialogue permettant la consultation (en mode read-only) des informations relatives à un utilisateur (nom, prénom, etc.). En plus de ces informations, deux autres types d'informations sont affichées :
la liste des accomptes de cet utilisateur, avec leur désignation et leur valeur actuelle
la liste des abonnements de cet utilisateur, avec leur désignation et leur valeur actuelle.
L'affichage de toutes ces informations est permis par l'envoi de l'identifiant d'un utilisateur au clic sur son nom (envoi via la méthode load de JQuery :
| $("#dialog").load('', { id: userId }, |
L'action executeAjaxUserInfo reçoit alors cet identifiant, et renvoie les données au template.
Une requête dans la table account_user nous permet de connaître tous les comptes associés à un utilisateur :
| $userAccountsQuery = Doctrine::getTable('AccountUser')->findByUserId($request->getParameter('id')); |
Tous les accomptes sont alors affichés dans la boîte de dialogue, avec leur désignation et leur valeur actuelle. Le code couleur suivant a été retenu :
Valeur |
Message |
Couleur |
|---|---|---|
| supérieure à 10 unités | valeur restante | noire |
| comprise entre 0 et 10 unités | valeur restante | bleu |
| égale à 0 unité | "acompte consommé en totalité" | rouge clair |
| négative | acompte négatif, valeur | rouge vif |
Ensuite, une requête dans la table Imputation puis Imputation_subscription permet d'obtenir tous les abonnements d'un utilisateur ainsi que leur date de fin de validité :
| $userSubscriptionsQuery = Doctrine::getTable('Imputation') ->createQuery() ->select('i.*') ->from('Imputation i') ->where('i.user_id = ?', $request->getParameter('id')) ->addWhere('i.imputation_type = ?', "5") ->execute(); foreach ($userSubscriptionsQuery as $userSubscriptionQuery) { $userSubscriptionsFinalDateQuery = Doctrine::getTable('ImputationSubscription')->findOneByImputationId($userSubscriptionQuery->getId()); $endOfSubscription = strtotime($userSubscriptionsFinalDateQuery->getFinalDate()); ... |
Comme précédemment, en fonction de la fin de la date de validité, un code couleur a été choisi :
Date de fin (par rapport à la date du jour) |
Message |
Couleur |
|---|---|---|
| ultérieure à 10 jours | expire le « date de fin » | noire |
| comprise entre 0 et 10 jours | expire le « date de fin » + attention, cet abonnement sera périmé dans X jours | bleu |
| aujourd'hui | expire le « date de fin » + expire aujourd'hui | rouge clair |
| postérieure à 10 jours | expire le « date de fin » + abonnement périmé depuis X jours | rouge vif |
Gestion des comptes
La dernière fonctionnalité offerte par le module de Gestion des Utilisateurs est la gestion des comptes. La page d'accueil de cette fonctionnalité est une liste de tous les comptes, avec le nom, l'utilisateur et la valeur du comtpe. Les comptes monétaires ainsi que les comptes non monétaires sont référencés ici.
Pour supprimer un compte, il suffit de le sélectionner dans la liste et de cliquer sur « Supprimer... ». Une boîte de dialogue s'ouvre alors, et indique à l'animateur quels utilisateurs seront affectés par cette suppression. En effet, il est possible qu'un compte (monétaire ou non) soit partagé par plusieurs utilisateurs.
Pour connaître quels utilisateurs possèdent le compte sélectionné, nous effectuons la requête suivante :
| $accountUsers = Doctrine::getTable('AccountUser')->findByAccountId($accountToDelete); foreach($accountUsers as $affectedUser) { $user = Doctrine::getTable('User')->findOneById($affectedUser->getUserId()); $userName[$accountToDelete][] = $user->getName()." ".$user->getSurname(); } |
Si l'utilisateur confirme son choix, le compte est supprimé et aucun utilisateur ne peut plus en bénéficier.
Haut de page
VIII - Usages
Objectifs du module
L'objectif du module d'imputation des actes est de permettre l'enregistrement des actes effectués par les utilisateurs. Selon le type des actes enregistrés certains paramètres sont à définir au cours de l'imputation.
Ergonomie
Comme ce module est celui qui sera le plus fréquemment utilisé, un effort a été fait sur l'ergonomie de l'interface.
La définition d'un acte est réalisée à travers 4 panneaux qui apparaissent après validation des blocs précédents. Un scrolling automatique (effectué par des encres) est réalisé à l'apparition de chaque nouveau panneau. Il est possible de sélectionner un utilisateur unique en un seul clic. Le choix de la catégorie de personne est automatique dans le cas d'un utilisateur unique ou dans le cas de plusieurs personnes appartenant à la même catégorie de public. La sélection d'une entrée dans une liste se fait par un simple clic sur la ligne correspondante. Lors de la définition d'un acte le curseur est positionné automatiquement sur le premier champ susceptible d'être modifié.
Les retours sur les sélections effectué dans les premiers panneaux doivent eux aussi être pris en compte. Ainsi, le retour sur le choix des utilisateurs entrainera le masquage des autres panneaux.
Architecture du module Usage (use)
Le module Imputation des actes est composé d'une classe de contôleurs, appelée actions.class.php. Cette classe correspond au contrôleur dans le modèle MVC. Elle contient les méthodes suivantes :
Nom de la méthode |
Fonction |
|---|---|
| executeIndex | Cette méthode est appelée lors du lancement du module. Elle permet de récupérer la liste des utilisateurs ainsi que la liste des catégories de public. |
| executeNewImputation | Cette méthode est le contrôleur chapeau pour la création de tous les types de formulaires d'imputation. Elle se base sur le type d'imputation, passé dans la requête pour rediriger vers une de ces 5 méthodes:
|
| executeNewAccountTransaction | Cette méthode est le contrôleur pour la création d'un formulaire de type « transaction sur compte ». Elle est séparée des autres méthodes executeNew* car ce formulaire ne peut pas être multi-utilisateurs. |
| executeCreateAccountTransaction | Cette méthode est le contôleur pour la validation et l'enregistrement d'un formulaire de type « transaction sur compte ». Elle redirige vers la page d'accueil des imputations ('use/index') si le formulaire est correct, sinon, elle le réaffiche avec les erreurs. |
| executeNewPurchase | Cette méthode est le contôleur chapeau pour la création d'un formulaire de type « achat ». Elle appelle la méthode executeNew avec le type « achat ». |
| executeCreatePurchase | Cette méthode est le contôleur chapeau pour la validation et l'enregistrement d'un formulaire de type « achat ». Elle appelle la méthode executeCreate avec le type « achat ». |
| executeNewCountableService | Cette méthode est le contôleur chapeau pour la création d'un formulaire de type «service comptable». Elle appelle la méthode executeNew avec le type «service comptable». |
| executeCreateCountableService | Cette méthode est le contôleur chapeau pour la validation et l'enregistrement d'un formulaire de type «service comptable». Elle appelle la méthode executeCreate avec le type «service comptable». |
| executeNewUnitaryService | Cette méthode est le contôleur chapeau pour la création d'un formulaire de type «service unitaire». Elle appelle la méthode executeNew avec le type «service unitaire». |
| executeCreateUnitaryService | Cette méthode est le contôleur chapeau pour la validation et l'enregistrement d'un formulaire de type «service unitaire». Elle appelle la méthode executeCreate avec le type «service unitaire». |
| executeNewSubscription | Cette méthode est le contôleur chapeau pour la création d'un formulaire de type «abonnement». Elle appelle la méthode executeNew avec le type « abonnement». |
| executeCreateSubscription |
Cette méthode est le contôleur chapeau pour la validation et l'enregistrement d'un formulaire de type «abonnement». Elle appelle la méthode executeCreate avec le type «abonnement». |
| executeNew | Cette méthode est le contrôleur pour la création des formulaires de type:
|
| executeCreate | Cette méthode est le contrôleur pour la validation et l'enregistrement des formulaires de type:
|
| processEachForm |
Cette méthode est chargée d'instancier un formulaire du bon type (celui passé en argument de la requête) pour chaque utilisateur concerné par l'imputation, en lui associant son moyen de paiment et eventuellement, son ordinateur. Pour chacun des ces utilisateurs, la méthode appelle processForm. |
| processForm | Cette méthode est chargée de la validation et de l'enregistrement d'un seul formulaire dont le type est parmis achat, abonnement, service unitaire et service comptable. Si la méthode de paiement est « compte », elle crée une imputation de type « transaction sur compte » qui décrémente le compte concerné. Si l'imputaiton est de type « service comptable », elle crée un compte eventuellement partagé entre plusieurs utilisateurs. |
| prepareToErrorPage | Cette méthode est chargée de passer un certain nombre de variables au template dans le cas d'une erreur à la validation du formulaire. |
| prepareToNewPage | Cette méthode est chargée de passer un certain nombre de variables au template dans le cas d'une création de formulaire. |
| processAccountTransactionForm | Cette méthode est chargée de valider et d'enregistrer un formulaire de type « transaction sur compte ». |
| executeAjaxPossibleActs | |
| executeHistory | |
| executeAjaxImputationInfo | |
| executeAjaxDeleteImputation | |
| executeDeleteImputation |
Présentons alors les templates utilisés dans ce module :
Nom du template |
Description |
Actions associées |
|---|---|---|
| indexSuccess.php | Il s'agit du template de l'index. Il contient la vue des panneaux: « sélection des utilisateurs » choix de la catégorie de public |
executeIndex |
| possibleActsSuccess.php | Il s'agit du template utilisé pour l'édition de l'utilisateur sélectionné. Il utilise le template _form.php | executeEdit |
| newAccountTransactionSuccess.php | Il s'agit du template qui permet d'afficher un formulaire de type « transaction sur compte ». Il contient également les scripts javascripts propre à ce formulaire. |
executeNewImputation executeNewAccountTransaction executeCreateAccountTransaction |
| newCountableServiceSuccess.php | Il s'agit du template qui permet d'afficher un formulaire de type « service comptable » Il contient également les scripts javascripts propre à ce formulaire. |
executeNewImputation executeNewCountableService executeNew executeCreateCountableService executeCreate |
| newPurchaseSuccess.php | Il s'agit du template qui permet d'afficher un formulaire de type « achat » Il contient également les scripts javascripts propre à ce formulaire. |
executeNewImputation executeNewPurchase executeNew executeCreatePurchase executeCreate |
| newSubscriptionSuccess.php | Il s'agit du template qui permet d'afficher un formulaire de type « abonnement » Il contient également les scripts javascripts propre à ce formulaire. |
executeNewImputation executeNewSubscription executeNew executeCreateSubscription executeCreate |
| newUnitaryServiceSuccess.php | Il s'agit du template qui permet d'afficher un formulaire de type « service unitaire » Il contient également les scripts javascripts propre à ce formulaire. |
executeNewImputation executeNewUnitaryService executeNew executeCreateUnitaryService executeCreate |
| _accountTransactionForm.php | Il s'agit du formulaire de définition d'une imputation de type « transaction sur compte » | cf Templates correspondants |
| _purchaseForm.php | Il s'agit du formulaire de définition d'une imputation de type « achat » | |
| _subscriptionForm.php | Il s'agit du formulaire de définition d'une imputation de type « abonnement » | |
| _unitaryServiceForm.php | Il s'agit du formulaire de définition d'une imputation de type « service unitaire » | |
| _countableServiceForm.php | Il s'agit du formulaire de définition d'une imputation de type « service multiple » | |
| deleteImputationSuccess.php | ||
| historySuccess.php | ||
| imputationInfoSuccess.php |
Enfin, ce module comporte également 2 classes de modèles:
Nom de la classe |
Description |
|---|---|
|
ImputationDefaultValues
|
Cette classe contient des méthodes statiques qui permettent d'obtenir la valeur par défaut à affecter aux champs salle, batiment et ordinateur lors de la création d'un formulaire d'imputation. Elle contient également une méthode qui permet de récupérer le symbole de la monnaie par défaut et une autre qui retrouve dynamiquement l'id de la méthode de paiement « compte ». |
| Age | Permet le calcul de l'âge des utilisateurs à partir de sa date de naissance. |
Ce module utilise également des méthodes contenues dans des classes du modèle lié aux tables de la base de données:
Nom de la classe |
Description |
|
|---|---|---|
| ImputationAccountTransaction | Chacune de ces classes contient une méthode preConfigure chargé de configurer l'objet courant en vue d'obtenir des formulaires pré-remplis |
Méthodes spécifiques à la manipulation des comptes des utilisateurs. |
| ImputationCountableService | Contient une méthode de création d'un compte-utilisateur (association d'un compte avec un utilisateur) | |
| ImputationPurchase | - | |
| ImputationSubscription | - | |
| ImputationUnitaryService | - | |
| Imputation | Méthodes génériques pouvant s'appliquer à tous les formulaires: factorisation des instanciations des objets et des formulaires, récupération des paramètres supplémentaires (méthodes de paiement, compte et ordinateur pour chaque utilisateur) | |
Problèmes rencontrés
Ce module utilise l'API « DataTables » proposée par jquery ( http://www.datatables.net/ ). Cette API est jeune, est quelques bugs subsistent. Nous avons rencontrés les problèmes suivants:
- - La fonction fnDeleteRow() est buguée: elle entraine une erreur: « oSettings.aoData[iRow] is null ». Une correction manuelle de la librairie nous permet de contourner l'erreur.
- - Suite à cette correction, la fonction fnDeleteRow() supprime visuellement la ligne. Mais lorsqu'on récupère les données du tableau avec fnGetData() les lignes effacées avec fnDeleteRow() sont vides mais existe toujours. Il ne faut donc pas se servir de la taille du tableau qui n'est donc pas à jour et faire attention aux lignes vides dans les traitements.
- - Les colonnes déclarées non-visibles dans la déclaration du datatable apparaissent lorsque le tableau est vide. En effet le message qui apparait lorsque le tableau est vide provoque ce dysfonctionnement. Il faut redéfinir le colspan de la classe du message pour masquer l'erreur.
Pour contourner cette erreur nous avons ajouté 2 astuces:
- . Nous définissons une fonction qui sera appelée à la fin du chargement du tableau. Même s'il est vide l'erreur sera alors masquée. Cette astuce ne fonctionne pas sous IE
| usersDatatable = $("#usersTab").dataTable({ "aoColumns": [ { "bSortable": false }, null, null, null, { "bVisible": false }, { "bVisible": false }, { "bSortable": false } ], "fnInitComplete": function(){ $('table tbody tr td[class="dataTables_empty"]').attr('colspan',5); }, "sPaginationType": "full_numbers", "bAutoWidth": false, "iDisplayLength": 10, "oLanguage": { "sUrl": "getUser()->getAttribute('relativeUrlRoot'); ?>" + "/lang/" + "" } } ); |
- . Nous ajoutons une action lors de l'utilisation du filtre de recherche (qui provoque l'erreur puisque le tableau est vide si aucune entrée ne correspond au critère de recherche). Cette astuce fonctionne bien avec firefox et IE.
| $("#users_to_add_filter").live('keydown, keyup', function() { $('table tbody tr td[class="dataTables_empty"]').attr('colspan',4); }); |
Nous espérons que ces erreurs seront corrigées dans les prochaines versions de datatables.
Fonctions Javascript
L'aspect dynamique de la page est rendu par des fonctions Javascript. Ces fonctions sont nombreuses et permettent d'articuler les différents panneaux et templates entre eux. Pour permettre une vision globale, le schéma suivant présente les fonctions JS principales, les templates utilisés et le découpage en panneaux.

Formulaires de définition des imputations
Le dernier panneau utilisé dans la page d'imputation des actes est le panneau qui contient les formulaires de définition des imputations, c'est à dire les champs nécéssaires à l'enregistrement des imputations.
Ces formulaires devaient être pré-remplis au maximum afin d'accélérer le temps de travail et de réduire le temps passé sur chaque imputation. Cet aspect a été réglé grâce à l'utilisation des valeurs par défaut et des prix prédéfinis dans la matrice des prix du module « actes ».
La création d'un formulaire est réalisé à l'aide d'une requête asynchrone.
Nous présentons ci-dessous l'arbre des appels pour la création d'un formulaire:

Nous présentons ci-dessous l'arbre des appels pour la validation et l'enregistrement d'un formulaire:

Haut de page
IX - Tableau de bord
Objectifs du module
L'objectif du module de tableau de bord est d'offrir à l'utilisateur des statistiques immédiates, ou « instantanées », lui permettant de connaître rapidement les chiffres relatifs à son EPI.
Ce module constitue l'accueil de l'application.
Architecture du module Tableau de bord (dashboard)
Le module user est composé d'une classe de contôleurs, appelée actions.class.php. Cette classe correspond au contrôleur dans le modèle MVC. Elle contient les méthodes suivantes :
Nom de la méthode |
Fonction |
|---|---|
| executeIndex | Cette méthode est appelée lors de l'accès à la page d'index du module. Elle est utilisée pour le calcul des chiffres « instantanés » suivants :
|
| executeNew | Cette méthode est appelée lorsqu'un utilisateur loggé tente d'accéder à une page qui n'existe pas. Il est redirigé sur la page « Tableau de bord », qui est la page d'accueil de l'application. |
Présentons alors le template utilisé dans ce module :
Nom du template |
Description |
Actions associées |
|---|---|---|
| executeIndex | Il s'agit du template de l'index. Il reprend l'allure du tableau défini par le client, et présenté dans le document de spécifications de ce module. | indexSuccess.php |
Haut de page
X - Statistiques
Le module de statistiques de GENEPI est basé sur la librairie php PHPExcel pour les exports. Nous vous recommandons de vous réferrer au site officiel de PHPExcel (en anglais) à cette adresse.
Flux RSS