motivation

CommonTreeDropdown permet de représenter une arborescence d'éléments. Cette arborescence est basée sur des caractèristiques exterieures aux éléments. Par exemple, la hiérarchie des lieux dépend de critères géographiques qui ne sont pas représentables dans la base de donnée. De la même manière, la structure administrative des entitées n'est pas modélisable.
Mais il existe des classes d'éléments qui contiennent implicitement, une hiérarchie qu'il est souhaitable de représenter sous la forme d'un arbre. C'est par exemple le cas des réseaux IP : le réseau 192.168.0.0/255.255.64.0 est naturellement descendant de 192.168.0.0/255.255.0.0. Mais il est le parent de 192.168.0.0/255.255.255.0 et de 192.168.1.0/255.255.255.0 (ces deux derniers étant frères).
Je proposes de gérer cette arborescence automatiquement par la mise à jours du champs $this->getForeignKeyField(). Mais il faut, également, tenir compte du fait que changer ces paremètres impact non seulement le père direct, mais également, l'ancien père, les anciens et les nouveaux enfants. En effet, ces derniers conservent les mêmes paramètres définissant leur position dans la hiérarchie. Donc, ils doivent être rattachés correctement.

proposition

Création d'une classe CommonImplicitTreeDropdown qui gère le déplacement de noeuds au sein de l'arbre en fonction d'information fournies par ses classes filles.

Cette classe a deux tâches :
  • D'une part, elle doit mettre à jours le noeud parent avant la mise à jours de la base de donnée ;
  • d'autre part, elle doit raccrocher les bons enfants aux bons parents.

Mise à jours du noeud parent

Cette étape doit se faire avant la mise à jours ou la création du noeud courant dans la base de données. En effet, elle profitera, ainsi, de la mise à jours automatique de ses champs "completename" et "level".
Elle utilise une méthode surchargeable (getMyNewAncestor) pour demander à sa classe fille l'identifiant de son nouveau père.

Raccrochage des bons enfants aux bons parents.

Afin de ne pas imposer à la classe fille de faire le tri entre les enfants directs et les petits-enfants, la méthode getPotentialSons doit renvoyer la liste complète de tous les enfants (directs et petits-enfants).
Il y a deux étapes dans cette méthode :
  • retrait de tous les anciens enfants qui ne sont plus dans la liste des nouveaux enfants. Pour cela, il suffit de rechercher dans la base de données tous les enfants (ie : $this->getForeignKeyField() = id du noeud courant) qui ne sont pas dans la liste des enfants potentiels et de changer leur père pour mettre l'ancien père du noeud courant ;
  • modification de tous les nouveaux enfant potentiels pour les faire pointer sur le bon père. Pour cela, il suffit de rechercher dans la base de données tous les enfants du nouveau noeud père qui sont dans la liste des enfants potentiels et modifier leur père pour le faire pointer sur le noeud courant.

implémentation

Le fichier joint contient une proposition de mise en oeuvre d'une telle classe.
En plus de ce fichier, il faut modifier la classe Dropdown. En effet, le déplacement massif d'élément n'est plus possible pour de tels éléments (inc/dropdown.class.php, ligne 1428, "$item instanceof CommonTreeDropdown" => "($item instanceof CommonTreeDropdown) && (!($item instanceof CommonImplicitTreeDropdown))").

commonimplicittreedropdown.class.php Magnifier (5.67 KB) webmyster, 08/19/2011 11:15 AM