LSrelation : add possibilty to handle relation with multiple key values

This commit is contained in:
Benjamin Renard 2017-04-28 17:04:55 +02:00
parent e226ebe684
commit 7909d55b39
3 changed files with 100 additions and 115 deletions

View file

@ -21,7 +21,8 @@
// Liaison simple // Liaison simple
'linkAttribute' => '[attribut de liaison]', 'linkAttribute' => '[attribut de liaison]',
'linkAttributeValue' => '[value de l'attribut de liaison]', 'linkAttributeValue' => '[valeur de l'attribut de liaison]',
'linkAttributeOtherValues' => array('[autres valeurs possible de l'attribut de liaison]', [...]),
// Liaison complexe // Liaison complexe
'list_function' => '[méthode1]', 'list_function' => '[méthode1]',
@ -81,12 +82,25 @@
<varlistentry> <varlistentry>
<term>linkAttributeValue</term> <term>linkAttributeValue</term>
<listitem> <listitem>
<simpara>Dans le cadre d'une relation simple, il s'agit du type de valeur pris <simpara>Dans le cadre d'une relation simple, il s'agit du type de valeur prisent
par l'attribut de liaison du type d'&LSobject; en relation avec le type courant. par l'attribut de liaison du type d'&LSobject; en relation avec le type courant.
Il peut s'agir du mot clé <literal>dn</literal> si l'attribut de liaison contient Il peut s'agir du mot clé <literal>dn</literal> si l'attribut de liaison contient
le <emphasis>DN</emphasis> de l'objet courant ou bien le nom d'un attribut du type le <emphasis>DN</emphasis> de l'objet courant ou bien le nom d'un attribut du type
d'objet courant dont la première valeur sera stockée par l'attribut de liaison. d'objet courant dont la première valeur sera stockée par l'attribut de liaison.
<emphasis>(Facultatif en cas de liaison simple)</emphasis></simpara> <emphasis>(Facultatif en cas de liaison complexe)</emphasis></simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>linkAttributeOtherValues</term>
<listitem>
<simpara>Dans le cadre d'une relation simple, il s'agit d'autres types de valeur
possiblement prisent par l'attribut en plus de celui défini par le paramètre
<literal>linkAttributeValue</literal>. Ce paramètre ne sert qu'a détecter des
liaisons établies à l'aide de valeurs autres que celle relative au paramètre
<literal>linkAttributeValue</literal> : en cas de nouvelle liaison, c'est la
valeur associée à ce dernier qui sera utilisée pour établir la liaison.
<emphasis>(Facultatif en cas de liaison complexe)</emphasis></simpara>
</listitem> </listitem>
</varlistentry> </varlistentry>

View file

@ -1307,25 +1307,31 @@ class LSldapObject {
* *
* @param[in] $object Un object de type $objectType * @param[in] $object Un object de type $objectType
* @param[in] $objectType Le type d'objet en relation * @param[in] $objectType Le type d'objet en relation
* @param[in] $value La valeur que doit avoir l'attribut : * @param[in] $attrValues La/les valeur(s) que doit/peut avoir l'attribut :
* - soit le dn (par defaut) * - soit le dn (par defaut)
* - soit la valeur [0] d'un attribut * - soit une des valeurs d'un attribut
* *
* @retval Mixed La valeur clef d'un objet en relation * @retval Mixed La valeur clef d'un objet en relation
**/ **/
function getObjectKeyValueInRelation($object,$objectType,$attrValue='dn') { function getObjectKeyValueInRelation($object,$objectType,$attrValues='dn') {
if (!$objectType) { if (!$objectType) {
LSerror :: addErrorCode('LSrelations_05','getObjectKeyValueInRelation'); LSerror :: addErrorCode('LSrelations_05','getObjectKeyValueInRelation');
return; return;
} }
if (!is_array($attrValues)) $attrValues=array($attrValues);
$keyValues=array();
foreach ($attrValues as $attrValue) {
if ($attrValue=='dn') { if ($attrValue=='dn') {
$val = $object -> getDn(); $dn=$object -> getDn();
if (!in_array($dn,$keyValues))
$keyValues[] = $dn;
} }
else { else {
$val = $object -> getValue($attrValue); foreach ($object -> getValue($attrValue) as $keyValue)
$val = $val[0]; if (!in_array($keyValue,$keyValues)) $keyValues[]=$keyValue;
} }
return $val; }
return $keyValues;
} }
/** /**
@ -1340,29 +1346,29 @@ class LSldapObject {
* @param[in] $object Un object de type $objectType * @param[in] $object Un object de type $objectType
* @param[in] $attr L'attribut dans lequel l'objet doit apparaitre * @param[in] $attr L'attribut dans lequel l'objet doit apparaitre
* @param[in] $objectType Le type d'objet en relation * @param[in] $objectType Le type d'objet en relation
* @param[in] $value La valeur que doit avoir l'attribut : * @param[in] $attrValues La/les valeur(s) que doit/peut avoir l'attribut :
* - soit le dn (par defaut) * - soit le dn (par defaut)
* - soit la valeur [0] d'un attribut * - soit une des valeurs d'un attribut
* *
* @retval Array of $objectType Les objets en relations * @retval Array of $objectType Les objets en relations
**/ **/
function listObjectsInRelation($object,$attr,$objectType,$attrValue='dn') { function listObjectsInRelation($object,$attr,$objectType,$attrValues='dn') {
if ((!$attr)||(!$objectType)) { if ((!$attr)||(!$objectType)) {
LSerror :: addErrorCode('LSrelations_05','listObjectsInRelation'); LSerror :: addErrorCode('LSrelations_05','listObjectsInRelation');
return; return;
} }
if ($attrValue=='dn') { if (!is_array($attrValues)) $attrValues=array($attrValues);
$val = $object -> getDn(); $keyValues=self :: getObjectKeyValueInRelation($object,$objectType,$attrValues);
if (!empty($keyValues)) {
$keyValuesFilters=array();
foreach($keyValues as $keyValue) {
$keyValuesFilters[] = Net_LDAP2_Filter::create($attr,'equals',$keyValue);
} }
else { $filter = LSldap::combineFilters('or', $keyValuesFilters);
$val = $object -> getValue($attrValue);
$val = $val[0];
}
if ($val) {
$filter = Net_LDAP2_Filter::create($attr,'equals',$val);
return $this -> listObjects($filter,LSsession :: getRootDn(),array('scope' => 'sub','recursive' => true,'withoutCache'=>true, 'onlyAccessible' => false)); return $this -> listObjects($filter,LSsession :: getRootDn(),array('scope' => 'sub','recursive' => true,'withoutCache'=>true, 'onlyAccessible' => false));
} }
return;
return array();
} }
/** /**
@ -1438,10 +1444,13 @@ class LSldapObject {
* - soit la valeur [0] d'un attribut * - soit la valeur [0] d'un attribut
* @param[in] $canEditFunction Le nom de la fonction pour vérifier que la * @param[in] $canEditFunction Le nom de la fonction pour vérifier que la
* relation avec l'objet est éditable par le user * relation avec l'objet est éditable par le user
* @param[in] $attrValues L'ensembe des valeurs que peut avoir l'attribut avant mise à jour :
* - soit le dn (par defaut)
* - soit une des valeurs d'un attribut
* *
* @retval boolean true si l'objet à été supprimé, False sinon * @retval boolean true si l'objet à été supprimé, False sinon
**/ **/
function deleteOneObjectInRelation($object,$attr,$objectType,$attrValue='dn',$canEditFunction=NULL) { function deleteOneObjectInRelation($object,$attr,$objectType,$attrValue='dn',$canEditFunction=NULL,$attrValues=null) {
if ((!$attr)||(!$objectType)) { if ((!$attr)||(!$objectType)) {
LSerror :: addErrorCode('LSrelations_05','deleteOneObjectInRelation'); LSerror :: addErrorCode('LSrelations_05','deleteOneObjectInRelation');
return; return;
@ -1458,13 +1467,8 @@ class LSldapObject {
return; return;
} }
if ($this -> attrs[$attr] instanceof LSattribute) { if ($this -> attrs[$attr] instanceof LSattribute) {
if ($attrValue=='dn') { if (!is_array($attrValues)) $attrValues=array($attrValue);
$val = $object -> getDn(); $keyValues=self :: getObjectKeyValueInRelation($object,$objectType,$attrValues);
}
else {
$val = $object -> getValue($attrValue);
$val = $val[0];
}
$values = $this -> attrs[$attr] -> getValue(); $values = $this -> attrs[$attr] -> getValue();
if ((!is_array($values)) && (!empty($values))) { if ((!is_array($values)) && (!empty($values))) {
$values = array($values); $values = array($values);
@ -1472,7 +1476,7 @@ class LSldapObject {
if (is_array($values)) { if (is_array($values)) {
$updateData=array(); $updateData=array();
foreach($values as $value) { foreach($values as $value) {
if ($value!=$val) { if (!in_array($value,$keyValues)) {
$updateData[]=$value; $updateData[]=$value;
} }
} }
@ -1487,7 +1491,8 @@ class LSldapObject {
* Renome un objet en relation dans l'attribut $attr de $this * Renome un objet en relation dans l'attribut $attr de $this
* *
* @param[in] $object Un objet de type $objectType à renomer * @param[in] $object Un objet de type $objectType à renomer
* @param[in] $oldValue string L'ancienne valeur faisant référence à l'objet * @param[in] $oldValues array|string Le(s) ancienne(s) valeur(s possible(s)
* faisant référence à l'objet
* @param[in] $attr L'attribut dans lequel l'objet doit être supprimé * @param[in] $attr L'attribut dans lequel l'objet doit être supprimé
* @param[in] $objectType Le type d'objet en relation * @param[in] $objectType Le type d'objet en relation
* @param[in] $attrValue La valeur que doit avoir l'attribut : * @param[in] $attrValue La valeur que doit avoir l'attribut :
@ -1496,11 +1501,12 @@ class LSldapObject {
* *
* @retval boolean True en cas de succès, False sinon * @retval boolean True en cas de succès, False sinon
*/ */
function renameOneObjectInRelation($object,$oldValue,$attr,$objectType,$attrValue='dn') { function renameOneObjectInRelation($object,$oldValues,$attr,$objectType,$attrValue='dn') {
if ((!$attr)||(!$objectType)) { if ((!$attr)||(!$objectType)) {
LSerror :: addErrorCode('LSrelations_05','renameOneObjectInRelation'); LSerror :: addErrorCode('LSrelations_05','renameOneObjectInRelation');
return; return;
} }
if (!is_array($oldValues)) $oldValues=array($oldValues);
if ($object instanceof $objectType) { if ($object instanceof $objectType) {
if ($this -> attrs[$attr] instanceof LSattribute) { if ($this -> attrs[$attr] instanceof LSattribute) {
$values = $this -> attrs[$attr] -> getValue(); $values = $this -> attrs[$attr] -> getValue();
@ -1510,7 +1516,7 @@ class LSldapObject {
if (is_array($values)) { if (is_array($values)) {
$updateData=array(); $updateData=array();
foreach($values as $value) { foreach($values as $value) {
if ($value!=$oldValue) { if (!in_array($value,$oldValues)) {
$updateData[] = $value; $updateData[] = $value;
} }
else { else {
@ -1545,64 +1551,37 @@ class LSldapObject {
* - soit la valeur [0] d'un attribut * - soit la valeur [0] d'un attribut
* @param[in] $canEditFunction Le nom de la fonction pour vérifier que la * @param[in] $canEditFunction Le nom de la fonction pour vérifier que la
* relation avec l'objet est éditable par le user * relation avec l'objet est éditable par le user
* @param[in] $attrValues L'ensembe des valeurs que peut avoir l'attribut avant mise à jour :
* - soit le dn (par defaut)
* - soit une des valeurs d'un attribut
* *
* @retval boolean true si tout c'est bien passé, False sinon * @retval boolean true si tout c'est bien passé, False sinon
**/ **/
function updateObjectsInRelation($object,$listDns,$attr,$objectType,$attrValue='dn',$canEditFunction=NULL) { function updateObjectsInRelation($object,$listDns,$attr,$objectType,$attrValue='dn',$canEditFunction=NULL,$attrValues=null) {
if ((!$attr)||(!$objectType)) { if ((!$attr)||(!$objectType)) {
LSerror :: addErrorCode('LSrelations_05','updateObjectsInRelation'); LSerror :: addErrorCode('LSrelations_05','updateObjectsInRelation');
return; return;
} }
$currentObjects = $this -> listObjectsInRelation($object,$attr,$objectType,$attrValue); if (!is_array($attrValues)) $attrValues=array($attrValue);
$type=$this -> getType(); $currentDns=array();
$currentObjects = $this -> listObjectsInRelation($object,$attr,$objectType,$attrValues);
if(is_array($currentObjects)) { if(is_array($currentObjects)) {
if (is_array($listDns)) {
$values=array();
if ($attrValue!='dn') {
$obj=new $objectType();
foreach ($listDns as $dn) {
$obj -> loadData($dn);
$val = $obj -> getValue($attrValue);
$values[$dn] = $val[0];
}
}
else {
foreach($listDns as $dn) {
$values[$dn] = $dn;
}
}
$dontDelete=array();
$dontAdd=array();
for ($i=0;$i<count($currentObjects);$i++) { for ($i=0;$i<count($currentObjects);$i++) {
if ($attrValue=='dn') { $currentDns[]=$currentObjects[$i] -> getDn();
$val = $currentObjects[$i] -> getDn();
}
else {
$val = $currentObjects[$i] -> getValue($attrValue);
$val = $val[0];
}
if (in_array($val, $listDns)) {
$dontDelete[$i]=true;
$dontAdd[]=$val;
} }
} }
$dontTouch=array_intersect($listDns,$currentDns);
for($i=0;$i<count($currentObjects);$i++) { for($i=0;$i<count($currentObjects);$i++) {
if ($dontDelete[$i]) { if (in_array($currentObjects[$i] -> getDn(),$dontTouch)) continue;
continue; if (!$currentObjects[$i] -> deleteOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction,$attrValues)) {
}
else {
if (!$currentObjects[$i] -> deleteOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction)) {
return; return;
} }
} }
}
foreach($values as $dn => $val) { $type=$this -> getType();
if (in_array($val,$dontAdd)) { foreach($listDns as $dn) {
continue; if (in_array($dn,$dontTouch)) continue;
}
else {
$obj = new $type(); $obj = new $type();
if ($obj -> loadData($dn)) { if ($obj -> loadData($dn)) {
if (!$obj -> addOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction)) { if (!$obj -> addOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction)) {
@ -1613,27 +1592,8 @@ class LSldapObject {
return; return;
} }
} }
}
return true; return true;
} }
}
else {
if(!is_array($listDns)) {
return true;
}
foreach($listDns as $dn) {
$obj = new $type();
if ($obj -> loadData($dn)) {
if (!$obj -> addOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction)) {
return;
}
}
else {
return;
}
}
}
}
/** /**
* Ajouter une action lors d'un événement * Ajouter une action lors d'un événement

View file

@ -52,7 +52,7 @@ class LSrelation {
return False; return False;
} }
elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) { elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) {
return $objRel -> listObjectsInRelation($this -> obj, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> config['linkAttributeValue']); return $objRel -> listObjectsInRelation($this -> obj, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> getLinkAttributeValues());
} }
else { else {
LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('listing related objects'))); LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('listing related objects')));
@ -64,6 +64,17 @@ class LSrelation {
return; return;
} }
public function getLinkAttributeValues() {
if (isset($this -> config['linkAttributeOtherValues'])) {
$linkAttributeValues=$this -> config['linkAttributeOtherValues'];
$linkAttributeValues[]=$this -> config['linkAttributeValue'];
return $linkAttributeValues;
}
else {
return $this -> config['linkAttributeValue'];
}
}
public function getRelatedKeyValue() { public function getRelatedKeyValue() {
if (LSsession :: loadLSobject($this -> config['LSobject'])) { if (LSsession :: loadLSobject($this -> config['LSobject'])) {
$objRel = new $this -> config['LSobject'](); $objRel = new $this -> config['LSobject']();
@ -121,7 +132,7 @@ class LSrelation {
return False; return False;
} }
elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) { elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) {
return $objRel -> deleteOneObjectInRelation($this -> obj, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> config['linkAttributeValue']); return $objRel -> deleteOneObjectInRelation($this -> obj, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> config['linkAttributeValue'], null, $this -> getLinkAttributeValues());
} }
else { else {
LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('removing relation with specific object'))); LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('removing relation with specific object')));
@ -156,7 +167,7 @@ class LSrelation {
LSerror :: addErrorCode('LSrelations_01',array('function' => $this -> config['update_function'], 'action' => _('updating'), 'relation' => $this -> relationName)); LSerror :: addErrorCode('LSrelations_01',array('function' => $this -> config['update_function'], 'action' => _('updating'), 'relation' => $this -> relationName));
} }
elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) { elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) {
return $objRel -> updateObjectsInRelation($this -> obj, $listDns, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> config['linkAttributeValue'],null); return $objRel -> updateObjectsInRelation($this -> obj, $listDns, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> config['linkAttributeValue'],null,$this -> getLinkAttributeValues());
} }
else { else {
LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('updating relations'))); LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('updating relations')));