Project Documentation - DIUF
Transcription
Project Documentation - DIUF
ImmObjects Etude d'une application de gestion du patrimoine mobilier pour Apartis, fondation pour le logement des étudiants Projet de séminaire de 12 ECTS dans le cadre du Bachelor Frédéric Noyer Juillet 2009 Supervisé par : Prof. Dr. Jacques Pasquier-Rocha et Dr. Patrik Fuhrer Groupe Génie Logiciel Groupe Génie Logiciel Département d'Informatique Université de Fribourg (Suisse) Résumé L'objectif de ce travail de séminaire est de servir de base à la réalisation d'ImmObjects, Apartis, fondation pour le logement des étudiants. Il rend compte de la formulation des fonctionnalités expriune application de gestion du patrimoine mobilier commanditée par mées par le client et propose un modèle de données détaillé pour y répondre. Il mentionne les alternatives possibles en terme d'architectures, avant d'arrêter son choix sur le framework de développement web CakePHP. Ce travail explore ensuite l'intérêt que représente pour le processus de développement le script de génération de code automatique de CakePHP (scaolding) par un exemple tiré du modèle de données. Finalement, il décrit à grands traits les travaux à entreprendre pour poursuivre la réalisation d'ImmObjects. Mots clés : Web Application, PHP, CakePHP, Pattern MVC, Data Model, Requirements Engineering, Immobilier, ERM Module i Table des matières 1 Introduction 2 Formulation du cahier des charges 2 3 2.1 Déroulement du travail d'analyse . . . . . . . . . . . . . . . . . . . . . . 3 2.2 Description des fonctionnalités . . . . . . . . . . . . . . . . . . . . . . . . 4 3 Description du modèle de données 3.1 7 Modèle du parc immobilier . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.1.1 Représentation optimisée de structures d'arbre en SQL . . . . . . 8 3.1.2 Modèle de données normalisé du parc immobilier . . . . . . . . . 9 3.2 Modèle de l'inventaire et de l'entretien des objets . . . . . . . . . . . . . 11 3.3 Initialisation des données . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.3.1 Importation des données du parc immobilier . . . . . . . . . . . . 12 3.3.2 Initialisation des données de gestion des objets . . . . . . . . . . . 12 4 Discussion des choix techniques 4.1 4.2 15 Choix de l'architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.1.1 16 Choix du langage et du framework web . . . . . . . . . . . . . . . Description du framework CakePHP . . . . . . . . . . . . . . . . . . . . 16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 4.2.1 Documentation 4.2.2 Introduction au pattern Modèle-Vue-Contrôleur 4.2.3 Principales fonctionnalités du framework CakePHP . . . . . . . . . . . . . . . . . . 5 Exemples d'utilisation du framework CakePHP 5.1 5.2 17 18 19 Utilisation du script de génération de code . . . . . . . . . . . . . . . . . 19 5.1.1 Conguration de l'environnement . . . . . . . . . . . . . . . . . . 19 5.1.2 Création de la structure de la base de données . . . . . . . . . . . 19 5.1.3 Génération du modèle, du contrôleur et des vues CRUD . . . . . 20 . . . . . . . . . . . . . . . . . . . 24 Adaptation de l'échafaudage de départ ii 6 Conclusion A Page web du projet B CD-ROM Bibliographie Sites Web 26 28 29 31 32 Liste des gures 2.1 Projet de layout de l'interface d'ImmObjects . . . . . . . . . . . . . . . . 3.3 nested set . . . . . . . . . . . . Nested set comme intervalles sur un axe Nested set comme espaces emboîtés . . . 3.4 MySQL Workbench, outil de modélisation de base de données 3.1 3.2 Arbre de . . . . . . . . . . . . . . . . . . 8 . . . . . . . . . . . . . . . . . . 8 . . . . . . . . . . . . . . . . . . 9 . . . . . . 10 . . . . . . . . . . 13 . . . . . . . . . . 14 3.6 hiérarchie des espaces Schéma de base de données (2) : gestion des objets . . 4.1 Comparaison entre le ux de données d'un script PHP normal (haut) 3.5 6 Schéma de base de données (1) : et comment CakePHP gère les responsabilités des diérents composants quant à ce même ux (en bas). Schéma tire de [Gol08] et modié. . . . . 17 5.1 Formulaire d'ajout d'un nouveau concierge . . . . . . . . . . . . . . . . . 24 5.2 Achage des enregistrements de la table 6.1 Informations de debogage achées dynamiquement par CakePHP au sein même des pages générées. B.1 sites. . . . . . . . . . . . . . . 25 . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Hiérarchie des données dans le CD-ROM . . . . . . . . . . . . . . . . . . 30 iv Liste des tableaux 4.1 Exemple de nommage pour la classe 1 Caretaker . . . . . . . . . . . . . . . 18 1 Introduction ImmObjects est un projet réalisé par Frédéric Noyer pour le compte de la Apartis, Fondation pour le logement des étudiants. Elle est issue de la mue de l'ancienne Régie estudiantine crée en 1991. Elle est pilotée par un Conseil de fondation où sont représentées les principales parties prenantes à savoir, le Canton de Fribourg, l'Université de Fribourg et l'Association générale des étudiants (AGEF). La régie exploite près de 700 unités de logements réparties sur 17 immeubles situés à Fribourg, Villars-sur-Glâne, Marly et Givisiez. Elle emploie quinze personnes et réalise un chire d'aaires annuel d'environ 3 million de francs. Fondation sans but lucratif, Apartis réinvesti son bénéce auprès du service social de l'Université ou dans l'amélioration de ses bâtiments. C'est avec son directeur, M. Jean-Pierre Gauch, qu'a été établi le cahier des charges du système d'information. Le système d'information a été baptisé ImmObjects en contractant les idées d'immobilier et d'objets. Ces derniers étant compris comme l'ensemble des possessions d'une régie immobilière s'étendant des unités de logement aux équipements qui y sont installés. C'est uniquement la phase initiale de ce projet qui est présentée dans ce rapport. Elle a été réalisée sous la supervision du Prof. Dr. Jacques Pasquier-Rocha, professeur ordinaire au département d'informatique de l'Université de Fribourg et assisté du Dr. Patrick Fuhrer. Le professeur Pasquier dirige le groupe de génie logiciel. C'est d'entente avec ces deux enseignants qu'ont été xés les buts de ce travail. Les buts de ce travail sont de rendre compte de l'analyse complète des besoins réalisée de concert avec le client, de proposer un modèle de données, de discuter du choix des solutions techniques pour implémenter les services dénis par le cahier des charges. Puis nalement, d'illustrer ce choix par un exemple présentant un framework utilisé en situation. Cette installation ne représente en aucun cas un système complet. C'est de ce travail que rend compte le présent rapport par le plan suivant : une description des fonctionnalités attendues par le client, la description du modèle de données, une discussion sur les outils de développement adaptés, un exemple qui met en valeur les avantages de l'utilisation du framework choisi, et, pour conclure, une évocation des tâches qui seront à accomplir, hors du présent travail, pour remplir le cahier des charges déni. 2 2 Formulation du cahier des charges 2.1 Déroulement du travail d'analyse . . . . . . . . . . . . . . . . . 3 2.2 Description des fonctionnalités 4 . . . . . . . . . . . . . . . . . . L'idée de ce projet est partie du directeur d'Apartis, M. Jean-Pierre Gauch, qui regrettait les limitations de son logiciel de gestion, Quorum [14], lequel ne permettait que l'inventaire des chambres louées. En eet, ce système ne décrit le parc immobilier que dans ses aspects de liés à la location et ne tient pas compte des locaux communs comme les cuisines, salles de bain, caves, etc. Or, c'est dans ces pièces communes que la fondation possède la majorité des objets qui lui appartiennent en propre et qui nécessitent une maintenance régulière. C'est le cas de l'électroménager, la plomberie mais aussi des revêtements muraux et des sols. Cette activité d'entretien représente une part énorme du budget d'Apartis. Maîtriser l'inventaire de ces équipements et leurs coûts de maintenance permettrait une vision synthétique des investissements consentis ainsi qu'une bien meilleure planication budgétaire. Relever ce dé imposait de reprendre la structure lacunaire du parc immobilier de Quorum, de la compléter et d'y greer un inventaire de ces équipements. C'est ce que se propose de faire ImmObjects. 2.1 Déroulement du travail d'analyse La première phase du projet aura consisté en un diagnostic systématique des manques présentés par l'outil de gestion actuel. L'enjeu était de décider quelle devait être l'articulation exacte entre Quorum et la béquille que l'on se proposait de développer. La version de ce logiciel installée à Apartis est assez ancienne et totalement propriétaire. Cela ne permettait donc pas d'y intégrer un module complémentaire pour remplir cette nouvelle fonctionnalité. Le moteur de base de données utilisé étant tout sauf standard et ne fournissait pas d'accès vers ses tables. Envisager de greer une application séparée qui vienne lire directement les données dans Quorum était donc à exclure. Finalement la solution d'un export unique des données vers une application totalement autonome s'est imposée comme une évidence. La formulation des requirements a eu lieu dans la première phase du projet par des ren- contres avec le directeur et les utilisateurs naux du système. Les buts des ces rencontres ont tout d'abord été d'analyser en détail les spécicités du parc immobilier de la régie. Pour ce faire, on a construit avec eux la structure générique d'un immeuble et la liste des 2.2. 4 Description des fonctionnalités catégories d'objets qu'il contient. Dans une deuxième phase, les discussions ont portés sur l'identication des cas d'utilisation auxquels devrait répondre le système. Il en a résulté un projet de modèle de données présenté au client ainsi qu'aux superviseurs de ce séminaire. Les diérents feed-back et les question suscités par ce projet ont permis d'aner la représentation initiale. Par la suite, on s'est penché sur la discussion des aspects théorique de la réalisation. En particulier la recherche d'un framework apte à réaliser ce projet. Cela a fait apparaître les exigences imposées par un tel outil. Le modèle de données a donc été adapté en conséquence, entre autre en le traduisant en anglais. Finalement, c'est la version de ce modèle issue du cahier des charges et de la discussion technique qui est présenté dans le chapitre 3 de ce rapport. Parallèlement à ce travail, un nouvel élément est alors venu s'ajouter à la réexion. Apartis va madater la société Trilogis [15] pour réaliser un projet pilote de monitoring de la température et de gestion du chauage à distance. Ce projet présentait des besoins similaires à ImmObjects sur deux points : la nécessité d'importer les données du parc immobilier depuis Quorum, et la conception d'un nouveau modèle de données pour la description des unités de logement. Des synergies ont été trouvées en partageant ces tâches. Je me suis occupé du modèle de données et Trilogis a parser les données importées de Quorum du format Microsoft Excel vers un script SQL d'insertion dans la nouvelle structure de tables. 2.2 Description des fonctionnalités Suite aux entretiens avec le personnel d'Apartis, les fonctionnalités suivantes ont été identiées. Navigation et fonctions d'édition de bases Il est possible de visionner tout enregistrement au sein du modèle de données. L'utilisateur a également à sa disposition des fonctions complètes d'édition, de création et de suppression sur tout élément du modèle de données mis à part sur les unités de logements qui ont été importées de Quorum. Celles-ci ne sont accessibles qu'en lecture. En eet, les modications au parc immobilier feront l'objet de modications manuelles pour éviter l'apparition d'inconsistances dans les données. Plusieurs cas particuliers sont à noter : lors de la suppression totale d'un équipement, celui-ci se voit attribuer un évènement nal de sortie de l'inventaire, mais il n'est pas supprimé de la base de données ; lors du remplacement d'un équipement pour un nouveau modèle, il n'est pas crée de nouvelle instance de celui-ci, mais l'instance actuelle est modiée. Ainsi par exemple, lorsqu'un frigo est remplacé dans une cuisine, on modie le numéro de série de l'équipement en question et on lui attribue un nouvel évènement remplacement avec le montant de l'installation. Il n'y a donc pas de création de nouvelle instance d'un équipement ; lors de la création d'une nouvelle catégorie d'équipement, on a la possibilité de déterminer quels sont les attributs qui la concernent. Par exemple, un numéro de série et une couleur. Ceci dit, modier par a posteriori la liste des attributs d'une catégorie est risqué car cela peut laisser apparaître rapidement des inconsistances. 2.2. Description des fonctionnalités 5 De manière évidente, l'intérêt de cette fonctionnalité consiste dans la possibilité de nourrir le système en nouvelles informations de manière à le faire correspondre à la réalité actuelle du parc immobilier. A noter, qu'il incombe à Apartis de saisir dans le système les relevés qui ont été réalisés sur le terrain. De même, pour l'initialisation des données, tous les équipements présents dans le parc immobilier à ce jour se verront attribuer une date d'installation ctive correspondant à la date de rénovation du bâtiment où ils se trouvent. Recherche d'équipements sur la base de critères Il est possible d'acher un sous-groupe quelconque d'équipements. Cela sur la base d'une recherche comportant un maximum de 5 critères diérents. Les critères sont à choisir parmi : une ou plusieurs catégories d'équipements ; un ou plusieurs critères sur un champ texte descriptif ; un intervalle sur un champ temporel ; A noter que la portée de la recherche peut être réduite au niveau de la hiérarchie des espaces du parc immobilier (par exemple seulement à l'échelle d'un site, d'un bâtiment ou d'un étage). Et que la liste retournée des équipements peut être classé de diérentes manières. Cette fonctionnalité de recherche fournit des listes d'équipements qui servent à l'aide à la décision dans toutes sortes de situations. Par exemple pour l'établissement de budgets d'investissement ou la planication de rénovations. Achage de l'historique d'un équipement Lorsque l'on a navigué jusqu'à un équipement particulier, il est possible d'acher tous les évènements qui l'ont concerné. Chaque évènement est saisi avec le montant de la dépense qu'il a engendré. Les applications concrètes de cette fonctionnalités sont multiples. On peut par exemple déterminer l'âge d'un équipement. Mais aussi, à la vue de l'historique et des montants engagés et en appliquant l'amortissement communément admis, il est possible d'estimer sa valeur actuelle. Agrégation sur les montants dépensés pour un type d'évènement Il est possible d'acher la somme totale engagée pour un ou plusieurs types d'évènements (par exemple : installation et réparation). On peut également limiter les évènements concernés à un intervalle temporel et à un niveau de la hiérarchie des espaces (par exemple : un site, un bâtiment, etc.). Pouvoir récapituler les frais consentis dans un certain type d'entretien, permet une analyse a posteriori de la gestion et de la qualité des biens loués. Cela permet également à moyen terme d'estimer plus nement le budget à allouer aux frais d'entretien. 2.2. Description des fonctionnalités 6 Fig. 2.1: Projet de layout de l'interface d'ImmObjects La gure 2.1 représente un exemple de mise en page et de menus orant ces fonctionnalités. 3 Description du modèle de données 3.1 Modèle du parc immobilier . . . . . . . . . . . . . . . . . . . . . 3.1.1 3.1.2 Représentation optimisée de structures d'arbre en SQL . . . . . Modèle de données normalisé du parc immobilier . . . . . . . . 7 8 9 3.2 Modèle de l'inventaire et de l'entretien des objets . . . . . . . 11 3.3 Initialisation des données . . . . . . . . . . . . . . . . . . . . . . 12 3.3.1 3.3.2 Importation des données du parc immobilier . . . . . . . . . . . Initialisation des données de gestion des objets . . . . . . . . . 12 12 Il s'agissait de répondre au cahier des charges par un triple dispositif : un modèle de données permettant de rendre compte du parc immobilier d'Apartis, un mappage des données de description dans celui-ci, et l'ajout de fonctionnalités de gestion des équipements installés dans leurs locaux loués. On tenait à se limiter à une solution logicielle légère, garantissant une maintenance aisée. Le modèle de données d'ImmObjects est constitué de deux parties : la partie contenant le parc immobilier géré par Apartis et celle décrivant l'inventaire et l'historique de l'entretien des objets installés dans les locaux loués. 3.1 Modèle du parc immobilier Les possessions d'Apartis peuvent être représentées par une structure hiérarchique qui mène du plus général un site, soit un complexe de plusieurs bâtiments jusqu'à la pièce la plus petite unité constituante des biens gérés par la régie. Les données qui alimentent ces tables dans ImmObjects ont été importées depuis Quorum, le logiciel utilisé par la fondation pour la gestion des locations, dans lequel l'ensemble de leurs locaux loués ont déjà été saisis. Les cuisines, salles de bains, caves et autres locaux techniques qui étaient jusqu'alors absents du système car n'étant pas directement liés aux versements d'une location mensuelle y ont été progressivement introduits. Avant d'appliquer un modèle calssique de données solution nalement retenue nous avons malgré tout tenté d'explorer une structure optimisée pour les hiérarchies. 3.1. 8 Modèle du parc immobilier Fig. 3.1: Arbre de Fig. 3.2: Nested set nested set comme intervalles sur un axe 3.1.1 Représentation optimisée de structures d'arbre en SQL De manière générique, on pourrait réduire le modèle théorique du parc immobilier à une hiérarchie composée d' espaces emboîtés les uns dans les autres. Nous avons essayé de pousser cette conception jusqu'au bout en tentant de l'appliquer à sa dénition en SQL. Pour ce faire, nous nous sommes appuyés sur l'ouvrage de Joe Celko[Cel04]. Cela revient à une solution dites des nested sets qui prévoit que chaque élément de la hiérarchie soit dénit comme une intervalle caractérisée par une borne gauche et une borne droite. Soit, 1 CREATE TABLE P a r c I m m o b i l i e r NOT NULL PRIMARY KEY, 3 l f t INTEGER NOT NULL , r g t INTEGER NOT NULL ) ; L'idée principale peut être représentée de deux manières équivalentes, soit par des intervalles sur une droite comme le montre la gure 3.2, soit sous forme d'espaces emboîtés les uns dans les autres nested comme on peut le voir à l'aide de la gure 3.3. Cette dernière correspond intuitivement parfaitement au parc immobilier et à sa structure d'espaces eux-mêmes constitués de sous-espaces. Cette dénition d'une structure hiérarchique mieux adaptée à un langage descriptif comme le SQL, permet d'optimiser fortement les requêtes pour l'extraction d'un sous-arbre de données. Rappelons que la solution traditionnelle voudrait que l'on dénisse chaque niveau de l'arbre par une table distincte. Ainsi de manière triviale dans notre cas, une pour le bâtiment, une pour l'étage, une pour l'appartement, une pour la pièce. Pour obtenir 3.1. 9 Modèle du parc immobilier Fig. 3.3: Nested set comme espaces emboîtés la liste de toutes les pièces d'un appartement donné, la profondeur de l'arbre va avoir un impact considérable sur les performances puisque à chaque niveau va correspondre une nouvelle sous-requête. Or dans le cas des nested sets, une seule table sut pour stocker l'ensemble des espaces de l'arbre. De plus les propriétés annexes de la construction de l'arbre permettent d'optimiser les requêtes. Ainsi retourner une liste des pièces devient une requête portant sur l'unique table rassemblant l'ensemble de tous les espaces. Cette requête se limite à dénir les espaces compris dans l'intervalle de son parent. Soit : 1 SELECT A p a r t . espace AS appartement , Piece . espace AS p i e c e FROM P a r c I m m o b i l i e r AS Apart , P a r c I m m o b i l i e r AS Piece 3 WHERE p i e c e . l f t > appartement . l f t AND p i e c e . r g t < appartement . r g t ; Sans détailler plus avant cette solution alternative des nested sets, cette conception de la hiérarchie fournit des solutions relativement plus performantes pour des requêtes de sélection portant sur plusieurs niveaux de l'arbre. Plus la profondeur de l'arbre augmente, plus le gain de performances est grand puisque l'on évite le recours à une sousrequête par niveau. Ceci dit, l'élégance est, comme souvent en génie logiciel, au détriment de l'expressivité des requêtes. C'est bien visible dans l'exemple pré-cité qui prend la forme d'un self-joint ParcImmobilier. qui demande la dénition d'alias pour les deux instances de la table Quoi qu'il en soit, l'application de cette représentation d'une hiérar- chie n'a nalement pas été retenue pour deux raisons qui tiennent aux avantages de la solution choisie. En eet, le framework utilisé génére à la volée les requêtes SQL, et cela à condition de respecter strictement des conventions de nommage pour désigner les relations entre les tables. Ainsi, il n'y avait aucun sens d'adopter une structure non standard dont il aurait fallu re-adapter les relations pour se conformer aux exigences. C'est donc le modèle normalisé qui est le plus judicieux dans notre cas. 3.1.2 Modèle de données normalisé du parc immobilier Pour la représentation graphique et la modélisation, on a utilisé MySQL Workbench, visual database design for professionnals [7], qui ore l'avantage de pouvoir rapidement représenter des modèles de données complexes. Dans une deuxième phase, cet outil permet de générer des chiers .sql de création des tables à partir du modèle. De même, une fonction identique permet de générer une documentation un peu comme une Javadoc. On trouvera les script SQL de création des tables ainsi que la documentation de ces scripts sur le CD-ROM annexé (voir ./DBDocumentation_framed/index.html) ainsi qu'une capture d'écran de cet outil à la gure 3.4. 3.1. 10 Modèle du parc immobilier Fig. 3.4: MySQL Workbench, outil de modélisation de base de données Le schéma de données n'est pas exactement au standard UML, il est néanmoins d'une clarté indéniable. Les cardinalités des relations sont indiquées de manière standard. Les champs sont caractérisés par un symbole de clé (clé primaire), un diamant bleu plein (champ NOT NULL), un diamant bleu vide (champ NULL), et un diamant rouge vide (clé étrangère). La gure 3.5 (voir page 13) illustre la structure nale du modèle de données du parc immobilier. Les espaces y sont distribués dans plusieurs tables, une pour chaque niveau. Cela forme la colonne vertébrale de la hiérarchie. Le choix de l'anglais pour ce modèle s'explique là aussi par les conventions de CakePHP qui jouent sur le singulier et le pluriel des noms des objets (ainsi room et rooms ). Par défaut, les conventions supposent les niveau niveaux, ne fonctionne simplement pas. La documentation, essentiellement en anglais, règles du pluriels de l'orthographe anglaise. L'utilisation du français, comme dans et ne fait pas mention de ce petit détail qui a de quoi donner du l à retordre au développeur francophone qui cherche en vain le bug, certain d'avoir pourtant conguré correctement... La colonne vertébrale consiste en un hiérarchie de tables liées par une relation plusieurs un à du général au particulier. Cela se décline comme suit : sites, un groupe de bâtiments sur le même site ; buildings, un bâtiment caractérisé par une adresse (postale) ; floors, un étage caractérisé par un niveau ; premises, des locaux compris comme un ensemble de pièces groupées par une fonction ; rooms, une pièce caractérisée par une fonction particulière. On aura remarqué que les conventions du framework imposent que le nom de la table 3.2. 11 Modèle de l'inventaire et de l'entretien des objets soit mis au pluriel. Ce qui distingue celle-ci, nous allons le voir, de l'objet dont elle stocke les instances. L'utilisation d'une relation un à plusieurs illustre de manière triviale le fait qu'un site comporte plusieurs bâtiments, que chacun de ces bâtiments peut avoir plusieurs étages et ainsi de suite. Sur cette colonne vertébrale viennent se greer des tables annexes qui stockent les caractéristiques de chacun de ces le niveau espaces. Il s'agit du floor_types, soit auquel se trouve l'étage (floors). Cela permet de pouvoir gérer la gradation des étages avec des descriptions du genre premier sous-sol ou rez-de-chaussée. Pour ce qui est des locaux (premises), le premise_types vient préciser la fonction de ce groupe de pièces. Ainsi comme un appartement, un abri anti-atomique, un groupe de pièce qui room_types, sert de locaux de fête, etc. Quant au il vient là encore caractériser l'utilité d'une pièce spécique. Il peut s'agir d'une cuisine, d'une cave, d'une salle de bain, etc. L'ensemble concierge (table caretakers) et moyens de contact (table contact_means) vient recueillir l'annuaire des concierges engagés par Apartis. Ceux-ci peuvent se voir assigner un ou plusieurs immeubles. C'est donc naturellement une relation plusieurs qui le relie à la table buildings. plusieurs à 3.2 Modèle de l'inventaire et de l'entretien des objets Le but de l'application ImmObjects place de manière évidente au centre le concept d'objet (table equipements), comme le montre la gure 3.6. Cela recouvre n'importe quel équipement appartenant à Apartis dans les pièces louées. C'est à dire autant des appareils ménagers comme un frigo que des surfaces murales ou du carrelage. Gérer ces objets revient théoriquement à trois choses : en tenir la liste exhaustive à jour ; déterminer pour chacun d'entre eux à quel groupe général il appartient et quelles sont ses caractéristiques propres ; garder trace de l'historique des interventions dont il a fait l'objet. Pour rendre compte de cette réalité, la première tâche est aisément remplie par la table equipements elle-même dont chaque enregistrement représente un objet. Une instance d'objet est caractérisé par deux relations fondamentales. Il est situé dans une pièce (table room) dont la clé étrangère room_id rend compte. C'est par ce lien que les équipements s'insèrent dans l'ensemble du parc immobilier, chacun dans une seule pièce. La seconde relation fondamentale est celle qui détermine la catégorie de l'objet. L'appartenance d'un objet à une seule catégorie permet d'aner les fonctions du module d'analyse de données en fournissant des statistiques par catégories. De plus, cette appartenance va déterminer quels sont les attributs obligatoires pour un tel équipement, lesquels seront diérents pour une lampe halogène que pour un évier. Au-delà de ces deux relations, chaque équipements voit son historique d'entretien stocké sous la forme de plusieurs évènements (table events) dont chacun est caractérisé logi- quement par une date, un coût. On dénit un nombre limité de type d'évènements (table event_types) dont on doit assigner exactement l'un d'entre à un évènement. Les relations circulaires entre les tables equipements, categories et attributs sont un peu plus abstraites à décrire sans devenir verbeux. Un exemple devrait clarier le principe. Pour créer un nouvel équipement tel qu'un frigo catégorie électroménager on doit renseigner deux attributs. Pour savoir lesquels, c'est une requête sur la table de liaison attributes_categories qui va nous apprendre quels sont les attributes.id 3.3. 12 Initialisation des données concernés : en l'occurrence il s'agira du numéro de série et du modèle. Les valeurs de ces deux attributs pour ce frigo spécique seront stockées dans la table de liaison attributes_equipements avec le champs equipement_id portant la valeur correspon- dant à cet équipement particulier. 3.3 Initialisation des données 3.3.1 Importation des données du parc immobilier Les données pour peupler la hiérarchie des espaces sont issues du logiciel de gestion des location Quorum. Celui-ci utilise un moteur de base de données du nom de Progress [1]. Heureusement, l'interface fournit un export des bases vers des tables Microsoft Excel, ce qui a permis d'en extraire les enregistrements. Les champs de ces diérentes tables ont été mappés pour venir peupler les tables prévues. On les a répartis dans les tables stockant respectivement les bâtiments, étages, locaux et pièces. Les champs de ces tables ont été remplis par nos soins. C'est un ltre d'export en PHP, réalisé par l'un des développeurs de Trilogis qui a formaté ces données pour les intégrer dans ImmObjects. En accord avec Apartis, la procédure en cas de modication du parc immobilier a été dénie comme suit : il a été décidé de faire un import initial unique depuis Quorum vers les tables MySQL d'ImmObjects. A l'avenir, les données ne seront travaillées en écriture que dans notre application. Ces changements ne seront reportés vers l'application de gestion à distances des thermostats développée par Trilogis que par un script d'export SQL. Les données des tables annexes ont été principalement saisies manuellement ou inspirées de Quorum. C'est le cas par exemple pour les types de pièces (table les dénominations des étages (table floor_types). room_types) ou pour 3.3.2 Initialisation des données de gestion des objets A la n de l'année 2008, Apartis a employé une collaboratrice en vue d'inventorier manuellement l'ensemble des objets présents dans des bâtiments d'Apartis. Elle a produit une table Microsoft Excel par appartement relevant les appareils ménagers et leur numéro de série ainsi que les détails des agencements de cuisine. Ces données n'étant pas standardisées et partiellement lacunaires, il a été convenu avec Apartis qu'elle seront saisies manuellement dans ImmObjects pour servir de données d'initialisation. Dès la validation des masques de création, d'édition et de suppression de cette partie du programme. Cela permettra du même coup aux employés de la fondation de donner un premier feed-back sur l'ergonomie du système. Apartis a décidé de ne pas tenir compte de l'historique passé des objets, mais de saisir les évènements à venir. Le module de reporting mettra donc un certain temps à pouvoir donner toute sa mesure. Néanmoins, chaque objet s'est vu attribué une date d'installation initiale, mais sans montant. Il sera déterminé par l'âge du bâtiment dans lequel l'équipement se trouve. C'est l'utilité des champs buildings.entryDate. 3.3. 13 Initialisation des données Fig. 3.5: Schéma de base de données (1) : hiérarchie des espaces 3.3. 14 Initialisation des données Fig. 3.6: Schéma de base de données (2) : gestion des objets 4 Discussion des choix techniques 4.1 Choix de l'architecture 4.1.1 4.2 . . . . . . . . . . . . . . . . . . . . . . . Choix du langage et du framework web . . . . . . . . . . . . . . Description du framework CakePHP . . . . . . . . . . . . . . . 4.2.1 4.2.2 4.2.3 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . Introduction au pattern Modèle-Vue-Contrôleur . . . . . . . . . Principales fonctionnalités du framework CakePHP . . . . . . . 15 16 16 16 17 18 Après l'évaluation de divers types de modèles de données et d'architectures, c'est la solution de l'application web qui s'est imposée. Celle-ci fournissant à la fois frugalité de mise en ÷uvre et d'entretien ainsi que les garanties susantes de documentation pour constituer une solution à long terme. On aura évité l'originalité au prot de solutions éprouvées. C'est la raison principale du choix d'un framework web basé sur un silo classique deux tiers Apache [19] et MySQL [18] avec PHP [17] comme langage de programmation. 4.1 Choix de l'architecture La réexion quant à l'architecture à adopter a porté sur le choix entre une solution centrée autour d'un client lourd ou d'un binôme client-serveur. En faveur du client lourd parlait le très petit nombre d'utilisateurs, la concentration de ceux-ci sur un seul site. Mais avec, par contre, le défaut de multiplier les travaux de maintenance sur chacune des stations de travail : déploiement, mise à jour des clients, validation après chaque mise à jour de l'environnement applicatif. Finalement, une application web semblait la meilleure réponse à ces défauts tant la technologie des frameworks web a évolué pour allier une rapidité de développement et une exibilité de déploiement. Le déploiement se résumait à peu de choses, Apartis disposant déjà d'une machine virtuelle, tournant sous Microsoft Windows Serveur R2, hébergée par le Service informatique de l'Université et apte à accueillir le serveur web et la base de données. C'était susant pour arrêter le choix d'un serveur de type WAMP [20] dont les solutions clé-en-main son nombreuses sous Windows. Parmi ce volumineux panel, on a retenu XAMPP [12] qui est l'un des plus répandus et des plus complets. 4.2. Description du framework CakePHP 16 4.1.1 Choix du langage et du framework web Restait à choisir le langage à utiliser. Les outils de développement web se sont multipliés dans chacun des langages de programmation vedettes. En particulier avec la variété des frameworks implémentant le design pattern Modèle/Vue/Contrôleur qui ont euri à la suite de Ruby on Rails [5]. Ce dernier a attiré dès sa sortie en 2004 beaucoup de programmeurs Java à la recherche d'une meilleure solution de développement web. La communauté autour du langage de Sun peu orientée vers les besoins légers du développement web dynamique ne prendra cette voie qu'avec un certain retard. Actuellement, l'une des options est celle du binôme Groovy Grail, un portage du principe de Ruby on Rails. Apartis tenait, avec raison, à choisir un langage qui draine une importante communauté de développeurs de manière à éviter d'avoir à chercher péniblement la perle rare pour assurer la maintenance du système à long terme. Cela écartait l'excellent Django [4] dont la popularité a cru fortement ces dernières années. Ce dernier avait l'air prometteur, au point de lui avoir consacré un week-end de tests, mais il a le défaut d'être basé sur le langage Python moins courant chez les développeurs que PHP. La communauté PHP propose de nombreuses implémentations du design pattern MVC. Or CakePHP n'était pas a priori le leader sur ce créneau. Ainsi on trouve le précurseur Zend [10] issu du groupe des créateurs du langage. Il a la réputation d'être plutôt destiné à de gros projets car d'une mise en oeuvre assez lourde. Autre concurrent très populaire, Symphony [9] par exemple, fait usage de chiers de description de données pour lesquels il utilise yalm [8], un langage de sérialisation de données. Cette méthode bien que plus exible n'a pas été retenue, pour tirer le prot maximal de l'avantage de CakePHP du codage par convention. Cet eort n'est plus une contrainte dans le cas de projets ex nihilo, comme c'est le cas pour ImmObjects, puisqu'il était possible de dénir très librement les conventions de nommage à appliquer au modèle de données. C'est nalement donc CakePHP qui semblait le framework le plus adapté au besoins relativement légers de ce projet tout en étant un acteur mature de la scène du développement web en PHP. 4.2 Description du framework CakePHP 4.2.1 Documentation Il existe une abondante documentation online à propos de CakePHP, dont le c÷ur est sans doute le site de l'équipe de développement [2]. Tout particulièrement utile est la documentation complète de l'ensemble des classes de CakePHP [6]. Mais son succès a produit plusieurs ouvrages techniques que nous avons utilisés pour nous introduire à cette Beginning CakePHP [Gol08], CakePHP Application Development [Sya08] qui donnent une vision progressive et illustrée des fonctionnalités du framework. Enn Practical CakePHP Project [Mil09] qui fournit des technologie. Dans un ordre croissant de diculté, signalons : exemples concrets d'applications qui démontrent comment jeter des ponts vers d'autres techniques comme les tests unitaires, vers des librairies comme Google Maps [?] ou Google Translator [16] ou comment étendre un site dynamique en CakePHP vers un CMS fait maison. 4.2. Description du framework CakePHP 17 Fig. 4.1: Comparaison entre le ux de données d'un script PHP normal (haut) et comment CakePHP gère les responsabilités des diérents composants quant à ce même ux (en bas). Schéma tire de [Gol08] et modié. 4.2.2 Introduction au pattern Modèle-Vue-Contrôleur Le principe central en est certainement le pattern Modèle-Vue-Contrôleur (ou MVC) [13]. En comparant, grâce à la gure 4.1, le principe de base des langage de programmation tel que PHP et la distribution des responsabilités dans l'implémentation du pattern MVC par CakePHP, on voit clairement l'intérêt de cette technologie. Le processus de traitement de la requête provenant du client est partagée entre les trois éléments constitutifs du pattern. Le modèle est directement lié à une structure de données (généralement une table) dont il constitue l'interface. Les relations éventuelles avec d'autres modèles sont également dénies à cet endroit. Toutes les actions concernant ce modèle comme par exemple pour une queue d'impression, vider la queue ou acher la liste des jobs doivent être implémentées dans le modèle. On dit que la logique métier de l'application est dénie dans les modèles. Chaque contrôleur sera appelé uniquement lorsque la requête correspondante est reçue du client. Pour préparer la réponse à cette requête, le contrôleur contient la suite des actions à entreprendre, mais pas le détails des actions elles-mêmes. Il va déléguer aux modèles concernés ces tâches en leur donnant l'ordre d'eectuer telle ou telle opération 4.2. 18 Description du framework CakePHP Type Nom chier. modèle caretaker.php controleur caretaker_controller.php vue Nom classe Repertoire Caretaker app/models CaretakersController app/controllers list.ctp app/views/caretakers Tab. 4.1: Exemple de nommage pour la classe Caretaker de logique métier. Les modèles vont retourner au contrôleur le résultat de leurs tâches. Ces résultats vont être passés à la vue pour leur donner une forme à même d'être transmise en réponse au client. On résume cette manière du contrôleur de déléguer en utilisant l'image des contrôleurs maigres versus modèles gras. La vue est une mise en forme en HTML de la réponse produite par l'application à la requête du client. La vue comporte des bouts de code PHP qui permettent d'intégrer dynamiquement les données transmises par le contrôleur. Le gain évident du pattern MVC tient au fait qu'il structure le code dans des segments modulaires qui sont clairement distincts. Cela facilite les modications et le débogage, le refactoring et la réutilisation de bouts de code. 4.2.3 Principales fonctionnalités du framework CakePHP Le trait caractéristique de CakePHP par rapport à d'autres comme Symphony par exemple, est que ce framework privilégie les conventions par rapport à la conguration. Cela impose des contraintes dans le choix du nom des tables, des chiers sources PHP qui dénissent un modèle, son contrôleur et l'arborescence de ses vues. L'utilisateur du framework n'a qu'un seul chier de conguration a modier obligatoirement, celui détermine les paramètres de connexion à la base de données. Ces conventions peuvent être volontairement ignorées en précisant à l'intérieur des éléments le nom des autres pièces du trinôme MVC. Cela pourrait permettre, par exemple, d'intégrer un module développé en CakePHP sur une base de données déjà existante dont on doit mapper les diérents champs. CakePHP fournit également un outil en ligne de commande qui permet de générer automatiquement le modèle, le contrôleur ou les vues des fonctions CRUD (pour Update, Delete) Create, Read, à partir du schéma d'une table. Une autre fonctionnalité très pratique consiste en une couche d'abstraction des données qui est capable de prendre en charge l'ensemble des requêtes SQL entre les modèles et la base de données. Ces mécanismes génèrent à la volée les requêtes SQL pour remplir les tâches business implémentées dans le modèle. Mais il est aussi possible de passer au framework des requêtes personnalisées dont il renvoie simplement les résultats. L'avantage d'un framework tel que CakePHP est de permettre d'intégrer aisément des bouts de code écrits par d'autres pour réaliser des tâches spéciques. La communauté des développeurs en a produit déjà une importante collection [3]. Ces solutions sont simplement partagées par leur auteurs et, en conséquence, pas toujours très bien documentées. Selon leur mode d'utilisation, on les répartit en catégories comme sion de contrôleur), helpers (extension de vue), models behaviors (exten- (modèle pré-congurer avec leur fonctions CRUD pour certaines sources de données courantes), prêtes à l'emploi), components plugins (mini-applications (aide à l'intérieur d'un modèle pour réaliser une tâche très spécique). A ce stade du projet ImmObjects, néanmoins, il n'a pas encore été nécessaire de faire appel à l'une de ces extensions. 5 Exemples d'utilisation du framework CakePHP 5.1 Utilisation du script de génération de code . . . . . . . . . . . 5.1.1 5.1.2 5.1.3 5.2 Conguration de l'environnement . . . . . . . . . . . . . . . . . Création de la structure de la base de données . . . . . . . . . . Génération du modèle, du contrôleur et des vues CRUD . . . . Adaptation de l'échafaudage de départ . . . . . . . . . . . . . 19 19 19 20 24 5.1 Utilisation du script de génération de code 5.1.1 Conguration de l'environnement La mise en place d'une instance du framework est d'une grande simplicité. L'on se procurera une version récente de CakePHP sur le site ociel [2]. La version utilisée est 1.2.3.8166, la distribution stable la plus récente. Une fois l'archive de la version actuelle de CakePHP déployée dans un répertoire du serveur web, il ne reste qu'à congurer la connexion avec un moteur de base de données accessible. Dans le cas d'ImmObject, nous avons équipé la machine virtuelle d'Apartis avec un serveur web Apache (version 2.2.11) et d'une base de données MySQL (version 5.1.33). Le module PHP d'Apache permet l'usage de la version 5.2.9 du langage. C'est un serveur FTP Filezilla (version 0.9) qui permet d'accéder avec le protocole FTP aux répertoires du serveur web. La conguration de l'accès à la base est une formalité qui se limite à compléter les champs du chier ./app/config/database.php. CakePHP prend en charge l'ensemble des produits phares dans ce domaine. 5.1.2 Création de la structure de la base de données Pour ImmObjects, nous avons utilisé un script SQL pour générer l'ensemble des tables et les peupler avec les données d'initialisation. Le listing 5.1 est l'extrait de ce script concernant la table concierges (caretakers). De même pour la table contact_means (listing 5.2) destinée à stocker les diérents coordonnées de contact des concierges, comme 5.1. 20 Utilisation du script de génération de code leurs numéros de téléphone ou leur adresse e-mail. Ces deux tables sont liées par une relations de un à plusieurs (voir gure 3.5 en page 13) puisque l'on doit pouvoir répertorier plusieurs moyens de contacter un concierge. C'est la clé étrangère table 2 4 6 8 10 contact_means caretaker_id dans la qui en témoigne. CREATE TABLE ‘ c a r e t a k e r s ‘ ( ‘ i d ‘ i n t ( 1 1 ) NOT NULL AUTO_INCREMENT, ‘ employeeNumber ‘ v a r c h a r ( 2 5 5 ) COLLATE u t f 8 _ b i n DEFAULT NULL , ‘ name ‘ v a r c h a r ( 2 5 5 ) COLLATE u t f 8 _ b i n NOT NULL , ‘ f i r s t N a m e ‘ v a r c h a r ( 2 5 5 ) COLLATE u t f 8 _ b i n NOT NULL , ‘ address ‘ v a r c h a r ( 2 5 5 ) COLLATE u t f 8 _ b i n DEFAULT NULL , ‘ postcode ‘ v a r c h a r ( 1 0 ) COLLATE u t f 8 _ b i n DEFAULT NULL , ‘ l o c a l i t y ‘ v a r c h a r ( 2 5 5 ) COLLATE u t f 8 _ b i n DEFAULT NULL , PRIMARY KEY ( ‘ i d ‘ ) ) ENGINE=InnoDB DEFAULT CHARSET= u t f 8 COLLATE= u t f 8 _ b i n ; Listing 5.1: Script SQL de génération de la table caretakers. CREATE TABLE ‘ contact_means ‘ ( ‘ i d ‘ i n t ( 1 1 ) NOT NULL AUTO_INCREMENT, ‘ contactReference ‘ v a r c h a r ( 2 5 5 ) COLLATE u t f 8 _ b i n NOT NULL , 4 ‘ c a r e t a k e r _ i d ‘ i n t ( 1 1 ) NOT NULL , PRIMARY KEY ( ‘ i d ‘ ) , 6 KEY ‘ FK_caretaker_id ‘ ( ‘ c a r e t a k e r _ i d ‘ ) ) ENGINE=InnoDB DEFAULT CHARSET= u t f 8 COLLATE= u t f 8 _ b i n ; 2 Listing 5.2: Script de génération de la table contact_means. 5.1.3 Génération du modèle, du contrôleur et des vues CRUD Création du modèle CakePHP fournit un outil en ligne de commande pour générer les diérents éléments lié à une classe particulière sur la base de la structure de la table concernée. Elle génère les modèles ainsi que les associations entre eux. Le listing 5.3 montre un output de ce processus pour la table caretaker. 1 C : \ ImmObjects \ TESTstack \ xampp \ htdocs \ immobjects >cake bake 3 Welcome t o CakePHP v1 . 2 . 3 . 8 1 6 6 Console −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− 5 App : app Path : C : / ImmObjects / TESTstack / xampp / htdocs / immobjects / app 7 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− I n t e r a c t i v e Bake S h e l l 9 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− [ D ] atabase C o n f i g u r a t i o n 11 [M] o d e l [ V ] iew 13 [ C ] o n t r o l l e r [P] roject 15 [Q] u i t What would you l i k e t o Bake? (D /M/ V / C / P /Q) 17 > m −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− 19 Bake Model Path : C : / ImmObjects / TESTstack / xampp / htdocs / immobjects \ app \ models \ 21 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Use Database C o n f i g : ( d e f a u l t / t e s t ) 23 [ d e f a u l t ] > P o s s i b l e Models based on your c u r r e n t database : 25 1 . A t t r i b u t e 2. AttributesCategory 27 3 . A t t r i b u t e s E q u i p e m e n t 5.1. 21 Utilisation du script de génération de code 4. Building 29 5 . C a r e t a k e r 6 . Category 31 7 . ContactMean 33 E n t e r a number from t h e [q] > 35 Would [y] > 37 Would [y] > l i s t above , t y p e i n t h e name o f a n o t h e r model , o r ’ q ’ t o e x i t 5 you l i k e t o s u p p l y v a l i d a t i o n c r i t e r i a f o r t h e f i e l d s i n your model? ( y / n ) n you l i k e t o d e f i n e model a s s o c i a t i o n s ( hasMany , hasOne , belongsTo , e t c . ) ? ( y / n ) y 39 One moment while t h e a s s o c i a t i o n s are d e t e c t e d . 41 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Please c o n f i r m t h e f o l l o w i n g a s s o c i a t i o n s : 43 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− C a r e t a k e r hasMany ContactMean? ( y / n ) 45 [ y ] > y C a r e t a k e r hasOne ContactMean? ( y / n ) 47 [ y ] > n Would you l i k e t o d e f i n e some a d d i t i o n a l model a s s o c i a t i o n s ? ( y / n ) 49 [ n ] > n 51 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− The f o l l o w i n g Model w i l l be c r e a t e d : 53 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Name : Caretaker 55 A s s o c i a t i o n s : C a r e t a k e r hasMany ContactMean −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− Listing 5.3: Output de l'outil de génération de code lors de la création du modèle pour la table Caretaker. Cette commande aura généré le chier ./app/models/caretaker.php (voir listing 5.4). L'examen de ce chier révèle que CakePHP a créé uniquement le code minimum. Il n'y a aucune fonctionnalité pour l'instant. Le nom de la classe est choisi selon le nom de la table mais au singulier et en lui mettant une majuscule, comme c'est le cas habituellement AppModel. N'est entre caretakers et pour les classes. Cette classe étend le modèle générique de CakePHP caretaker.php que la relation contact_means. Pour cela, on utilise l'array $hasMany (listing ?? ligne 4), lequel contient dénit explicitement dans le chier la liste exhaustive de toutes les relations un-à-plusieurs. Pour chacune d'entre elles, on crée un nouvel array qui précise les paramètres du modèle liés par cette relation : le nom de sa classe, le nom de la clé étrangère de caretaker dans la table liée et si l'eacement d'un enregistrement de concierge doit être propagé aux enregistrements liés. <?php 2 class C a r e t a k e r extends AppModel { / / r e l a t i o n ’ c a r e t a k e r ’ has many ’ contact_mean ’ v a r $hasMany = a r r a y ( ’ ContactMean ’ => a r r a y ( ’ className ’ => ’ ContactMean ’ , h t t p : / / a p i . cakephp . org / c l a s s e s ’ f o r e i g n K e y ’ => ’ c a r e t a k e r _ i d ’ , ’ dependent ’ => f a l s e ) ); 4 6 8 10 } 12 ?> Listing 5.4: Modèle caretaker.php 5.1. 22 Utilisation du script de génération de code Création du contrôleur Même principe pour générer le contrôleur, le listing Listing 5.5 présente la partie centrale de ce processus. A la de celui-ci, les lignes 7-8 montrent les méthodes des fonctions CRUD générées par défaut par CakePHP. −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− 2 Baking C a r e t a k e r s C o n t r o l l e r −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− interactively? Warning : Choosing no w i l l o v e r w r i t e t h e C a r e t a k e r s C o n t r o l l e r . ( y / n ) 6 [y] > n Would you l i k e t o i n c l u d e some b a s i c class methods ( i n d e x ( ) , add ( ) , view ( ) , e d i t ( ) ) ? ( y / n ) 8 [y] > y 4 Would you l i k e t o b u i l d your c o n t r o l l e r Listing 5.5: Création du contrôleur pour la table Le système a alors crée le chier caretakers ./app/controllers/caretakers_controller.php le- quel est présenté dans le listing Listing 5.6. <?php 2 class C a r e t a k e r s C o n t r o l l e r extends A p p C o n t r o l l e r { 4 v a r $ h e l p e r s = a r r a y ( ’ Html ’ , ’ Form ’ ) ; 6 // // i c i f u n c t i o n index ( ) i c i f u n c t i o n view ( ) ... ... 8 10 12 14 16 18 20 22 f u n c t i o n add ( ) { i f ( ! empty ( $ t h i s −>data ) ) { $ t h i s −>Caretaker −>c r e a t e ( ) ; i f ( $ t h i s −>Caretaker −>save ( $ t h i s −>data ) ) { $ t h i s −>Session−>s e t F l a s h ( __ ( ’ The C a r e t a k e r has been saved ’ , t r u e ) ) ; $ t h i s −> r e d i r e c t ( a r r a y ( ’ a c t i o n ’ => ’ i n d e x ’ ) ) ; } else { $ t h i s −>Session−>s e t F l a s h ( __ ( ’ The C a r e t a k e r c o u l d n o t be saved . Please , t r y again . ’ , true ) ) ; } } } // i c i function edit () ... // i c i function delete ( ) . . . }? > Listing 5.6: Contrôleur caretaker_controller.php On voit à la ligne 2 que, pour le nom de la classe et la classe parent AppControler, c'est le même principe que dans le cas du modèle. Conformément à son rôle, le contrôleur dénit les étapes du processus pour chacune des fonctions CRUD : lister, acher, ajouter un nouveau concierge, éditer ou supprimer l'un des enregistrement. Cependant, le contrôleur ne contient aucune implémentation de ces opérations, il en appelle aux fonctions dénies dans le modèle, ou dans le cas de ces fonctions de base du toute interface utilisateur aux méthodes dénies dans la classe parent du modèle Pour l'exemple, nous nous sommes limité à présenter caretaker.php : AppModel. la fonction add(). On voit cette manière de déléguer la responsabilité au modèle à la ligne 11, avec l'invocation de la méthode create() de la classe Caretaker. Cette fonction initialise le modèle pour la saisie d'un nouvel enregistrement en récupérant les éventuelles valeurs par défaut dans la base. Puis, à la ligne suivante l'instruction $this->Caretaker->save($this->data) est vrai si, de retour du formulaire de saisie, le modèle a renvoyé la référence vers un array de données dans $this->data. Lequel array a la forme générique suivante : 5.1. 23 Utilisation du script de génération de code Array 2 ( [ ModelName ] => A r r a y ( [ f i e l d n a m e 1 ] => ’ v a l u e ’ [ f i e l d n a m e 2 ] => ’ v a l u e ’ ) 4 6 8 ) Le reste du code du contrôleur ne concerne que la gestion d'erreur qui est, elle aussi, judicieusement générée par défaut. Il ne reste plus qu'à créer les vues pour chacune des fonctions dénies dans le contrôleur. Création des vues L'outil en ligne de commande est d'une utilisation parfaitement similaire à la création du modèle et du contrôleur. Il va créer quatre chiers, un pour chaque masque d'achage. Concrètement, il s'agit de chiers qui prendront le nom de la fonction correspondante dans le contrôleur : index.ctp, view.ctp, add.ctp et edit.ctp. On se contentera de détailler dans le listing 5.7 le masque d'ajout pour démontrer le principe. A noter que la traduction en français de ce formulaire a été faite manuellement par après. < d i v class= " c a r e t a k e r s form " > 2 <?php echo $form−>c r e a t e ( ’ C a r e t a k e r ’ ) ;? > 4 6 8 10 12 14 16 18 20 22 <fieldset > <legend ><?php __ ( ’ A j o u r d \ ’ un c o n c i e r g e ’ ) ;? > </ legend > <?php echo $form−>i n p u t ( ’ numéro d \ ’ employé ’ ) ; echo $form−>i n p u t ( ’nom ’ ) ; echo $form−>i n p u t ( ’ prénom ’ ) ; echo $form−>i n p u t ( ’ adresse ’ ) ; echo $form−>i n p u t ( ’ code p o s t a l ’ ) ; echo $form−>i n p u t ( ’ l o c a l i t é ’ ) ; ?> </ f i e l d s e t > <?php echo $form−>end ( ’ Submit ’ ) ;? > </ d i v > < d i v class= " a c t i o n s " > <ul > < l i ><?php echo $html −> l i n k ( __ ( ’ L i s t e des c o n c i e r g e s ’ , t r u e ) , a r r a y ( ’ a c t i o n ’ => ’ i n d e x ’ ) ) ;? > </ l i > < l i ><?php echo $html −> l i n k ( __ ( ’ L i s t e des données de c o n t a c t ’ , t r u e ) , a r r a y ( ’ c o n t r o l l e r ’ => ’ contact_means ’ , ’ a c t i o n ’ => ’ i n d e x ’ ) ) ; ?> </ l i > < l i ><?php echo $html −> l i n k ( __ ( ’ A j o u t de données de c o n t a c t ’ , t r u e ) , a r r a y ( ’ c o n t r o l l e r ’ => ’ contact_means ’ , ’ a c t i o n ’ => ’ add ’ ) ) ; ?> </ l i > </ u l > </ d i v > Listing 5.7: Vue La balise HTML add.ctp pour l'ajout d'un nouveau concierge <div class=caretaker form> dont le script PHP va générer le contenu à la volée, ne présente aucune diculté particulière. Ce script, appelé par le contrôleur caretaker_controller.php, ne fait que d'enrober le formulaire dans un tag <fieldset>. Les paramètres de $form->input n'est que le label apposé à côté du champ de saisie. Et la navigation du client vers cette page produit le résultat reproduit à la gure 5.1 en page 24. Le processus serait parfaitement identique pour la table contact_means qui viendrait compléter les informations à propos des concierges. Nous avons vu la manière par laquelle CakePHP permet de créer très rapidement les échafaudages (scaolding en anglais) d'une application en générant les masques des fonctions CRUD sur la base du schéma de données. 5.2. Adaptation de l'échafaudage de départ 24 Fig. 5.1: Formulaire d'ajout d'un nouveau concierge 5.2 Adaptation de l'échafaudage de départ Les opérations de navigation, d'édition et de saisie fournies par défaut grâce à CakePHP permettent de réaliser toutes les fonctionnalités de base très rapidement. Certains détails, qui sont souvent fastidieux, sont déjà pris en compte. Comme par exemple, la liste des enregistrements dans une table (voir gure 5.2) ache automatiquement un système de navigation par pagination en-dessous des entrées elles-mêmes et un compteur qui indique l'intervalle au-dessus. Cette présentation n'est probablement pas judicieuse dans tous les cas de gure. Mais comme pour toutes les bouts de code fournis par le framework, ils peuvent être réutilisés tels quels dans un autre contexte où ils se justient. Cependant, ces automatismes ne doivent pas faire oublier qu'ils ne sont que le préalable à un gros travail d'adaptation et de modication qui touche tous les aspects de l'application. La partie la plus conséquente consiste à donner une cohérence aux actions oertes à l'utilisateur dans chacune des vues. En eet, le script de CakePHP génère l'ensemble 5.2. 25 Adaptation de l'échafaudage de départ Fig. 5.2: Achage des enregistrements de la table sites. des fonctions CRUD, ce qui a pour conséquence que les écrans obtenus sont pourvus de certaines vues qui n'ont pas forcément de sens dans l'application. C'est à partir de cet échafaudage fourni par CakePHP qu'il faut donner une logique à la navigation pour donner corps aux cas d'utilisation. Après avoir choisi le framework et l'avoir testé, on peut débuter l'implémentation en s'attaquant unes-à-unes aux fonctionnalités décrites par le client dans le cahier des charges. En particulier, le masque de recherche qui permet à l'utilisateur de retrouver aisément un sous-ensemble d'unités de logement. Celui-ci, par le jeu de champs à choix multiples d'un formulaire de saisie, rassemblera les critères de recherche choisis par l'utilisateur. Sur la base de ceux-ci, une requête SQL est créée. Elle sera passée à CakePHP et l'achage de son résultat (par exemple un appartement particulier du parc immobilier) ouvre sur des fonctions de gestion des équipements (création d'un nouvel équipement, modication de l'historique, etc.). Pour améliorer la représentation que l'utilisateur se fait du parc immobilier, il serait judicieux de fournir un autre moyen de navigation. Comme un écran dans lequel les unités de logement soient représentées par un contrôle semblable à une tree view ). arborescence de chiers ( De nombreuses implémentations de ce type existent déjà prêtes à être intégrées dans du code PHP. Cela permettrait de descendre visuellement du site vers un appartement particulier par exemple. Cette méthode complèterait l'écran de recherche précédemment décrit. L'un des autres gros points concerne les écrans qui achent les récapitulatifs des frais engagés par catégorie d'équipements ou par type d'évènement. Les détails des calculs pourraient être réservés à la génération d'un chier .xls qui permettrait de poursuivre l'analyse des données dans des programmes externes. Finalement, il faut particulièrement soigner l'ergonomie des menus de manière à faire du site ImmObjects une réelle application web. Pour ce faire, CakePHP propose des helpers fournissant des interfaces pour utiliser des technologies d'achage avancées comme Ajax ou ash. 6 Conclusion Portée de ce travail Dans ce rapport, nous avons pu récolter les exigences de fonctionnalités de manière sufsamment précise pour permettre la réalisation d'un modèle de données. Nous avons pu armer que ce modèle est à la fois capable de répondre au requirements et de rendre compte de la réalité du parc immobilier d'Apartis. Néanmoins, il est probable que certains aspects de cette structure de données vont devoir être révisés au fur et à mesure de la progression du projet. Sans doute, les apports de ce travail auraient été plus riches si la phase d'implémentation de l'application avait été poussée plus avant. Malgré cela, les choix arrêtés et les tests menés permettent de passer maintenant résolument au développement proprement dit. Ce qui se fera hors du cadre de ce travail. Critique des outils Dans la phase de design de la base de données, MySQL Workbench de Sun a été fortement apprécié pour ses fonctionnalités de génération automatique de la documentation et dans l'export en format tion ) .sql ou sous forme d'image. La version utilisée (standard edi- est payante, mais reste parfaitement abordable en comparaison d'autres produits concurrents. Pour ce qui est des outils de programmation, NetBeans ore un plugin PHP tout à fait décent en regard des outils qu'il ore aux développeurs Java. Il tient également la comparaison avec d'autres produits intégrés spéciquement destinés au développement d'applications web comme Komodo IDE [11] par exemple. Évidement, ces derniers orent tout de même des fonctions de développement en équipe et des outils de debogage beaucoup plus évolués. Les manques en termes de debogage sont partiellement compensés par les excellentes informations fournies par CakePHP lui-même. En eet, les pages web générées par le framework permettent de visionner directement dans le navigateur les messages d'erreurs levés lors de la compilation du code PHP (voir pour exemple la gure 6.1 ci-après). A propos de CakePHP, nous avons montré le fonctionnement de la génération automatique de code pour des relations simples. Dans le cas de relations complexes, le développeur se doit d'introduire des paramètres directement dans le code PHP pour obtenir une interface adéquate pour l'utilisateur. Il ne s'agit en aucun cas d'un défaut à ce niveau de technologie. Cependant, il est bon de rappeler que ce framework n'a absolument rien d'une solution clé en main d'applications web dynamique. Une fois ce point clarié, dans les faits, CakePHP 26 27 Fig. 6.1: Informations de debogage achées dynamiquement par CakePHP au sein même des pages générées. permet à l'évidence d'accélérer le développement de solutions web 2.0 et il garanti un code source propre en facilitant l'implémentation du pattern MVC. La maintenance et le développement futur en seront grandement facilités. De plus, pour un programmeur PHP conrmé, le gain de temps est réel, et l'intégration de composants mis à disposition par la communauté CakePHP est une opportunité à saisir absolument. Evidement, comme tous les frameworks, CakePHP nécessite un temps d'apprentissage qui ne portera ses fruits qu'après quelques temps de pratique. Pour autant que l'on ne connaisse pas au moins une autre implémentation du pattern MVC. A Page web du projet La page ocielle du projet est : http://diuf.unifr.ch/softeng/student-projects/08-09/apartis.html. Sur cette page vous trouverez : la documentation complète du modèle de données la version électronique de ce rapport le script SQL d'initialisation de la base avec des données de test 28 B CD-ROM Le CD-ROM joint au présent rapport contient les annexes suivantes en version électronique : Code source : une archive des chiers du site de test présentant les interfaces générées par CakePHP le framework CakePHP dans la version utilisée pour ce projet avec la documentation HTML complète de l'API un script SQL qui permet de générer l'ensemble du modèle de données et des données d'exemple pour les tables faisant l'objet d'une interface Documentation : la documentation du modèle de données au format HTML telle que générée par MySQL Workbench et les schémas des tables la version stable actuelle du framework CakePHP (version 1.2.3.8166) dans sa distribution ocielle la documentation de Quorum dans sa version 5.40 Fig. B.1 fourni le menu du contenu des répertoires du CD-ROM. Le contenu du CD-ROM peut aussi être téléchargé sur le site ociel du projet (voir annexe A). 29 30 |-| | | |-| | | | | |-| | | | |-| | `-- cakePHP |-- API `-- CakePHP v. 1.2.3.8166_stable //API de CakePHP. //Verion actuelle de CakePHP. ImmObjectsTest |-- app |-- cake `-- vendors //Modele de donnees pour ImmObjects //Fichiers specifiques a l'application //Noyau du framework //Extraits de code venant //d'autres fournisseurs. modeleDonnees |-- doc |-- schema_tables `-- sql //Modele de donnees pour ImmObjects //Documentation HTML. //Schema au format .png. //Script SQL. Quorum `-- doc //Documentation de Quorum rapport //Ce document en format .pdf Fig. B.1: Hiérarchie des données dans le CD-ROM Bibliographie Trees and Hierarchies in SQL for Smarties. Elsevier, 2004. Golding. Beginning CakePHP : From novice to Professionnal. [Cel04] Joe Celko. [Gol08] David Apress, 2008. [Mil09] Kai Chan ; John Omokore ; Richard K. Miller. Practical CakePHP Projects. Apress, 2009. [Sya08] Ahsanul Bari ; Anupom Syam. CakePHP Application Development. blishing, 2008. 31 Packt Pu- Sites Web [1] Progress des Software version est et Object Database Management System, leur probablement utilisée pour l'application de dont l'une gestion de Software. http://web.progress.com/Product-Capabilities/ object-database-management.html (dernière consultation le 28 juin 2009). Quorum [2] CakePHP, framework de développement web implémentant en PHP les design pattern MVC et ORM. http://cakephp.org/ (dernière consultation le 28 juin 2009). [3] CakePHP, the Bakery. Collection de code snippets pour étendre les fonctionnalités du framework avec des solutions spéciques. categories/view/3 http://bakery.cakephp.org/ (dernière consultation le 28 juin 2009). [4] Django, framework web MVC écrit en Python. http://djangoproject.com/ (der- nière consultation le 28 juin 2009). [5] Framework open-source écrit en Ruby. http://rubyonrails.org/ (dernière consul- tation le 28 juin 2009). [6] Index de la documentation de toutes les classes du framework CakePHP. //api.cakephp.org/classes http: (dernière consultation le 28 juin 2009). [7] MySQL Workbench 5.0.30 Standard Edition. http://dev.mysql.com/workbench/ (dernière consultation le 28 juin 2009). [8] Standard de sérialisation de données multi-language. http://yaml.org/ (dernière consultation le 28 juin 2009). [9] Symphony, framework symfony-project.org/ de développement web open-source. http://www. (dernière consultation le 28 juin 2009). [10] Zend, gamme de produit intégrant tous les aspects de la production de site web 2.0 du framework MVC au serveur web. Issu du groupe qui a développé le language PHP. http://zend.com/ (dernière consultation le 28 juin 2009). [11] Komodo IDE, produit par ActiveState. Environnement de développement professionnel dédié aux langages dynamiques comme PHP, Python ou Ruby avec prises en charges de leurs framework web respectifs les plus répandus. activestate.com/komodo/ http://www. (dernière consultation le 28 juin 2009). [12] XAMPP, Distribution localisée d'Apache disponible pour Linux, Windows, Max OS X et Solaris. Elle fournit Apache, MySQL, PHP et Filezilla FTP Server ainsi qu'une multitude d'outils et de modules apache les plus courants. apachefriends.org/en/xampp.html http://www. (dernière consultation le 28 juin 2009). 32 33 Sites Web design pattern [13] Modèle Vue Contrôleur, architectural qui tend à isoler la logique business des aspects liés à l'interface utilisateur. Model_view_controller http://en.wikipedia.org/wiki/ (dernière consultation le 28 juin 2009). [14] Quorum Software, société basée à Genève, Lausanne et Aarau qui proposent une solution de gestion pour les agences immobilières. http://quorumsoftware.ch/ (dernière consultation le 28 juin 2009). [15] Trilogis, entretprise de service avec siège à Auvernier(NE). http://trilogis.ch/ (dernière consultation le 28 juin 2009). [16] Google Translate, outil de traduction online fournit par Google Inc. translate.google.com http:// (dernière consultation le 28 juin 2009). [17] Language de programmation objet PHP. http://www.php.net/ (dernière consulta- tion le 28 juin 2009). [18] Projet open-source de moteur de base de donnée MySQL. http://www.mysql.com/ (dernière consultation le 28 juin 2009). [19] Projet open-source de serveur HTTP de l'Apache Software Fondation. httpd.apache.org/ http:// (dernière consultation le 28 juin 2009). [20] WAMP, package de distribution d'un ensemble de programmes indépendants qui permettent ensemble d'héberger un serveur de sites web dynamique. wikipedia.org/wiki/Wamp (dernière consultation le 28 juin 2009). http://en.