Justification¶
Les CommonDBRelation
et CommonDBChild
sont communs à un certain nombre de classes. On peut ainsi centraliser dedans certaines méthodes.
Souvent, un "enfant" ne peut être créé que si on a les mêmes droits sur l'élément auquel on l'attache. Par exemple, on ne peut attacher un port réseau à un équipement que si l'on a accès en écriture à cet élément.
C'est pourquoi on centralise des codes de gestion des droits (canCreate
, canView
, canCreateItem
...).
Le second champ d'application de la centralisation est la gestion de la mise à jours de l'historique.
Terminologie¶
- On appel l'élément fils (ou fils) l'objet qui hérite de la classe
CommonDBRelation
ou deCommonDBChild
; - On appel l'élément père (ou père) l'objet sur lequel s'appuie l'élément fils. On notera qu'un fils de type
CommonDBChild
possède un père alors qu'un filsCommonDBRelation
en possède deux ; - On appel cohérence d'entitée le fait que deux éléments peuvent être reliés (un
CommonDBChild
et sonItem
, deux père entre eux par unCommonDBRelation
...) car dans des entitées compatibles (mêmes entitées ou l'une est l'entitée ancêtre de l'autre avec une recursivité) ; - On appel un fils sans père, un
CommonDBChild
ou unCommonDBRelation
de le père ou l'un des pères ne pointe sur aucun item (ie. :$itemtype
?= NULL
et/ou$items_id
?= 0
) Cela pourrait être le cas d'un composant dans le stock, non affecté à unItem
.
Méta-centralisation¶
Ces deux classes reposent sur des items définis par <itemtype
?, items_id
?> (un item pour CommonDBChild
, deux items pour CommonDBRelation
) qui fonctionnent de la même manière ($itemtype
= _nom de classe_ ou itemtype
pour un type dynamique).
Donc, il est logique de mettre en commun certains bouts de code.
La nouvelle classe CommonDBConnexity
centralise ce code (les deux autres classes en héritent).
Gestion des droits¶
Les droits sur un fils (création, visualisation, destruction, mise à jour) par rapport au(x) père(s) sont de trois natures différentes :- le fils peut être manipulé quelque soit le droit que l'on a sur le père ou lorsque l'on ne souhaite pas faire de tests des droits du père :
DONT_CHECK_ITEM_RIGHTS
- le fils peut être manipulé uniquement si on a le droit de voir le père (exemple : on peut utiliser un
DropDown
sans avoir le droit de le créer) :HAVE_VIEW_RIGHT_ON_ITEM
; - le fils ne peut être manipulé que si on a le même droit sur le père (on ne peut modifier un fils que si on peut modifier son père) :
HAVE_VIEW_RIGHT_ON_ITEM
;
Nota : pour un CommonDBRelation
les droits vis-à-vis d'un des deux père peut être différent de ceux pour l'autre père.
Amélioration pour les fils sans père¶
On peut envisager d'ajouter un masque (CAN_BE_FREE
) en plus de ces trois paramètres pour permettre la création de fils sans père.
En effet, pour le moment, par défaut, les canCreateItem
, canViewItem
... reposent sur la possibilité de lire les droits sur le père.
Donc, si on ne peut charger le père (le cas lorsque le fils est sans père), le CommonDBConnexity
renvoie qu'il est impossible de créer, modifier, voir ou supprimer le fils. Donc, l'opération est interdite.
Nota : dans ce cas, il faut également prévoir un mécanisme pour s'assurer de la cohérence d'entitée entre le fils et son ou ses pères.
Gestion de l'historique¶
L'historique est géré automatiquement par les classes CommonDBRelation
et CommonDBChild
: on notifie automatiquement l'historique du père pour signaler l'ajout, la modification ou la destruction d'un fils.
Le CommonDBChild
n'est pas paramétrable : quoiqu'il arrive le père est notifié (cf. la section "Limitation" ci-dessous).
CommonDBRelation
, deux paremètres booléens permettent de le configurer :
$logs_for_itemtype_1
précise s'il faut le notifier le premier père lorsque la relation est modifiée ;$logs_for_itemtype_2
précise s'il faut le notifier le second père lorsque la relation est modifiée ;
Limitation¶
Cette gestion automatique de l'historique repose sur la surcharge des méthodespost_addItem
, post_updateItem
et post_deleteFromDB
.Si la classe héritée surcharge ces méthodes sans faire appel à ces méthodes par appel à
parent::post_
*, alors on perd ce comportement.C'est à la fois un problème et une bonne chose :
- c'est un problème car beaucoup de classes héritées utilisent leur propres mécanisme de gestion de l'historique qui peut être imparfait ou lacunaire. Ainsi, elless perdent le bénéfice de cette factorisation. Un travail de recensement serait utile à ce niveau (cf. #3828) ;
- c'est un bénéfice car pour certains cas, on peut souhaiter avoir un traitement spécifique de l'historique indépendant de ce mécanisme commun. La surcharge de ces méthode permet de passer outre.
Amélioration¶
On peut réfléchir, avec cette centralisation, à gérer les historiques en cascade : lorsqu'on notifie l'historique du père, si ce dernier est lui-même un CommonDBRelation
ou un CommonDBChild
, on peut notifier l'historiques des pères de ce père. Cela permet de propager la notification jusqu'aux éléments principaux (ordinateur, imprimante, switch ...).
Traitements spécifiques et compatibilité avec les versions antérieures¶
On ne peut faire abstraction de ce qui existait jusque là (cf. version 0.83.x).
CommonDBRelation
¶
Les méthod canCreate
, canCreateItem
, canView
... de CommonDBRelation
ont été surchargées.
La seule solution pour désactiver ces mécanismes de contrôle des droits est de paramétrer correctement $checkItem_1_Rights
et $checkItem_2_Rights
.
cohérence d'entité¶
En plus des tests unitaires sur chaque père (paramétrés par $checkItem_1_Rights
et $checkItem_2_Rights
), on paramètre la cohérence d'entité avec un troisième paramètre $check_entity_coherency
.
compatibilité de contrôle des droits¶
Jusque là, les tests des droits sur le CommonDBRelation
étaient gérés par la surcharge de la méthode can
. Cela est contraire à la philosophie introduite par #3806.
Par défaut, les droits étaient gérés par les attributs $check_entities
et $checks_only_for_itemtype1
.
Pour garantir la compatibilité, il faut suivre les règles suivantes :
$check_entity_coherency = $check_entities;
$checkItem_1_Rights = self::HAVE_SAME_RIGHT_ON_ITEM;
$checkItem_2_Rights = ($checks_only_for_itemtype1 ? self::DONT_CHECK_ITEM_RIGHTS : self::HAVE_SAME_RIGHT_ON_ITEM);
compatibilité de gestion de l'historique¶
Dans la version précédente de GLPI, la gestion de l'historique du CommonDBRelation
était limitée à l'ajout et à la suppression. De plus, on pouvait désactiver le log sur le père 2 avec l'attribut $logs_only_for_itemtype1
.
La nouvelle version est plus avancée car elle permet de gérer indépendamment le log pour chacun des pères. De plus, on peut logger la mise à jour d'un CommonDBRelation
. Cela est utile lorsque la relation comporte quelques champs supplémentaire (cf. Item_Device
?).
Pour garantir la compatibilité, il faut suivre les règles suivantes :
$logs_for_itemtype_1 = true;
$logs_for_itemtype_2 = ($logs_only_for_itemtype1 == false);
CommonDBChild
¶
Précédemment, aucun test sur les droits n'étaient réalisés par les CommonDBChild
. Il en résulte une grande anarchie. C'est pourquoi les méthodes canCreate
, canUpdate
, canCreateItem
... n'ont pas été surchargées dans CommonDBChild
.
Il revient donc, à chaque classe héritée, de les surcharger. Par exemple, pour la création (canCreate
et canCreateItem
), on peut surcharger comme cela :
static function canCreate() {
return (Session::haveRight('networking','w') // check specific right for this class
&& parent::canChild('canCreate'));
}
function canCreateItem() {
return parent::canChildItem('canCreateItem', 'canCreate');
}
On notera, que dans le cas du canCreateItem
on n'a plus besoin de tester les droits spécifiques de la classe car ils sont déjà testés par canCreate
.