- LSsearch/LSsearchEntry : Added a new classes to doing and exploit ldap object search
authorBenjamin Renard <brenard@easter-eggs.com>
Fri, 30 Oct 2009 00:03:17 +0000 (00:03 +0000)
committerBenjamin Renard <brenard@easter-eggs.com>
Fri, 30 Oct 2009 00:03:17 +0000 (00:03 +0000)
  -> view/select => change to use it (php+template+js)
  -> LSattr_html_select_object/LSattr_html_select_list => change to use it
  -> LSldapObject :
    -> change listObjectsName() / searchObject() / getSelectArray() / listObjects()
    -> comment search() function
    -> Add triggers to clean cache
  -> LSpeople : Update search config
  -> LSsession  : Change function to use it :
    - getSubDnLdapServer()
    - loadLSprofiles()
- LSrelation : Deplace error codes declaration from LSsession in class file
- LSldapObject :
  -> change getObjectFilter() / getLabel() / getSubDnValue() / getSubDnName() for can call then staticaly
  -> Add afterModify() function and trigger
  -> Change getObjectFilter() / listObjectsInRelation() to use Net_LDAP2_Filter
  -> Add __get() function
  -> Move one LSerror code for LSrelation function from LSsession class file
  -> Add a global variable to save cached data ($cache)
  -> Change subDn and subDnName access methods
- LSauth : Move LSsession auth procedure in a dedicated class
  -> LSsession : Change startLSsession() to use it
- LSsession :
  -> Add getRootDn() function
  -> Fix getTopDn() to return root DN if no topDn is currently defined
  -> Create dedicated functions to support recoveryPassword mecanism :
    - recoverPasswd()
    - recoverPasswdSendMail()
    - recoverPasswdFirstStep()
    - recoverPasswdSecondStep
  -> Customize LSdebug return and display (php+js)
  -> Clean unused error codes
  -> Move LSrelation error codes
  -> Comment ajax method

17 files changed:
trunk/conf/LSobjects/config.LSobjects.LSpeople.php
trunk/conf/config.inc.php
trunk/includes/class/class.LSattr_html_select_list.php
trunk/includes/class/class.LSattr_html_select_object.php
trunk/includes/class/class.LSauth.php [new file with mode: 0644]
trunk/includes/class/class.LSldapObject.php
trunk/includes/class/class.LSrelation.php
trunk/includes/class/class.LSsearch.php [new file with mode: 0644]
trunk/includes/class/class.LSsearchEntry.php [new file with mode: 0644]
trunk/includes/class/class.LSsession.php
trunk/includes/js/LSselect.js
trunk/select.php
trunk/templates/default/select.tpl
trunk/templates/default/select_table.tpl
trunk/templates/default/viewList.tpl [deleted file]
trunk/templates/default/viewSearch.tpl [new file with mode: 0644]
trunk/view.php

index ba17e1a..4276d22 100644 (file)
@@ -115,7 +115,9 @@ $GLOBALS['LSobjects']['LSpeople'] = array (
       'uid',
       'mail'
     ),
-    'recursive' => true
+    'params' => array (
+      'recursive' => true
+    )
   ),
   
   // Attributes
index 2d8e328..215e13e 100644 (file)
@@ -65,7 +65,7 @@ $GLOBALS['LSconfig'] = array(
               'basedn' => 'ou=people,o=ls'
             ),
             'LSgroup' => array (
-              'filter' => 'lsGodfatherDn=%{dn}'
+              'filter' => '(lsGodfatherDn=%{dn})'
             )
           )
         )
index c87d0cb..764ba51 100644 (file)
@@ -94,36 +94,36 @@ class LSattr_html_select_list extends LSattr_html{
             LSerror :: addErrorCode('LSattr_html_select_list_01',$this -> name);
             break;
           }
-          if (!LSsession :: loadLSobject($val['object_type'])) {
+          if (!LSsession :: loadLSclass('LSsearch')) {
             return;
           }
-          $obj = new $val['object_type']();
-          if($val['scope']) {
-            $param=array('scope' => $val['scope']);
-          }
-          else {
-            $param=array();
-          }
           
-          $param['attributes'] = getFieldInFormat($val['display_name_format']);
+          $param=array(
+            'filter' => $val['filter'],
+            'basedn' => $val['basedn'],
+            'scope' => $val['scope'],
+            'displayFormat' => $val['display_name_format'],
+          );
+          
+          
           
           if ($val['value_attribute']!='dn') {
             $param['attributes'][] = $val['value_attribute'];
           }
           
-          $list = $obj -> search($val['filter'],$val['basedn'],$param);
+          $LSsearch = new LSsearch($val['object_type'],'LSattr_html_select_list',$param,true);
+          $LSsearch -> run();
           if(($val['value_attribute']=='dn')||($val['value_attribute']=='%{dn}')) {
-            for($i=0;$i<count($list);$i++) {
-              $retInfos[$list[$i]['dn']]=getFData($val['display_name_format'],$list[$i]['attrs']);
-            }
+            $retInfos = $LSsearch -> listObjectsName();
           }
           else {
-            for($i=0;$i<count($list);$i++) {
-              $key = $list[$i]['attrs'][$val['value_attribute']];
+            $list = $LSsearch -> getSearchEntries();
+            foreach($list as $entry) {
+              $key = $entry -> get($val['value_attribute']);
               if(is_array($key)) {
                 $key = $key[0];
               }
-              $retInfos[$key]=getFData($val['display_name_format'],$list[$i]['attrs']);
+              $retInfos[$key]=$entry -> displayName;
             }
           }
         }
index 6d0e2cc..b0eeae6 100644 (file)
@@ -148,19 +148,21 @@ class LSattr_html_select_object extends LSattr_html{
           }
         }
         else {
-          $filter='';
+          $filters=array();
           foreach($values as $val) {
             if (!empty($val)) {
-              $filter.='('.$conf['value_attribute'].'='.$val.')';
+              $filters[]=Net_LDAP2_Filter::create($conf['value_attribute'],'equals',$val);
             }
           }
-          if ($filter!='') {
-            $filter='(|'.$filter.')';
-            $obj = new $conf['object_type']();
-            $listobj = $obj -> listObjectsName($filter,NULL,array(),$conf['display_name_format']);
-            foreach($listobj as $dn => $name) {
-              $DNs[]=$dn;
-              $retInfos[$dn] = $name;
+          if (!empty($filters)) {
+            $filter=LSldap::combineFilters('or',$filters);
+            if ($filter) {
+              $obj = new $conf['object_type']();
+              $listobj = $obj -> listObjectsName($filter,NULL,array(),$conf['display_name_format']);
+              foreach($listobj as $dn => $name) {
+                $DNs[]=$dn;
+                $retInfos[$dn] = $name;
+              }
             }
           }
         }
diff --git a/trunk/includes/class/class.LSauth.php b/trunk/includes/class/class.LSauth.php
new file mode 100644 (file)
index 0000000..38979a3
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+/*******************************************************************************
+ * Copyright (C) 2007 Easter-eggs
+ * http://ldapsaisie.labs.libre-entreprise.org
+ *
+ * Author: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+******************************************************************************/
+
+/**
+ * Gestion de l'authentification d'un utilisateur
+ *
+ * Cette classe gere l'authentification des utilisateurs à l'interface
+ *
+ * @author Benjamin Renard <brenard@easter-eggs.com>
+ */
+class LSauth {
+  
+  /**
+   * Check user login
+   *
+   * @param[in] $username The username
+   * @param[in] $password The password
+   *
+   * @retval LSldapObject|false The LSldapObject of the user authificated or false 
+   */
+  public static function authenticate($username,$password) {
+    if (LSsession :: loadLSobject(LSsession :: $ldapServer['authObjectType'])) {
+      $authobject = new LSsession :: $ldapServer['authObjectType']();
+      $result = $authobject -> searchObject(
+        $username,
+        LSsession :: getTopDn(),
+        LSsession :: $ldapServer['authObjectFilter']
+      );
+      $nbresult=count($result);
+      
+      if ($nbresult==0) {
+        // identifiant incorrect
+        LSdebug('identifiant incorrect');
+        LSerror :: addErrorCode('LSauth_01');
+      }
+      else if ($nbresult>1) {
+        // duplication d'authentité
+        LSerror :: addErrorCode('LSauth_02');
+      }
+      elseif ( self :: checkUserPwd($result[0],$password) ) {
+        // Authentication succeeded
+        return $result[0];
+      }
+      else {
+        LSerror :: addErrorCode('LSauth_01');
+        LSdebug('mdp incorrect');
+      }
+    }
+    else {
+      LSerror :: addErrorCode('LSauth_03');
+    }
+    return;
+  }
+  
+ /**
+  * Test un couple LSobject/pwd
+  *
+  * Test un bind sur le serveur avec le dn de l'objet et le mot de passe fourni.
+  *
+  * @param[in] LSobject L'object "user" pour l'authentification
+  * @param[in] string Le mot de passe à tester
+  *
+  * @retval boolean True si l'authentification à réussi, false sinon.
+  */
+  public static function checkUserPwd($object,$pwd) {
+    return LSldap :: checkBind($object -> getValue('dn'),$pwd);
+  }
+  
+}
+
+/*
+ * Error Codes
+ */
+LSerror :: defineError('LSauth_01',
+_("LSauth : Login or password incorrect.")
+);
+LSerror :: defineError('LSauth_02',
+_("LSauth : Impossible to identify you : Duplication of identities.")
+);
+LSerror :: defineError('LSauth_03',
+_("LSsession : Could not load type of identifiable objects.")
+);
+?>
index d613dbb..d0bdc31 100644 (file)
@@ -41,12 +41,13 @@ class LSldapObject {
   var $other_values=array();
   var $submitError=true;
   var $_whoami=NULL;
-  var $_subDn_value=NULL;
   var $_LSrelationsCache=array();
 
   var $_events=array();
   var $_objectEvents=array();
   
+  var $cache=array();
+  
   /**
    * Constructeur
    *
@@ -149,7 +150,7 @@ class LSldapObject {
     }
     $val = $this -> getFData($spe,&$this -> attrs,'getDisplayValue');
     if (LSsession :: haveSubDn() && $full) {
-      $val.=' ('.$this -> getSubDnName().')';
+      $val.=' ('.$this -> subDnName.')';
     }
     return $val;
   }
@@ -626,17 +627,27 @@ class LSldapObject {
    *
    * @retval string le filtre ldap correspondant au type de l'objet
    */ 
-  function getObjectFilter() {
-    if(!isset($this -> config['objectclass'])) return;
-    $filter="(&";
-    foreach ($this -> config['objectclass'] as $class) {
-      $filter.='(objectClass='.$class.')';
+  function getObjectFilter($type=null) {
+    if (is_null($type)) {
+      $type = $this -> type_name;
+    }
+    $oc=LSconfig::get("LSobjects.$type.objectclass");
+    if(!is_array($oc)) return;
+    $filters=array();
+    foreach ($oc as $class) {
+      $filters[]=Net_LDAP2_Filter::create('objectClass','equals',$class);
     }
-    $filter.=')';
-    if ($this -> config['filter']) {
-      $filter="(&(".$this -> config['filter'].")$filter)";
+    
+    $filter=LSconfig::get("LSobjects.$type.filter");
+    if ($filter) {
+      $filters[]=$filter;
     }
-    return $filter;
+
+    $filter = LSldap::combineFilters('and',$filters,true);
+    if ($filter)
+      return $filter;
+    LSerror :: addErrorCode('LSldapObject_30',$type);
+    return;
   }
   
   /**
@@ -691,17 +702,34 @@ class LSldapObject {
    * @retval array Tableau d'objets correspondant au resultat de la recherche
    */ 
   function listObjects($filter=NULL,$basedn=NULL,$params=array()) {
-    $retInfos=array();
+    if (!LSsession :: loadLSclass('LSsearch')) {
+      LSerror::addErrorCode('LSsession_05','LSsearch');
+      return;
+    }
     
-    $ret = $this -> search($filter,$basedn,$params);
+    $sparams = array(
+      'basedn' => $basedn,
+      'filter' => $filter,
+      'attributes' => array('dn')
+    );
+
+    if (is_array($params)) {    
+      $sparams=array_merge($sparams,$params);
+    }
+    $LSsearch = new LSsearch($this -> type_name,'LSldapObjet::listObjects',$sparams,true);
+    
+    $LSsearch -> run();
+    
+    return $LSsearch -> listObjects();
     
-    // Création d'un tableau d'objet correspondant au valeur retourné
+/*
     for($i=0;$i<count($ret);$i++) {
       $retInfos[$i] = new $this -> type_name($this -> config);
       $retInfos[$i] -> loadData($ret[$i]['dn']);
     }
     
     return $retInfos;
+*/
   }
   
   /**
@@ -719,6 +747,7 @@ class LSldapObject {
    *
    * @retval array Tableau d'objets correspondant au resultat de la recherche
    */ 
+/*
   function search($filter='',$basedn=NULL,$params=array()) {
     $retInfos=array();
     $attrs=false;
@@ -901,6 +930,7 @@ class LSldapObject {
     }
     return $ret;
   }
+*/
   
   /**
    * Retourne une liste d'objet du même type et retourne leur noms
@@ -917,31 +947,31 @@ class LSldapObject {
    *
    * @retval array Tableau dn => name correspondant au resultat de la recherche
    */ 
-  function listObjectsName($filter=NULL,$sbasedn=NULL,$sparams=array(),$displayFormat=false) {
-    $retInfos=array();
+  function listObjectsName($filter=NULL,$sbasedn=NULL,$sparams=array(),$displayFormat=false,$cache=true) {
+    if (!LSsession :: loadLSclass('LSsearch')) {
+      LSerror::addErrorCode('LSsession_05','LSsearch');
+      return;
+    }
     
     if (!$displayFormat) {
       $displayFormat = $this -> getDisplayNameFormat();
     }
-    // Attributes
-    $attrs = getFieldInFormat($displayFormat);
-    if(!empty($attrs)) {
-      $sparams['attributes'] = $attrs;
+    
+    $params = array(
+      'displayFormat' => $displayFormat,
+      'basedn' => $sbasedn,
+      'filter' => $filter
+    );
+
+    if (is_array($sparams)) {    
+      $params=array_merge($sparams,$params);
     }
     
-    // Lancement de la recherche
-    $ret=$this -> search ($filter,$sbasedn,$sparams);
+    $LSsearch = new LSsearch($this -> type_name,'LSldapObject::listObjectsName',$params,true);
     
-    if (is_array($ret)) {
-      foreach($ret as $obj) {
-        if (in_array('subDnName',$attrs)) {
-          $obj['attrs']['subDnName']=$this -> getSubDnName($obj['dn']);
-        }
-        $retInfos[$obj['dn']] = getFData($displayFormat,$obj['attrs']);
-      }
-    }
+    $LSsearch -> run($cache);
     
-    return $retInfos;
+    return $LSsearch -> listObjectsName();
   }
  
  
@@ -955,17 +985,18 @@ class LSldapObject {
    * @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
+   * @param[in] $params array Tableau de paramètres
    * 
    * @retval array Tableau d'objets correspondant au resultat de la recherche
    */
-  function searchObject($name,$basedn=NULL,$filter=NULL) {
+  function searchObject($name,$basedn=NULL,$filter=NULL,$params=NULL) {
     if (!$filter) {
-      $filter = $this -> config['rdn'].'='.$name;
+      $filter = '('.$this -> config['rdn'].'='.$name.')';
     }
     else {
       $filter = getFData($filter,$name);
     }
-    return $this -> listObjects($filter,$basedn); 
+    return $this -> listObjects($filter,$basedn,$params); 
   }
 
   /**
@@ -993,10 +1024,10 @@ class LSldapObject {
       return $this -> attrs[ $this -> config['rdn'] ] -> getValue();
     }
     else if(($val=='subDn')||($val=='%{subDn}')) {
-      return $this -> getSubDnValue();
+      return $this -> subDnValue;
     }
     else if(($val=='subDnName')||($val=='%{subDnName}')) {
-      return $this -> getSubDnName();
+      return $this -> subDnName;
     }
     else if(isset($this ->  attrs[$val])){
       if (method_exists($this ->  attrs[$val],'getValue'))
@@ -1019,9 +1050,8 @@ class LSldapObject {
    *
    * @retval array('dn' => 'display')
    */
-  function getSelectArray($pattern=NULL,$topDn=NULL,$displayFormat=NULL,$approx=false) {
-    $filter=$this -> getPatternFilter($pattern,$approx);
-    return $this -> listObjectsName($filter,$topDn,array(),$displayFormat);
+  function getSelectArray($pattern=NULL,$topDn=NULL,$displayFormat=NULL,$approx=false,$cache=true) {
+    return $this -> listObjectsName($filter,$topDn,array('pattern' => $pattern),$displayFormat,$cache);
   }
 
   /**
@@ -1089,8 +1119,11 @@ class LSldapObject {
    * 
    * @retval string Le label de l'objet ($this -> config['label'])
    */
-  function getLabel() {
-    return __($this -> config['label']);
+  function getLabel($type=null) {
+    if (is_null($type)) {
+      $type = $this -> type_name;
+    }
+    return __(LSconfig::get("LSobjects.$type.label"));
   }
   
   
@@ -1134,13 +1167,7 @@ class LSldapObject {
    * 
    * @return string La valeur du subDn de l'object
    */
-  function getSubDnValue($dn=NULL) {
-    if (!$dn) {
-      $dn = $this -> getValue('dn');
-    }
-    if ($this -> _subDn_value[$dn]) {
-      return $this -> _subDn_value[$dn];
-    }
+  public static function getSubDnValue($dn) {
     $subDn_value='';
     $subDnLdapServer = LSsession :: getSortSubDnLdapServer();
     foreach ($subDnLdapServer as $subDn => $subDn_name) {
@@ -1149,7 +1176,6 @@ class LSldapObject {
         break;
       }
     }
-    $this -> _subDn_value[$dn] = $subDn_value;
     return $subDn_value;
   }
 
@@ -1160,9 +1186,9 @@ class LSldapObject {
    * 
    * @return string Le nom du subDn de l'object
    */
-  function getSubDnName($dn=NULL) {
+  public static function getSubDnName($dn) {
     $subDnLdapServer = LSsession :: getSortSubDnLdapServer();
-    return $subDnLdapServer[$this -> getSubDnValue($dn)];
+    return $subDnLdapServer[self :: getSubDnValue($dn)];
   }
   
   /**
@@ -1318,6 +1344,11 @@ class LSldapObject {
       }
     }
     
+    // LSsearch : Purge LSobject cache
+    if (LSsession :: loadLSclass('LSsearch')) {
+      LSsearch :: purgeCache($this -> type_name);
+    }
+    
     return !$error;
   }
   
@@ -1361,6 +1392,31 @@ class LSldapObject {
       }
     }
     
+    // LSsearch : Purge LSobject cache
+    if (LSsession :: loadLSclass('LSsearch')) {
+      LSsearch :: purgeCache($this -> type_name);
+    }
+    
+    return !$error;
+  }
+  
+  /**
+   * Methode executant les actions nécéssaires après la modification de
+   * l'objet.
+   * 
+   * Cette méthode n'est qu'un exemple et elle doit être certainement réécrite
+   * pour les objets plus complexe.
+   * 
+   * @retval True en cas de cas ce succès, False sinon.
+   */
+  function afterModify() {
+    $error = 0;
+    
+    // LSsearch : Purge LSobject cache
+    if (LSsession :: loadLSclass('LSsearch')) {
+      LSsearch :: purgeCache($this -> type_name);
+    }
+    
     return !$error;
   }
   
@@ -1422,9 +1478,8 @@ class LSldapObject {
       $val = $val[0];
     }
     if ($val) {
-      $filter = $this -> getObjectFilter();
-      $filter = '(&'.$filter.'('.$attr.'='.$val.'))';
-      return $this -> listObjects($filter,LSsession :: $ldapServer['ldap_config']['basedn'],array('scope' => 'sub'));
+      $filter = Net_LDAP2_Filter::create($attr,'equals',$val);
+      return $this -> listObjects($filter,LSsession :: getRootDn(),array('scope' => 'sub','recursive' => true,'withoutCache'=>true));
     }
     return;
   }
@@ -1814,7 +1869,7 @@ class LSldapObject {
    * @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':
@@ -1823,10 +1878,8 @@ class LSldapObject {
         return $this -> afterDelete();
       case 'after_rename':
         return $this -> afterRename();
-/*
       case 'after_modify':
         return $this -> afterModify();
-*/
 /*
       case 'before_create':
         return $this -> beforeCreate();
@@ -1843,6 +1896,30 @@ class LSldapObject {
     return true;
   }
   
+  /**
+   * Access to infos of the object
+   * 
+   * @param[in] $key string The name of the value
+   * 
+   * @retval mixed The value
+   **/
+  function __get($key) {
+    if ($key=='subDnValue') {
+      if ($this -> cache['subDnValue']) {
+        return $this -> cache['subDnValue'];
+      }
+      $this -> cache['subDnValue'] = self :: getSubDnValue($this -> dn);
+      return $this -> cache['subDnValue'];
+    }
+    if ($key=='subDnName') {
+      if ($this -> cache['subDnName']) {
+        return $this -> cache['subDnName'];
+      }
+      $this -> cache['subDnName'] = self :: getSubDnName($this -> dn);
+      return $this -> cache['subDnName'];
+    }
+  }
+  
 }
 
 /**
@@ -1944,5 +2021,13 @@ _("LSldapObject : %{meth} method, to be executed on object event %{event}, doesn
 LSerror :: defineError('LSldapObject_29',
 _("LSldapObject : Error during execution of %{meth} method on object event %{event}.")
 );
+LSerror :: defineError('LSldapObject_30',
+_("LSldapObject : Error during generate LDAP filter for %{LSobject}.")
+);
+
+// LSrelation
+LSerror :: defineError('LSrelations_05',
+_("LSrelation : Some parameters are missing in the call of methods to handle standard relations (Method : %{meth}).")
+);
 
 ?>
index 8f9782e..cb9b54c 100644 (file)
@@ -295,4 +295,20 @@ class LSrelation {
   }
 }
 
+/**
+ * Error Codes
+ **/
+LSerror :: defineError('LSrelations_01',
+_("LSrelation : The listing function for the relation %{relation} is unknow.")
+);
+LSerror :: defineError('LSrelations_02',
+_("LSrelation : The update function of the relation %{relation} is unknow.")
+);
+LSerror :: defineError('LSrelations_03',
+_("LSrelation : Error during relation update of the relation %{relation}.")
+);
+LSerror :: defineError('LSrelations_04',
+_("LSrelation : Object type %{LSobject} unknow (Relation : %{relation}).")
+);
+
 ?>
diff --git a/trunk/includes/class/class.LSsearch.php b/trunk/includes/class/class.LSsearch.php
new file mode 100644 (file)
index 0000000..57f8386
--- /dev/null
@@ -0,0 +1,1130 @@
+<?php
+/*******************************************************************************
+ * Copyright (C) 2007 Easter-eggs
+ * http://ldapsaisie.labs.libre-entreprise.org
+ *
+ * Author: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+******************************************************************************/
+
+/**
+ * Object LSsearch
+ *
+ * @author Benjamin Renard <brenard@easter-eggs.com>
+ */
+class LSsearch { 
+  
+  // The LdapObject type of search
+  private $LSobject=NULL;
+  
+  // The configuration of search
+  private $config;
+  
+  // The context of search
+  private $context;
+  
+  // The parameters of the search
+  private $params=array (
+    // Search params
+    'filter' => NULL,
+    'pattern' => NULL,
+    'basedn' => NULL,
+    'subDn' => NULL,
+    'scope' => NULL,
+    'sizelimit' => 0,
+    'attronly' => false,    // If true, only attribute names are returned
+    'approx' => false,
+    'recursive' => false,
+    'attributes' => array(),
+    // Display params
+    'sortDirection' => NULL,
+    'sortBy' => NULL,
+    'sortlimit' => 0,
+    'displaySubDn' => NULL,
+    'displayFormat' => NULL,
+    'nbObjectsByPage' => NB_LSOBJECT_LIST,
+    'nbPageLinkByPage' => 10,
+    'withoutCache' => false
+  );
+  
+  // The cache of search parameters
+  private $_searchParams = NULL;
+  
+  // The cache of the hash of the search parameters
+  private $_hash = NULL;
+  
+  // The result of the search
+  private $result=NULL;
+  
+  // Caches
+  private $_canCopy=NULL;
+  
+  /**
+   * Constructor
+   * 
+   * @param[in] $LSobject string The LdapObject type of search
+   * @param[in] $context string Context of search (LSrelation / LSldapObject/ ...)
+   * @param[in] $params array Parameters of search
+   * @param[in] $purgeParams boolean If params in session have to be purged
+   * 
+   **/
+  function LSsearch($LSobject,$context,$params=null,$purgeParams=false) {
+    if (!LSsession :: loadLSobject($LSobject)) {
+      return;
+    }
+    $this -> LSobject = $LSobject;
+    
+    $this -> loadConfig();
+    
+    if (isset($_REQUEST['LSsearchPurgeSession'])) {
+      $this -> purgeSession();
+    }
+    
+    $this -> context = $context;
+    
+    if (!$purgeParams) {
+      if (! $this -> loadParamsFromSession()) {
+        LSdebug('LSsearch : load default parameters');
+        $this -> loadDefaultParameters();
+      }
+    }
+    else {
+      $this -> purgeParams();
+      $this -> loadDefaultParameters();
+    }
+    
+    if (is_array($params)) {
+      $this -> setParams($params);
+    }
+    
+  }
+
+  /**
+   * Load configuration from LSconfig
+   * 
+   * @retval void
+   */
+  private function loadConfig() {
+    $this -> config = LSconfig::get("LSobjects.".$this -> LSobject.".LSsearch");
+  }
+  
+  /**
+   * Load default search parameters from configuration
+   * 
+   * @retval boolean True on success or False
+   */
+  private function loadDefaultParameters() {
+    if (is_array($this -> config['params'])) {
+      return $this -> setParams($this -> config['params']);
+    }
+    return true;
+  }
+  
+  /**
+   * Load search parameters from session
+   * 
+   * @retval boolean True if params has been loaded from session or False
+   */
+  private function loadParamsFromSession() {
+    LSdebug('LSsearch : load context params session '.$this -> context);
+    if (is_array($_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context])) {
+      $params = $_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context];
+      
+      if ($params['filter']) {
+        $params['filter'] = Net_LDAP2_Filter::parse($params['filter']);
+      }
+      
+      $this -> params = $params;
+      return true;
+    }
+    return;
+  }
+
+  /**
+   * Save search parameters in session
+   * 
+   * @retval void
+   */
+  private function saveParamsInSession() {
+    LSdebug('LSsearch : save context params session '.$this -> context);
+    $params = $this -> params;
+    if ($params['filter'] instanceof Net_LDAP2_Filter) {
+      $params['filter'] = $params['filter'] -> asString();
+    }
+    
+    foreach ($params as $param => $value) {
+      if ($_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context][$param]!=$value) {
+        LSdebug("S: $param => $value");
+        $_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context][$param]=$value;
+      }
+    }
+  }
+  
+  /**
+   * Purge parameters in session
+   * 
+   * @param[in] $LSobject string The LSobject type
+   * 
+   * @retval void
+   */
+  public function purgeParams($LSobject=NULL) {
+    if (is_null($LSobject)) {
+      $LSobject = $this -> LSobject;
+    }
+    unset($_SESSION['LSsession']['LSsearch'][$LSobject]['params']);
+  }
+  
+  /**
+   * Purge cache
+   * 
+   * @retval void
+   */
+  public function purgeCache($LSobject=NULL) {
+    if (is_null($LSobject))
+      $LSobject = $this -> LSobject;
+    unset($_SESSION['LSsession']['LSsearch'][$LSobject]);
+  }
+  
+  /**
+   * Purge session
+   * 
+   * @retval void
+   */
+  private function purgeSession() {
+    unset($_SESSION['LSsession']['LSsearch']);
+  }
+  
+  /**
+   * Define one search parameter
+   * 
+   * @param[in] $param string The parameter name
+   * @param[in] $value mixed The parameter value
+   * 
+   * @retval boolean True on success or False
+   */
+  public function setParam($param,$value) {
+    return $this -> setParams(array($param => $value));
+  }
+  
+  /**
+   * Define search parameters
+   * 
+   * @param[in] $params array Parameters of search
+   * 
+   * @retval boolean True on success or False
+   */
+  public function setParams($params) {
+    $OK=true;
+    
+    // Filter
+    if (is_string($params['filter'])) {
+      $filter = Net_LDAP2_Filter::parse($params['filter']);
+      if (!LSerror::isLdapError($filter)) {
+        $this -> params['filter'] = $filter;
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_01',$params['filter']);
+        $OK=false;
+      }
+    }
+    elseif($params['filter'] instanceof Net_LDAP2_Filter) {
+      $this -> params['filter'] =& $params['filter'];
+    }
+
+    // Approx
+    if (isset($params['approx'])) {
+      if (is_bool($params['approx']) || $params['approx']==0 || $params['approx']==1) {
+        $this -> params['approx'] = (bool)$params['approx'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_05','approx');
+        $OK=false;
+      }
+    }
+    
+    // Without Cache
+    if (isset($params['withoutCache'])) {
+      if (is_bool($params['withoutCache']) || $params['withoutCache']==0 || $params['withoutCache']==1) {
+        $this -> params['withoutCache'] = (bool)$params['withoutCache'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_05','withoutCache');
+        $OK=false;
+      }
+    }
+    
+    // Patterm
+    if (isset($params['pattern']) && $params['pattern']=="") {
+      $this -> params['pattern'] = NULL;
+      $this -> params['filter'] = NULL;
+    }
+    elseif (self :: isValidPattern($params['pattern'])) {
+      $this -> params['pattern'] = $params['pattern'];
+      if (!is_string($params['filter'])) {
+        $this -> params['filter']=NULL;
+      }
+    }
+    
+    
+    // BaseDN
+    if (is_string($params['basedn'])) {
+      if (isCompatibleDNs(LSsession :: getRootDn(),$params['basedn'])) {
+        $this -> params['basedn'] = $params['basedn'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_02',$params['basedn']);
+        $OK=false;
+      }
+    }
+    
+    // subDn
+    if (is_string($params['subDn'])) {
+      if (LSsession :: validSubDnLdapServer($params['subDn'])) {
+        $this -> params['subDn'] = $params['subDn'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_03','subDn');
+        $OK=false;
+      }
+    }
+    
+    // Scope
+    if (is_string($params['scope'])) {
+      if (in_array($params['scope'],array('sub','one','base'))) {
+        $this -> params['scope'] = $params['scope'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_03','scope');
+        $OK=false;
+      }
+    }
+    
+    // nbObjectsByPage
+    if (isset($params['nbObjectsByPage'])) {
+      if (((int)$params['nbObjectsByPage'])>1 ) {
+        $this -> params['nbObjectsByPage'] = (int)$params['nbObjectsByPage'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_03','nbObjectsByPage');
+        $OK=false;
+      }
+    }
+    
+    // Sort Limit
+    if (isset($params['sortlimit'])) {
+      if (is_int($params['sortlimit']) && $params['sortlimit']>=0 ) {
+        $this -> params['sortlimit'] = $params['sortlimit'];
+      }
+      elseif ((int)$params['sortlimit'] > 0) {
+        $this -> params['sortlimit'] = (int)$params['sortlimit'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_03','sortlimit');
+        $OK=false;
+      }
+    }
+    
+    // Sort Direction
+    if (is_string($params['sortDirection'])) {
+      if (in_array($params['sortDirection'],array('ASC','DESC'))) {
+        $this -> params['sortDirection'] = $params['sortDirection'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_03','sortDirection');
+        $OK=false;
+      }
+    }
+    
+    // Sort By
+    if (is_string($params['sortBy'])) {
+      if (in_array($params['sortBy'],array('displayName','subDn'))) {
+        if ($this -> params['sortBy'] == $params['sortBy']) {
+          $this -> toggleSortDirection();
+        }
+        else {
+          $this -> params['sortBy'] = $params['sortBy'];
+          if (!is_string($params['sortDirection'])) {
+            $this -> params['sortDirection']='ASC';
+          }
+        }
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_03','sortBy');
+        $OK=false;
+      }
+    }
+    
+    // Size Limit
+    if (isset($params['sizelimit'])) {
+      if (((int)$params['sizelimit']) >= 0) {
+        $this -> params['sizelimit'] = $params['sizelimit'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_04');
+        $OK=false;
+      }
+    }
+    
+    // Attronly
+    if (isset($params['attronly'])) {
+      if (is_bool($params['attronly']) || $params['attronly']==0 || $params['attronly']==1) {
+        $this -> params['attronly'] = (bool)$params['attronly'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_05','attronly');
+        $OK=false;
+      }
+    }
+    
+    // Recursive
+    if (isset($params['recursive'])) {
+      if (is_bool($params['recursive']) || $params['recursive']==0 || $params['recursive']==1) {
+        $this -> params['recursive'] = (bool)$params['recursive'];
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_05','recursive');
+        $OK=false;
+      }
+    }
+    
+    // displaySubDn
+    if (isset($params['displaySubDn'])) {
+      if (! LSsession :: isSubDnLSobject($this -> LSobject) ) {
+        if (is_bool($params['displaySubDn']) || $params['displaySubDn']==0 || $params['displaySubDn']==1) {
+          $this -> params['displaySubDn'] = (bool)$params['displaySubDn'];
+        }
+        else {
+          LSerror :: addErrorCode('LSsearch_05','displaySubDn');
+          $OK=false;
+        }
+      }
+    }
+    
+    // Attributes
+    if (isset($params['attributes'])) {
+      if (is_string($params['attributes'])) {
+        $this -> params['attributes'] = array($params['attributes']);
+      }
+      elseif (is_array($params['attributes'])) {
+        $this -> params['attributes']=array();
+        foreach ($this -> params['attributes'] as $attr) {
+          if (is_string($attr)) {
+            if (LSconfig::get("LSobjects.".$this -> LSobject.".attrs.$attr")) {;
+              $this -> params['attributes'][] = $attr;
+            }
+            else {
+              LSerror :: addErrorCode('LSsearch_11',$attr);
+            }
+          }
+        }
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_06');
+        $OK=false;
+      }
+    }
+    
+    // Display Format
+    if (is_string($params['displayFormat'])) {
+      $this -> params['displayFormat'] = $params['displayFormat'];
+    }
+
+    $this -> saveParamsInSession();
+    return $OK;
+  }
+
+  /**
+   * Define search parameters by reading Post Data ($_REQUEST)
+   * 
+   * @retval void
+   */
+  public function setParamsFormPostData() {
+    $data = $_REQUEST;
+    
+    if (isset($data['LSsearch_submit'])) {
+      // Recursive 
+      if (is_null($data['recursive'])) {
+        $data['recursive']=false;
+      }
+      else {
+        $data['recursive']=true;
+      }
+      
+      // Approx 
+      if (is_null($data['approx'])) {
+        $data['approx']=false;
+      }
+      else {
+        $data['approx']=true;
+      }
+      
+      if (isset($data['ajax']) && !isset($data['pattern'])) {
+        $data['pattern']="";
+      }
+    }
+    
+    $this -> setParams($data);
+  }
+  
+  /**
+   * Toggle the sort direction
+   * 
+   * @retval void
+   **/
+  private function toggleSortDirection() {
+    if ($this -> params['sortDirection']=="ASC") {
+      $this -> params['sortDirection'] = "DESC";
+    }
+    else {
+      $this -> params['sortDirection'] = "ASC";
+    }
+  }
+  
+  /**
+   * Make a filter object with a pattern of search
+   *
+   * @param[in] $pattern The pattern of search. If is null, the pattern in params will be used.
+   * 
+   * @retval mixed Net_LDAP2_Filter on success or False
+   */ 
+  function getFilterFromPattern($pattern=NULL) {
+    if ($pattern==NULL) {
+      $pattern=$this -> params['pattern'];
+    }
+    if (self :: isValidPattern($pattern)) {
+      $operator=( ($params['approx'])?'approx':'contains' );
+      $attrsList=LSconfig::get("LSobjects.".$this -> LSobject.".LSsearch.attrs");
+      if (!is_array($attrsList)) {
+        $attrsList = array_keys(LSconfig::get("LSobjects.".$this -> LSobject.".attrs"));
+      }
+      
+      if (empty($attrsList)) {
+        LSerror :: addErrorCode('LSsearch_07');
+        return;
+      }
+      
+      $filters=array();
+      foreach ($attrsList as $attr) {
+        $filter=Net_LDAP2_Filter::create($attr,$operator,$pattern);
+        if (!Net_LDAP2::isError($filter)) {
+          $filters[]=$filter;
+        }
+        else {
+          LSerror :: addErrorCode('LSsearch_08',array('attr' => $attr,'pattern' => $pattern));
+          return;
+        }
+      }
+      if(!empty($filters)) {
+        $filter=LSldap::combineFilters('or',$filters);
+        if ($filter) {
+          return $filter;
+        }
+        else {
+          LSerror :: addErrorCode('LSsearch_09');
+        }
+      }
+    }
+    else {
+      LSerror :: addErrorCode('LSsearch_10');
+    }
+    return;
+  }
+  
+  /**
+   * Check if search pattern is valid
+   * 
+   * @param[in] $pattern string The pattern
+   * 
+   * @retval boolean True if pattern is valid or False
+   **/
+  static function isValidPattern($pattern) {
+    return (is_string($pattern) && $pattern!= "" && $pattern!="*");
+  }
+  
+  /**
+   * Check if cache is enabled
+   * 
+   * @retval boolean True if cache is enabled or False
+   **/
+  public function cacheIsEnabled() {
+    if (isset($this -> config['cache'])) {
+      $conf=$this -> config['cache'];
+      if (is_bool($conf) || $conf==0 || $conf==1) {
+        return (bool)$conf;
+      }
+      else {
+        LSerror :: addErrorCode('LSsearch_03','cache');
+      }
+    }
+    return LSsession :: cacheSearch();
+  }
+  
+  /**
+   * Methode for parameters value access
+   * 
+   * @param[in] $key string The parameter name
+   * 
+   * @retval mixed The parameter value or NULL
+   **/
+  public function getParam($key) {
+    if(in_array($key,array_keys($this -> params))) {
+      return $this -> params[$key];
+    }
+    return NULL;
+  }
+  
+  /**
+   * Return hidden fileds to add in search form
+   * 
+   * @retval array The hield fields whith their values
+   **/
+  public function getHiddenFieldForm() {
+    return array (
+      'LSobject' => $this -> LSobject
+    );
+  }
+  
+  /**
+   * Generate an array with search parameters, only parameters whitch have to be
+   * passed to Net_LDAP2 for the LDAP search. This array will be store in 
+   * $this -> _searchParams private variable.
+   * 
+   * @retval void
+   **/
+  private function generateSearchParams() {
+    // Purge the cache of the hash
+    $this -> _hash = NULL;
+    
+    // Base
+    $retval = array(
+      'filter' => $this -> params['filter'],
+      'basedn' => $this -> params['basedn'],
+      'scope' => $this -> params['scope'],
+      'sizelimit' => $this -> params['sizelimit'],
+      'attronly' => $this -> params['attronly'],
+      'attributes' => $this -> params['attributes']
+    );
+    
+    // Pattern
+    if (!is_null($this -> params['pattern'])) {
+      $filter=$this ->getFilterFromPattern();
+      if (is_null($retval['filter'])) {
+        $retval['filter']=$filter;
+      }
+      else {
+        $retval['filter']=LSldap::combineFilters('and',array($retval['filter'],$filter));
+      }
+    }
+    
+    // Filter
+    $objFilter=LSldapObject::getObjectFilter($this -> LSobject);
+    if ($objFilter) {
+      if (!is_null($retval['filter'])) {
+        $filter=LSldap::combineFilters('and',array($objFilter,$retval['filter']));
+        if ($filter) {
+          $retval['filter']=$filter;
+        }
+      }
+      else {
+        $retval['filter']=$objFilter;
+      }
+    }
+    
+    
+    // Recursive
+    if (is_null($retval['basedn'])) {
+      if (!is_null($this -> params['subDn'])) {
+        if ($this -> params['recursive']) {
+          $retval['basedn'] = $this -> params['subDn'];
+        }
+        else {
+          $retval['basedn'] = LSconfig::get("LSobjects.".$this -> LSobject.".container_dn").','.$this -> params['subDn'];
+        }
+      }
+      else {
+        if ($this -> params['recursive']) {
+          $retval['basedn'] = LSsession :: getTopDn();
+        }
+        else {
+          $retval['basedn'] = LSconfig::get("LSobjects.".$this -> LSobject.".container_dn").','.LSsession :: getTopDn();
+        }
+      }
+    }
+    if ($this -> params['recursive'] || !isset($retval['scope'])) {
+      $retval['scope'] = 'sub';
+    }
+    
+    if (is_null($this -> params['displayFormat'])) {
+      $this -> params['displayFormat']=LSconfig::get("LSobjects.".$this -> LSobject.".display_name_format");
+    }
+    
+    // Display Format
+    $attrs=getFieldInFormat($this -> params['displayFormat']);
+    if(is_array($retval['attributes'])) {
+      $retval['attributes']=array_merge($attrs,$retval['attributes']);
+    }
+    else {
+      $retval['attributes']=$attrs;
+    }
+    
+    $this -> _searchParams = $retval;
+  }
+  
+  /**
+   * Run the search
+   *
+   * @param[in] $cache boolean Define if the cache can be used
+   * 
+   * @retval boolean True on success or False
+   */ 
+  public function run($cache=true) {
+    $this -> generateSearchParams();
+    if ($this -> _searchParams['filter'] instanceof Net_LDAP2_Filter) {
+      LSdebug('LSsearch : filter : '.$this -> _searchParams['filter']->asString());
+    }
+    LSdebug('LSsearch : basedn : '.$this -> _searchParams['basedn'].' - scope : '.$this -> _searchParams['scope']);
+    
+    if( $cache && (!isset($_REQUEST['refresh'])) && (!$this -> params['withoutCache']) ) {
+      LSdebug('LSsearch : with the cache');
+      $this -> result = $this -> getResultFromCache();
+    }
+    else {
+      LSdebug('LSsearch : without the cache');
+      $this -> setParam('withoutCache',false);
+    }
+    
+    if (!$this -> result) {
+      LSdebug('LSsearch : Not in cache');
+      $this -> result=array(
+        'sortBy' => NULL,
+        'sortDirection' => NULL
+      );
+      $this -> result['list'] = LSldap :: search(
+        $this -> _searchParams['filter'],
+        $this -> _searchParams['basedn'],
+        $this -> _searchParams
+      );
+      if ($this -> result['list'] === false) {
+        LSerror :: addErrorCode('LSsearch_12');
+        unset($this -> result['list']);
+        return;
+      }
+      $this -> addResultToCache();
+    }
+    
+    $this -> doSort();
+    
+    return true;
+  }
+  
+  /**
+   * Return an hash corresponding to the parameters of the search
+   * 
+   * @param[in] $searchParams array An optional search params array
+   * 
+   * @retval string The hash of the parameters of the search
+   **/  
+  public function getHash($searchParams=null) {
+    if(is_null($searchParams)) {
+      $searchParams=$this -> _searchParams;
+      if ($this -> _hash) {
+        return $this -> _hash;
+      }
+    }
+    if ($searchParams['filter'] instanceof Net_LDAP_Filter) {
+      $searchParams['filter']=$searchParams['filter']->asString();
+    }
+    return hash('md5',print_r($searchParams,true));
+  }
+  
+  /**
+   * Add the result of the search to cache of the session
+   * 
+   * @retval void
+   **/  
+  public function addResultToCache() {
+    if ($this -> cacheIsEnabled()) {
+      LSdebug('LSsearch : Save result in cache.');
+      $hash=$this->getHash();
+      $_SESSION['LSsession']['LSsearch'][$this -> LSobject][$hash]=$this->result;
+    }
+  }
+  
+  /**
+   * Get the result of the search from cache of the session
+   * 
+   * @retval array | False The array of the result of the search or False
+   **/  
+  private function getResultFromCache() {
+    if ($this -> cacheIsEnabled()) {
+      $hash=$this->getHash();
+      if (isset($_SESSION['LSsession']['LSsearch'][$this -> LSobject][$hash])) {
+        LSdebug('LSsearch : Load result from cache.');
+        return $_SESSION['LSsession']['LSsearch'][$this -> LSobject][$hash];
+      }
+    }
+    return;
+  }
+  
+  /**
+   * Get page informations to display
+   * 
+   * @param[in] $page integer The number of the page
+   * 
+   * @retval array The information of the page
+   **/
+  public function getPage($page=0) {
+    if (!LSsession::loadLSclass('LSsearchEntry')) {
+      LSerror::addErrorCode('LSsession_05',$this -> LSobject);
+      return;
+    }
+    $page = (int)$page;
+
+    $retval=array(
+      'nb' => $page,
+      'nbPages' => 1,
+      'list' => array(),
+      'total' => $this -> total
+    );
+    
+    if ($retval['total']>0) {
+      LSdebug('Total : '.$retval['total']);
+      
+      if (!$this->params['nbObjectsByPage']) {
+        $this->params['nbObjectsByPage']=NB_LSOBJECT_LIST;
+      }
+      $retval['nbPages']=ceil($retval['total']/$this->params['nbObjectsByPage']);
+      
+      $sortTable=$this -> getSortTable();
+      
+      $list = array_slice(
+        $sortTable,
+        ($page * $this->params['nbObjectsByPage']),
+        $this->params['nbObjectsByPage']
+      );
+      
+      foreach ($list as $key => $id) {
+        $retval['list'][]=new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$id);
+      }
+    }
+    return $retval;
+  }
+  
+  /**
+   * Get search entries
+   * 
+   * @retval array The entries
+   **/
+  public function getSearchEntries() {
+    if (!LSsession::loadLSclass('LSsearchEntry')) {
+      LSerror::addErrorCode('LSsession_05',$this -> LSobject);
+      return;
+    }
+    $retval=array();
+    if ($this -> total>0) {
+      $sortTable=$this -> getSortTable();
+      
+      foreach ($sortTable as $key => $id) {
+        $retval[]=new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$id);
+      }
+    }
+    return $retval;
+  }
+  
+  /**
+   * Access to information of this object
+   * 
+   * @param[in] $key string The key of the info
+   * 
+   * @retval mixed The info
+   **/
+  public function __get($key) {
+    $params = array (
+      'sortBy',
+      'sortDirection'
+    );
+    if ($key=='LSobject') {
+      return $this -> LSobject;
+    }
+    elseif (in_array($key,$params)) {
+      return $this -> params[$key];
+    }
+    elseif ($key=='label_objectName') {
+      return LSldapObject::getLabel($this -> LSobject);
+    }
+    elseif ($key=='label_level') {
+      return LSsession :: getSubDnLabel();
+    }
+    elseif ($key=='label_actions') {
+      return _('Actions');
+    }
+    elseif ($key=='label_no_result') {
+      return _("This search didn't get any result.");
+    }
+    elseif ($key=='sort') {
+      if (isset($this -> params['sortlimit']) && ($this -> params['sortlimit']>0)) {
+        return ($this -> total < $this -> params['sortlimit']);
+      }
+      return true;
+    }
+    elseif ($key=='sortlimit') {
+      return $this -> params['sortlimit'];
+    }
+    elseif ($key=='total') {
+      return count($this -> result['list']);
+    }
+    elseif ($key=='label_total') {
+      return $this -> total." ".$this -> label_objectName;
+    }
+    elseif ($key=='displaySubDn') {
+      if (LSsession :: subDnIsEnabled()) {
+        if (!is_null($this -> params[$key])) {
+          return $this -> params[$key];
+        }
+        else {
+          return (! LSsession :: isSubDnLSobject($this -> LSobject) );
+        }
+      }
+      return false;
+    }
+    elseif ($key=='canCopy') {
+      if (!is_null($this -> _canCopy))
+        return $this -> _canCopy;
+      $this -> _canCopy = LSsession :: canCreate($this -> LSobject);
+      return $this -> _canCopy;
+    }
+    else {
+      throw new Exception('Incorrect property !');
+    }
+  }
+  
+  /**
+   * Function use with uasort to sort two entry
+   * 
+   * @param[in] $a array One line of result
+   * @param[in] $b array One line of result
+   * 
+   * @retval int Value for uasort
+   **/
+  private function _sortTwoEntry(&$a,&$b) {
+    $sortBy = $this -> params['sortBy'];
+    $sortDirection = $this -> params['sortDirection'];
+    if ($sortDirection=='ASC') {
+      $dir = -1;
+    }
+    else {
+      $dir = 1;
+    }
+    $oa = new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$a);
+    $va = $oa->$sortBy;
+    $ob = new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$b);
+    $vb = $ob->$sortBy;
+    
+    if ($va == $vb) return 0;
+    
+    $val = array($va,$vb);
+    sort($val);
+    
+    if ($val[0]==$va)
+      return 1*$dir;
+      
+    return -1*$dir;
+  }
+  
+  /**
+   * Function to run after using the result. It's update the cache
+   * 
+   * IT'S FUNCTION IS VERY IMPORTANT !!!
+   * 
+   * @retval void
+   **/
+  function afterUsingResult() {
+    $this -> addResultToCache();
+  }
+  
+  /**
+   * Run the sort if it's enabled and if the result is not in the cache
+   * 
+   * @retval boolean True on success or false
+   **/
+  function doSort() {
+    if (!$this -> sort) {
+      LSdebug('doSort : sort is disabled');
+      return true;
+    }
+    if (is_null($this -> params['sortBy'])) {
+      return;
+    }
+    if (is_null($this -> params['sortDirection'])) {
+      $this -> params['sortDirection']='ASC';
+    }
+
+    if ($this->total==0) {
+      return true;
+    }
+    
+    if (isset($this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']])) {
+      LSdebug('doSort : from cache');
+      return true;
+    }
+     
+    LSdebug('doSort : '.$this -> params['sortBy'].' - '.$this -> params['sortDirection']);
+    
+    $this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']]=range(0,($this -> total-1));
+    
+    if (!LSsession :: loadLSClass('LSsearchEntry')) {
+      LSerror::addErrorCode('LSsession_05','LSsearchEntry');
+      return;
+    }
+    
+    if (!uasort(
+      $this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']],
+      array($this,'_sortTwoEntry')
+    )) {
+      LSerror :: addErrorCode('LSsearch_13');
+      return;
+    }
+    
+    return true;
+  }
+  
+  /**
+   * Returns the id of table rows in the result sorted according to criteria 
+   * defined in the parameters
+   * 
+   * @retval array The Table of id lines of results sorted
+   **/
+  function getSortTable() {
+    if ($this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']]) {
+      return $this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']];
+    }
+    return range(0,($this -> total-1));
+  }
+  
+  /**
+   * List objects name
+   * 
+   * @retval Array DN associate with name
+   **/
+  public function listObjectsName() {
+    if (!LSsession::loadLSclass('LSsearchEntry')) {
+      LSerror::addErrorCode('LSsession_05',$this -> LSobject);
+      return;
+    }
+    
+    $retval=array();
+    
+    if ($this -> total>0) {
+      $sortTable=$this -> getSortTable();
+      
+      foreach ($sortTable as $key => $id) {
+        $entry=new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$id);
+        $retval[$entry->dn]=$entry->displayName;
+      }
+    }
+    
+    return $retval;
+  }
+  
+  /**
+   * List LSldapObjects 
+   * 
+   * @retval Array of LSldapObjects
+   **/
+  public function listObjects() {    
+    $retval=array();
+    
+    if ($this -> total>0) {
+      $sortTable=$this -> getSortTable();
+
+      $c=0;      
+      foreach ($sortTable as $key => $id) {
+        $retval[$c]=new $this -> LSobject();
+        $retval[$c] -> loadData($this -> result['list'][$id]['dn']);
+        $c++;
+      }
+    }
+    
+    return $retval;
+  }
+  
+  /**
+   * List objects dn
+   * 
+   * @retval Array of DN
+   **/
+  public function listObjectsDn() {    
+    $retval=array();
+    
+    if ($this -> total>0) {
+      $sortTable=$this -> getSortTable();
+
+      $c=0;      
+      foreach ($sortTable as $key => $id) {
+        $retval[$c] = $this -> result['list'][$id]['dn'];
+        $c++;
+      }
+    }
+    
+    return $retval;
+  }
+  
+}
+
+/**
+ * Error Codes
+ **/
+LSerror :: defineError('LSsearch_01',
+_("LSsearch : Invalid filter : %{filter}.")
+);
+LSerror :: defineError('LSsearch_02',
+_("LSsearch : Invalid basedn : %{basedn}.")
+);
+LSerror :: defineError('LSsearch_03',
+_("LSsearch : Invalid value for %{param} parameter.")
+);
+LSerror :: defineError('LSsearch_04',
+_("LSsearch : Invalid size limit. Must be an integer greater or equal to 0.")
+);
+LSerror :: defineError('LSsearch_05',
+_("LSsearch : Invalid parameter %{attr}. Must be an boolean.")
+);
+LSerror :: defineError('LSsearch_06',
+_("LSsearch : Invalid parameter attributes. Must be an string or an array of strings.")
+);
+LSerror :: defineError('LSsearch_07',
+_("LSsearch : Can't build attributes list for make filter.")
+);
+LSerror :: defineError('LSsearch_08',
+_("LSsearch : Error building filter with attribute '%{attr}' and pattern '%{pattern}'")
+);
+LSerror :: defineError('LSsearch_09',
+_("LSsearch : Error combining filters.")
+);
+LSerror :: defineError('LSsearch_10',
+_("LSsearch : Invalid pattern.")
+);
+LSerror :: defineError('LSsearch_11',
+_("LSsearch : Invalid attribute %{attr} in parameters.")
+);
+LSerror :: defineError('LSsearch_12',
+_("LSsearch : Error during the search.")
+);
+LSerror :: defineError('LSsearch_13',
+_("LSsearch : Error sorting the search.")
+);
+
+?>
diff --git a/trunk/includes/class/class.LSsearchEntry.php b/trunk/includes/class/class.LSsearchEntry.php
new file mode 100644 (file)
index 0000000..65e0edb
--- /dev/null
@@ -0,0 +1,184 @@
+<?php
+/*******************************************************************************
+ * Copyright (C) 2007 Easter-eggs
+ * http://ldapsaisie.labs.libre-entreprise.org
+ *
+ * Author: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+******************************************************************************/
+
+/**
+ * Object LSsearchEntry
+ *
+ * @author Benjamin Renard <brenard@easter-eggs.com>
+ */
+class LSsearchEntry { 
+  
+  // The LSsearch object
+  private $LSsearch=NULL;
+  
+  // The LdapObject type of search
+  private $LSobject=NULL;
+  
+  // DN
+  private $dn;
+  
+  // The parameters of the search
+  private $params=array ();
+  
+  // The hash of the search parameters
+  private $hash = NULL;
+  
+  // The attributes values
+  private $attrs=array();
+  
+  // Cache
+  private $cache=array();
+  
+  /**
+   * Constructor
+   * 
+   * @param[in] $LSobject string The LdapObject type of search
+   * @param[in] $params array Parameters of search
+   * @param[in] $hash array Parameters of search
+   * @param[in] $resultEntry array The data of the result entry
+   * 
+   **/
+  function LSsearchEntry(&$LSsearch,$LSobject,$params,$hash,&$result,$id) {
+    if (!LSsession :: loadLSobject($LSobject)) {
+      return;
+    }
+    $this -> LSsearch = $LSsearch;
+    $this -> LSobject = $LSobject;
+    $this -> params = $params;
+    $this -> id = $id;
+    $this -> dn =& $result[$id]['dn'];
+    $this -> attrs =& $result[$id]['attrs'];
+    $this -> cache =& $result[$id]['cache'];
+  }
+  
+  /**
+   * Get text value of entry
+   * 
+   * @param[in] $key string The name of the value
+   * 
+   * @retval mixed The value
+   **/
+  public function get($key) {
+    if (in_array($key,array_keys($this -> attrs))) {
+      return $this -> attrs[$key];
+    }
+    elseif ($key=='subDn' || $key=='subDnName') {
+      return $this -> subDn;
+    }
+  }
+
+  /**
+   * Get formated text value of entry
+   * 
+   * @param[in] $format string The format of the value
+   * 
+   * @retval mixed The formated value
+   **/  
+  public function getFData($format) {
+    return getFData($format,$this,'get');
+  }
+  
+  
+  /**
+   * Access to infos of the entry
+   * 
+   * @param[in] $key string The name of the value
+   * 
+   * @retval mixed The value
+   **/
+  public function __get($key) {
+    if ($key=='displayName') {
+      if (isset($this -> cache['displayName'])) {
+        return $this -> cache['displayName'];
+      }
+      $this -> cache['displayName'] = $this -> getFData($this -> params['displayFormat']);
+      return $this -> cache['displayName'];
+    }
+    elseif ($key=='dn') {
+      return $this -> dn;
+    }
+    elseif ($key=='subDn' || $key=='subDnName') {
+      if ($this -> cache['subDn']) {
+        return $this -> cache['subDn'];
+      }
+      if ($this -> LSsearch -> displaySubDn) {
+        $this -> cache['subDn'] = LSldapObject::getSubDnName($this -> dn);
+        return $this -> cache['subDn'];
+      }
+    }
+    elseif ($key=='actions') {
+      if (isset($this -> cache['actions'])) {
+        return $this -> cache['actions'];
+      }
+      $this -> cache['actions'] = array (
+        array(
+          'label' => _('View'),
+          'url' =>'view.php?LSobject='.$this -> LSobject.'&amp;dn='.$this -> dn,
+          'action' => 'view'
+        )
+      );
+      
+      if (LSsession :: canEdit($this -> LSobject,$this -> dn)) {
+        $this -> cache['actions'][]=array(
+          'label' => _('Modify'),
+          'url' => 'modify.php?LSobject='.$this -> LSobject.'&amp;dn='.$this -> dn,
+          'action' => 'modify'
+        );
+      }
+      
+      if ($this -> LSsearch -> canCopy) {
+        $this -> cache['actions'][] = array(
+          'label' => _('Copy'),
+          'url' =>'create.php?LSobject='.$this -> LSobject.'&amp;load='.$this -> dn,
+          'action' => 'copy'
+        );
+      }
+      
+      if (LSsession :: canRemove($this -> LSobject,$this -> dn)) {
+        $this -> cache['actions'][] = array (
+          'label' => _('Delete'),
+          'url' => 'remove.php?LSobject='.$this -> LSobject.'&amp;dn='.$this -> dn,
+          'action' => 'delete'
+        );
+      }
+      $this -> LSsearch -> addResultToCache();
+      return $this -> cache['actions'];
+    }
+    elseif ($key=='LSselect') {
+      if (is_array($_SESSION['LSselect'][$this -> LSobject])) {
+        if(in_array($this -> dn,$_SESSION['LSselect'][$this -> LSobject])) {
+          return true;
+        }
+      }
+      return;
+    }
+    elseif (in_array($key,array_keys($this -> attrs))) {
+      return $this -> attrs[$key];
+    }
+    else {
+      return __("Unknown property !");
+    }
+  }
+
+}
+
+?>
index e341599..7cb6b47 100644 (file)
@@ -161,7 +161,23 @@ class LSsession {
   * @retval string le topDn de la session
   */
   public static function getTopDn() {
-    return self :: $topDn;
+    if (!is_null(self :: $topDn)) {
+      return self :: $topDn;
+    }
+    else {
+      return self :: getRootDn();
+    }
+  }
+  
+ /**
+  * Retourne le rootDn de la session
+  *
+  * @author Benjamin Renard <brenard@easter-eggs.com>
+  *
+  * @retval string le rootDn de la session
+  */
+  public static function getRootDn() {
+    return self :: $ldapServer['ldap_config']['basedn'];
   }
 
  /**
@@ -493,8 +509,6 @@ class LSsession {
     }
     else {
       // Session inexistante
-      $recoveryPasswordInfos=array();
-
       if (isset($_POST['LSsession_user'])) {
         if (isset($_POST['LSsession_ldapserver'])) {
           self :: setLdapServer($_POST['LSsession_ldapserver']);
@@ -515,189 +529,31 @@ class LSsession {
           }
           $_SESSION['LSsession_topDn']=self :: $topDn;
 
-          if ( self :: loadLSobject(self :: $ldapServer['authObjectType']) ) {
-            $authobject = new self :: $ldapServer['authObjectType']();
-            $find=true;
-            if (isset($_GET['recoveryHash'])) {
-              $filter=self :: $ldapServer['recoverPassword']['recoveryHashAttr']."=".$_GET['recoveryHash'];
-              $result = $authobject -> listObjects($filter,self :: $topDn);
-              $nbresult=count($result);
-              if ($nbresult==1) {
-                $rdn = $result[0] -> getValue('rdn');
-                $rdn = $rdn[0];
-                $_POST['LSsession_user'] = $rdn;
-                $find=false;
-              }
-            }
-            if ($find) {
-              $result = $authobject -> searchObject($_POST['LSsession_user'],self :: $topDn,self :: $ldapServer['authObjectFilter']);
-              $nbresult=count($result);
-            }
-            if ($nbresult==0) {
-              // identifiant incorrect
-              LSdebug('identifiant incorrect');
-              LSerror :: addErrorCode('LSsession_06');
-            }
-            else if ($nbresult>1) {
-              // duplication d'authentité
-              LSerror :: addErrorCode('LSsession_07');
-            }
-            else {
-              if (isset($_GET['LSsession_recoverPassword'])) {
-                LSdebug('Recover : Id trouvé');
-                if (self :: $ldapServer['recoverPassword']) {
-                  if (self :: loadLSaddon('mail')) {
-                    LSdebug('Récupération active');
-                    $user=$result[0];
-                    $emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']);
-                    $emailAddress = $emailAddress[0];
-                    
-                    // Header des mails
-                    $sendParams=array();
-                    if (self :: $ldapServer['recoverPassword']['recoveryEmailSender']) {
-                      $sendParams['From']=self :: $ldapServer['recoverPassword']['recoveryEmailSender'];
-                    }
-                    
-                    if (checkEmail($emailAddress)) {
-                      LSdebug('Email : '.$emailAddress);
-                      self :: $dn = $user -> getDn();
-                      // 1ère étape : envoie du recoveryHash
-                      if (!isset($_GET['recoveryHash'])) {
-                        // Generer un hash
-                        $rdn=$user -> getValue('rdn');
-                        $rdn = $rdn[0];
-                        $recovery_hash = md5($rdn . strval(time()) . strval(rand()));
-                        
-                        $lostPasswdForm = $user -> getForm('lostPassword');
-                        $lostPasswdForm -> setPostData(
-                          array(
-                            self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => $recovery_hash
-                          )
-                          ,true
-                        );
-                        
-                        if($lostPasswdForm -> validate()) {
-                          if ($user -> updateData('lostPassword')) {
-                            // recoveryHash de l'utilisateur mis à jour
-                            if ($_SERVER['HTTPS']=='on') {
-                              $recovery_url='https://';
-                            }
-                            else {
-                              $recovery_url='http://';
-                            }
-                            $recovery_url .= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&recoveryHash='.$recovery_hash;
-
-                            if (
-                              sendMail(
-                                $emailAddress,
-                                self :: $ldapServer['recoverPassword']['recoveryHashMail']['subject'],
-                                getFData(self :: $ldapServer['recoverPassword']['recoveryHashMail']['msg'],$recovery_url),
-                                $sendParams
-                              )
-                            ){
-                              // Mail a bien été envoyé
-                              $recoveryPasswordInfos['recoveryHashMail']=$emailAddress;
-                            }
-                            else {
-                              // Problème durant l'envoie du mail
-                              LSdebug("Problème durant l'envoie du mail");
-                              LSerror :: addErrorCode('LSsession_20',7);
-                            }
-                          }
-                          else {
-                            // Erreur durant la mise à jour de l'objet
-                            LSdebug("Erreur durant la mise à jour de l'objet");
-                            LSerror :: addErrorCode('LSsession_20',6);
-                          }
-                        }
-                        else {
-                          // Erreur durant la validation du formulaire de modification de perte de password
-                          LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
-                          LSerror :: addErrorCode('LSsession_20',5);
-                        }
-                      }
-                      // 2nd étape : génération du mot de passe + envoie par mail
-                      else {
-                        $attr=$user -> attrs[self :: $ldapServer['authObjectTypeAttrPwd']];
-                        if ($attr instanceof LSattribute) {
-                          $mdp = generatePassword($attr -> config['html_options']['chars'],$attr -> config['html_options']['lenght']);
-                          LSdebug('Nvx mpd : '.$mdp);
-                          $lostPasswdForm = $user -> getForm('lostPassword');
-                          $lostPasswdForm -> setPostData(
-                            array(
-                              self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
-                              self :: $ldapServer['authObjectTypeAttrPwd'] => array($mdp)
-                            )
-                            ,true
-                          );
-                          if($lostPasswdForm -> validate()) {
-                            if ($user -> updateData('lostPassword')) {
-                              if (
-                                sendMail(
-                                  $emailAddress,
-                                  self :: $ldapServer['recoverPassword']['newPasswordMail']['subject'],
-                                  getFData(self :: $ldapServer['recoverPassword']['newPasswordMail']['msg'],$mdp),
-                                  $sendParams
-                                )
-                              ){
-                                // Mail a bien été envoyé
-                                $recoveryPasswordInfos['newPasswordMail']=$emailAddress;
-                              }
-                              else {
-                                // Problème durant l'envoie du mail
-                                LSdebug("Problème durant l'envoie du mail");
-                                LSerror :: addErrorCode('LSsession_20',4);
-                              }
-                            }
-                            else {
-                              // Erreur durant la mise à jour de l'objet
-                              LSdebug("Erreur durant la mise à jour de l'objet");
-                              LSerror :: addErrorCode('LSsession_20',3);
-                            }
-                          }
-                          else {
-                            // Erreur durant la validation du formulaire de modification de perte de password
-                            LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
-                            LSerror :: addErrorCode('LSsession_20',2);
-                          }
-                        }
-                        else {
-                          // l'attribut password n'existe pas
-                          LSdebug("L'attribut password n'existe pas");
-                          LSerror :: addErrorCode('LSsession_20',1);
-                        }
-                      }
-                    }
-                    else {
-                      LSerror :: addErrorCode('LSsession_19');
-                    }
-                  }
-                }
-                else {
-                  LSerror :: addErrorCode('LSsession_18');
-                }
-              }
-              else {
-                if ( self :: checkUserPwd($result[0],$_POST['LSsession_pwd']) ) {
-                  // Authentification réussi
-                  self :: $LSuserObject = $result[0];
-                  self :: $dn = $result[0]->getValue('dn');
-                  self :: $rdn = $result[0]->getValue('rdn');
-                  self :: loadLSprofiles();
-                  self :: loadLSaccess();
-                  $GLOBALS['Smarty'] -> assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
-                  $_SESSION['LSsession']=self :: getContextInfos();
-                  return true;
-                }
-                else {
-                  LSerror :: addErrorCode('LSsession_06');
-                  LSdebug('mdp incorrect');
-                }
-              }
-            }
+          
+          if (isset($_GET['LSsession_recoverPassword'])) {
+            $recoveryPasswordInfos = self :: recoverPasswd(
+                                        $_REQUEST['LSsession_user'],
+                                        $_GET['recoveryHash']
+                                     );
           }
           else {
-            LSerror :: addErrorCode('LSsession_10');
+            if (self :: loadLSclass('LSauth')) {
+              $LSuserObject = LSauth :: authenticate(
+                $_REQUEST['LSsession_user'],
+                $_REQUEST['LSsession_pwd']
+              );
+              if ($LSuserObject) {
+                // Authentification réussi
+                self :: $LSuserObject = $LSuserObject;
+                self :: $dn = $LSuserObject->getValue('dn');
+                self :: $rdn = $LSuserObject->getValue('rdn');
+                self :: loadLSprofiles();
+                self :: loadLSaccess();
+                $GLOBALS['Smarty'] -> assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
+                $_SESSION['LSsession']=self :: getContextInfos();
+                return true;
+              }
+            }
           }
         }
         else {
@@ -718,6 +574,227 @@ class LSsession {
     }
   }
   
+  /**
+   * Do recover password
+   * 
+   * @param[in] $username string The submited username
+   * @param[in] $recoveryHash string The submited recoveryHash
+   * 
+   * @retval array The recoveryPassword infos for template
+   **/
+  private static function recoverPasswd($username,$recoveryHash) {
+    $recoveryPasswordInfos=array();
+    if ( self :: loadLSobject(self :: $ldapServer['authObjectType']) ) {
+      $authobject = new self :: $ldapServer['authObjectType']();
+      if (!empty($recoveryHash)) {
+        $filter=Net_LDAP2_Filter::create(
+          self :: $ldapServer['recoverPassword']['recoveryHashAttr'],
+          'equals',
+          $recoveryHash
+        );
+        $result = $authobject -> listObjects($filter,self :: $topDn);
+      }
+      else {
+        $result = $authobject -> searchObject(
+                    $username,
+                    self :: $topDn,
+                    self :: $ldapServer['authObjectFilter']
+                  );
+      }
+      
+      $nbresult=count($result);
+      
+      if ($nbresult==0) {
+        LSdebug('hash/username incorrect');
+        LSerror :: addErrorCode('LSsession_06');  
+      }
+      elseif ($nbresult>1) {
+        LSerror :: addErrorCode('LSsession_07');
+      }
+      else {
+        $rdn = $result[0] -> getValue('rdn');
+        $username = $rdn[0];
+        LSdebug('Recover : Id trouvé : '.$username);
+        if (self :: $ldapServer['recoverPassword']) {
+          if (self :: loadLSaddon('mail')) {
+            LSdebug('Récupération active');
+            $user=$result[0];
+            $emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']);
+            $emailAddress = $emailAddress[0];
+            
+            if (checkEmail($emailAddress)) {
+              LSdebug('Email : '.$emailAddress);
+              self :: $dn = $user -> getDn();
+              
+              // 1ère étape : envoie du recoveryHash
+              if (empty($recoveryHash)) {
+                $hash=self :: recoverPasswdFirstStep($user);
+                if ($hash) {
+                  if (self :: recoverPasswdSendMail($emailAddress,1,$hash)) {
+                    // Mail a bien été envoyé
+                    $recoveryPasswordInfos['recoveryHashMail']=$emailAddress;
+                  }
+                }
+              }
+              // 2nd étape : génération du mot de passe + envoie par mail
+              else {
+                $pwd=self :: recoverPasswdSecondStep($user);
+                if ($pwd) {
+                  if (self :: recoverPasswdSendMail($emailAddress,2,$pwd)){
+                    // Mail a bien été envoyé
+                    $recoveryPasswordInfos['newPasswordMail']=$emailAddress;
+                  }
+                }
+              }
+            }
+            else {
+              LSerror :: addErrorCode('LSsession_19');
+            }
+          }
+        }
+        else {
+          LSerror :: addErrorCode('LSsession_18');
+        }
+      }
+    }
+    return $recoveryPasswordInfos;
+  }
+  
+  /**
+   * Send recover password mail
+   * 
+   * @param[in] $mail string The user's mail
+   * @param[in] $step integer The step
+   * @param[in] $info string The info for formatted message
+   * 
+   * @retval boolean True on success or False
+   **/
+  private static function recoverPasswdSendMail($mail,$step,$info) {
+    // Header des mails
+    $sendParams=array();
+    if (self :: $ldapServer['recoverPassword']['recoveryEmailSender']) {
+      $sendParams['From']=self :: $ldapServer['recoverPassword']['recoveryEmailSender'];
+    }
+    
+    if ($step==1) {
+      if ($_SERVER['HTTPS']=='on') {
+        $recovery_url='https://';
+      }
+      else {
+        $recovery_url='http://';
+      }
+      $recovery_url .= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&recoveryHash='.$info;
+      
+      $subject = self :: $ldapServer['recoverPassword']['recoveryHashMail']['subject'];
+      $msg = getFData(
+        self :: $ldapServer['recoverPassword']['recoveryHashMail']['msg'],
+        $recovery_url
+      );
+    }
+    else {
+      $subject = self :: $ldapServer['recoverPassword']['newPasswordMail']['subject'];
+      $msg = getFData(
+        self :: $ldapServer['recoverPassword']['newPasswordMail']['msg'],
+        $info
+      );
+    }
+    
+    if (!sendMail($mail,$subject,$msg,$sendParams)) {
+      LSdebug("Problème durant l'envoie du mail");
+      LSerror :: addErrorCode('LSsession_20',4);
+      return;
+    }
+    return true;
+  }
+  
+  
+  /**
+   * Do first step of recovering password
+   * 
+   * @param[in] $user LSldapObject The LSldapObject of the user
+   * 
+   * @retval string|False The recory hash on success or False
+   **/
+  private static function recoverPasswdFirstStep($user) {
+    // Generer un hash
+    $rdn=$user -> getValue('rdn');
+    $rdn = $rdn[0];
+    $recovery_hash = md5($rdn . strval(time()) . strval(rand()));
+    
+    $lostPasswdForm = $user -> getForm('lostPassword');
+    $lostPasswdForm -> setPostData(
+      array(
+        self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => $recovery_hash
+      )
+      ,true
+    );
+      
+    if($lostPasswdForm -> validate()) {
+      if ($user -> updateData('lostPassword')) {
+        // recoveryHash de l'utilisateur mis à jour
+        return $recovery_hash;
+      }
+      else {
+        // Erreur durant la mise à jour de l'objet
+        LSdebug("Erreur durant la mise à jour de l'objet");
+        LSerror :: addErrorCode('LSsession_20',6);
+      }
+    }
+    else {
+      // Erreur durant la validation du formulaire de modification de perte de password
+      LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
+      LSerror :: addErrorCode('LSsession_20',5);
+    }
+    return;
+  }
+
+  /**
+   * Do second step of recovering password
+   * 
+   * @param[in] $user LSldapObject The LSldapObject of the user
+   * 
+   * @retval string|False The new password on success or False
+   **/
+  private static function recoverPasswdSecondStep($user) {
+    $attr=$user -> attrs[self :: $ldapServer['authObjectTypeAttrPwd']];
+    if ($attr instanceof LSattribute) {
+      $mdp = generatePassword(
+       $attr -> config['html_options']['chars'],
+       $attr -> config['html_options']['lenght']
+      );
+      LSdebug('Nvx mpd : '.$mdp);
+      $lostPasswdForm = $user -> getForm('lostPassword');
+      $lostPasswdForm -> setPostData(
+        array(
+          self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
+          self :: $ldapServer['authObjectTypeAttrPwd'] => array($mdp)
+        )
+        ,true
+      );
+      if($lostPasswdForm -> validate()) {
+        if ($user -> updateData('lostPassword')) {
+          return $mdp;
+        }
+        else {
+          // Erreur durant la mise à jour de l'objet
+          LSdebug("Erreur durant la mise à jour de l'objet");
+          LSerror :: addErrorCode('LSsession_20',3);
+        }
+      }
+      else {
+        // Erreur durant la validation du formulaire de modification de perte de password
+        LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
+        LSerror :: addErrorCode('LSsession_20',2);
+      }
+    }
+    else {
+      // l'attribut password n'existe pas
+      LSdebug("L'attribut password n'existe pas");
+      LSerror :: addErrorCode('LSsession_20',1);
+    }
+    return;
+  }
+  
  /**
   * Retourne les informations du contexte
   *
@@ -885,7 +962,7 @@ class LSsession {
               $basedn = $LSoject_config['basedn'];
             }
             else {
-              $basedn = NULL;
+              $basedn = self::getRootDn();
             }
             if ($LSoject_config['displayName']) {
               $displayName = $LSoject_config['displayName'];
@@ -1312,7 +1389,7 @@ class LSsession {
     }
 
     if (LSdebugDefined()) {
-      $data['LSdebug'] = LSdebug_print(true);
+      $data['LSdebug'] = LSdebug_print(true,false);
     }
 
     echo json_encode($data);  
@@ -1350,22 +1427,27 @@ class LSsession {
             if ($topDn == 'LSobjects') {
               if (is_array($rightsInfos)) {
                 foreach ($rightsInfos as $LSobject => $listInfos) {
-                  if (self :: loadLSobject($LSobject)) {
-                    if ($object = new $LSobject()) {
-                      if ($listInfos['filter']) {
-                        $filter = self :: getLSuserObject() -> getFData($listInfos['filter']);
-                      }
-                      else {
-                        $filter = $listInfos['attr'].'='.self :: getLSuserObject() -> getFData($listInfos['attr_value']);
-                      }
-                      $list = $object -> search($filter,$listInfos['basedn'],$listInfos['params']);
-                      foreach($list as $obj) {
-                        self :: $LSprofiles[$profile][] = $obj['dn'];
-                      }
+                  if (self :: loadLSclass('LSsearch')) {
+                    if ($listInfos['filter']) {
+                      $filter = self :: getLSuserObject() -> getFData($listInfos['filter']);
                     }
                     else {
-                      LSdebug('Impossible de créer l\'objet de type : '.$LSobject);
+                      $filter = '('.$listInfos['attr'].'='.self :: getLSuserObject() -> getFData($listInfos['attr_value']).')';
+                    }
+                    
+                    $params = array (
+                      'basedn' => $listInfos['basedn'],
+                      'filter' => $filter
+                    );
+                    
+                    if (is_array($listInfos['params'])) {
+                      $params = array_merge($listInfos['params'],$params);
                     }
+                    
+                    $LSsearch = new LSsearch($LSobject,'LSsession :: loadLSprofiles',$params,true);
+                    $LSsearch -> run(false);
+                    
+                    $LSprofiles[$profile] = $LSsearch -> listObjectsDn();
                   }
                 }
               }
@@ -1438,7 +1520,7 @@ class LSsession {
             foreach($config as $objectType => $objectConf) {
               if (self :: loadLSobject($objectType)) {
                 if ($subdnobject = new $objectType()) {
-                  $tbl = $subdnobject -> getSelectArray();
+                  $tbl = $subdnobject -> getSelectArray(NULL,self::getRootDn(),NULL,NULL,false);
                   if (is_array($tbl)) {
                     // Définition des accès
                     $access=array();
@@ -1572,7 +1654,7 @@ class LSsession {
       else {
         $obj = new $LSobject();
         $obj -> dn = $dn;
-        if (!self :: in_menu($LSobject,$obj -> getSubDnValue())) {
+        if (!self :: in_menu($LSobject,$obj -> subDnValue)) {
           return;
         }
       }
@@ -2006,15 +2088,11 @@ class LSsession {
     LSerror :: defineError('LSsession_07',
     _("LSsession : Impossible to identify you : Duplication of identities.")
     );
-    LSerror :: defineError('LSsession_08',
-    _("LSsession : Can't load Smarty template engine.")
-    );
+    // 08
     LSerror :: defineError('LSsession_09',
     _("LSsession : Can't connect to LDAP server.")
     );
-    LSerror :: defineError('LSsession_10',
-    _("LSsession : Could not load type of identifiable objects.")
-    );
+    // 10
     LSerror :: defineError('LSsession_11',
     _("LSsession : Your are not authorized to do this action.")
     );
@@ -2038,26 +2116,15 @@ class LSsession {
     LSerror :: defineError('LSsession_22',
     _("LSsession : problem during initialisation.")
     );
-
-
-    // LSrelations
-    LSerror :: defineError('LSrelations_01',
-    _("LSrelation : The listing function for the relation %{relation} is unknow.")
-    );
-    LSerror :: defineError('LSrelations_02',
-    _("LSrelation : The update function of the relation %{relation} is unknow.")
-    );
-    LSerror :: defineError('LSrelations_03',
-    _("LSrelation : Error during relation update of the relation %{relation}.")
-    );
-    LSerror :: defineError('LSrelations_04',
-    _("LSrelation : Object type %{LSobject} unknow (Relation : %{relation}).")
-    );
-    LSerror :: defineError('LSrelations_05',
-    _("LSrelation : Some parameters are missing in the call of methods to handle standard relations (Method : %{meth}).")
-    );
   }
 
+  /**
+   * Ajax method when change ldapserver on login form
+   * 
+   * @param[in] $data array The return data address
+   * 
+   * @retval void
+   **/
   public static function ajax_onLdapServerChangedLogin(&$data) {  
     if ( isset($_REQUEST['server']) ) {
       self :: setLdapServer($_REQUEST['server']);
@@ -2080,6 +2147,13 @@ class LSsession {
     }
   }
   
+  /**
+   * Ajax method when change ldapserver on recoverPassword form
+   * 
+   * @param[in] $data array The return data address
+   * 
+   * @retval void
+   **/
   public static function ajax_onLdapServerChangedRecoverPassword(&$data) {  
     if ( isset($_REQUEST['server']) ) {
       self :: setLdapServer($_REQUEST['server']);
index bed1a0d..dc78489 100644 (file)
@@ -137,7 +137,7 @@ var LSselect = new Class({
     
     sortBy: function(value) {
       this.tempInput['sortBy'] = new Element('input');
-      this.tempInput['sortBy'].setProperty('name','orderby');
+      this.tempInput['sortBy'].setProperty('name','sortBy');
       this.tempInput['sortBy'].setProperty('type','hidden');
       this.tempInput['sortBy'].setProperty('value',value);
       this.tempInput['sortBy'].injectInside(this.LSselect_search_form);
index f6c0ab7..9a46f34 100644 (file)
@@ -27,290 +27,74 @@ if(LSsession :: startLSsession()) {
     $LSobject = $_REQUEST['LSobject'];
     
     if ( LSsession ::loadLSobject($LSobject) ) {
-      $objectList=array();
-      $object = new $LSobject();
-      
-      $GLOBALS['Smarty']->assign('pagetitle',$object -> getLabel());
-      $GLOBALS['Smarty']->assign('LSobject_list_objectname',$object -> getLabel());
-      
-      if (isset($_SESSION['LSsession']['LSsearch'][$LSobject])) {
-        $filter = $_SESSION['LSsession']['LSsearch'][$LSobject]['filter'];
-        if (isCompatibleDNs($_SESSION['LSsession']['LSsearch'][$LSobject]['topDn'],LSsession :: getTopDn())) {
-          $topDn = $_SESSION['LSsession']['LSsearch'][$LSobject]['topDn'];
-          if (isset($_SESSION['LSsession']['LSsearch'][$LSobject]['selectedTopDn'])) {
-            $selectedTopDn = $_SESSION['LSsession']['LSsearch'][$LSobject]['selectedTopDn'];
-          }
-          else {
-            $selectedTopDn = LSsession :: getTopDn();
-          }
-        }
-        else {
-          $selectedTopDn  = LSsession :: getTopDn();
-          $topDn = $object -> config['container_dn'].','.LSsession :: getTopDn();
-        }
-        $params = $_SESSION['LSsession']['LSsearch'][$LSobject]['params'];
-        $pattern = $_SESSION['LSsession']['LSsearch'][$LSobject]['pattern'];
-        $recur = $_SESSION['LSsession']['LSsearch'][$LSobject]['recur'];
-        $approx = $_SESSION['LSsession']['LSsearch'][$LSobject]['approx'];
-        $orderby = $_SESSION['LSsession']['LSsearch'][$LSobject]['orderby'];
-        $ordersense = $_SESSION['LSsession']['LSsearch'][$LSobject]['ordersense'];
-        $doSubDn = $_SESSION['LSsession']['LSsearch'][$LSobject]['doSubDn'];
-      }
-      else {
-        $filter = NULL;
-        $topDn = $object -> config['container_dn'].','.LSsession :: getTopDn();
-        $params = array('scope' => 'one');
-        $pattern = false;
-        $recur = LSconfig :: get("LSobjects.$LSobject.LSsearch.recursive");
-        $approx = false;
-        $selectedTopDn = LSsession :: getTopDn();
-        $orderby = false;
-        $_REQUEST['orderby']=LSconfig :: get("LSobjects.$LSobject.orderby");
-        $ordersense = 'ASC';
-        $subDnLdapServer = LSsession :: getSubDnLdapServer();
-        $doSubDn = (($subDnLdapServer)&&(!LSsession :: isSubDnLSobject($LSobject)));
-      }
-      
-      if (isset($_REQUEST['LSview_search_submit'])) {
-        if ( $_REQUEST['LSview_pattern']!=$pattern ) {
-          $pattern = $_REQUEST['LSview_pattern'];
-        }
-
-        $approx = (isset($_REQUEST['LSview_approx']));
+      if (LSsession :: loadLSclass('LSsearch')) {
+        $object = new $LSobject();
+        $GLOBALS['Smarty']->assign('pagetitle',$object -> getLabel());
         
-        if ($pattern && $pattern!='') {
-          $filter=$object -> getPatternFilter($pattern,$approx);
-        }
-        else {
-          $filter = NULL;
-        }
+        $LSsearch = new LSsearch($LSobject,'LSselect');
+        $LSsearch -> setParamsFormPostData();
+        $LSsearch -> setParam('nbObjectsByPage',NB_LSOBJECT_LIST_SELECT);
         
-        if (isset($_REQUEST['LSview_recur'])) {
-          $recur = true;
-        }
-        else {
-          $recur = false;
-        }
-      }
-      
-      if ($recur) {
-        $params['scope'] = 'sub';
-        if (LSsession :: validSubDnLdapServer($_REQUEST['LSselect_topDn'])) {
-          $topDn = $_REQUEST['LSselect_topDn'];
-          $selectedTopDn = $topDn;
-        }
-        else {
-          $topDn = LSsession :: getTopDn();
-          $selectedTopDn = $topDn;
-        }
-      }
-      else {
-        $params['scope'] = 'one';
-        if (LSsession :: validSubDnLdapServer($_REQUEST['LSselect_topDn'])) {
-          $topDn = $object -> config['container_dn'].','.$_REQUEST['LSselect_topDn'];
-          $selectedTopDn = $_REQUEST['LSselect_topDn'];
-        }
-        else {
-          $topDn = $object -> config['container_dn'].','.LSsession :: getTopDn();
-          $selectedTopDn = LSsession :: getTopDn();
-        }
-      }
-      
-      $sort=false;
-      if ((isset($_REQUEST['orderby']))) {
-        $possible_values= array('displayName','subDn');
-        if (in_array($_REQUEST['orderby'],$possible_values)) {
-          $sort=true;
-          if ($orderby==$_REQUEST['orderby']) {
-            $ordersense = ($ordersense=='ASC')?'DESC':'ASC';
-          }
-          else {
-            $ordersense = 'ASC';
-          }
-          $orderby=$_REQUEST['orderby'];
-        }
-      }
-      
-      $GLOBALS['Smarty']->assign('LSobject_list_subDn',$doSubDn);
-      
-      // Sauvegarde en Session
-      $_SESSION['LSsession']['LSsearch'][$LSobject] = array(
-        'filter' => $filter,
-        'topDn' => $topDn,
-        'params' => $params,
-        'pattern' => $pattern,
-        'recur' => $recur,
-        'approx' => $approx,
-        'selectedTopDn' => $selectedTopDn,
-        'orderby' => $orderby,
-        'ordersense' => $ordersense,
-        'doSubDn' => $doSubDn
-      );
-
-      $GLOBALS['Smarty']->assign('LSview_search_pattern',$pattern);
-
-      if ($recur) {
-        $GLOBALS['Smarty']->assign('LSview_search_recur',true);
-      }
-      if ($approx) {
-        $GLOBALS['Smarty']->assign('LSview_search_approx',true);
-      }
-      $GLOBALS['Smarty']->assign('LSselect_topDn',$selectedTopDn);
-      
-      $multiple = (isset($_REQUEST['multiple']))?1:0;
-      
-      // Hidden fields
-      $GLOBALS['Smarty']->assign('LSview_search_hidden_fields',array(
-        'LSobject' => $LSobject,
-        'LSview_search_submit' => 1,
-        'ajax' => 1,
-        'multiple' => $multiple
-      ));
-      
-      // Hash de la recherche déterminer à partir des paramètres de la recherche
-      $hash = mhash (MHASH_MD5, 
-        print_r(
-          array(
-            'LSobject' => $LSobject,
-            'filter' => $filter,
-            'topDn' => $topDn,
-            'params' => $params
+        $multiple = ((isset($_REQUEST['multiple']))?1:0);
+        
+        $searchForm = array (
+          'action' => $_SERVER['PHP_SELF'],
+          'recursive' => (! LSsession :: isSubDnLSobject($LSobject) ),
+          'multiple' => $multiple,
+          'labels' => array (
+            'submit' => _('Search'),
+            'approx' => _('Approximative search'),
+            'recursive' => _('Recursive search'),
+            'level' => _('Level')
           ),
-          true
-        )
-      );
-      
-      if ((LSsession :: cacheSearch()) && isset($_SESSION['LSsession']['LSsearch'][$hash]) && (!isset($_REQUEST['refresh']))) {
-        // On affiche à partir du cache
-        $searchData=$_SESSION['LSsession']['LSsearch'][$hash];
-        LSdebug('From cache');
-      }
-      else {
-        LSdebug('Load');
-        $LSview_actions[] = array (
-          'label' => _('Refresh'),
-          'url' => 'view.php?LSobject='.$LSobject.'&amp;refresh',
-          'action' => 'refresh'
+          'values' => array (
+            'pattern' => $LSsearch->getParam('pattern'),
+            'approx' => $LSsearch->getParam('approx'),
+            'recursive' => $LSsearch->getParam('recursive'),
+            'basedn' => $LSsearch->getParam('basedn')
+          ),
+          'names' => array (
+            'submit' => 'LSsearch_submit'
+          ),
+          'hiddenFields' => array_merge(
+            $LSsearch -> getHiddenFieldForm(),
+            array(
+              'ajax' => 1,
+              'multiple' => $multiple
+            )
+          )
         );
+        $GLOBALS['Smarty']->assign('searchForm',$searchForm);
         
-        $list=$object -> listObjectsName($filter,$topDn,$params);
-        $nbObjects=count($list);
-        $searchData['LSobject_list_nbresult']=$nbObjects;
-
-        $c=0;
+        $LSview_actions=array(
+          array (
+            'label' => 'Refresh',
+            'url' => 'view.php?LSobject='.$LSobject.'&amp;refresh',
+            'action' => 'refresh'
+          )
+        );
+        $GLOBALS['Smarty']->assign('LSview_actions',$LSview_actions);
         
-        foreach($list as $objDn => $objName) {
-          if (LSsession :: canAccess($LSobject,$objDn)) {
+        $LSsearch -> run();
+        $page=(int)$_REQUEST['page'];
+        $page = $LSsearch -> getPage($page);
+        $GLOBALS['Smarty']->assign('page',$page);
+        $GLOBALS['Smarty']->assign('LSsearch',$LSsearch);
 
-            $c++;
-            unset($actions);
-            
-            $subDn_name=false;
-            if ($doSubDn) {
-              $subDn_name = $object -> getSubDnName($objDn);
-            }
-            
-            $objectList[]=array(
-              'dn' => $objDn,
-              'displayName' => $objName,
-              'subDn' => $subDn_name
-            );
-          }
-          else {
-            LSdebug($dn);
-          }
-        }
-        $searchData['objectList']=$objectList;
-        $searchData['LSview_actions'] = $LSview_actions;
-        if (LSsession :: cacheSearch()) {
-          $_SESSION['LSsession']['LSsearch'][$hash]=$searchData;
-        }
-        if ($orderby) {
-          $sort=true;
-        }
-      }
-      $GLOBALS['Smarty']->assign('LSobject_list_nbresult',$searchData['LSobject_list_nbresult']);
-      
-      // Order by if $sort
-      if ($sort) {
-        function sortBy($a,$b) {
-          global $ordersense;
-          global $orderby;
-          
-          if ($ordersense=='ASC') {
-            $sense = -1;
-          }
-          else {
-            $sense = 1;
-          }
-          
-          if ($a == $b) return 0;
-          $sort = array($a[$orderby],$b[$orderby]);
-          sort($sort);
-          if ($sort[0]==$a[$orderby])
-            return 1*$sense;
-          return -1*$sense;
-        }
-        if (!uasort($searchData['objectList'],'sortBy')) {
-          LSdebug('Erreur durant le trie.');
-        }
-        $_SESSION['LSsession']['LSsearch'][$hash]=$searchData;
-      }
-      $GLOBALS['Smarty']->assign('LSobject_list_orderby',$orderby);
-      $GLOBALS['Smarty']->assign('LSobject_list_ordersense',$ordersense);
-      
-      // Pagination
-      if ($searchData['LSobject_list_nbresult'] > NB_LSOBJECT_LIST_SELECT) {
-        if (isset($_REQUEST['page'])) {
-          $searchData['objectList'] = array_slice($searchData['objectList'], ($_REQUEST['page']) * NB_LSOBJECT_LIST_SELECT, NB_LSOBJECT_LIST_SELECT);
-          $GLOBALS['Smarty']->assign('LSobject_list_currentpage',$_REQUEST['page']);
-          
-        }
-        else {
-          $searchData['objectList'] = array_slice($searchData['objectList'], 0, NB_LSOBJECT_LIST_SELECT);
-          $GLOBALS['Smarty']->assign('LSobject_list_currentpage',0);
-        }
-        $searchData['LSobject_list_nbpage']=ceil($searchData['LSobject_list_nbresult'] / NB_LSOBJECT_LIST_SELECT);
-        $GLOBALS['Smarty']->assign('LSobject_list_nbpage',$searchData['LSobject_list_nbpage']);
-      }
-      
-      // Select/Pas Select
-      for($i=0;$i<count($searchData['objectList']);$i++) {
-        if (is_array($_SESSION['LSselect'][$LSobject])) {
-          if(in_array($searchData['objectList'][$i]['dn'],$_SESSION['LSselect'][$LSobject])) {
-            $select = true;
-          }
-          else {
-            $select = false;
-          }
+        $GLOBALS['Smarty']->assign('LSobject_list_objectname',$object -> getLabel());
+        
+        if (isset($_REQUEST['ajax'])) {
+          LSsession :: setTemplate('select_table.tpl');
         }
         else {
-          $select = false;
+          LSsession :: setTemplate('select.tpl');
         }
-        $searchData['objectList'][$i]['select']=$select;
-      }        
-      
-      $GLOBALS['Smarty']->assign('LSview_search',array(
-        'action' => $_SERVER['PHP_SELF'],
-        'submit' => _('Search'),
-        'LSobject' => $LSobject
-      ));
-      
-      $GLOBALS['Smarty']->assign('LSview_search_recur_label',_('Recursive search'));
-      $GLOBALS['Smarty']->assign('LSview_search_approx_label',_('Approximative search'));
-
-      $GLOBALS['Smarty']->assign('LSobject_list_without_result_label',_("This search didn't get any result."));
-      $GLOBALS['Smarty']->assign('LSobject_list',$searchData['objectList']);
-      $GLOBALS['Smarty']->assign('LSobject_list_objecttype',$LSobject);
-      $GLOBALS['Smarty'] -> assign('LSview_actions',$searchData['LSview_actions']);
-      $GLOBALS['Smarty'] -> assign('LSselect_multiple',$multiple);
-      if (isset($_REQUEST['ajax'])) {
-        LSsession :: setTemplate('select_table.tpl');
+        
+        LSsession :: setAjaxDisplay();
       }
       else {
-        LSsession :: setTemplate('select.tpl');
+        LSsession :: addErrorCode('LSsession_05','LSsearch');
       }
-      LSsession :: setAjaxDisplay();
     }
   }
   else {
@@ -323,4 +107,8 @@ else {
 
 // Affichage des retours d'erreurs
 LSsession :: displayTemplate();
+
+if (isset($LSsearch)) {
+  $LSsearch->afterUsingResult();
+}
 ?>
index aa02119..adeb003 100644 (file)
@@ -3,25 +3,25 @@
     {$pagetitle}
   </h1>
 
-  <form action='{$LSview_search.action}' method='post' class='LSview_search LSselect_search btn' id='LSselect_search_form'>
-    {foreach from=$LSview_search_hidden_fields item=field_value key=field_name}
+  <form action='{$searchForm.action}' method='post' class='LSview_search LSselect_search btn' id='LSselect_search_form'>
+    {foreach from=$searchForm.hiddenFields item=field_value key=field_name}
       <input type='hidden' name='{$field_name}' value='{$field_value}' />
     {/foreach}
     
     {if $LSsession_subDn!=""}
-      <label id='LSselect_topDn_label'>{$label_level}
-        <select name='LSselect_topDn' id='LSselect_topDn'>
-          {html_options values=$LSsession_subDn_indexes output=$LSsession_subDn_names selected=$LSselect_topDn}
+      <label id='LSselect_topDn_label'>{$searchForm.labels.level}
+        <select name='subDn' id='LSselect_topDn'>
+          {html_options values=$LSsession_subDn_indexes output=$LSsession_subDn_names selected=$searchForm.values.basedn}
         </select>
       </label>
     {/if}
     <div class='LSselect_search'>
-      <input type='text' name='LSview_pattern' class='LSview_search' value="{$LSview_search_pattern}"/>
-      <input type='submit' value='{$LSview_search.submit}' name='LSview_search_submit' class='LSview_search' />
-      <img src='{$LS_IMAGES_DIR}/refresh.png' alt='{$_refresh}' title='{$_refresh}' id='LSselect_refresh_btn' />
+      <input type='text' name='pattern' class='LSview_search' value="{$searchForm.values.pattern}"/>
+      <input type='submit' value='{$searchForm.labels.submit}' name='{$searchForm.names.submit}' class='LSview_search' />
+      <img src='{$LS_IMAGES_DIR}/refresh.png' alt='{$searchForm.labels.refresh}' title='{$searchForm.labels.refresh}' id='LSselect_refresh_btn' />
       <p id='LSview_search_param'>
-        <label class='LSview_search'>{$LSview_search_approx_label} : <input type='checkbox' name='LSview_approx' class='LSview_search' {if $LSview_search_approx!=''}checked="true"{/if} /></label>
-        {if $LSsession_subDn!=""}<label class='LSview_search'>{$LSview_search_recur_label} : <input type='checkbox' name='LSview_recur' class='LSview_search' {if $LSview_search_recur!=''}checked="true"{/if}/></label>{/if}
+        <label class='LSview_search'>{$searchForm.labels.approx} : <input type='checkbox' name='approx' class='LSview_search' {if $searchForm.values.approx!=''}checked="true"{/if} /></label>
+        {if $searchForm.recursive}<label class='LSview_search'>{$searchForm.labels.recursive} : <input type='checkbox' name='recursive' class='LSview_search' {if $searchForm.values.recursive!=''}checked="true"{/if}/></label>{/if}
       </p>
     </div>
   </form>
@@ -30,6 +30,6 @@
   </div>
 </div>
 <script type='text/javascript'>
-LSselect_multiple = {$LSselect_multiple};
+LSselect_multiple = {$searchForm.multiple};
 varLSselect = new LSselect();
 </script>
index 5b2a4f8..1e529d7 100644 (file)
@@ -1,32 +1,78 @@
-<table class='LSobject-list' id='LSselect-object' caption='{$LSobject_list_objecttype}'>
+<table class='LSobject-list' id='LSselect-object' caption='{$LSsearch->LSobject}'>
   <tr class='LSobject-list'>
     <th class='LSobject-list LSobject-select-check'></th>
-    <th class='LSobject-list sortBy_displayName'>{if $LSobject_list_orderby == 'displayName'}<strong>{$LSobject_list_objectname}</strong><img src='{$LS_IMAGES_DIR}/{$LSobject_list_ordersense}.png' class='LSobject-list-ordersense' alt='{$LSobject_list_ordersense}'/>{else}{$LSobject_list_objectname}{/if}</th>
-    {if $LSobject_list_subDn}<th class='LSobject-list LSobject-list-subdn sortBy_subDn'>{if $LSobject_list_orderby == 'subDn'}<strong>{$label_level}</strong><img src='{$LS_IMAGES_DIR}/{$LSobject_list_ordersense}.png' class='LSobject-list-ordersense' alt='{$LSobject_list_ordersense}'/>{else}{$label_level}{/if}</th>{/if}
+    <th class='LSobject-list{if $LSsearch->sort} sortBy_displayName{/if}'>
+      {if $LSsearch->sortBy == 'displayName'}
+        <strong>{$LSsearch->label_objectName}</strong>
+        <img src='{$LS_IMAGES_DIR}/{$LSsearch->sortDirection}.png' class='LSobject-list-ordersense' alt='{$LSsearch->sortDirection}'/>
+      {else}
+        {$LSsearch->label_objectName}
+      {/if}
+    </th>
+    {if $LSsearch->displaySubDn}
+      <th class='LSobject-list LSobject-list-subdn{if $LSsearch->sort} sortBy_subDn{/if}'>
+        {if $LSsearch->sort}
+          {if $LSsearch->sortBy == 'subDn'}
+            <strong>{$LSsearch->label_level}</strong>
+            <img src='{$LS_IMAGES_DIR}/{$LSsearch->sortDirection}.png' class='LSobject-list-ordersense' alt='{$LSsearch->sortDirection}'/>
+          {else}
+            {$LSsearch->label_level}
+          {/if}
+        {else}
+          {$LSsearch->label_level}
+        {/if}
+      </th>
+    {/if}
   </tr>
-{assign var='bis' value=false}
-{foreach from=$LSobject_list item=object}
-    <tr class='LSobject-list{if $bis} LSobject-list-bis{assign var='bis' value=false}{else}{assign var='bis' value=true}{/if}'>
-        <td class='LSobject-list LSobject-select-check'><input type='{if $LSselect_multiple}checkbox{else}radio{/if}' name='LSobjects_selected[]' value='{$object.dn}' {if $object.select}checked="true"{/if} class='LSobject-select' /></td>
-        <td class='LSobject-list LSobject-select-names'>{$object.displayName}</td>
-        {if $LSobject_list_subDn}<td class='LSobject-list LSobject-select-level'>{$object.subDn}</td>{/if}
+{foreach from=$page.list item=object}
+    <tr class='{cycle values="LSobject-list,LSobject-list LSobject-list-bis"}'>
+        <td class='LSobject-list LSobject-select-check'><input type='{if $searchForm.multiple}checkbox{else}radio{/if}' name='LSobjects_selected[]' value='{$object->dn}' {if $object->LSselect}checked="true"{/if} class='LSobject-select' /></td>
+        <td class='LSobject-list LSobject-select-names'>{$object->displayName}</td>
+        {if $LSsearch->displaySubDn}
+          <td class='LSobject-list LSobject-select-level'>{$object->subDn}</td>
+        {/if}
     </tr>
 {foreachelse}
     <tr class='LSobject-list'>
-      <td colspan='3' class='LSobject-list-without-result'>{$LSobject_list_without_result_label}</td>
+      <td colspan='3' class='LSobject-list-without-result'>{$LSsearch->label_no_result}</td>
     </tr> 
 {/foreach}
 </table>
-{if $LSobject_list_nbpage}
+
+
+{if $page.nbPages > 1}
   <p class='LSobject-list-page'>
-  {section name=listpage loop=$LSobject_list_nbpage step=1}
-    {if $LSobject_list_currentpage == $smarty.section.listpage.index}
-      <strong class='LSobject-list-page'>{$LSobject_list_currentpage+1}</strong> 
+  {if $page.nbPages > 10}
+    {php}$this->assign('range', range(0,10));{/php}
+    {if $page.nb > 5}
+      {if $page.nb > $page.nbPages-6}
+        {assign var=start value=$page.nbPages-12}
+       {else}
+        {assign var=start value=$page.nb-6}
+      {/if}
     {else}
-      <a href='select.php?LSobject={$LSobject_list_objecttype}&amp;multiple={$LSselect_multiple}&amp;page={$smarty.section.listpage.index}&amp;{$LSobject_list_filter}'  class='LSobject-list-page'>{$smarty.section.listpage.index+1}</a> 
+      {assign var=start value=0}
     {/if}
-  {/section}
+    <a href='select.php?LSobject={$LSsearch->LSobject}&amp;page=0&amp;multiple={$searchForm.multiple}' class='LSobject-list-page'><</a> 
+    {foreach from=$range item=i}
+      {if $page.nb==$start+$i}
+        <strong class='LSobject-list-page'>{$page.nb+1}</strong> 
+      {else}
+        <a href='select.php?LSobject={$LSsearch->LSobject}&amp;page={$i+$start}&amp;multiple={$searchForm.multiple}'  class='LSobject-list-page'>{$i+$start+1}</a> 
+      {/if}
+    {/foreach}
+    <a href='select.php?LSobject={$LSsearch->LSobject}&amp;page={$page.nbPages-1}&amp;multiple={$searchForm.multiple}' class='LSobject-list-page'>></a> 
+  {else}
+    {section name=listpage loop=$page.nbPages step=1}
+      {if $page.nb == $smarty.section.listpage.index}
+        <strong class='LSobject-list-page'>{$page.nb+1}</strong> 
+      {else}
+        <a href='select.php?LSobject={$LSsearch->LSobject}&amp;page={$smarty.section.listpage.index}&amp;multiple={$searchForm.multiple}'  class='LSobject-list-page'>{$smarty.section.listpage.index+1}</a> 
+      {/if}
+    {/section}
+  {/if}
   </p>
 {/if}
-<div id='LSdebug_txt'>{$LSdebug_txt}</div>
-<div id='LSerror_txt'>{$LSerror_txt}</div>
+
+<div id='LSdebug_txt_ajax' style='display: none'>{$LSdebug_txt}</div>
+<div id='LSerror_txt_ajax' style='display: none'>{$LSerror_txt}</div>
diff --git a/trunk/templates/default/viewList.tpl b/trunk/templates/default/viewList.tpl
deleted file mode 100644 (file)
index 3b4be1e..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-{include file='top.tpl'}
-      <form action='{$LSview_search.action}' method='post' class='LSview_search'>
-        {foreach from=$LSview_search_hidden_fields item=value key=name}
-          <input type='hidden' name='{$name}' value='{$value}' />
-        {/foreach}
-        <input type='text' name='LSview_pattern' class='LSview_search' value="{$LSview_search_pattern}"/>
-        <input type='submit' value='{$LSview_search.submit}' name='LSview_search_submit' class='LSview_search' />
-        <p id='LSview_search_param'>
-          <label class='LSview_search'>{$LSview_search_approx_label} : <input type='checkbox' name='LSview_approx' class='LSview_search' {if $LSview_search_approx!=''}checked="true"{/if} /></label>
-          {if $LSobject_list_subDn}<label class='LSview_search'>{$LSview_search_recur_label} : <input type='checkbox' name='LSview_recur' class='LSview_search' {if $LSview_search_recur!=''}checked="true"{/if}/></label>{/if}
-        </p>
-      </form>
-    <h1>
-      {$pagetitle}
-    </h1>
-    
-    {if $LSview_actions != ''}
-    <ul class='LSview-actions'>
-      {foreach from=$LSview_actions item=item}
-        {if is_array($item)}
-          <li class='LSview-actions'><a href='{$item.url}' class='LSview-actions'><img src='{$LS_IMAGES_DIR}/{$item.action}.png' alt='{php}tr('label');{/php}' title='{php}tr('label');{/php}' /> {php}tr('item','label');{/php}</a></li>
-        {/if}
-      {/foreach}
-    </ul>
-    {/if}
-
-      <table class='LSobject-list'>
-        <tr class='LSobject-list'>
-          <th class='LSobject-list'><a href='view.php?LSobject={$LSobject_list_objecttype}&amp;orderby=displayName'>{if $LSobject_list_orderby == 'displayName'}<strong>{$LSobject_list_objectname}</strong><img src='{$LS_IMAGES_DIR}/{$LSobject_list_ordersense}.png' class='LSobject-list-ordersense' alt='{$LSobject_list_ordersense}'/>{else}{$LSobject_list_objectname}{/if}</a></th>
-          {if $LSobject_list_subDn}<th class='LSobject-list LSobject-list-subdn'><a href='view.php?LSobject={$LSobject_list_objecttype}&amp;orderby=subDn'>{if $LSobject_list_orderby == 'subDn'}<strong>{$label_level}</strong><img src='{$LS_IMAGES_DIR}/{$LSobject_list_ordersense}.png' class='LSobject-list-ordersense' alt='{$LSobject_list_ordersense}'/>{else}{$label_level}{/if}</a></th>{/if}
-          <th class='LSobject-list'>{$_Actions}</th>
-        </tr>
-        {assign var='bis' value=false}
-        {foreach from=$LSobject_list item=object}
-        <tr class='LSobject-list{if $bis} LSobject-list-bis{assign var='bis' value=false}{else}{assign var='bis' value=true}{/if}'>
-            <td class='LSobject-list LSobject-list-names'><a href='view.php?LSobject={$LSobject_list_objecttype}&amp;dn={$object.dn}'  class='LSobject-list'>{$object.displayName}</a> </td>
-            {if $LSobject_list_subDn}<td class='LSobject-list'>{$object.subDn}</td>{/if}
-            <td class='LSobject-list LSobject-list-actions'>
-            {if $object.actions!=''}
-            {foreach from=$object.actions item=item}
-              <a href='{$item.url}'  class='LSobject-list-actions'><img src='{$LS_IMAGES_DIR}/{$item.action}.png' alt='{$item.label}' title='{$item.label}'/></a>
-            {/foreach}
-            {/if}
-            </td>
-        </tr>
-        {foreachelse}
-          <tr class='LSobject-list'>
-            <td colspan='3' class='LSobject-list-without-result'>{$LSobject_list_without_result_label}</td>
-          </tr>  
-        {/foreach}
-    </table>
-    <span id='LSobject_list_nbresult'>{$LSobject_list_nbresult} {$pagetitle}</span>
-    {if $LSobject_list_nbpage}
-      <p class='LSobject-list-page'>
-      {section name=listpage loop=$LSobject_list_nbpage step=1}
-        {if $LSobject_list_currentpage == $smarty.section.listpage.index}
-          <strong class='LSobject-list-page'>{$LSobject_list_currentpage+1}</strong> 
-        {else}
-          <a href='view.php?LSobject={$LSobject_list_objecttype}&amp;page={$smarty.section.listpage.index}&amp;{$LSobject_list_filter}'  class='LSobject-list-page'>{$smarty.section.listpage.index+1}</a> 
-        {/if}
-      {/section}
-      </p>
-    {/if}
-{include file='bottom.tpl'}
diff --git a/trunk/templates/default/viewSearch.tpl b/trunk/templates/default/viewSearch.tpl
new file mode 100644 (file)
index 0000000..467b3df
--- /dev/null
@@ -0,0 +1,115 @@
+{include file='top.tpl'}
+<form action='{$searchForm.action}' method='post' class='LSview_search'>
+  
+  {foreach from=$searchForm.hiddenFields item=value key=name}
+    <input type='hidden' name='{$name}' value='{$value}' />
+  {/foreach}
+  
+  <input type='text' name='pattern' class='LSview_search' value="{$searchForm.values.pattern}"/>
+  <input type='submit' value='{$searchForm.labels.submit}' name='{$searchForm.names.submit}' class='LSview_search' />
+  <p id='LSview_search_param'>
+    <label class='LSview_search'>{$searchForm.labels.approx} : <input type='checkbox' name='approx' class='LSview_search' {if $searchForm.values.approx!=''}checked="true"{/if} /></label>
+    {if $searchForm.recursive}<label class='LSview_search'>{$searchForm.labels.recursive} : <input type='checkbox' name='recursive' class='LSview_search' {if $searchForm.values.recursive!=''}checked="true"{/if}/></label>{/if}
+  </p>
+</form>
+
+<h1>
+  {$pagetitle}
+</h1>
+
+{if $LSview_actions != ''}
+<ul class='LSview-actions'>
+  {foreach from=$LSview_actions item=item}
+    {if is_array($item)}
+      <li class='LSview-actions'><a href='{$item.url}' class='LSview-actions'><img src='{$LS_IMAGES_DIR}/{$item.action}.png' alt='{php}tr('label');{/php}' title='{php}tr('label');{/php}' /> {php}tr('item','label');{/php}</a></li>
+    {/if}
+  {/foreach}
+</ul>
+{/if}
+
+<table class='LSobject-list'>
+    <tr class='LSobject-list'>
+      <th class='LSobject-list'>
+        {if $LSsearch->sort}
+        <a href='view.php?LSobject={$LSsearch->LSobject}&amp;sortBy=displayName&amp;nocache={$smarty.now}'>
+          {if $LSsearch->sortBy == 'displayName'}
+            <strong>{$LSsearch->label_objectName}</strong>
+            <img src='{$LS_IMAGES_DIR}/{$LSsearch->sortDirection}.png' class='LSobject-list-ordersense' alt='{$LSsearch->sortDirection}'/>
+          {else}
+            {$LSsearch->label_objectName}
+          {/if}
+        </a>
+        {else}
+          {$LSsearch->label_objectName}
+        {/if}
+      </th>
+      {if $LSsearch->displaySubDn}
+        <th class='LSobject-list LSobject-list-subdn'>
+        {if $LSsearch->sort}
+          <a href='view.php?LSobject={$LSsearch->LSobject}&amp;sortBy=subDn&amp;nocache={$smarty.now}'>
+          {if $LSsearch->sortBy == 'subDn'}
+            <strong>{$LSsearch->label_level}</strong>
+            <img src='{$LS_IMAGES_DIR}/{$LSsearch->sortDirection}.png' class='LSobject-list-ordersense' alt='{$LSsearch->sortDirection}'/>
+          {else}
+            {$LSsearch->label_level}
+          {/if}
+          </a>
+        {else}
+          {$LSsearch->label_level}
+        {/if}
+        </th>
+      {/if}
+      <th class='LSobject-list'>{$LSsearch->label_actions}</th>
+    </tr>
+    {foreach from=$page.list item=object}
+    <tr class='{cycle values="LSobject-list,LSobject-list LSobject-list-bis"}'>
+        <td class='LSobject-list LSobject-list-names'><a href='view.php?LSobject={$LSsearch->LSobject}&amp;dn={$object->dn}'  class='LSobject-list'>{$object->displayName}</a> </td>
+        {if $LSsearch->displaySubDn}<td class='LSobject-list'>{$object->subDn}</td>{/if}
+        <td class='LSobject-list LSobject-list-actions'>
+        {foreach from=$object->actions item=item}
+          <a href='{$item.url}'  class='LSobject-list-actions'><img src='{$LS_IMAGES_DIR}/{$item.action}.png' alt='{$item.label}' title='{$item.label}'/></a>
+        {/foreach}
+        </td>
+    </tr>
+    {foreachelse}
+      <tr class='LSobject-list'>
+        <td colspan='3' class='LSobject-list-without-result'>{$LSsearch->label_no_result}</td>
+      </tr>   
+    {/foreach}
+</table>
+<span id='LSobject_list_nbresult'>{$LSsearch->label_total}</span>
+{if $page.nbPages > 1}
+  <p class='LSobject-list-page'>
+    
+  {if $page.nbPages > 10}
+    {php}$this->assign('range', range(0,10));{/php}
+    {if $page.nb > 5}
+      {if $page.nb > $page.nbPages-6}
+        {assign var=start value=$page.nbPages-12}
+       {else}
+        {assign var=start value=$page.nb-6}
+      {/if}
+    {else}
+      {assign var=start value=0}
+    {/if}
+    <a href='view.php?LSobject={$LSsearch->LSobject}&amp;page=0' class='LSobject-list-page'><</a> 
+    {foreach from=$range item=i}
+      {if $page.nb==$start+$i}
+        <strong class='LSobject-list-page'>{$page.nb+1}</strong> 
+      {else}
+        <a href='view.php?LSobject={$LSsearch->LSobject}&amp;page={$i+$start}'  class='LSobject-list-page'>{$i+$start+1}</a> 
+      {/if}
+    {/foreach}
+    <a href='view.php?LSobject={$LSsearch->LSobject}&amp;page={$page.nbPages-1}' class='LSobject-list-page'>></a> 
+  {else}
+    {section name=listpage loop=$page.nbPages step=1}
+      {if $page.nb == $smarty.section.listpage.index}
+        <strong class='LSobject-list-page'>{$page.nb+1}</strong> 
+      {else}
+        <a href='view.php?LSobject={$LSsearch->LSobject}&amp;page={$smarty.section.listpage.index}'  class='LSobject-list-page'>{$smarty.section.listpage.index+1}</a> 
+      {/if}
+    {/section}
+  {/if}
+  </p>
+{/if}
+{include file='bottom.tpl'}
index cc9a5ce..13dd0ff 100644 (file)
@@ -88,306 +88,67 @@ if(LSsession :: startLSsession()) {
           }
         }
         // Affichage d'une liste d'un type d'objet
-        else {
-          $objectList=array();
+        elseif (LSsession :: loadLSclass('LSsearch')) {
           $object = new $LSobject();
-          
           $GLOBALS['Smarty']->assign('pagetitle',$object -> getLabel());
-          $GLOBALS['Smarty']->assign('LSobject_list_objectname',$object -> getLabel());
           
-          if (isset($_SESSION['LSsession']['LSsearch'][$LSobject])) {
-            $filter = $_SESSION['LSsession']['LSsearch'][$LSobject]['filter'];
-            $params = $_SESSION['LSsession']['LSsearch'][$LSobject]['params'];
-            $pattern = $_SESSION['LSsession']['LSsearch'][$LSobject]['pattern'];
-            $recur = $_SESSION['LSsession']['LSsearch'][$LSobject]['recur'];
-            if ($recur) {
-              $topDn = LSsession :: getTopDn();
-            }
-            else {
-              $topDn = $object -> config['container_dn'].','.LSsession :: getTopDn();
-            }
-            $approx = $_SESSION['LSsession']['LSsearch'][$LSobject]['approx'];
-            $orderby = $_SESSION['LSsession']['LSsearch'][$LSobject]['orderby'];
-            $ordersense = $_SESSION['LSsession']['LSsearch'][$LSobject]['ordersense'];
-            $doSubDn = $_SESSION['LSsession']['LSsearch'][$LSobject]['doSubDn'];
-          }
-          else {
-            $filter = NULL;
-            $topDn = $object -> config['container_dn'].','.LSsession :: getTopDn();
-            $params = array('scope' => 'one');
-            $pattern = false;
-            $recur = LSconfig :: get("LSobjects.$LSobject.LSsearch.recursive");
-            $approx = false;
-            $orderby = false;
-            $_REQUEST['orderby']=LSconfig :: get("LSobjects.$LSobject.orderby");
-            $ordersense = 'ASC';
-            $subDnLdapServer = LSsession :: getSubDnLdapServer();
-            $doSubDn = (($subDnLdapServer)&&(!LSsession :: isSubDnLSobject($LSobject)));
-          }
+          $LSsearch = new LSsearch($LSobject,'LSview');
+          $LSsearch -> setParamsFormPostData();
           
-          if (isset($_REQUEST['LSview_search_submit'])) {
-            if (isset($_REQUEST['LSview_pattern']) && ($_REQUEST['LSview_pattern']!=$pattern)) {
-              $pattern = $_REQUEST['LSview_pattern'];
-            }
-
-            $approx = (isset($_REQUEST['LSview_approx']));
-            
-            if ($pattern && $pattern!='') {
-              $filter=$object -> getPatternFilter($pattern,$approx);
-            }
-            else {
-              $filter = NULL;
-            }
-            
-            if (isset($_REQUEST['LSview_recur'])) {
-              $recur = true;
-            }
-            else {
-              $recur = false;
-            }
-          }
-          
-          if ($recur) {
-            $params['scope'] = 'sub';
-            $topDn = LSsession :: getTopDn();
-          }
-          else {
-            $params['scope'] = 'one';
-            $topDn = $object -> config['container_dn'].','.LSsession :: getTopDn();
-          }
-          
-          $sort=false;
-          if ((isset($_REQUEST['orderby']))) {
-            $possible_values= array('displayName','subDn');
-            if (in_array($_REQUEST['orderby'],$possible_values)) {
-              $sort=true;
-              if ($orderby==$_REQUEST['orderby']) {
-                $ordersense = ($ordersense=='ASC')?'DESC':'ASC';
-              }
-              else {
-                $ordersense = 'ASC';
-              }
-              $orderby=$_REQUEST['orderby'];
-            }
-          }
-          
-          $GLOBALS['Smarty']->assign('LSobject_list_subDn',$doSubDn);
-          
-          // Sauvegarde en Session
-          $_SESSION['LSsession']['LSsearch'][$LSobject] = array(
-            'filter' => $filter,
-            'topDn' => $topDn,
-            'params' => $params,
-            'pattern' => $pattern,
-            'recur' => $recur,
-            'approx' => $approx,
-            'orderby' => $orderby,
-            'ordersense' => $ordersense,
-            'doSubDn' => $doSubDn
-          );
-          
-          $GLOBALS['Smarty']->assign('LSview_search_pattern',$pattern);
-
-          if ($recur) {
-            $GLOBALS['Smarty']->assign('LSview_search_recur',true);
-          }
-          if ($approx) {
-            $GLOBALS['Smarty']->assign('LSview_search_approx',true);
-          }
-          
-          // Hidden fields
-          $GLOBALS['Smarty']->assign('LSview_search_hidden_fields',array(
-            'LSobject' => $LSobject,
-            'LSview_search_submit' => 1
-          ));
-          
-          // Hash de la recherche déterminer à partir des paramètres de la recherche
-          $hash = mhash (MHASH_MD5, 
-            print_r(
-              array(
-                'LSobject' => $LSobject,
-                'filter' => $filter,
-                'topDn' => $topDn,
-                'params' => $params
-              ),
-              true
-            )
+          $searchForm = array (
+            'action' => $_SERVER['PHP_SELF'],
+            'recursive' => (! LSsession :: isSubDnLSobject($LSobject) ),
+            'labels' => array (
+              'submit' => _('Search'),
+              'approx' => _('Approximative search'),
+              'recursive' => _('Recursive search')
+            ),
+            'values' => array (
+              'pattern' => $LSsearch->getParam('pattern'),
+              'approx' => $LSsearch->getParam('approx'),
+              'recursive' => $LSsearch->getParam('recursive')
+            ),
+            'names' => array (
+              'submit' => 'LSsearch_submit'
+            ),
+            'hiddenFields' => $LSsearch -> getHiddenFieldForm()
           );
-          
-          if ((LSsession :: cacheSearch()) && isset($_SESSION['LSsession']['LSsearch'][$hash]) && (!isset($_REQUEST['refresh']))) {
-            // On affiche à partir du cache
-            $searchData=$_SESSION['LSsession']['LSsearch'][$hash];
-            LSdebug('Find : From cache');
-            if(!isset($searchData['LSview_actions']['create'])) {
-              LSdebug('Recherche : Check Create()');
-              if (LSsession :: canCreate($LSobject)) {
-                $searchData['LSview_actions']['create'] = array (
-                  'label' => 'New',
-                  'url' => 'create.php?LSobject='.$LSobject,
-                  'action' => 'create'
-                );
-              }
-              else {
-                $searchData['LSview_actions']['create'] = false;
-              }
-              $_SESSION['LSsession']['LSsearch'][$hash]=$searchData;
-            }
-          }
-          else { // Load
-            LSdebug('Find : Load');
-            if (LSsession :: canCreate($LSobject)) {
-              $LSview_actions['create'] = array (
-                'label' => 'New',
-                'url' => 'create.php?LSobject='.$LSobject,
-                'action' => 'create'
-              );
-              $canCopy=true;
-            }
-            else {
-              $LSview_actions['create'] = false;
-            }
-            $LSview_actions['refresh'] = array (
-              'label' => 'Refresh',
-              'url' => 'view.php?LSobject='.$LSobject.'&amp;refresh',
-              'action' => 'refresh'
+          $GLOBALS['Smarty']->assign('searchForm',$searchForm);
+          
+          $LSview_actions=array();
+          if(LSsession :: canCreate($LSobject)) {
+            $LSview_actions['create'] = array (
+              'label' => 'New',
+              'url' => 'create.php?LSobject='.$LSobject,
+              'action' => 'create'
             );
-            
-            $list=$object -> listObjectsName($filter,$topDn,$params);
-
-            $nbObjects=0;
-            foreach($list as $objDn => $objName) {
-              if (LSsession :: canAccess($LSobject,$objDn)) {
-                $subDn_name=false;
-                if ($doSubDn) {
-                  $subDn_name = $object -> getSubDnName($objDn);
-                }
-                $nbObjects++;
-
-                
-                $objectList[]=array(
-                  'dn' => $objDn,
-                  'displayName' => $objName,
-                  'subDn' => $subDn_name
-                );
-              }
-            }
-            
-            $searchData['LSobject_list_nbresult']=$nbObjects;
-            
-            $searchData['objectList']=$objectList;
-            $searchData['LSview_actions'] = $LSview_actions;
-            if ($orderby) {
-              $sort=true;
-            }
-          } // Fin Load
-          
-          if ((!isset($searchData['objectList'][0]['actions']))&&(!empty($searchData['objectList']))) {
-            LSdebug('Load actions');
-            for($i=0;$i<$searchData['LSobject_list_nbresult'];$i++) {
-              $actions=array();
-              
-              $actions[] = array(
-                'label' => _('View'),
-                'url' =>'view.php?LSobject='.$LSobject.'&amp;dn='.$searchData['objectList'][$i]['dn'],
-                'action' => 'view'
-              );
-              
-              if (LSsession :: canEdit($LSobject,$searchData['objectList'][$i]['dn'])) {
-                $actions[]=array(
-                  'label' => _('Modify'),
-                  'url' => 'modify.php?LSobject='.$LSobject.'&amp;dn='.$searchData['objectList'][$i]['dn'],
-                  'action' => 'modify'
-                );
-              }
-              
-              if ($canCopy) {
-                $actions[] = array(
-                  'label' => _('Copy'),
-                  'url' =>'create.php?LSobject='.$LSobject.'&amp;load='.$searchData['objectList'][$i]['dn'],
-                  'action' => 'copy'
-                );
-              }
-              
-              if (LSsession :: canRemove($LSobject,$searchData['objectList'][$i]['dn'])) {
-                $actions[] = array (
-                  'label' => _('Delete'),
-                  'url' => 'remove.php?LSobject='.$LSobject.'&amp;dn='.$searchData['objectList'][$i]['dn'],
-                  'action' => 'delete'
-                );
-              }
-              $searchData['objectList'][$i]['actions']=$actions;
-            }
           }
-          
-          $GLOBALS['Smarty']->assign('LSobject_list_nbresult',$searchData['LSobject_list_nbresult']);
-          
-          // Order by if $sort
-          if ($sort) {
-            function sortBy($a,$b) {
-              global $ordersense;
-              global $orderby;
-              
-              if ($ordersense=='ASC') {
-                $sense = -1;
-              }
-              else {
-                $sense = 1;
-              }
-              
-              if ($a == $b) return 0;
-              $sort = array($a[$orderby],$b[$orderby]);
-              sort($sort);
-              if ($sort[0]==$a[$orderby])
-                return 1*$sense;
-              return -1*$sense;
-            }
-            if (!uasort($searchData['objectList'],'sortBy')) {
-              LSdebug('Error while sorting.');
-            }
-          } // Fin Order by
-          $GLOBALS['Smarty']->assign('LSobject_list_orderby',$orderby);
-          $GLOBALS['Smarty']->assign('LSobject_list_ordersense',$ordersense);
-          
-          // Mise en cache
-          if (LSsession :: cacheSearch()) {
-            $_SESSION['LSsession']['LSsearch'][$hash]=$searchData;
-          }
-          
-          // Pagination
-          if ($searchData['LSobject_list_nbresult'] > NB_LSOBJECT_LIST) {
-            if (isset($_REQUEST['page'])) {
-              $searchData['objectList'] = array_slice($searchData['objectList'], ($_REQUEST['page']) * NB_LSOBJECT_LIST, NB_LSOBJECT_LIST);
-              $GLOBALS['Smarty']->assign('LSobject_list_currentpage',$_REQUEST['page']);
-              
-            }
-            else {
-              $searchData['objectList'] = array_slice($searchData['objectList'], 0, NB_LSOBJECT_LIST);
-              $GLOBALS['Smarty']->assign('LSobject_list_currentpage',0);
-            }
-            $searchData['LSobject_list_nbpage']=ceil($searchData['LSobject_list_nbresult'] / NB_LSOBJECT_LIST);
-            $GLOBALS['Smarty']->assign('LSobject_list_nbpage',$searchData['LSobject_list_nbpage']);
-          } // Fin Pagination
+          $LSview_actions['refresh'] = array (
+            'label' => 'Refresh',
+            'url' => 'view.php?LSobject='.$LSobject.'&amp;refresh',
+            'action' => 'refresh'
+          );
+          /*$LSview_actions['purge'] = array (
+            'label' => 'Purge the cache',
+            'url' => 'view.php?LSobject='.$LSobject.'&amp;LSsearchPurgeSession',
+            'action' => 'delete'
+          );*/
+          $GLOBALS['Smarty']->assign('LSview_actions',$LSview_actions);
+          
+          $LSsearch -> run();
+          $page=(int)$_REQUEST['page'];
+          $page = $LSsearch -> getPage($page);
+          $GLOBALS['Smarty']->assign('page',$page);
+          $GLOBALS['Smarty']->assign('LSsearch',$LSsearch);
           
           if (LSsession :: loadLSclass('LSform')) {
             LSform :: loadDependenciesDisplayView();
           }
           
-          $GLOBALS['Smarty']->assign('LSview_search',array(
-            'action' => $_SERVER['PHP_SELF'],
-            'submit' => _('Search'),
-            'LSobject' => $LSobject
-          ));
-          
-          $GLOBALS['Smarty']->assign('LSview_search_recur_label',_('Recursive search'));
-          $GLOBALS['Smarty']->assign('LSview_search_approx_label',_('Approximative search'));
-
-          $GLOBALS['Smarty']->assign('LSobject_list_without_result_label',_("This search didn't get any result."));
-          $GLOBALS['Smarty']->assign('_Actions',_('Actions'));
-          $GLOBALS['Smarty']->assign('_Modifier',_('Modify'));
-          $GLOBALS['Smarty']->assign('LSobject_list',$searchData['objectList']);
-          $GLOBALS['Smarty']->assign('LSobject_list_objecttype',$LSobject);
-          $GLOBALS['Smarty'] -> assign('LSview_actions',$searchData['LSview_actions']);
-          LSsession :: setTemplate('viewList.tpl');
+          LSsession :: setTemplate('viewSearch.tpl');
+        }
+        else {
+          LSsession :: addErrorCode('LSsession_05','LSsearch');
         }
       }
     }
@@ -402,7 +163,11 @@ if(LSsession :: startLSsession()) {
 else {
   LSsession :: setTemplate('login.tpl');
 }
-
 // Affichage des retours d'erreurs
 LSsession :: displayTemplate();
+
+if (isset($LSsearch)) {
+  $LSsearch->afterUsingResult();
+}
+
 ?>