- LSldapObject & LSattribute : Ajout du support des triggers before_create et after_c...
[ldapsaisie.git] / trunk / includes / class / class.LSldapObject.php
index 50665a9..8c8bb95 100644 (file)
@@ -37,11 +37,15 @@ class LSldapObject {
   var $forms;
   var $view;
   var $dn=false;
+  var $oldDn=false;
   var $other_values=array();
   var $submitError=true;
   var $_whoami=NULL;
   var $_subDn_value=NULL;
   var $_LSrelationsCache=array();
+
+  var $_events=array();
+  var $_objectEvents=array();
   
   /**
    * Constructeur
@@ -73,6 +77,7 @@ class LSldapObject {
         return;
       }
     }
+    
     return true;
   }
   
@@ -210,6 +215,9 @@ class LSldapObject {
         }
       }      
     }
+    LSsession :: addJSconfigParam('LSform_'.$idForm,array(
+      'ajaxSubmit' => ((isset($this -> config['LSform']['ajaxSubmit']))?$this -> config['LSform']['ajaxSubmit']:1)
+    ));
     return $LSform;
   }
   
@@ -304,19 +312,12 @@ class LSldapObject {
     }
     if($this -> validateAttrsData($idForm)) {
       LSdebug("les données sont validées");
-      if(isset($this -> config['before_modify'])) {
-        if(function_exists($this -> config['before_modify'])) {
-          if(!$this -> config['before_modify']($this)) {
-            LSerror :: addErrorCode('LSldapObject_08',$this -> config['before_modify']);
-            return;
-          }
-        }
-        else {
-          LSerror :: addErrorCode('LSldapObject_07',$this -> config['before_modify']);
-          return;
-        }
+      
+      if (!$this -> fireEvent('before_modify')) {
+        return;
       }
-      // $this -> attrs[*] => before_modify
+      
+      // $this -> attrs[ {inNewData} ] -> fireEvent('before_modify')
       foreach($new_data as $attr_name => $attr_val) {
         if (!$this -> attrs[$attr_name] -> fireEvent('before_modify')) {
           return;
@@ -332,15 +333,10 @@ class LSldapObject {
       else {
         return;
       }
-      if((isset($this -> config['after_modify']))&&(!$this -> submitError)) {
-        if(function_exists($this -> config['after_modify'])) {
-          if(!$this -> config['after_modify']($this)) {
-            LSerror :: addErrorCode('LSldapObject_10',$this -> config['after_modify']);
-          }
-        }
-        else {
-          LSerror :: addErrorCode('LSldapObject_09',$this -> config['after_modify']);
-        }
+      
+      // Event After Modify
+      if(!$this -> submitError) {
+        $this -> fireEvent('after_modify');
       }
       
       // $this -> attrs[*] => After Modify
@@ -430,7 +426,7 @@ class LSldapObject {
           $msg_error=getFData($test['msg'],$this,'getValue');
         }
         else {
-          $msg_error=getFData(_("L'attribut %{attr} n'est pas valide."),$attr -> getLabel());
+          $msg_error=getFData(_("The attribute %{attr} is not valid."),$attr -> getLabel());
         }
         foreach($data as $val) {
           // validation par check LDAP
@@ -530,7 +526,7 @@ class LSldapObject {
         if(($attr -> name == $this -> config['rdn'])&&(!$new)) {
           $new = true;
           LSdebug('Rename');
-          if (!$this -> beforeRename()) {
+          if (!$this -> fireEvent('before_rename')) {
             LSerror :: addErrorCode('LSldapObject_16');
             return;
           }
@@ -542,7 +538,8 @@ class LSldapObject {
               return;
             }
             $this -> dn = $newDn;
-            if (!$this -> afterRename($oldDn,$newDn)) {
+            $this -> oldDn = $oldDn;
+            if (!$this -> fireEvent('after_rename')) {
               LSerror :: addErrorCode('LSldapObject_17');
               return;
             }
@@ -561,14 +558,32 @@ class LSldapObject {
       if($dn) {
         $this -> dn=$dn;
         LSdebug($submitData);
+        if ($new) {
+          if (!$this -> fireEvent('before_create')) {
+            LSerror :: addErrorCode('LSldapObject_20');
+            return;
+          }
+          foreach ($submitData as $attr_name => $attr) {
+            if (!$this -> attrs[$attr_name] -> fireEvent('before_create')) {
+              LSerror :: addErrorCode('LSldapObject_20');
+              return;
+            }
+          }
+        }
         if (!LSldap :: update($this -> getType(),$dn, $submitData)) {
           return;
         }
         if ($new) {
-          if (!$this -> afterCreate()) {
+          if (!$this -> fireEvent('after_create')) {
             LSerror :: addErrorCode('LSldapObject_21');
             return;
           }
+          foreach ($submitData as $attr_name => $attr) {
+            if (!$this -> attrs[$attr_name] -> fireEvent('after_create')) {
+              LSerror :: addErrorCode('LSldapObject_21');
+              return;
+            }
+          }
         }
         return true;
       }
@@ -629,6 +644,43 @@ class LSldapObject {
   }
   
   /**
+   * Retourne le filtre correpondants au pattern passé
+   * 
+   * @author Benjamin Renard <brenard@easter-eggs.com>
+   * 
+   * @param[in] $pattern string Le mot clé recherché
+   * @param[in] $approx booléen Booléen activant ou non la recherche approximative
+   *
+   * @retval string le filtre ldap correspondant
+   */ 
+  function getPatternFilter($pattern=null,$approx=null) {
+    if ($pattern!=NULL) {
+      if (is_array($GLOBALS['LSobjects'][$this -> getType()]['LSsearch']['attrs'])) {
+        $attrs=$GLOBALS['LSobjects'][$this -> getType()]['LSsearch']['attrs'];
+      }
+      else {
+        $attrs=array($GLOBALS['LSobjects'][$this -> getType()]['rdn']);
+      }
+      $pfilter='(|';
+      if ($approx) {
+        foreach ($attrs as $attr_name) {
+          $pfilter.='('.$attr_name.'~='.$pattern.')';
+        }
+      }
+      else {
+        foreach ($attrs as $attr_name) {
+          $pfilter.='('.$attr_name.'=*'.$pattern.'*)';
+        }
+      }
+      $pfilter.=')';
+      return $pfilter;
+    }
+    else {
+      return NULL;
+    }
+  }
+  
+  /**
    * Retourne une liste d'objet du même type.
    *
    * Effectue une recherche en fonction des paramètres passé et retourne un
@@ -895,17 +947,25 @@ class LSldapObject {
  
  
   /**
-   * Recherche un objet à partir de la valeur exact de son RDN
+   * Recherche un objet à partir de la valeur exact de son RDN ou d'un filtre de
+   * recherche LDAP sous la forme d'un LSformat qui sera construit avec la valeur
+   * de $name.
    * 
    * @author Benjamin Renard <brenard@easter-eggs.com>
    * 
-   * @param[in] $name string Valeur de son RDN
+   * @param[in] $name string Valeur de son RDN ou de la valeur pour composer le filtre
    * @param[in] $basedn string Le DN de base de la recherche
+   * @param[in] $filter string Le filtre de recherche de l'objet
    * 
    * @retval array Tableau d'objets correspondant au resultat de la recherche
    */
-  function searchObject($name,$basedn=NULL) {
-    $filter = $this -> config['rdn'].'='.$name; 
+  function searchObject($name,$basedn=NULL,$filter=NULL) {
+    if (!$filter) {
+      $filter = $this -> config['rdn'].'='.$name;
+    }
+    else {
+      $filter = getFData($filter,$name);
+    }
     return $this -> listObjects($filter,$basedn); 
   }
 
@@ -961,23 +1021,7 @@ class LSldapObject {
    * @retval array('dn' => 'display')
    */
   function getSelectArray($pattern=NULL,$topDn=NULL,$displayFormat=NULL,$approx=false) {
-    if ($pattern!=NULL) {
-      $filter='(|';
-      if ($approx) {
-        foreach ($this -> attrs as $attr_name => $attr_val) {
-          $filter.='('.$attr_name.'~='.$pattern.')';
-        }
-      }
-      else {
-        foreach ($this -> attrs as $attr_name => $attr_val) {
-          $filter.='('.$attr_name.'=*'.$pattern.'*)';
-        }
-      }
-      $filter.=')';
-    }
-    else {
-      $filter=NULL;
-    }
+    $filter=$this -> getPatternFilter($pattern,$approx);
     return $this -> listObjectsName($filter,$topDn,array(),$displayFormat);
   }
 
@@ -1059,9 +1103,9 @@ class LSldapObject {
    * @retval boolean True si l'objet Ã  Ã©té supprimé, false sinon
    */
   function remove() {
-    if ($this -> beforeDelete()) {
+    if ($this -> fireEvent('before_delete')) {
       if (LSldap :: remove($this -> getDn())) {
-        if ($this -> afterDelete()) {
+        if ($this -> fireEvent('after_delete')) {
           return true;
         }
         LSerror :: addErrorCode('LSldapObject_19');
@@ -1178,6 +1222,7 @@ class LSldapObject {
    * @retval True en cas de cas ce succès, False sinon.
    */
   function beforeRename() {
+    // LSrelations
     return $this -> updateLSrelationsCache();
   }
   
@@ -1188,17 +1233,17 @@ class LSldapObject {
    * Cette méthode n'est qu'un exemple et elle doit être certainement réécrite
    * pour les objets plus complexe.
    * 
-   * @param[in] $oldDn string L'ancien DN de l'objet
-   * @param[in] $newDn string Le nouveau DN de l'objet
-   * 
    * @retval True en cas de cas ce succès, False sinon.
    */
-  function afterRename($oldDn,$newDn) {
+  function afterRename() {
     $error = 0;
-    if(LSsession :: getLSuserObjectDn() == $oldDn) {
+    
+    // Change LSsession -> userObject Dn
+    if(LSsession :: getLSuserObjectDn() == $this -> oldDn) {
       LSsession :: changeAuthUser($this);
     }
     
+    // LSrelations
     foreach($this -> _LSrelationsCache as $relation_name => $objInfos) {
       if ((isset($this->config['LSrelation'][$relation_name]['rename_function']))&&(is_array($objInfos['list']))) {
         foreach($objInfos['list'] as $obj) {
@@ -1249,6 +1294,8 @@ class LSldapObject {
    */
   function afterDelete() {
     $error = 0;
+    
+    // LSrelations
     foreach($this -> _LSrelationsCache as $relation_name => $objInfos) {
       if ((isset($this->config['LSrelation'][$relation_name]['remove_function']))&&(is_array($objInfos['list']))) {
         foreach($objInfos['list'] as $obj) {
@@ -1265,27 +1312,7 @@ class LSldapObject {
       }
     }
     
-    if (isset($this -> config['after_delete'])) {
-      if (is_array($this -> config['after_delete'])) {
-        $config = $this -> config['after_delete'];
-      }
-      else {
-        $config = array($this -> config['after_delete']);
-      }
-      foreach($config as $action) {
-        if(function_exists($action)) {
-          if(!$action($this)) {
-            LSerror :: addErrorCode('LSldapObject_25',$action);
-            $error=true;
-          }
-        }
-        else {
-          LSerror :: addErrorCode('LSldapObject_24',$action);
-          $error=true;
-        }
-      }
-    }
-    
+    // Binding LSattributes
     foreach(array_keys($this -> attrs) as $attr_name) {
       if (!$this -> attrs[$attr_name] -> fireEvent('after_delete')) {
         $error = true;
@@ -1307,6 +1334,8 @@ class LSldapObject {
   function afterCreate() {
     LSdebug('after');
     $error = 0;
+    
+    // container_auto_create
     if (LSsession :: isSubDnLSobject($this -> getType())) {
       if (is_array(LSsession :: $ldapServer['subDn']['LSobject'][$this -> getType()]['LSobjects'])) {
         foreach(LSsession :: $ldapServer['subDn']['LSobject'][$this -> getType()]['LSobjects'] as $type) {
@@ -1332,27 +1361,6 @@ class LSldapObject {
       }
     }
     
-    if (isset($this -> config['after_create'])) {
-      if (is_array($this -> config['after_create'])) {
-        $config = $this -> config['after_create'];
-      }
-      else {
-        $config = array($this -> config['after_create']);
-      }
-      foreach($config as $action) {
-        if(function_exists($action)) {
-          if(!$action($this)) {
-            LSerror :: addErrorCode('LSldapObject_23',$action);
-            $error=true;
-          }
-        }
-        else {
-          LSerror :: addErrorCode('LSldapObject_22',$action);
-          $error=true;
-        }
-      }
-    }
-    
     return !$error;
   }
   
@@ -1665,19 +1673,189 @@ class LSldapObject {
     }
   }
   
+  /**
+   * Ajouter une action lors d'un événement
+   * 
+   * @param[in] $event string Le nom de l'événement
+   * @param[in] $fct string Le nom de la fonction à exectuer
+   * @param[in] $param mixed Paramètre pour le lancement de la fonction
+   * @param[in] $class Nom de la classe possèdant la méthode $fct à executer
+   * 
+   * @retval void
+   */
+  function addEvent($event,$fct,$param=NULL,$class=NULL) {
+    $this -> _events[$event][] = array(
+      'function'  => $fct,
+      'param'    => $param,
+      'class'     => $class
+    );
+  }
+  
+  /**
+   * Ajouter une action sur un objet lors d'un événement
+   * 
+   * @param[in] $event string Le nom de l'événement
+   * @param[in] $obj object L'objet dont la méthode doit être executé
+   * @param[in] $meth string Le nom de la méthode
+   * @param[in] $param mixed Paramètre d'execution de la méthode
+   * 
+   * @retval void
+   */
+  function addObjectEvent($event,&$obj,$meth,$param=NULL) {
+    $this -> _objectEvents[$event][] = array(
+      'obj'  => $obj,
+      'meth'  => $meth,
+      'param'    => $param
+    );
+  }
+  
+  /**
+   * Lance les actions à executer lors d'un événement
+   * 
+   * @param[in] $event string Le nom de l'événement
+   * 
+   * @retval boolean True si tout c'est bien passé, false sinon
+   */
+  function fireEvent($event) {
+    
+    // Object event
+    $return = $this -> fireObjectEvent($event);
+    
+    // Config
+    if(isset($this -> config[$event])) {
+      if (!is_array($this -> config[$event])) {
+        $funcs = array($this -> config[$event]);
+      }
+      else {
+        $funcs = $this -> config[$event];
+      }
+      foreach($funcs as $func) {
+        if(function_exists($func)) {
+          if(!$func($this)) {
+            $return = false;
+            LSerror :: addErrorCode('LSldapObject_07',array('func' => $func,'event' => $event));
+          }
+        }
+        else {
+          $return = false;
+          LSerror :: addErrorCode('LSldapObject_06',array('func' => $func,'event' => $event));
+        }
+      }
+    }
+    
+    // Binding via addEvent
+    if (is_array($this -> _events[$event])) {
+      foreach ($this -> _events[$event] as $e) {
+        if ($e['class']) {
+          if (class_exists($e['class'])) {
+            $obj = new $e['class']();
+            if (method_exists($obj,$e['fct'])) {
+              try {
+                $obj -> $e['fct']($e['param']);
+              }
+              catch(Exception $er) {
+                LSerror :: addErrorCode('LSldapObject_10',array('class' => $e['class'],'meth' => $e['fct'],'event' => $event));
+                $return = false;
+              }
+            }
+            else {
+              LSerror :: addErrorCode('LSldapObject_09',array('class' => $e['class'],'meth' => $e['fct'],'event' => $event));
+              $return = false;
+            }
+          }
+          else {
+            LSerror :: addErrorCode('LSldapObject_08',array('class' => $e['class'],'meth' => $e['fct'],'event' => $event));
+            $return = false;
+          }
+        }
+        else {
+          if (function_exists($e['fct'])) {
+            try {
+              $e['fct']($e['param']);
+            }
+            catch(Exception $er) {
+              LSerror :: addErrorCode('LSldapObject_27',array('func' => $e['fct'],'event' => $event));
+              $return = false;
+            }
+          }
+          else {
+            LSerror :: addErrorCode('LSldapObject_26',array('func' => $e['fct'],'event' => $event));
+            $return = false;
+          }
+        }
+      }
+    }
+    
+    // Binding via addObjectEvent
+    if (is_array($this -> _objectEvents[$event])) {
+      foreach ($this -> _objectEvents[$event] as $e) {
+        if (method_exists($e['obj'],$e['meth'])) {
+          try {
+            $e['obj'] -> $e['meth']($e['param']);
+          }
+          catch(Exception $er) {
+            LSerror :: addErrorCode('LSldapObject_29',array('meth' => $e['meth'],'event' => $event));
+            $return = false;
+          }
+        }
+        else {
+          LSerror :: addErrorCode('LSldapObject_28',array('meth' => $e['meth'],'event' => $event));
+          $return = false;
+        }
+      }
+    }
+    
+    return $return;
+  }
+  
+  /**
+   * Lance les actions à executer lors d'un événement sur l'objet lui-même
+   * 
+   * @param[in] $event string Le nom de l'événement
+   * 
+   * @retval boolean True si tout c'est bien passé, false sinon
+   */
+  function fireObjectEvent($event) {
+    switch($event) {
+      case 'after_create':
+        return $this -> afterCreate();
+      case 'after_delete':
+        return $this -> afterDelete();
+      case 'after_rename':
+        return $this -> afterRename();
+/*
+      case 'after_modify':
+        return $this -> afterModify();
+*/
+/*
+      case 'before_create':
+        return $this -> beforeCreate();
+*/
+      case 'before_delete':
+        return $this -> beforeDelete();
+      case 'before_rename':
+        return $this -> beforeRename();
+/*
+      case 'before_modify':
+        return $this -> beforeModify();
+*/
+    }
+    return true;
+  }
+  
 }
 
 /**
  * Error Codes
  **/
 LSerror :: defineError('LSldapObject_01',
-_("LSldapObject : Object type unknow.")
+_("LSldapObject : Object type unknown.")
 );
 LSerror :: defineError('LSldapObject_02',
 _("LSldapObject : Update form is not defined for the object %{obj}.")
 );
 LSerror :: defineError('LSldapObject_03',
-_("LSldapObject : No form exist for the object %{obj}.")
+_("LSldapObject : No form exists for the object %{obj}.")
 );
 LSerror :: defineError('LSldapObject_04',
 _("LSldapObject : The function %{func} to validate the attribute %{attr} the object %{obj} is unknow.")
@@ -1685,23 +1863,24 @@ _("LSldapObject : The function %{func} to validate the attribute %{attr} the obj
 LSerror :: defineError('LSldapObject_05',
 _("LSldapObject : Configuration data are missing to validate the attribute %{attr} of the object %{obj}.")
 );
-/* No longer used
-LSerror :: defineError(26,
-_("LSldapObject : Configuration error : The object %{obj} doesn't had attribute %{attr}.")
+
+LSerror :: defineError('LSldapObject_06',
+_("LSldapObject : The function %{func} to be executed on the object event %{event} doesn't exist.")
 );
-*/
 LSerror :: defineError('LSldapObject_07',
-_("LSldapObject : The function %{func} to be executed before changing the object doesn't exist.")
+_("LSldapObject : The %{func} execution on the object event %{event} failed.")
 );
+
 LSerror :: defineError('LSldapObject_08',
-_("LSldapObject : The execution of the function %{func} to be executed before changing the object failed.")
+_("LSldapObject : Class %{class}, which method %{meth} to be executed on the object event %{event}, doesn't exist.")
 );
 LSerror :: defineError('LSldapObject_09',
-_("LSldapObject : The function %{func} to be executed after changing the object doesn't exist.")
+_("LSldapObject : Method %{meth} within %{class} class to be executed on object event %{event}, deoesn't exist.")
 );
 LSerror :: defineError('LSldapObject_10',
-_("LSldapObject : The execution of the function %{func} to be executed after changing the object failed.")
+_("LSldapObject : Error while executin %{meth} method within %{class} class, to be executed on object event %{event}.")
 );
+
 LSerror :: defineError('LSldapObject_11',
 _("LSldapObject : Some configuration data of the object type %{obj} are missing to generate the DN of the new object.")
 );
@@ -1717,22 +1896,28 @@ _("LSldapObject : The attribute %{attr_depend} depending on the attribute %{attr
 LSerror :: defineError('LSldapObject_15',
 _("LSldapObject : Error during deleting the object %{objectname}.")
 );
+
 LSerror :: defineError('LSldapObject_16',
 _("LSldapObject : Error during actions to be executed before renaming the objet.")
 );
 LSerror :: defineError('LSldapObject_17',
 _("LSldapObject : Error during actions to be executed after renaming the objet.")
 );
+
 LSerror :: defineError('LSldapObject_18',
 _("LSldapObject : Error during actions to be executed before deleting the objet.")
 );
 LSerror :: defineError('LSldapObject_19',
 _("LSldapObject : Error during actions to be executed after deleting the objet.")
 );
-// 20 : not used
+
+LSerror :: defineError('LSldapObject_20',
+_("LSldapObject : Error during the actions to be executed before creating the object.")
+);
 LSerror :: defineError('LSldapObject_21',
 _("LSldapObject : Error during the actions to be executed after creating the object. It was created anyway.")
 );
+
 LSerror :: defineError('LSldapObject_22',
 _("LSldapObject : The function %{func} to be generated before creating the object doesn't exist.")
 );
@@ -1745,18 +1930,19 @@ _("LSldapObject : The function %{func} to be generated after deleting the object
 LSerror :: defineError('LSldapObject_25',
 _("LSldapObject : Error during the execution of the function %{func} to be generated after creating the object.")
 );
-/* Not yet used
-LSerror :: defineError(306,
-_("LSldapObject : The function %{func} to be executed after changing the attribute %{attr} is unknow.")
+
+LSerror :: defineError('LSldapObject_26',
+_("LSldapObject : %{func} function, to be executed on object event %{event}, doesn't exist.")
 );
-LSerror :: defineError(307,
-_("LSldapObject : The execution of the function %{func} to be executed after changing the attribute %{attr} failed.")
+LSerror :: defineError('LSldapObject_27',
+_("LSldapObject : Error during the execution of %{func} function on object event %{event}.")
 );
-LSerror :: defineError(308,
-_("LSldapObject : The function %{func} to be executed before changing the attribute %{attr} is unknow.")
+
+LSerror :: defineError('LSldapObject_28',
+_("LSldapObject : %{meth} method, to be executed on object event %{event}, doesn't exist.")
 );
-LSerror :: defineError(309,
-_("LSldapObject : The execution of the function %{func} to be executed before changing the attribute %{attr} failed.")
+LSerror :: defineError('LSldapObject_29',
+_("LSldapObject : Error during execution of %{meth} method on object event %{event}.")
 );
-*/
+
 ?>