Recherche




Documentation développeur

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
  • Computer_machine_type
  • Computer_os
  • Imputation_unitary_service
  • Room
Computer_type_of_connexion

Enregistrement des types de connexion possibles.

  • Computer
Computer_machine_type

Enregistrement des types de machine possibles.

  • Computer
Computer_os

Enregistrement des noms des systèmes d'exploitation possibles, pour une famille donnée.

  • Computer_os_family
  • Computer
Computer_os_family

Enregistrement des familles des systèmes d'exploitation possibles.

  • Computer_os
Structure

Enregistrement des informations relatives à la structure qui utilise le progiciel.

  • Address
Address

Enregistrement d'une adresse, avec un numéro de téléphone.

  • Address_city
  • Structure
  • Building
  • User
Address_city

Enregistrement d'une ville et du code postal associé. Chacun de ces couples est associé à un pays.

  • Address_country
Address_country

Enregistrement des pays.

  • Address_city
Building

Enregistrement des infor mations relatives à un bâtiment de la structure.

  • Address
  • Room
  • Imputation
Room

Enregistrement des informations relatives à une pièce d'un bâtiment de la structure.

  • Computer
  • Building
  • Imputation
User

Enregistrement des informations relatives à un utilisateur de l'espace.

  • User_seg
  • User_awareness
  • User_gender
  • Address
  • Login (emploi futur)
  • Imputation
  • Account_user
  • Act_public_category
User_seg

Enregistrement des SEG (Socio-Economic Groups), c'est-à-dire les CSP en français.

  • User
User_awareness

Enregistrement des moyens de connaissance de la structure.

  • User
User_gender

Enregistrement du sexe de l'utilisateur.

  • User
Act

Enregistrement de toutes les informations relatives à un acte prédéfini.

  • Act_type
  • Act_price
  • Unity
  • Account
  • Imputation
Act_type

Enregistrement des types d'actes par défaut.

  • Act
Act_price

Enregistrement du prix d'un acte pour une catégorie de public donnée.

  • Act
  • Act_public_category
Act_public_category

Enregistrement des différentes catégories de public.

  • Act_price
  • User
Unity

Enregistrement des différentes unités disponibles.

  • Act
  • Imputation
Imputation

Enregistrement de toutes les informations relatives à l'imputation d'un acte prédéfini ou non à un utilisateur.

  • Imputation_method_of_payment
  • Imputation_account_transaction
  • Imputation_purchase
  • Imputation_countable_service
  • Imputation_unitary_service
  • Imputation_subscription
  • Moderator
  • Account
  • Unity
  • Act
  • User
  • Room
  • Building
Imputation_method_of_payment

Enregistrement des méthodes de paiement disponibles.

  • Imputation
Imputation_account_transaction

Enregistrement des informations relatives à une transaction sur un acompte.

  • Imputation
Imputation_purchase

Enregistrement des informations relatives à un achat.

  • Imputation
Imputation_countable_service

Enregistrement des informations relatives à un service dénombrable.

  • Imputation
Imputation_unitary_service

Enregistrement des informations relatives à un service unitaire.

  • Imputation
  • Computer
Imputation_subscription

Enregistrement des informations relatives à un abonnement.

  • Imputation
Moderator

Enregistrement des informations relatives à un animateur.

  • Imputation
  • Login
Login

Enregistrement des couples identifiant/mot de passe.

  • User (emploi futur)
  • Moderator
Account

Enregistrement des informations relatives à un acompte.

  • Imputation
  • Act
  • Account_user
Account_user

Table permettant de faire le lien entre un acompte et son ou ses possesseur(s).

  • Account
  • User
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:

  • . Son nom
  • . Obligatoire ou non
  • . Son entrée dans le menu principal
  • . Ses dépendances
  • . Un ensemble de logiques métier et de vues
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:Architecture en classes du Noyau

 

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 »
L'accès aux applications et aux modules peut être définis selon ces deux types de droits.
Si les règles d'accès sont définies pour une application, elles seront appliquées par défaut aux modules de cette application. On peut définir plus précisément les règles pour un module.
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:
is_secure: true //permet de restreindre l'accès au personne identifiée
credentials: admin //permet de restreindre l'accès au personne possédant le credential « admin »

Pour ajouter ces droits à un utilisateur, on utilise les méthodes:

$myUser->setAuthenticated(true);
$myUser->addCredential('admin');

La gestion des droits est expliquée plus précisément à l'adresse suivante.

Les accès non-autorisés
Lorsqu'un utilisateur non-authentifié accède à un page non-autorisée, il est redirigé vers l'action définie par le fichier /config/setting.yml (de l'application ou du module) de la manière suivante:

 

all:
.actions:
secure_module: auth
secure_action: secure

 

Lorsqu'un utilisateur authentifié mais ne possédant pas les credentials nécessaires accède à un page non-autorisée, il est redirigé vers l'action définie par le fichier /config/setting.yml (de l'application ou du module) de la manière suivante:

 

all:
.actions:
secure_module: auth
secure_action: secure

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();
$action = $context->getController()->getAction($module->getModuleName(), 'index');
$credential =  $action->getCredential();
$haveCredentials =$this->context->getUser()->hasCredential($credential);

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)

Architecture en classes du module de configuration

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:

Architecture en classes du 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 « 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
  • - executeNewPurchasse
  • - executeNewCountableService
  • - executeNewUnitaryService
  • - executeNewSubscription
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:
  • - achat
  • - abonnement
  • - service unitaire
  • - service comptable
Elle récupère les paramètres (id des utilisateurs, id de l'acte et id de la catégorie de public) et instancie le formulaire en le pré-remplissant à l'aide d'un objet de type correpondant. Elle apelle ensuite prepareToNewPage pour passer des variables au template.
executeCreate Cette méthode est le contrôleur pour la validation et l'enregistrement des formulaires de type:
  • - achat
  • - abonnement
  • - service unitaire
  • - service comptable
Elle récupère les paramètres et appelle processEachForm pour la validation et l'enregistrement. Elle redirige ensuite vers la page d'accueil des imputations ('use/index') si le formulaire est correct, sinon, elle le réaffiche avec les erreurs (prepareToErrorPage).
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

  • abstraite
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 :
  • - total des usages
  • - nombre de visiteurs uniques
  • - nombre d'utilisateurs réguliers
  • - total de la caisse
  • - nombre d'abonnements valide au début et à la fin de la période
  • - nombre et temps passés par les utilisateurs en fonction de leur catégorie.
La période est prédéfinie : il s'agit du mois en cours. Cette période n'est pas modifiable.
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.

 

Newsletter

Newsletter

Inscrivez-vous à notre newsletter


Création, développement, référencement et hébergement kyxar (romans - drome) développement kyxar Opérateur sur le réseau ADN / ADTiM (Fibre Optique, ADSL et SDSL) - Réseau de communication haut et très haut débit reliant la Drôme et l’Ardèche Creation Site Internet Drome - Creations Sites Web Drome (romans - valence - lyon - grenoble) Site Web Drome - Creations Sites Web Drome (romans - valence - lyon - grenoble) site internet intranet extranet (romans - valence - lyon - grenoble) Développement de site web PHP MySQL - Developpement web PHP MySQL en Rhone-Alpes Création Site Internet Valence Romans Drome - Réalisation  Sites Web Drôme Lyon (Rhône) Grenoble (Isére) Hébergement Web Lyon Grenoble Valence Romans Drome - Hebergements Sites Web : Internet Intranet Extranet Drome Conception Internet Intranet Extranet Lyon Grenoble Valence Romans Drome - Réalisation Internet Drome Fournisseur d'Applications Hebergees Internet Intranet Extranet (SOA) - Hebergement d'Application Hebergee Sur Romans Valence (Drome) Lyon Grenoble Référencement et Positionnement naturel Creation Site Web Drome Rhônes Alpes - Valence Romans Lyon (Rhone) Grenoble (Isere)