LSrelation : add possibilty to handle relation with multiple key values
authorBenjamin Renard <brenard@easter-eggs.com>
Fri, 28 Apr 2017 15:04:55 +0000 (17:04 +0200)
committerBenjamin Renard <brenard@easter-eggs.com>
Fri, 28 Apr 2017 15:04:55 +0000 (17:04 +0200)
doc/conf/LSobject/LSrelation.docbook
public_html/includes/class/class.LSldapObject.php
public_html/includes/class/class.LSrelation.php

index ca9c06e..acc35c9 100644 (file)
@@ -21,7 +21,8 @@
 
     // Liaison simple
     '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
     'list_function' => '[méthode1]',
 <varlistentry>
   <term>linkAttributeValue</term>
   <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.
     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
     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>
 </varlistentry>
 
index 51fd5c7..c2e5e14 100644 (file)
@@ -1307,25 +1307,31 @@ class LSldapObject {
    * 
    * @param[in] $object Un object de type $objectType
    * @param[in] $objectType Le type d'objet en relation
-   * @param[in] $value La valeur que doit avoir l'attribut :
-   *                      - soit le dn (par defaut)
-   *                      - soit la valeur [0] d'un attribut
+   * @param[in] $attrValues La/les valeur(s) que doit/peut avoir l'attribut :
+   *                        - soit le dn (par defaut)
+   *                        - soit une des valeurs d'un attribut
    * 
    * @retval Mixed La valeur clef d'un objet en relation
    **/
-  function getObjectKeyValueInRelation($object,$objectType,$attrValue='dn') {
+  function getObjectKeyValueInRelation($object,$objectType,$attrValues='dn') {
     if (!$objectType) {
       LSerror :: addErrorCode('LSrelations_05','getObjectKeyValueInRelation');
       return;
     }
-    if ($attrValue=='dn') {
-      $val = $object -> getDn();
-    }
-    else {
-      $val = $object -> getValue($attrValue);
-      $val = $val[0];
+    if (!is_array($attrValues)) $attrValues=array($attrValues);
+    $keyValues=array();
+    foreach ($attrValues as $attrValue) {
+      if ($attrValue=='dn') {
+        $dn=$object -> getDn();
+        if (!in_array($dn,$keyValues))
+          $keyValues[] = $dn;
+      }
+      else {
+        foreach ($object -> getValue($attrValue) as $keyValue)
+          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] $attr L'attribut dans lequel l'objet doit apparaitre
    * @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 la valeur [0] d'un attribut
+   *                      - soit une des valeurs d'un attribut
    * 
    * @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)) {
       LSerror :: addErrorCode('LSrelations_05','listObjectsInRelation');
       return;
     }
-    if ($attrValue=='dn') {
-      $val = $object -> getDn();
-    }
-    else {
-      $val = $object -> getValue($attrValue);
-      $val = $val[0];
-    }
-    if ($val) {
-      $filter = Net_LDAP2_Filter::create($attr,'equals',$val);
+    if (!is_array($attrValues)) $attrValues=array($attrValues);
+    $keyValues=self :: getObjectKeyValueInRelation($object,$objectType,$attrValues);
+    if (!empty($keyValues)) {
+      $keyValuesFilters=array();
+      foreach($keyValues as $keyValue) {
+        $keyValuesFilters[] = Net_LDAP2_Filter::create($attr,'equals',$keyValue);
+      }
+      $filter = LSldap::combineFilters('or', $keyValuesFilters);
       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
    * @param[in] $canEditFunction  Le nom de la fonction pour vérifier que la
    *                              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
    **/  
-  function deleteOneObjectInRelation($object,$attr,$objectType,$attrValue='dn',$canEditFunction=NULL) {
+  function deleteOneObjectInRelation($object,$attr,$objectType,$attrValue='dn',$canEditFunction=NULL,$attrValues=null) {
     if ((!$attr)||(!$objectType)) {
       LSerror :: addErrorCode('LSrelations_05','deleteOneObjectInRelation');
       return;
@@ -1458,13 +1467,8 @@ class LSldapObject {
         return;
       }
       if ($this -> attrs[$attr] instanceof LSattribute) {
-        if ($attrValue=='dn') {
-          $val = $object -> getDn();
-        }
-        else {
-          $val = $object -> getValue($attrValue);
-          $val = $val[0];
-        }
+        if (!is_array($attrValues)) $attrValues=array($attrValue);
+        $keyValues=self :: getObjectKeyValueInRelation($object,$objectType,$attrValues);
         $values = $this -> attrs[$attr] -> getValue();
         if ((!is_array($values)) && (!empty($values))) {
           $values = array($values);
@@ -1472,7 +1476,7 @@ class LSldapObject {
         if (is_array($values)) {
           $updateData=array();
           foreach($values as $value) {
-            if ($value!=$val) {
+            if (!in_array($value,$keyValues)) {
               $updateData[]=$value;
             }
           }
@@ -1487,7 +1491,8 @@ class LSldapObject {
   * Renome un objet en relation dans l'attribut $attr de $this
   * 
   * @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] $objectType Le type d'objet en relation
   * @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
   */
-  function renameOneObjectInRelation($object,$oldValue,$attr,$objectType,$attrValue='dn') {
+  function renameOneObjectInRelation($object,$oldValues,$attr,$objectType,$attrValue='dn') {
     if ((!$attr)||(!$objectType)) {
       LSerror :: addErrorCode('LSrelations_05','renameOneObjectInRelation');
       return;
     }
+    if (!is_array($oldValues)) $oldValues=array($oldValues);
     if ($object instanceof $objectType) {
       if ($this -> attrs[$attr] instanceof LSattribute) {
         $values = $this -> attrs[$attr] -> getValue();
@@ -1510,7 +1516,7 @@ class LSldapObject {
         if (is_array($values)) {
           $updateData=array();
           foreach($values as $value) {
-            if ($value!=$oldValue) {
+            if (!in_array($value,$oldValues)) {
               $updateData[] = $value;
             }
             else {
@@ -1545,94 +1551,48 @@ class LSldapObject {
    *                      - soit la valeur [0] d'un attribut
    * @param[in] $canEditFunction  Le nom de la fonction pour vérifier que la
    *                              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
    **/  
-  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)) {
       LSerror :: addErrorCode('LSrelations_05','updateObjectsInRelation');
       return;
     }
-    $currentObjects = $this -> listObjectsInRelation($object,$attr,$objectType,$attrValue);
-    $type=$this -> getType();
+    if (!is_array($attrValues)) $attrValues=array($attrValue);
+    $currentDns=array();
+    $currentObjects = $this -> listObjectsInRelation($object,$attr,$objectType,$attrValues);
     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++) {
-          if ($attrValue=='dn') {
-            $val = $currentObjects[$i] -> getDn();
-          }
-          else {
-            $val = $currentObjects[$i] -> getValue($attrValue);
-            $val = $val[0];
-          }
-          if (in_array($val, $listDns)) {
-            $dontDelete[$i]=true;
-            $dontAdd[]=$val;
-          }
-        }
-        
-        for($i=0;$i<count($currentObjects);$i++) {
-          if ($dontDelete[$i]) {
-            continue;
-          }
-          else {
-            if (!$currentObjects[$i] -> deleteOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction)) {
-              return;
-            }
-          }
-        }
-        
-        foreach($values as $dn => $val) {
-          if (in_array($val,$dontAdd)) {
-            continue;
-          }
-          else {
-            $obj = new $type();
-            if ($obj -> loadData($dn)) {
-              if (!$obj -> addOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction)) {
-                return;
-              }
-            }
-            else {
-              return;
-            }
-          }
-        }
-        return true;
+      for ($i=0;$i<count($currentObjects);$i++) {
+        $currentDns[]=$currentObjects[$i] -> getDn();
       }
     }
-    else {
-      if(!is_array($listDns)) {
-        return true;
+    $dontTouch=array_intersect($listDns,$currentDns);
+
+    for($i=0;$i<count($currentObjects);$i++) {
+      if (in_array($currentObjects[$i] -> getDn(),$dontTouch)) continue;
+      if (!$currentObjects[$i] -> deleteOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction,$attrValues)) {
+        return;
       }
-      foreach($listDns as $dn) {
-        $obj = new $type();
-        if ($obj -> loadData($dn)) {
-          if (!$obj -> addOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction)) {
-            return;
-          }
-        }
-        else {
+    }
+
+    $type=$this -> getType();
+    foreach($listDns as $dn) {
+      if (in_array($dn,$dontTouch)) continue;
+      $obj = new $type();
+      if ($obj -> loadData($dn)) {
+        if (!$obj -> addOneObjectInRelation($object,$attr,$objectType,$attrValue,$canEditFunction)) {
           return;
         }
       }
+      else {
+        return;
+      }
     }
+    return true;
   }
   
   /**
index e911824..226e546 100644 (file)
@@ -52,7 +52,7 @@ class LSrelation {
         return False;
       }
       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 {
         LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('listing related objects')));
@@ -64,6 +64,17 @@ class LSrelation {
     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() {
     if (LSsession :: loadLSobject($this -> config['LSobject'])) {
       $objRel = new $this -> config['LSobject']();
@@ -121,7 +132,7 @@ class LSrelation {
       return False;
     }
     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 {
       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));
       }
       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 {
         LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('updating relations')));