Evolution #84
ouvertGestion des listes administrables
60%
Description
L'application utilise plusieurs listes dont le contenu doit être administrable (édition via l'interface web).
Ces listes sont stockées en base de données, elles concernent par exemple plusieurs champs des fiches usagers (documents fournis, profession, etc...), les types d'ateliers, la liste des organismes, les services proposés dans les salles...
Le code existant est resté celui d'origine d'EpnAdmin (0.8). La nouvelle version 100% Symfony doit donc fournir une nouvelle interface pour administrer ces listes. C'est également l'occasion pour revoir leur implémentation et les principes de fonctionnement souhaités.
Mis à jour par Grégory MARIGOT - TEICEE il y a presque 14 ans
- Statut changé de Nouveau à In Progress
- % réalisé changé de 0 à 50
Modifications publiées sur le svn (r346) :
Principe de fonctionnement des listes¶
La plupart des principes des listes administrables en place dans EPNadmin sont conservés :- les items peuvent disposer d'une description et d'une image en plus de leur libellés
- un champs numérique permet de forcer leur ordre à la présentation des listes
- des listes à plusieurs niveaux sont possibles, chaque item pouvant référencer un item parent
- un champs status permet de retirer/masquer des items sans les supprimer pour autant, assurant la cohérence des données pour des objets les utilisant encore
- un item peut être exclusif à un EPN, permettant la personnalisation des listes
- la création/modification des items sont tracés (auteurs et dates)
- titre général de la liste
- status
- mode de gestion des items propre aux EPN (interdit, en supplément ou exclusif ?)
- profondeur maximale autorisée pour la hiérarchie des items
- depth qui mémorise le niveau de profondeur de l'item, facilement initialisable à sa création (depth du parent + 1), il permettra une manipulation plus aisée des listes arborescentes et du controle de la profondeur max autorisée.
- tag qui pourra avoir deux utilités : soit une alternative courte au libellé (pour présenter des choix multiples de manières synthétique par exemple) ; soit une alternative à l'id (auto-incrément) si on souhaite gérer des références plus "parlante" et plus fixe que l'id numérique.
A noter que le tag utilisé en remplaçant de l'id apporte une différence : ce n'est pas un champs unique. Son utilisation pourra donc être utile avec des items personnalisés (propre à un EPN) qui sauront réutiliser la même "clé" que l'item d'origine qu'ils sont sensés surcharger.
Modification de la base de données¶
Les tables utilisées précédement subissent plusieurs changements :- suppression de la table inutilisée list_container_link
- création d'une table des listes nommées list_type
- renommage de la table list_container en list_item
- renommage des champs de list_item pour cohérence du nommage
- adaptations / ajouts de certaines colonnes
- recréation des index et clés étrangères
- peuplement de la table list_type
DROP TABLE list_container_link;
ALTER TABLE list_container CHANGE lc_id id INT(11) NOT NULL AUTO_INCREMENT; ALTER TABLE list_container CHANGE lc_parent_id parent_id INT(11) NULL DEFAULT NULL; ALTER TABLE list_container CHANGE lc_list_name list_name VARCHAR(25) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT ''; ALTER TABLE list_container CHANGE lc_item label VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT ''; ALTER TABLE list_container CHANGE lc_description description TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL; ALTER TABLE list_container CHANGE lc_status status VARCHAR(15) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT 'active'; ALTER TABLE list_container CHANGE lc_order rank SMALLINT(5) NOT NULL DEFAULT '10'; ALTER TABLE list_container CHANGE lc_img icon VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT ''; ALTER TABLE list_container CHANGE lc_st_id structure_id INT(11) NULL DEFAULT NULL; ALTER TABLE list_container CHANGE lc_create_date created_at DATETIME NULL DEFAULT NULL; ALTER TABLE list_container CHANGE lc_update_author updated_by INT(11) NULL DEFAULT NULL; ALTER TABLE list_container CHANGE lc_create_date created_at DATETIME NULL DEFAULT NULL; ALTER TABLE list_container CHANGE lc_update_author updated_by INT(11) NULL DEFAULT NULL; ALTER TABLE list_container DROP lc_options;
UPDATE list_container SET status=1 WHERE status='active'; UPDATE list_container SET status=0 WHERE status='inactive'; UPDATE list_container SET status=-1 WHERE status='hidden'; ALTER TABLE list_container CHANGE status status SMALLINT(15) NOT NULL DEFAULT '1'; ALTER TABLE list_container ADD depth SMALLINT NOT NULL DEFAULT '0' AFTER parent_id; ALTER TABLE list_container ADD tag VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' AFTER label;
RENAME TABLE list_container TO list_item; ALTER TABLE list_item DROP INDEX lc_list_name; ALTER TABLE list_item DROP INDEX lc_item; ALTER TABLE list_item DROP INDEX lc_status; ALTER TABLE list_item DROP INDEX lc_order; ALTER TABLE list_item ADD INDEX tag (tag); ALTER TABLE list_item ADD INDEX list_name (list_name); ALTER TABLE list_item ADD INDEX structure_id (structure_id); ALTER TABLE list_item ENGINE=InnoDB
CREATE TABLE list_type ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(25) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, title VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '', description TEXT CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, status SMALLINT NOT NULL DEFAULT '1', max_depth SMALLINT NOT NULL DEFAULT '1', mode SMALLINT NOT NULL DEFAULT '0', UNIQUE (name)) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
INSERT INTO list_type (name) SELECT DISTINCT list_name FROM list_item; ALTER TABLE list_item ADD FOREIGN KEY (list_name) REFERENCES list_type (name) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE list_item ADD FOREIGN KEY (structure_id) REFERENCES structure (id) ON DELETE CASCADE;
TODO¶
Si tout est défini sur le papier et a été appliqué sur le schéma de la BdD, l'exploitation de toutes ses fonctionnalités dans le code reste à mettre en place.
Pour le moment, le minimum est assuré avec l'adaptation de la classe myListDB qui permet l'interrogation des listes (récupération de tous les éléments d'une liste ou récupération d'un libellé pour un item donné).
Ainsi l'application reste fonctionnelle, les listes actuelles n'exploitant pas les fonctionnalités évoluées pensées ici. Par contre l'interface permettant leur administration est à refaire avec le framework Symfony.
Mis à jour par Grégory MARIGOT - TEICEE il y a presque 14 ans
Modifications publiées sur le svn (r352) :
Un module est créé afin d'administrer les listes et leurs items (module nommé 'list' avec la route '/listes').
Les tables list_type et list_item sont gérées par Propel et les classes du modèle objet sont générées (avec peer, form et filter).
La classe statique myListDB est conservée par commodité, elle devient un simple wrapper pour appeler des méthodes de la classe ListItemPeer.
Le module permet d'administrer entièrement les listes via l'interface web en tant que "superadmin". Cependant, plusieurs points resteront à développer...
TODO :¶
- Application de la politique de droits pour pouvoir autoriser la gestion de listes personnalisées aux animateurs ou coordinateurs (items visibles/editables, cohérence structure/parent, affichage des valeurs selon priorité entre item global/personnalisé).
- Controles sur le niveau de profondeur max autorisé par la liste.
- Présentation des listes d'items en arborescence pour rendre compte de la hiérarchisation
- Améliorer l'ergonomie de l'interface d'administration (éditer par lot les items, ordonner la liste...)
Mis à jour par Grégory MARIGOT - TEICEE il y a plus de 13 ans
- % réalisé changé de 50 à 60
Modifications publiées sur le svn (r412) :
Ajouts de méthodes pour utiliser les listes avec le tag plutot que l'id :- ListItemPeer::retrieveByTag($tag, $list_name)
- myListDB::getValuesByTag($name, $all=false)
- myListDB::getValueByTag($name, $tag, $default='')
Le tag pouvant servir pour se substituer à l'id dans l'utilisation des listes, il devient dans ce cas indispensable.
Ainsi une option est ajoutée à la définition des listes pour spécifier si le tag est requis ou non.
(au passage l'autre option 'status' devient aussi une booléenne)
ALTER TABLE list_type ADD tag_required TINYINT(1) NOT NULL DEFAULT '0' AFTER status; ALTER TABLE list_type CHANGE status status TINYINT(1) NOT NULL DEFAULT '1';
Mis à jour par Grégory MARIGOT - TEICEE il y a plus de 13 ans
- Version cible changé de ProxyEPN 2.0 à ProxyEPN 2.x
Le fonctionnement de base des listes administrables est en place pour la version 2.0
Les développements doivent continuer pour améliorer l'interface de gestion (ergonomie, actions par lots, etc), ainsi que pour offrir la possibilité à chaque EPN de redéfinir certaines listes à sa guise.
Mis à jour par Grégory MARIGOT - TEICEE il y a plus de 8 ans
Modifications publiées sur le svn (r764) :
Utilisation d'un cache pour les résultats de la BdD¶
Le code a été réorganisé pour que toutes les requêtes sur la base soient centralisées dans des méthodes load qui font systématiquement usage d'un cache pour gérer leurs résultats :load($name, $all=false)
loadItem($name, $id)
loadItemByTag($name, $tag)
loadDefaults($name)
Différents formats possibles pour les libellés des éléments¶
Un objet list_item
dispose d'un unique champs label pour son texte à afficher.
Un cas particulier était pratiqué sur les services des salles : les libellés sont tous de la forme "SIGLE : Nom complet"
, les deux parties séparées par le ':' étant parfois traitées séparément (affichage du complet ou uniquement du sigle).
list_item
et les méthodes de myListDB
peuvent proposer un paramètre $format
pour choisir le type de libellé à retourner :
- 'Short' : utilise la méthode
getLabelShort
deslist_item
pour ne retourner que la 1ère partie (ie sigle) - 'Long' : utilise la méthode
getLabelLong
deslist_item
pour ne retourner que la 2nde partie (ie nom complet) - 'Parts' : utilise la méthode
getLabelParts
deslist_item
pour retourner un array des 2 parties
Si ces méthodes sont utilisées alors que le label d'un list_item
ne contient aucun ':', alors la 1ère partie retournée vaudra '###' tandis que la 2nde partie contiendra l'intégralité du libellé.